aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/aic7xxx
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/aic7xxx')
-rw-r--r--drivers/scsi/aic7xxx/Kconfig.aic7xxx2
-rw-r--r--drivers/scsi/aic7xxx/aic79xx.h4
-rw-r--r--drivers/scsi/aic7xxx/aic79xx_core.c166
-rw-r--r--drivers/scsi/aic7xxx/aic79xx_osm.c4
4 files changed, 69 insertions, 107 deletions
diff --git a/drivers/scsi/aic7xxx/Kconfig.aic7xxx b/drivers/scsi/aic7xxx/Kconfig.aic7xxx
index 6c2c395554ff..5517da5855f0 100644
--- a/drivers/scsi/aic7xxx/Kconfig.aic7xxx
+++ b/drivers/scsi/aic7xxx/Kconfig.aic7xxx
@@ -86,7 +86,7 @@ config AIC7XXX_DEBUG_MASK
86 default "0" 86 default "0"
87 help 87 help
88 Bit mask of debug options that is only valid if the 88 Bit mask of debug options that is only valid if the
89 CONFIG_AIC7XXX_DEBUG_ENBLE option is enabled. The bits in this mask 89 CONFIG_AIC7XXX_DEBUG_ENABLE option is enabled. The bits in this mask
90 are defined in the drivers/scsi/aic7xxx/aic7xxx.h - search for the 90 are defined in the drivers/scsi/aic7xxx/aic7xxx.h - search for the
91 variable ahc_debug in that file to find them. 91 variable ahc_debug in that file to find them.
92 92
diff --git a/drivers/scsi/aic7xxx/aic79xx.h b/drivers/scsi/aic7xxx/aic79xx.h
index 1d11f7e77564..bb5166da4358 100644
--- a/drivers/scsi/aic7xxx/aic79xx.h
+++ b/drivers/scsi/aic7xxx/aic79xx.h
@@ -372,7 +372,7 @@ typedef enum {
372 AHD_CURRENT_SENSING = 0x40000, 372 AHD_CURRENT_SENSING = 0x40000,
373 AHD_SCB_CONFIG_USED = 0x80000,/* No SEEPROM but SCB had info. */ 373 AHD_SCB_CONFIG_USED = 0x80000,/* No SEEPROM but SCB had info. */
374 AHD_HP_BOARD = 0x100000, 374 AHD_HP_BOARD = 0x100000,
375 AHD_RESET_POLL_ACTIVE = 0x200000, 375 AHD_BUS_RESET_ACTIVE = 0x200000,
376 AHD_UPDATE_PEND_CMDS = 0x400000, 376 AHD_UPDATE_PEND_CMDS = 0x400000,
377 AHD_RUNNING_QOUTFIFO = 0x800000, 377 AHD_RUNNING_QOUTFIFO = 0x800000,
378 AHD_HAD_FIRST_SEL = 0x1000000 378 AHD_HAD_FIRST_SEL = 0x1000000
@@ -589,7 +589,7 @@ typedef enum {
589 SCB_PACKETIZED = 0x00800, 589 SCB_PACKETIZED = 0x00800,
590 SCB_EXPECT_PPR_BUSFREE = 0x01000, 590 SCB_EXPECT_PPR_BUSFREE = 0x01000,
591 SCB_PKT_SENSE = 0x02000, 591 SCB_PKT_SENSE = 0x02000,
592 SCB_CMDPHASE_ABORT = 0x04000, 592 SCB_EXTERNAL_RESET = 0x04000,/* Device was reset externally */
593 SCB_ON_COL_LIST = 0x08000, 593 SCB_ON_COL_LIST = 0x08000,
594 SCB_SILENT = 0x10000 /* 594 SCB_SILENT = 0x10000 /*
595 * Be quiet about transmission type 595 * Be quiet about transmission type
diff --git a/drivers/scsi/aic7xxx/aic79xx_core.c b/drivers/scsi/aic7xxx/aic79xx_core.c
index 326a62226235..08771f6f6859 100644
--- a/drivers/scsi/aic7xxx/aic79xx_core.c
+++ b/drivers/scsi/aic7xxx/aic79xx_core.c
@@ -207,7 +207,6 @@ static void ahd_add_scb_to_free_list(struct ahd_softc *ahd,
207static u_int ahd_rem_wscb(struct ahd_softc *ahd, u_int scbid, 207static u_int ahd_rem_wscb(struct ahd_softc *ahd, u_int scbid,
208 u_int prev, u_int next, u_int tid); 208 u_int prev, u_int next, u_int tid);
209static void ahd_reset_current_bus(struct ahd_softc *ahd); 209static void ahd_reset_current_bus(struct ahd_softc *ahd);
210static ahd_callback_t ahd_reset_poll;
211static ahd_callback_t ahd_stat_timer; 210static ahd_callback_t ahd_stat_timer;
212#ifdef AHD_DUMP_SEQ 211#ifdef AHD_DUMP_SEQ
213static void ahd_dumpseq(struct ahd_softc *ahd); 212static void ahd_dumpseq(struct ahd_softc *ahd);
@@ -1054,12 +1053,10 @@ ahd_handle_seqint(struct ahd_softc *ahd, u_int intstat)
1054 * If a target takes us into the command phase 1053 * If a target takes us into the command phase
1055 * assume that it has been externally reset and 1054 * assume that it has been externally reset and
1056 * has thus lost our previous packetized negotiation 1055 * has thus lost our previous packetized negotiation
1057 * agreement. Since we have not sent an identify 1056 * agreement.
1058 * message and may not have fully qualified the 1057 * Revert to async/narrow transfers until we
1059 * connection, we change our command to TUR, assert 1058 * can renegotiate with the device and notify
1060 * ATN and ABORT the task when we go to message in 1059 * the OSM about the reset.
1061 * phase. The OSM will see the REQUEUE_REQUEST
1062 * status and retry the command.
1063 */ 1060 */
1064 scbid = ahd_get_scbptr(ahd); 1061 scbid = ahd_get_scbptr(ahd);
1065 scb = ahd_lookup_scb(ahd, scbid); 1062 scb = ahd_lookup_scb(ahd, scbid);
@@ -1086,31 +1083,15 @@ ahd_handle_seqint(struct ahd_softc *ahd, u_int intstat)
1086 ahd_set_syncrate(ahd, &devinfo, /*period*/0, 1083 ahd_set_syncrate(ahd, &devinfo, /*period*/0,
1087 /*offset*/0, /*ppr_options*/0, 1084 /*offset*/0, /*ppr_options*/0,
1088 AHD_TRANS_ACTIVE, /*paused*/TRUE); 1085 AHD_TRANS_ACTIVE, /*paused*/TRUE);
1089 ahd_outb(ahd, SCB_CDB_STORE, 0); 1086 scb->flags |= SCB_EXTERNAL_RESET;
1090 ahd_outb(ahd, SCB_CDB_STORE+1, 0);
1091 ahd_outb(ahd, SCB_CDB_STORE+2, 0);
1092 ahd_outb(ahd, SCB_CDB_STORE+3, 0);
1093 ahd_outb(ahd, SCB_CDB_STORE+4, 0);
1094 ahd_outb(ahd, SCB_CDB_STORE+5, 0);
1095 ahd_outb(ahd, SCB_CDB_LEN, 6);
1096 scb->hscb->control &= ~(TAG_ENB|SCB_TAG_TYPE);
1097 scb->hscb->control |= MK_MESSAGE;
1098 ahd_outb(ahd, SCB_CONTROL, scb->hscb->control);
1099 ahd_outb(ahd, MSG_OUT, HOST_MSG);
1100 ahd_outb(ahd, SAVED_SCSIID, scb->hscb->scsiid);
1101 /*
1102 * The lun is 0, regardless of the SCB's lun
1103 * as we have not sent an identify message.
1104 */
1105 ahd_outb(ahd, SAVED_LUN, 0);
1106 ahd_outb(ahd, SEQ_FLAGS, 0);
1107 ahd_assert_atn(ahd);
1108 scb->flags &= ~SCB_PACKETIZED;
1109 scb->flags |= SCB_ABORT|SCB_CMDPHASE_ABORT;
1110 ahd_freeze_devq(ahd, scb); 1087 ahd_freeze_devq(ahd, scb);
1111 ahd_set_transaction_status(scb, CAM_REQUEUE_REQ); 1088 ahd_set_transaction_status(scb, CAM_REQUEUE_REQ);
1112 ahd_freeze_scb(scb); 1089 ahd_freeze_scb(scb);
1113 1090
1091 /* Notify XPT */
1092 ahd_send_async(ahd, devinfo.channel, devinfo.target,
1093 CAM_LUN_WILDCARD, AC_SENT_BDR, NULL);
1094
1114 /* 1095 /*
1115 * Allow the sequencer to continue with 1096 * Allow the sequencer to continue with
1116 * non-pack processing. 1097 * non-pack processing.
@@ -1534,6 +1515,18 @@ ahd_handle_scsiint(struct ahd_softc *ahd, u_int intstat)
1534 lqistat1 = ahd_inb(ahd, LQISTAT1); 1515 lqistat1 = ahd_inb(ahd, LQISTAT1);
1535 lqostat0 = ahd_inb(ahd, LQOSTAT0); 1516 lqostat0 = ahd_inb(ahd, LQOSTAT0);
1536 busfreetime = ahd_inb(ahd, SSTAT2) & BUSFREETIME; 1517 busfreetime = ahd_inb(ahd, SSTAT2) & BUSFREETIME;
1518
1519 /*
1520 * Ignore external resets after a bus reset.
1521 */
1522 if (((status & SCSIRSTI) != 0) && (ahd->flags & AHD_BUS_RESET_ACTIVE))
1523 return;
1524
1525 /*
1526 * Clear bus reset flag
1527 */
1528 ahd->flags &= ~AHD_BUS_RESET_ACTIVE;
1529
1537 if ((status0 & (SELDI|SELDO)) != 0) { 1530 if ((status0 & (SELDI|SELDO)) != 0) {
1538 u_int simode0; 1531 u_int simode0;
1539 1532
@@ -2207,22 +2200,6 @@ ahd_handle_nonpkt_busfree(struct ahd_softc *ahd)
2207 if (sent_msg == MSG_ABORT_TAG) 2200 if (sent_msg == MSG_ABORT_TAG)
2208 tag = SCB_GET_TAG(scb); 2201 tag = SCB_GET_TAG(scb);
2209 2202
2210 if ((scb->flags & SCB_CMDPHASE_ABORT) != 0) {
2211 /*
2212 * This abort is in response to an
2213 * unexpected switch to command phase
2214 * for a packetized connection. Since
2215 * the identify message was never sent,
2216 * "saved lun" is 0. We really want to
2217 * abort only the SCB that encountered
2218 * this error, which could have a different
2219 * lun. The SCB will be retried so the OS
2220 * will see the UA after renegotiating to
2221 * packetized.
2222 */
2223 tag = SCB_GET_TAG(scb);
2224 saved_lun = scb->hscb->lun;
2225 }
2226 found = ahd_abort_scbs(ahd, target, 'A', saved_lun, 2203 found = ahd_abort_scbs(ahd, target, 'A', saved_lun,
2227 tag, ROLE_INITIATOR, 2204 tag, ROLE_INITIATOR,
2228 CAM_REQ_ABORTED); 2205 CAM_REQ_ABORTED);
@@ -7847,6 +7824,17 @@ ahd_reset_channel(struct ahd_softc *ahd, char channel, int initiate_reset)
7847 int found; 7824 int found;
7848 u_int fifo; 7825 u_int fifo;
7849 u_int next_fifo; 7826 u_int next_fifo;
7827 uint8_t scsiseq;
7828
7829 /*
7830 * Check if the last bus reset is cleared
7831 */
7832 if (ahd->flags & AHD_BUS_RESET_ACTIVE) {
7833 printf("%s: bus reset still active\n",
7834 ahd_name(ahd));
7835 return 0;
7836 }
7837 ahd->flags |= AHD_BUS_RESET_ACTIVE;
7850 7838
7851 ahd->pending_device = NULL; 7839 ahd->pending_device = NULL;
7852 7840
@@ -7860,6 +7848,12 @@ ahd_reset_channel(struct ahd_softc *ahd, char channel, int initiate_reset)
7860 /* Make sure the sequencer is in a safe location. */ 7848 /* Make sure the sequencer is in a safe location. */
7861 ahd_clear_critical_section(ahd); 7849 ahd_clear_critical_section(ahd);
7862 7850
7851 /*
7852 * Run our command complete fifos to ensure that we perform
7853 * completion processing on any commands that 'completed'
7854 * before the reset occurred.
7855 */
7856 ahd_run_qoutfifo(ahd);
7863#ifdef AHD_TARGET_MODE 7857#ifdef AHD_TARGET_MODE
7864 if ((ahd->flags & AHD_TARGETROLE) != 0) { 7858 if ((ahd->flags & AHD_TARGETROLE) != 0) {
7865 ahd_run_tqinfifo(ahd, /*paused*/TRUE); 7859 ahd_run_tqinfifo(ahd, /*paused*/TRUE);
@@ -7924,30 +7918,14 @@ ahd_reset_channel(struct ahd_softc *ahd, char channel, int initiate_reset)
7924 ahd_clear_fifo(ahd, 1); 7918 ahd_clear_fifo(ahd, 1);
7925 7919
7926 /* 7920 /*
7927 * Revert to async/narrow transfers until we renegotiate. 7921 * Reenable selections
7928 */ 7922 */
7929 max_scsiid = (ahd->features & AHD_WIDE) ? 15 : 7; 7923 ahd_outb(ahd, SIMODE1, ahd_inb(ahd, SIMODE1) | ENSCSIRST);
7930 for (target = 0; target <= max_scsiid; target++) { 7924 scsiseq = ahd_inb(ahd, SCSISEQ_TEMPLATE);
7931 7925 ahd_outb(ahd, SCSISEQ1, scsiseq & (ENSELI|ENRSELI|ENAUTOATNP));
7932 if (ahd->enabled_targets[target] == NULL)
7933 continue;
7934 for (initiator = 0; initiator <= max_scsiid; initiator++) {
7935 struct ahd_devinfo devinfo;
7936
7937 ahd_compile_devinfo(&devinfo, target, initiator,
7938 CAM_LUN_WILDCARD,
7939 'A', ROLE_UNKNOWN);
7940 ahd_set_width(ahd, &devinfo, MSG_EXT_WDTR_BUS_8_BIT,
7941 AHD_TRANS_CUR, /*paused*/TRUE);
7942 ahd_set_syncrate(ahd, &devinfo, /*period*/0,
7943 /*offset*/0, /*ppr_options*/0,
7944 AHD_TRANS_CUR, /*paused*/TRUE);
7945 }
7946 }
7947 7926
7948#ifdef AHD_TARGET_MODE
7949 max_scsiid = (ahd->features & AHD_WIDE) ? 15 : 7; 7927 max_scsiid = (ahd->features & AHD_WIDE) ? 15 : 7;
7950 7928#ifdef AHD_TARGET_MODE
7951 /* 7929 /*
7952 * Send an immediate notify ccb to all target more peripheral 7930 * Send an immediate notify ccb to all target more peripheral
7953 * drivers affected by this action. 7931 * drivers affected by this action.
@@ -7975,51 +7953,31 @@ ahd_reset_channel(struct ahd_softc *ahd, char channel, int initiate_reset)
7975 /* Notify the XPT that a bus reset occurred */ 7953 /* Notify the XPT that a bus reset occurred */
7976 ahd_send_async(ahd, devinfo.channel, CAM_TARGET_WILDCARD, 7954 ahd_send_async(ahd, devinfo.channel, CAM_TARGET_WILDCARD,
7977 CAM_LUN_WILDCARD, AC_BUS_RESET, NULL); 7955 CAM_LUN_WILDCARD, AC_BUS_RESET, NULL);
7978 ahd_restart(ahd); 7956
7979 /* 7957 /*
7980 * Freeze the SIMQ until our poller can determine that 7958 * Revert to async/narrow transfers until we renegotiate.
7981 * the bus reset has really gone away. We set the initial
7982 * timer to 0 to have the check performed as soon as possible
7983 * from the timer context.
7984 */ 7959 */
7985 if ((ahd->flags & AHD_RESET_POLL_ACTIVE) == 0) { 7960 for (target = 0; target <= max_scsiid; target++) {
7986 ahd->flags |= AHD_RESET_POLL_ACTIVE;
7987 ahd_freeze_simq(ahd);
7988 ahd_timer_reset(&ahd->reset_timer, 0, ahd_reset_poll, ahd);
7989 }
7990 return (found);
7991}
7992 7961
7962 if (ahd->enabled_targets[target] == NULL)
7963 continue;
7964 for (initiator = 0; initiator <= max_scsiid; initiator++) {
7965 struct ahd_devinfo devinfo;
7993 7966
7994#define AHD_RESET_POLL_US 1000 7967 ahd_compile_devinfo(&devinfo, target, initiator,
7995static void 7968 CAM_LUN_WILDCARD,
7996ahd_reset_poll(void *arg) 7969 'A', ROLE_UNKNOWN);
7997{ 7970 ahd_set_width(ahd, &devinfo, MSG_EXT_WDTR_BUS_8_BIT,
7998 struct ahd_softc *ahd = arg; 7971 AHD_TRANS_CUR, /*paused*/TRUE);
7999 u_int scsiseq1; 7972 ahd_set_syncrate(ahd, &devinfo, /*period*/0,
8000 u_long s; 7973 /*offset*/0, /*ppr_options*/0,
8001 7974 AHD_TRANS_CUR, /*paused*/TRUE);
8002 ahd_lock(ahd, &s); 7975 }
8003 ahd_pause(ahd);
8004 ahd_update_modes(ahd);
8005 ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI);
8006 ahd_outb(ahd, CLRSINT1, CLRSCSIRSTI);
8007 if ((ahd_inb(ahd, SSTAT1) & SCSIRSTI) != 0) {
8008 ahd_timer_reset(&ahd->reset_timer, AHD_RESET_POLL_US,
8009 ahd_reset_poll, ahd);
8010 ahd_unpause(ahd);
8011 ahd_unlock(ahd, &s);
8012 return;
8013 } 7976 }
8014 7977
8015 /* Reset is now low. Complete chip reinitialization. */ 7978 ahd_restart(ahd);
8016 ahd_outb(ahd, SIMODE1, ahd_inb(ahd, SIMODE1) | ENSCSIRST); 7979
8017 scsiseq1 = ahd_inb(ahd, SCSISEQ_TEMPLATE); 7980 return (found);
8018 ahd_outb(ahd, SCSISEQ1, scsiseq1 & (ENSELI|ENRSELI|ENAUTOATNP));
8019 ahd_unpause(ahd);
8020 ahd->flags &= ~AHD_RESET_POLL_ACTIVE;
8021 ahd_unlock(ahd, &s);
8022 ahd_release_simq(ahd);
8023} 7981}
8024 7982
8025/**************************** Statistics Processing ***************************/ 7983/**************************** Statistics Processing ***************************/
diff --git a/drivers/scsi/aic7xxx/aic79xx_osm.c b/drivers/scsi/aic7xxx/aic79xx_osm.c
index bcced0a417e6..66e4a47bb9ee 100644
--- a/drivers/scsi/aic7xxx/aic79xx_osm.c
+++ b/drivers/scsi/aic7xxx/aic79xx_osm.c
@@ -782,6 +782,7 @@ ahd_linux_bus_reset(struct scsi_cmnd *cmd)
782{ 782{
783 struct ahd_softc *ahd; 783 struct ahd_softc *ahd;
784 int found; 784 int found;
785 unsigned long flags;
785 786
786 ahd = *(struct ahd_softc **)cmd->device->host->hostdata; 787 ahd = *(struct ahd_softc **)cmd->device->host->hostdata;
787#ifdef AHD_DEBUG 788#ifdef AHD_DEBUG
@@ -789,8 +790,11 @@ ahd_linux_bus_reset(struct scsi_cmnd *cmd)
789 printf("%s: Bus reset called for cmd %p\n", 790 printf("%s: Bus reset called for cmd %p\n",
790 ahd_name(ahd), cmd); 791 ahd_name(ahd), cmd);
791#endif 792#endif
793 ahd_lock(ahd, &flags);
794
792 found = ahd_reset_channel(ahd, scmd_channel(cmd) + 'A', 795 found = ahd_reset_channel(ahd, scmd_channel(cmd) + 'A',
793 /*initiate reset*/TRUE); 796 /*initiate reset*/TRUE);
797 ahd_unlock(ahd, &flags);
794 798
795 if (bootverbose) 799 if (bootverbose)
796 printf("%s: SCSI bus reset delivered. " 800 printf("%s: SCSI bus reset delivered. "