]> git.neil.brown.name Git - history.git/commitdiff
Linux 2.2.13pre17 2.2.13pre17
authorAlan Cox <alan@lxorguk.ukuu.org.uk>
Fri, 23 Nov 2007 20:20:02 +0000 (15:20 -0500)
committerAlan Cox <alan@lxorguk.ukuu.org.uk>
Fri, 23 Nov 2007 20:20:02 +0000 (15:20 -0500)
o Fix real time signal queue corruption (Dave Miller)
o Work around a thinkpad APM bug (Paul Martin)
o Adaptec AIC7xxx update (Doug Ledford)
o Soundpro doc updates (Ionut Badescu)
o Small poll cleanup (Andrea Arcangeli)

12 files changed:
Documentation/Configure.help
Documentation/sound/SoundPro [new file with mode: 0644]
Makefile
arch/i386/kernel/apm.c
arch/sparc64/config.in
arch/sparc64/defconfig
drivers/scsi/README.aic7xxx
drivers/scsi/aic7xxx.c
drivers/sound/Config.in
include/linux/apm_bios.h
include/linux/poll.h
kernel/signal.c

index 67b37841ff9f0fcd3eca3a401e9f340aed33b61d..b9173039238d48e17d4ff746154258ac62f5f25d 100644 (file)
@@ -9536,6 +9536,11 @@ CONFIG_SOUND_MSS
   have their own MSS support and saying Y to this option will cause a
   conflict.
 
+SoundPro chip support
+CONFIG_SOUND_SPRO
+  If you have a (usually Taiwanese) motherboard with the SoundPro chip
+  on board, say Y here. Otherwise say N.
+
 Ensoniq Soundscape support
 CONFIG_SOUND_SSCAPE
   Answer Y if you have a sound card based on the Ensoniq SoundScape
diff --git a/Documentation/sound/SoundPro b/Documentation/sound/SoundPro
new file mode 100644 (file)
index 0000000..6e8c69e
--- /dev/null
@@ -0,0 +1,103 @@
+Documentation for the SoundPro CMI8330 extensions in the WSS driver (ad1848.o)
+------------------------------------------------------------------------------
+
+Ion Badulescu, ionut@cs.columbia.edu
+February 24, 1999
+
+(derived from the OPL3-SA2 documentation by Scott Murray)
+
+The SoundPro CMI8330 (ISA) is a chip usually found on some Taiwanese
+motherboards.  The official name in the documentation is CMI8330, SoundPro
+is the nickname and the big inscription on the chip itself.
+
+The chip emulates a WSS as well as a SB16, but it has certain differences
+in the mixer section which require separate support. It also emulates an
+MPU401 and an OPL3 synthesizer, so you probably want to enable support
+for these, too.
+
+The chip identifies itself as an AD1848, but its mixer is significantly
+more advanced than the original AD1848 one. If your system works with
+either WSS or SB16 and you are having problems with some mixer controls
+(no CD audio, no line-in, etc), you might want to give this driver a try.
+Detection should work, but it hasn't been widely tested, so it might still
+mis-identify the chip. You can still force soundpro=1 in the modprobe
+parameters for ad1848. Please let me know if it happens to you, so I can
+adjust the detection routine.
+
+The chip is capable of doing full-duplex, but since the driver sees it as an
+AD1848, it cannot take advantage of this.  Moreover, the full-duplex mode is
+not achievable through the WSS interface, b/c it needs a dma16 line which is
+assigned only to the SB16 subdevice (with isapnp). Windows documentation
+says the user must use WSS Playback and SB16 Recording for full-duplex, so
+it might be possible to do the same thing under Linux. You can try loading
+up both ad1848 and sb then use one for playback and the other for
+recording. I don't know if this works, b/c I haven't tested it. Anyway, if
+you try it, be very careful: the SB16 mixer *mostly* works, but certain
+settings can have unexpected effects. Use the WSS mixer for best results.
+
+There is also a PCI SoundPro chip. I have not seen this chip, so I have
+no idea if the driver will work with it. I suspect it won't.
+
+As with PnP cards, some configuration is required.  There are two ways
+of doing this.  The most common is to use the isapnptools package to
+initialize the card, and use the kernel module form of the sound
+subsystem and sound drivers.  Alternatively, some BIOS's allow manual
+configuration of installed PnP devices in a BIOS menu, which should
+allow using the non-modular sound drivers, i.e. built into the kernel.
+Since in this latter case you cannot use module parameters, you will
+have to enable support for the SoundPro at compile time.
+
+The IRQ and DMA values can be any that are considered acceptable for a
+WSS.  Assuming you've got isapnp all happy, then you should be able to
+do something like the following (which *must* match the isapnp/BIOS
+configuration):
+
+modprobe ad1848 io=0x530 irq=11 dma=0 soundpro=1
+-and maybe-
+modprobe sb io=0x220 irq=5 dma=1 dma16=5
+
+-then-
+modprobe mpu401 io=0x330 irq=9
+modprobe opl3 io=0x388
+
+If all goes well and you see no error messages, you should be able to
+start using the sound capabilities of your system.  If you get an
+error message while trying to insert the module(s), then make
+sure that the values of the various arguments match what you specified
+in your isapnp configuration file, and that there is no conflict with
+another device for an I/O port or interrupt.  Checking the contents of
+/proc/ioports and /proc/interrupts can be useful to see if you're
+butting heads with another device.
+
+If you do not see the chipset version message, and none of the other
+messages present in the system log are helpful, try adding 'debug=1'
+to the ad1848 parameters, email me the syslog results and I'll do
+my best to help. 
+
+Lastly, if you're using modules and want to set up automatic module
+loading with kmod, the kernel module loader, here is the section I
+currently use in my conf.modules file:
+
+# Sound
+post-install sound modprobe -k ad1848; modprobe -k mpu401; modprobe -k opl3
+options ad1848 io=0x530 irq=11 dma=0
+options sb io=0x220 irq=5 dma=1 dma16=5
+options mpu401 io=0x330 irq=9
+options opl3 io=0x388
+
+The above ensures that ad1848 will be loaded whenever the sound system
+is being used.
+
+Good luck.
+
+Ion
+
+NOT REALLY TESTED:
+- recording
+- recording device selection
+- full-duplex
+
+TODO:
+- implement mixer support for surround, loud, digital CD switches.
+- come up with a scheme which allows recording volumes for each subdevice.
+This is a major OSS API change.
index 6dab743e30f2dbd51b3cdc672c03ab4e0c24b992..8a60d13cdcd9be1d6c062f8bc39bfeededaba3ed 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,7 +1,7 @@
 VERSION = 2
 PATCHLEVEL = 2
 SUBLEVEL = 13
