diff --git a/drivers/scsi/aic7xxx/aic79xx.h b/drivers/scsi/aic7xxx/aic79xx.h index 933e5101edf6..bb5166da4358 100644 --- a/drivers/scsi/aic7xxx/aic79xx.h +++ b/drivers/scsi/aic7xxx/aic79xx.h @@ -589,7 +589,7 @@ typedef enum { SCB_PACKETIZED = 0x00800, SCB_EXPECT_PPR_BUSFREE = 0x01000, SCB_PKT_SENSE = 0x02000, - SCB_CMDPHASE_ABORT = 0x04000, + SCB_EXTERNAL_RESET = 0x04000,/* Device was reset externally */ SCB_ON_COL_LIST = 0x08000, SCB_SILENT = 0x10000 /* * Be quiet about transmission type diff --git a/drivers/scsi/aic7xxx/aic79xx_core.c b/drivers/scsi/aic7xxx/aic79xx_core.c index 880a10def1aa..08771f6f6859 100644 --- a/drivers/scsi/aic7xxx/aic79xx_core.c +++ b/drivers/scsi/aic7xxx/aic79xx_core.c @@ -1053,12 +1053,10 @@ ahd_handle_seqint(struct ahd_softc *ahd, u_int intstat) * If a target takes us into the command phase * assume that it has been externally reset and * has thus lost our previous packetized negotiation - * agreement. Since we have not sent an identify - * message and may not have fully qualified the - * connection, we change our command to TUR, assert - * ATN and ABORT the task when we go to message in - * phase. The OSM will see the REQUEUE_REQUEST - * status and retry the command. + * agreement. + * Revert to async/narrow transfers until we + * can renegotiate with the device and notify + * the OSM about the reset. */ scbid = ahd_get_scbptr(ahd); scb = ahd_lookup_scb(ahd, scbid); @@ -1085,31 +1083,15 @@ ahd_handle_seqint(struct ahd_softc *ahd, u_int intstat) ahd_set_syncrate(ahd, &devinfo, /*period*/0, /*offset*/0, /*ppr_options*/0, AHD_TRANS_ACTIVE, /*paused*/TRUE); - ahd_outb(ahd, SCB_CDB_STORE, 0); - ahd_outb(ahd, SCB_CDB_STORE+1, 0); - ahd_outb(ahd, SCB_CDB_STORE+2, 0); - ahd_outb(ahd, SCB_CDB_STORE+3, 0); - ahd_outb(ahd, SCB_CDB_STORE+4, 0); - ahd_outb(ahd, SCB_CDB_STORE+5, 0); - ahd_outb(ahd, SCB_CDB_LEN, 6); - scb->hscb->control &= ~(TAG_ENB|SCB_TAG_TYPE); - scb->hscb->control |= MK_MESSAGE; - ahd_outb(ahd, SCB_CONTROL, scb->hscb->control); - ahd_outb(ahd, MSG_OUT, HOST_MSG); - ahd_outb(ahd, SAVED_SCSIID, scb->hscb->scsiid); - /* - * The lun is 0, regardless of the SCB's lun - * as we have not sent an identify message. - */ - ahd_outb(ahd, SAVED_LUN, 0); - ahd_outb(ahd, SEQ_FLAGS, 0); - ahd_assert_atn(ahd); - scb->flags &= ~SCB_PACKETIZED; - scb->flags |= SCB_ABORT|SCB_CMDPHASE_ABORT; + scb->flags |= SCB_EXTERNAL_RESET; ahd_freeze_devq(ahd, scb); ahd_set_transaction_status(scb, CAM_REQUEUE_REQ); ahd_freeze_scb(scb); + /* Notify XPT */ + ahd_send_async(ahd, devinfo.channel, devinfo.target, + CAM_LUN_WILDCARD, AC_SENT_BDR, NULL); + /* * Allow the sequencer to continue with * non-pack processing. @@ -2218,22 +2200,6 @@ ahd_handle_nonpkt_busfree(struct ahd_softc *ahd) if (sent_msg == MSG_ABORT_TAG) tag = SCB_GET_TAG(scb); - if ((scb->flags & SCB_CMDPHASE_ABORT) != 0) { - /* - * This abort is in response to an - * unexpected switch to command phase - * for a packetized connection. Since - * the identify message was never sent, - * "saved lun" is 0. We really want to - * abort only the SCB that encountered - * this error, which could have a different - * lun. The SCB will be retried so the OS - * will see the UA after renegotiating to - * packetized. - */ - tag = SCB_GET_TAG(scb); - saved_lun = scb->hscb->lun; - } found = ahd_abort_scbs(ahd, target, 'A', saved_lun, tag, ROLE_INITIATOR, CAM_REQ_ABORTED);