]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - drivers/scsi/aic7xxx/aic7xxx_core.c
[SCSI] aic7xx: mitigate HOST_MSG_LOOP invalid SCB ff panic
[linux-2.6-omap-h63xx.git] / drivers / scsi / aic7xxx / aic7xxx_core.c
index 50ef785224defd6e79f2d938f7ee5961a6cbbaaa..64e62ce59c152fbedf5495021d0b7d3a6f9e536e 100644 (file)
@@ -695,15 +695,16 @@ ahc_handle_seqint(struct ahc_softc *ahc, u_int intstat)
                        scb_index = ahc_inb(ahc, SCB_TAG);
                        scb = ahc_lookup_scb(ahc, scb_index);
                        if (devinfo.role == ROLE_INITIATOR) {
-                               if (scb == NULL)
-                                       panic("HOST_MSG_LOOP with "
-                                             "invalid SCB %x\n", scb_index);
+                               if (bus_phase == P_MESGOUT) {
+                                       if (scb == NULL)
+                                               panic("HOST_MSG_LOOP with "
+                                                     "invalid SCB %x\n",
+                                                     scb_index);
 
-                               if (bus_phase == P_MESGOUT)
                                        ahc_setup_initiator_msgout(ahc,
                                                                   &devinfo,
                                                                   scb);
-                               else {
+                               else {
                                        ahc->msg_type =
                                            MSG_TYPE_INITIATOR_MSGIN;
                                        ahc->msgin_index = 0;
@@ -1701,7 +1702,16 @@ ahc_find_syncrate(struct ahc_softc *ahc, u_int *period,
        if ((*ppr_options & MSG_EXT_PPR_DT_REQ) == 0
         && maxsync < AHC_SYNCRATE_ULTRA2)
                maxsync = AHC_SYNCRATE_ULTRA2;
-       
+
+       /* Now set the maxsync based on the card capabilities
+        * DT is already done above */
+       if ((ahc->features & (AHC_DT | AHC_ULTRA2)) == 0
+           && maxsync < AHC_SYNCRATE_ULTRA)
+               maxsync = AHC_SYNCRATE_ULTRA;
+       if ((ahc->features & (AHC_DT | AHC_ULTRA2 | AHC_ULTRA)) == 0
+           && maxsync < AHC_SYNCRATE_FAST)
+               maxsync = AHC_SYNCRATE_FAST;
+
        for (syncrate = &ahc_syncrates[maxsync];
             syncrate->rate != NULL;
             syncrate++) {
@@ -1765,6 +1775,17 @@ ahc_find_period(struct ahc_softc *ahc, u_int scsirate, u_int maxsync)
        else
                scsirate &= SXFR;
 
+       /* now set maxsync based on card capabilities */
+       if ((ahc->features & AHC_DT) == 0 && maxsync < AHC_SYNCRATE_ULTRA2)
+               maxsync = AHC_SYNCRATE_ULTRA2;
+       if ((ahc->features & (AHC_DT | AHC_ULTRA2)) == 0
+           && maxsync < AHC_SYNCRATE_ULTRA)
+               maxsync = AHC_SYNCRATE_ULTRA;
+       if ((ahc->features & (AHC_DT | AHC_ULTRA2 | AHC_ULTRA)) == 0
+           && maxsync < AHC_SYNCRATE_FAST)
+               maxsync = AHC_SYNCRATE_FAST;
+
+
        syncrate = &ahc_syncrates[maxsync];
        while (syncrate->rate != NULL) {
 
@@ -2073,7 +2094,7 @@ ahc_set_width(struct ahc_softc *ahc, struct ahc_devinfo *devinfo,
 /*
  * Update the current state of tagged queuing for a given target.
  */
-void
+static void
 ahc_set_tags(struct ahc_softc *ahc, struct scsi_cmnd *cmd,
             struct ahc_devinfo *devinfo, ahc_queue_alg alg)
 {
@@ -5058,6 +5079,7 @@ ahc_pause_and_flushwork(struct ahc_softc *ahc)
        ahc->flags &= ~AHC_ALL_INTERRUPTS;
 }
 
+#ifdef CONFIG_PM
 int
 ahc_suspend(struct ahc_softc *ahc)
 {
@@ -5093,7 +5115,7 @@ ahc_resume(struct ahc_softc *ahc)
        ahc_restart(ahc);
        return (0);
 }
-
+#endif
 /************************** Busy Target Table *********************************/
 /*
  * Return the untagged transaction id for a given target/channel lun.