-EXTRAVERSION = pre16
+EXTRAVERSION = pre17
 
 ARCH := $(shell uname -m | sed -e s/i.86/i386/ -e s/sun4u/sparc64/ -e s/arm.*/arm/ -e s/sa110/arm/)
 
index e77575e0703f91cf640b9d12b22253bf5778c361..6e7c3c4b8cdc496423210d28495bc822608f1e5e 100644 (file)
@@ -389,6 +389,7 @@ static const lookup_t error_table[] = {
        { APM_RESUME_DISABLED,  "Resume timer disabled" },
        { APM_BAD_STATE,        "Unable to enter requested state" },
 /* N/A { APM_NO_EVENTS,        "No events pending" }, */
+       { APM_NO_ERROR,         "BIOS did not set a return code" },
        { APM_NOT_PRESENT,      "No APM present" }
 };
 #define ERROR_COUNT    (sizeof(error_table)/sizeof(lookup_t))
@@ -660,7 +661,7 @@ int apm_display_blank(void)
        if (!apm_enabled)
                return 0;
        error = apm_set_display_power_state(APM_STATE_STANDBY);
-       if (error == APM_SUCCESS)
+       if ((error == APM_SUCCESS) || (error == APM_NO_ERROR))
                return 1;
        apm_error("set display standby", error);
 #endif
@@ -676,7 +677,7 @@ int apm_display_unblank(void)
        if (!apm_enabled)
                return 0;
        error = apm_set_display_power_state(APM_STATE_READY);
-       if (error == APM_SUCCESS)
+       if ((error == APM_SUCCESS) || (error == APM_NO_ERROR))
                return 1;
        apm_error("set display ready", error);
 #endif
@@ -791,7 +792,7 @@ static void suspend(void)
 #endif
 
        err = apm_set_power_state(APM_STATE_SUSPEND);
-       if (err)
+       if ((err != APM_SUCCESS) && (err != APM_NO_ERROR))
                apm_error("suspend", err);
 #ifdef INIT_TIMER_AFTER_SUSPEND
        save_flags(flags);
@@ -813,7 +814,7 @@ static void standby(void)
        int     err;
 
        err = apm_set_power_state(APM_STATE_STANDBY);
-       if (err)
+       if ((err != APM_SUCCESS) && (err != APM_NO_ERROR))
                apm_error("standby", err);
 }
 
index eaed97933896966b1f173c1f806e81610db5639c..cbdb33bb1d2912aaa5d2ef457bf09b8f1187bfb4 100644 (file)
@@ -164,14 +164,10 @@ if [ "$CONFIG_SCSI" != "n" ]; then
        if [ "$CONFIG_PCI" != "n" ]; then
          dep_tristate 'Adaptec AIC7xxx support' CONFIG_SCSI_AIC7XXX $CONFIG_SCSI
          if [ "$CONFIG_SCSI_AIC7XXX" != "n" ]; then
-           bool '   Enable tagged command queueing' CONFIG_AIC7XXX_TAGGED_QUEUEING Y
-           bool '   Override driver defaults for commands per LUN' CONFIG_OVERRIDE_CMDS N
-           if [ "$CONFIG_OVERRIDE_CMDS" != "n" ]; then
-             int  '   Maximum number of commands per LUN' CONFIG_AIC7XXX_CMDS_PER_LUN 8
-           fi
-           bool '   Enable SCB paging' CONFIG_AIC7XXX_PAGE_ENABLE N
+           bool '   Enable Tagged Command Queueing (TCQ) by default' CONFIG_AIC7XXX_TCQ_ON_BY_DEFAULT
+           int  '   Maximum number of TCQ commands per device' CONFIG_AIC7XXX_CMDS_PER_DEVICE 8
            bool '   Collect statistics to report in /proc' CONFIG_AIC7XXX_PROC_STATS N
-           int  '   Delay in seconds after SCSI bus reset' CONFIG_AIC7XXX_RESET_DELAY 15
+           int  '   Delay in seconds after SCSI bus reset' CONFIG_AIC7XXX_RESET_DELAY 5
          fi
          dep_tristate 'NCR53C8XX SCSI support' CONFIG_SCSI_NCR53C8XX $CONFIG_SCSI
          if [ "$CONFIG_SCSI_NCR53C8XX" != "n" ]; then
index 5f5a5ce3f77cdb65b21fc8cd92bda480adeaf02d..231dc11e0d942df263054ab34a8e0fdd2f9d8fd5 100644 (file)
@@ -199,10 +199,9 @@ CONFIG_SCSI_CONSTANTS=y
 CONFIG_SCSI_SUNESP=y
 CONFIG_SCSI_QLOGICPTI=m
 CONFIG_SCSI_AIC7XXX=y
-# CONFIG_AIC7XXX_TAGGED_QUEUEING is not set
-# CONFIG_OVERRIDE_CMDS is not set
-# CONFIG_AIC7XXX_PAGE_ENABLE is not set
-# CONFIG_AIC7XXX_PROC_STATS is not set
+# CONFIG_AIC7XXX_TCQ_ON_BY_DEFAULT is not set
+# CONFIG_CMDS_PER_DEVICE is not set
+CONFIG_AIC7XXX_PROC_STATS=y
 CONFIG_AIC7XXX_RESET_DELAY=5
 CONFIG_SCSI_NCR53C8XX=y
 CONFIG_SCSI_NCR53C8XX_DEFAULT_TAGS=4
index 0497bbb10f115f6af2f70bbc193059302d7aa75f..100f9ff959b4dfe2191010dea9e7d7814a83ba92 100644 (file)
@@ -20,11 +20,13 @@ linux-1.1.x and fairly stable since linux-1.2.x, and are also in FreeBSD
     AHA-2920C
     AHA-2930
     AHA-2930U
+    AHA-2930CU
     AHA-2930U2
     AHA-2940               
     AHA-2940W              
     AHA-2940U              
     AHA-2940UW
+    AHA-2940UW-PRO
     AHA-2940AU 
     AHA-2940U2W
     AHA-2940U2
@@ -37,6 +39,7 @@ linux-1.1.x and fairly stable since linux-1.2.x, and are also in FreeBSD
     AHA-2950U2
     AHA-2950U2W
     AHA-2950U2B
+    AHA-29160M
     AHA-3940
     AHA-3940U
     AHA-3940W
@@ -45,6 +48,8 @@ linux-1.1.x and fairly stable since linux-1.2.x, and are also in FreeBSD
     AHA-3940U2W
     AHA-3950U2B
     AHA-3950U2D
+    AHA-3960D
+    AHA-39160M
     AHA-3985
     AHA-3985U
     AHA-3985W
@@ -159,6 +164,12 @@ linux-1.1.x and fairly stable since linux-1.2.x, and are also in FreeBSD
         on your controller.  This helps those people who have cards without
         a SEEPROM make sure that linux and all other operating systems think
         the same way about your hard drives.
+
+    "aic7xxx=scbram" - Some cards have external SCB RAM that can be used to
+        give the card more hardware SCB slots.  This allows the driver to use
+       that SCB RAM.  Without this option, the driver won't touch the SCB
+       RAM because it is known to cause problems on a few cards out there
+       (such as 3985 class cards).
        
     "aic7xxx=irq_trigger:x" - Replace x with either 0 or 1 to force the kernel
         to use the correct IRQ type for your card.  This only applies to EISA
@@ -464,10 +475,9 @@ linux-1.1.x and fairly stable since linux-1.2.x, and are also in FreeBSD
   FTP sites
   ------------------------------
     ftp://ftp.redhat.com/pub/aic/
-      - Primary site for Doug Ledford developed driver releases
-    ftp://ftp.dialnet.net/pub/linux/aic7xxx
-      - Temporary mirror of the redhat.com ftp site while people
-        get used to the new address
+      - Out of date.  I used to keep stuff here, but too many people
+        complained about having a hard time getting into Red Hat's ftp
+       server.  So use the web site below instead.
     ftp://ftp.pcnet.com/users/eischen/Linux/
       - Dan Eischen's driver distribution area
     ftp://ekf2.vsb.cz/pub/linux/kernel/aic7xxx/ftp.teleport.com/
@@ -475,10 +485,8 @@ linux-1.1.x and fairly stable since linux-1.2.x, and are also in FreeBSD
 
   Web sites
   ------------------------------
-    http://developer.redhat.com/aic7xxx/
-      - Primary web site maintained by Doug Ledford.  I haven't actually
-        put anything up yet....but I'm planning on it.  This information
-       is put here as an add for the vapor page :)
+    http://people.redhat.com/dledford/aic7xxx.html
+      - Primary web site maintained by Doug Ledford.
 
 Dean W. Gehnert
 deang@teleport.com
index 40e9352904a7da70bf3457b941e6c585cdffea4e..275c67809fcb63b1ccbdaa563ed8cbf47c7ce6c5 100644 (file)
@@ -270,7 +270,7 @@ struct proc_dir_entry proc_scsi_aic7xxx = {
     0, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL
 };
 
-#define AIC7XXX_C_VERSION  "5.1.19"
+#define AIC7XXX_C_VERSION  "5.1.20"
 
 #define NUMBER(arr)     (sizeof(arr) / sizeof(arr[0]))
 #define MIN(a,b)        (((a) < (b)) ? (a) : (b))
@@ -879,13 +879,14 @@ typedef enum {
   AHC_SG_PRELOAD       = 0x0080,
   AHC_SPIOCAP          = 0x0100,
   AHC_ULTRA3           = 0x0200,
+  AHC_NEW_AUTOTERM     = 0x0400,
   AHC_AIC7770_FE       = AHC_FENONE,
   AHC_AIC7850_FE       = AHC_SPIOCAP,
   AHC_AIC7860_FE       = AHC_ULTRA|AHC_SPIOCAP,
   AHC_AIC7870_FE       = AHC_FENONE,
   AHC_AIC7880_FE       = AHC_ULTRA,
   AHC_AIC7890_FE       = AHC_MORE_SRAM|AHC_CMD_CHAN|AHC_ULTRA2|
-                         AHC_QUEUE_REGS|AHC_SG_PRELOAD,
+                         AHC_QUEUE_REGS|AHC_SG_PRELOAD|AHC_NEW_AUTOTERM,
   AHC_AIC7895_FE       = AHC_MORE_SRAM|AHC_CMD_CHAN|AHC_ULTRA,
   AHC_AIC7896_FE       = AHC_AIC7890_FE,
   AHC_AIC7892_FE       = AHC_AIC7890_FE|AHC_ULTRA3,
@@ -1352,7 +1353,14 @@ static int aic7xxx_dump_sequencer = 0;
  * would result in never finding any devices :)
  */
 static int aic7xxx_no_probe = 0;
-
+/*
+ * On some machines, enabling the external SCB RAM isn't reliable yet.  I
+ * haven't had time to make test patches for things like changing the
+ * timing mode on that external RAM either.  Some of those changes may
+ * fix the problem.  Until then though, we default to external SCB RAM
+ * off and give a command line option to enable it.
+ */
+static int aic7xxx_scbram = 0;
 /*
  * So that insmod can find the variable and make it point to something
  */
@@ -1451,13 +1459,12 @@ aic_inb(struct aic7xxx_host *p, long port)
   unsigned char x;
   if(p->maddr)
   {
-    x = p->maddr[port];
+    x = readb(p->maddr + port);
   }
   else
   {
     x = inb(p->base + port);
   }
-  mb();
   return(x);
 #else
   return(inb(p->base + port));
@@ -1470,7 +1477,7 @@ aic_outb(struct aic7xxx_host *p, unsigned char val, long port)
 #ifdef MMAPIO
   if(p->maddr)
   {
-    p->maddr[port] = val;
+    writeb(val, p->maddr + port);
   }
   else
   {
@@ -1514,6 +1521,7 @@ aic7xxx_setup(char *s, int *dummy)
     { "pci_parity", &aic7xxx_pci_parity },
     { "dump_card", &aic7xxx_dump_card },
     { "dump_sequencer", &aic7xxx_dump_sequencer },
+    { "scbram", &aic7xxx_scbram },
     { "tag_info",    NULL }
   };
 
@@ -6194,7 +6202,7 @@ aic7xxx_handle_scsiint(struct aic7xxx_host *p, unsigned char intstat)
         cmd->result = 0;
         scb = NULL;
       }
-      if (scb->cmd == p->dev_dtr_cmnd[TARGET_INDEX(scb->cmd)])
+      else if (scb->cmd == p->dev_dtr_cmnd[TARGET_INDEX(scb->cmd)])
       {
         /*
          * Turn off the needsdtr, needwdtr, and needppr bits since this device
@@ -6542,6 +6550,105 @@ aic7xxx_check_scbs(struct aic7xxx_host *p, char *buffer)
 }
 #endif
 
+
+/*+F*************************************************************************
+ * Function:
+ *   aic7xxx_handle_command_completion_intr
+ *
+ * Description:
+ *   SCSI command completion interrupt handler.
+ *-F*************************************************************************/
+static void
+aic7xxx_handle_command_completion_intr(struct aic7xxx_host *p)
+{
+  struct aic7xxx_scb *scb = NULL;
+  Scsi_Cmnd *cmd;
+  unsigned char scb_index;
+
+#ifdef AIC7XXX_VERBOSE_DEBUGGING
+  if( (p->isr_count < 16) && (aic7xxx_verbose > 0xffff) )
+    printk(INFO_LEAD "Command Complete Int.\n", p->host_no, -1, -1, -1);
+#endif
+    
+  /*
+   * Read the INTSTAT location after clearing the CMDINT bit.  This forces
+   * any posted PCI writes to flush to memory.  Gerard Roudier suggested
+   * this fix to the possible race of clearing the CMDINT bit but not
+   * having all command bytes flushed onto the qoutfifo.
+   */
+  aic_outb(p, CLRCMDINT, CLRINT);
+  aic_inb(p, INTSTAT);
+  /*
+   * The sequencer will continue running when it
+   * issues this interrupt. There may be >1 commands
+   * finished, so loop until we've processed them all.
+   */
+
+  while (p->qoutfifo[p->qoutfifonext] != SCB_LIST_NULL)
+  {
+    scb_index = p->qoutfifo[p->qoutfifonext];
+    p->qoutfifo[p->qoutfifonext++] = SCB_LIST_NULL;
+    if ( scb_index >= p->scb_data->numscbs )
+      scb = NULL;
+    else
+      scb = p->scb_data->scb_array[scb_index];
+    if (scb == NULL)
+    {
+      printk(WARN_LEAD "CMDCMPLT with invalid SCB index %d\n", p->host_no,
+        -1, -1, -1, scb_index);
+      continue;
+    }
+    else if (!(scb->flags & SCB_ACTIVE) || (scb->cmd == NULL))
+    {
+      printk(WARN_LEAD "CMDCMPLT without command for SCB %d, SCB flags "
+        "0x%x, cmd 0x%lx\n", p->host_no, -1, -1, -1, scb_index, scb->flags,
+        (unsigned long) scb->cmd);
+      continue;
+    }
+    else if (scb->flags & SCB_QUEUED_ABORT)
+    {
+      pause_sequencer(p);
+      if ( ((aic_inb(p, LASTPHASE) & PHASE_MASK) != P_BUSFREE) &&
+           (aic_inb(p, SCB_TAG) == scb->hscb->tag) )
+      {
+        unpause_sequencer(p, FALSE);
+        continue;
+      }
+      aic7xxx_reset_device(p, scb->cmd->target, scb->cmd->channel,
+        scb->cmd->lun, scb->hscb->tag);
+      scb->flags &= ~(SCB_QUEUED_FOR_DONE | SCB_RESET | SCB_ABORT |
+        SCB_QUEUED_ABORT);
+      unpause_sequencer(p, FALSE);
+    }
+    else if (scb->flags & SCB_ABORT)
+    {
+      /*
+       * We started to abort this, but it completed on us, let it
+       * through as successful
+       */
+      scb->flags &= ~(SCB_ABORT|SCB_RESET);
+    }
+    switch (status_byte(scb->hscb->target_status))
+    {
+      case QUEUE_FULL:
+      case BUSY:
+        scb->hscb->target_status = 0;
+        scb->cmd->result = 0;
+        aic7xxx_error(scb->cmd) = DID_OK;
+        break;
+      default:
+        cmd = scb->cmd;
+        if (scb->hscb->residual_SG_segment_count != 0)
+        {
+          aic7xxx_calculate_residual(p, scb);
+        }
+        cmd->result |= (aic7xxx_error(cmd) << 16);
+        aic7xxx_done(p, scb);
+        break;
+    }      
+  }
+}
+
 /*+F*************************************************************************
  * Function:
  *   aic7xxx_isr
@@ -6601,95 +6708,7 @@ aic7xxx_isr(int irq, void *dev_id, struct pt_regs *regs)
    */
   if (intstat & CMDCMPLT)
   {
-    struct aic7xxx_scb *scb = NULL;
-    Scsi_Cmnd *cmd;
-    unsigned char scb_index;
-
-#ifdef AIC7XXX_VERBOSE_DEBUGGING
-    if( (p->isr_count < 16) && (aic7xxx_verbose > 0xffff) )
-      printk(INFO_LEAD "Command Complete Int.\n", p->host_no, -1, -1, -1);
-#endif
-    
-    /*
-     * Clear interrupt status before running the completion loop.
-     * This eliminates a race condition whereby a command could
-     * complete between the last check of qoutfifo and the
-     * CLRCMDINT statement.  This would result in us thinking the
-     * qoutfifo was empty when it wasn't, and in actuality be a lost
-     * completion interrupt.  With multiple devices or tagged queueing
-     * this could be very bad if we caught all but the last completion
-     * and no more are imediately sent.
-     */
-    aic_outb(p, CLRCMDINT, CLRINT);
-    /*
-     * The sequencer will continue running when it
-     * issues this interrupt. There may be >1 commands
-     * finished, so loop until we've processed them all.
-     */
-
-    while (p->qoutfifo[p->qoutfifonext] != SCB_LIST_NULL)
-    {
-      scb_index = p->qoutfifo[p->qoutfifonext];
-      p->qoutfifo[p->qoutfifonext++] = SCB_LIST_NULL;
-      if ( scb_index >= p->scb_data->numscbs )
-        scb = NULL;
-      else
-        scb = p->scb_data->scb_array[scb_index];
-      if (scb == NULL)
-      {
-        printk(WARN_LEAD "CMDCMPLT with invalid SCB index %d\n", p->host_no,
-          -1, -1, -1, scb_index);
-        continue;
-      }
-      else if (!(scb->flags & SCB_ACTIVE) || (scb->cmd == NULL))
-      {
-        printk(WARN_LEAD "CMDCMPLT without command for SCB %d, SCB flags "
-          "0x%x, cmd 0x%lx\n", p->host_no, -1, -1, -1, scb_index, scb->flags,
-          (unsigned long) scb->cmd);
-        continue;
-      }
-      else if (scb->flags & SCB_QUEUED_ABORT)
-      {
-        pause_sequencer(p);
-        if ( ((aic_inb(p, LASTPHASE) & PHASE_MASK) != P_BUSFREE) &&
-             (aic_inb(p, SCB_TAG) == scb->hscb->tag) )
-        {
-          unpause_sequencer(p, FALSE);
-          continue;
-        }
-        aic7xxx_reset_device(p, scb->cmd->target, scb->cmd->channel,
-          scb->cmd->lun, scb->hscb->tag);
-        scb->flags &= ~(SCB_QUEUED_FOR_DONE | SCB_RESET | SCB_ABORT |
-          SCB_QUEUED_ABORT);
-        unpause_sequencer(p, FALSE);
-      }
-      else if (scb->flags & SCB_ABORT)
-      {
-        /*
-         * We started to abort this, but it completed on us, let it
-         * through as successful
-         */
-        scb->flags &= ~(SCB_ABORT|SCB_RESET);
-      }
-      switch (status_byte(scb->hscb->target_status))
-      {
-        case QUEUE_FULL:
-        case BUSY:
-          scb->hscb->target_status = 0;
-          scb->cmd->result = 0;
-          aic7xxx_error(scb->cmd) = DID_OK;
-          break;
-        default:
-          cmd = scb->cmd;
-          if (scb->hscb->residual_SG_segment_count != 0)
-          {
-            aic7xxx_calculate_residual(p, scb);
-          }
-          cmd->result |= (aic7xxx_error(cmd) << 16);
-          aic7xxx_done(p, scb);
-          break;
-      }      
-    }
+    aic7xxx_handle_command_completion_intr(p);
   }
 
   if (intstat & BRKADRINT)
@@ -7620,9 +7639,10 @@ configure_termination(struct aic7xxx_host *p)
     aic_outb(p, SEEMS | SEECS, SEECTL);
     sxfrctl1 &= ~STPWEN;
     if ( (p->adapter_control & CFAUTOTERM) ||
-         (p->features & AHC_ULTRA2) )
+         (p->features & AHC_NEW_AUTOTERM) )
     {
-      if ( (p->adapter_control & CFAUTOTERM) && !(p->features & AHC_ULTRA2) )
+      if ( (p->adapter_control & CFAUTOTERM) &&
+          !(p->features & AHC_NEW_AUTOTERM) )
       {
         printk(KERN_INFO "(scsi%d) Warning - detected auto-termination\n",
                p->host_no);
@@ -7636,7 +7656,7 @@ configure_termination(struct aic7xxx_host *p)
       }
       /* Configure auto termination. */
 
-      if (p->features & AHC_ULTRA2)
+      if (p->features & AHC_NEW_AUTOTERM)
       {
         if (aic7xxx_override_term == -1)
           aic7xxx_ultra2_term_detect(p, &enableSE_low, &enableSE_high,
@@ -7669,7 +7689,7 @@ configure_termination(struct aic7xxx_host *p)
       if (max_target <= 8)
         internal68_present = 0;
 
-      if ( !(p->features & AHC_ULTRA2) )
+      if ( !(p->features & AHC_NEW_AUTOTERM) )
       {
         if (max_target > 8)
         {
@@ -7699,7 +7719,7 @@ configure_termination(struct aic7xxx_host *p)
        * SE Low Term Enable = BRDDAT5 (7890)
        * LVD High Term Enable = BRDDAT4 (7890)
        */
-      if ( !(p->features & AHC_ULTRA2) &&
+      if ( !(p->features & AHC_NEW_AUTOTERM) &&
            (internal50_present && internal68_present && external_present) )
       {
         printk(KERN_INFO "(scsi%d) Illegal cable configuration!!  Only two\n",
@@ -7732,7 +7752,7 @@ configure_termination(struct aic7xxx_host *p)
              (external_present   ? 1 : 0)) <= 1) ||
            (enableSE_low != 0) )
       {
-        if (p->features & AHC_ULTRA2)
+        if (p->features & AHC_NEW_AUTOTERM)
           brddat |= BRDDAT5;
         else
           sxfrctl1 |= STPWEN;
@@ -7763,7 +7783,7 @@ configure_termination(struct aic7xxx_host *p)
     {
       if (p->adapter_control & CFSTERM)
       {
-        if (p->features & AHC_ULTRA2)
+        if (p->features & AHC_NEW_AUTOTERM)
           brddat |= BRDDAT5;
         else
           sxfrctl1 |= STPWEN;
@@ -9406,7 +9426,7 @@ aic7xxx_detect(Scsi_Host_Template *template)
        AHC_PAGESCBS | AHC_BIOS_ENABLED, AHC_AIC7880_FE,     18,
        32, C46 },
       {PCI_VENDOR_ID_ADAPTEC, PCI_DEVICE_ID_ADAPTEC_7887, AHC_AIC7880,
-       AHC_PAGESCBS | AHC_BIOS_ENABLED, AHC_AIC7880_FE,     18,
+       AHC_PAGESCBS | AHC_BIOS_ENABLED, AHC_AIC7880_FE | AHC_NEW_AUTOTERM, 18,
        32, C46 },
       {PCI_VENDOR_ID_ADAPTEC, PCI_DEVICE_ID_ADAPTEC_7888, AHC_AIC7880,
        AHC_PAGESCBS | AHC_BIOS_ENABLED, AHC_AIC7880_FE,     18,
@@ -9538,7 +9558,7 @@ aic7xxx_detect(Scsi_Host_Template *template)
           temp_p->base &= PCI_BASE_ADDRESS_IO_MASK;
           temp_p->mbase &= PCI_BASE_ADDRESS_MEM_MASK;
           current_p = list_p;
-          while(current_p)
+          while(current_p && temp_p)
           {
             if ( ((current_p->pci_bus == temp_p->pci_bus) &&
                   (current_p->pci_device_fn == temp_p->pci_device_fn)) ||
@@ -9957,7 +9977,8 @@ aic7xxx_detect(Scsi_Host_Template *template)
 #endif
               if (temp_p->features & AHC_ULTRA2)
               {
-                if (aic_inb(temp_p, DSCOMMAND0) & RAMPSM_ULTRA2)
+                if ( (aic_inb(temp_p, DSCOMMAND0) & RAMPSM_ULTRA2) &&
+                     (aic7xxx_scbram) )
                 {
                   aic_outb(temp_p,
                            aic_inb(temp_p, DSCOMMAND0) & ~SCBRAMSEL_ULTRA2,
@@ -9965,12 +9986,33 @@ aic7xxx_detect(Scsi_Host_Template *template)
                   temp_p->flags |= AHC_EXTERNAL_SRAM;
                   devconfig |= EXTSCBPEN;
                 }
+                else if (aic_inb(temp_p, DSCOMMAND0) & RAMPSM_ULTRA2)
+                {
+                  printk(KERN_INFO "aic7xxx: <%s> at PCI %d/%d\n", 
+                    board_names[aic_pdevs[i].board_name_index],
+                    PCI_SLOT(temp_p->pci_device_fn),
+                    PCI_FUNC(temp_p->pci_device_fn));
+                  printk("aic7xxx: external SCB RAM detected, "
+                         "but not enabled\n");
+                }
               }
-              else if (devconfig & RAMPSM)
+              else
               {
-                devconfig &= ~SCBRAMSEL;
-                devconfig |= EXTSCBPEN;
-                temp_p->flags |= AHC_EXTERNAL_SRAM;
+                if ((devconfig & RAMPSM) && (aic7xxx_scbram))
+                {
+                  devconfig &= ~SCBRAMSEL;
+                  devconfig |= EXTSCBPEN;
+                  temp_p->flags |= AHC_EXTERNAL_SRAM;
+                }
+                else if (devconfig & RAMPSM)
+                {
+                  printk(KERN_INFO "aic7xxx: <%s> at PCI %d/%d\n", 
+                    board_names[aic_pdevs[i].board_name_index],
+                    PCI_SLOT(temp_p->pci_device_fn),
+                    PCI_FUNC(temp_p->pci_device_fn));
+                  printk("aic7xxx: external SCB RAM detected, "
+                         "but not enabled\n");
+                }
               }
 #if LINUX_VERSION_CODE > KERNEL_VERSION(2,1,92)
               pci_write_config_dword(pdev, DEVCONFIG, devconfig);
@@ -11587,13 +11629,17 @@ aic7xxx_reset(Scsi_Cmnd *cmd, unsigned int flags)
     if ( aic7xxx_scb_on_qoutfifo(p, scb) )
     {
       if(aic7xxx_verbose & VERBOSE_RESET_RETURN)
-        printk(INFO_LEAD "SCB on qoutfifo, returning.\n", p->host_no,
+        printk(INFO_LEAD "SCB on qoutfifo, completing.\n", p->host_no,
           CTL_OF_SCB(scb));
-      aic7xxx_run_done_queue(p, TRUE);
+      if ((aic_inb(p,INTSTAT) & CMDCMPLT) == 0)
+        printk(INFO_LEAD "missed CMDCMPLT interrupt!\n", p->host_no,
+          CTL_OF_SCB(scb));
+      aic7xxx_handle_command_completion_intr(p);
+      aic7xxx_done_cmds_complete(p);
       aic7xxx_run_waiting_queues(p);
       unpause_sequencer(p, FALSE);
       DRIVER_UNLOCK
-      return(SCSI_RESET_NOT_RUNNING);
+      return(SCSI_RESET_SUCCESS);
     }
     if ( flags & SCSI_RESET_SUGGEST_HOST_RESET )
     {
index 9ffc6d83c4e3f3635fe96ce5eb9ac82300e5230b..5d2a848c9751d198ca6d05dc10701d32b9a47cb6 100644 (file)
@@ -159,7 +159,7 @@ if [ "$CONFIG_SOUND_OSS" = "y" -o "$CONFIG_SOUND_OSS" = "m" ]; then
   
   dep_tristate 'Microsoft Sound System support' CONFIG_SOUND_MSS $CONFIG_SOUND_OSS
   if [ "$CONFIG_SOUND_MSS" = "y" ]; then
-      bool 'Enable support for the SoundPro mixer' CONFIG_SOUND_SPRO
+      bool '  Enable support for the SoundPro mixer' CONFIG_SOUND_SPRO
       hex 'MSS/WSS I/O base 530, 604, E80 or F40' CONFIG_MSS_BASE 530
       int 'MSS/WSS IRQ 7, 9, 10 or 11' CONFIG_MSS_IRQ 11
       int 'MSS/WSS DMA 0, 1 or 3' CONFIG_MSS_DMA 3
index a478c0c66f038668840eb3245f489974025108bc..7dc036b25ffe5630dc4cf9058f97662dad9abde0 100644 (file)
@@ -130,6 +130,7 @@ extern int          apm_display_unblank(void);
 #define APM_NOT_ENGAGED                0x0b
 #define APM_BAD_FUNCTION        0x0c
 #define APM_RESUME_DISABLED    0x0d
+#define APM_NO_ERROR           0x53
 #define APM_BAD_STATE          0x60
 #define APM_NO_EVENTS          0x80
 #define APM_NOT_PRESENT                0x86
index 972c0cb06fc67da51597a7413a5c744f0b3d0221..7eb57334fd4aedd868747a9d363278c4f4c7c40f 100644 (file)
@@ -59,6 +59,9 @@ typedef struct {
        unsigned long *res_in, *res_out, *res_ex;
 } fd_set_bits;
 
+/*
+ * How many longwords for "nr" bits?
+ */
 #define FDS_BITPERLONG (8*sizeof(long))
 #define FDS_LONGS(nr)  (((nr)+FDS_BITPERLONG-1)/FDS_BITPERLONG)
 #define FDS_BYTES(nr)  (FDS_LONGS(nr)*sizeof(long))
@@ -87,17 +90,14 @@ int get_fd_set(unsigned long nr, void *ufdset, unsigned long *fdset)
 static inline
 void set_fd_set(unsigned long nr, void *ufdset, unsigned long *fdset)
 {
-       if (ufdset) {
-               nr = FDS_BYTES(nr);
-               __copy_to_user(ufdset, fdset, nr);
-       }
+       if (ufdset)
+               __copy_to_user(ufdset, fdset, FDS_BYTES(nr));
 }
 
 static inline
 void zero_fd_set(unsigned long nr, unsigned long *fdset)
 {
-       nr = FDS_BYTES(nr);
-       memset(fdset, 0, nr);
+       memset(fdset, 0, FDS_BYTES(nr));
 }
 
 extern int do_select(int n, fd_set_bits *fds, long *timeout);
index 87bafcb868811ce5a49f859c702f90e5969065f0..1f9e480f9a4e303c18d2c37b98c9a42f470f5336 100644 (file)
@@ -872,7 +872,8 @@ do_sigaction(int sig, const struct k_sigaction *act, struct k_sigaction *oact)
                                        if (q->info.si_signo != sig)
                                                pp = &q->next;
                                        else {
-                                               *pp = q->next;
+                                               if ((*pp = q->next) == NULL)
+                                                       current->sigqueue_tail = pp;
                                                kmem_cache_free(signal_queue_cachep, q);
                                                atomic_dec(&nr_queued_signals);
                                        }