summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authormjacob <mjacob@FreeBSD.org>1999-02-09 01:08:38 +0000
committermjacob <mjacob@FreeBSD.org>1999-02-09 01:08:38 +0000
commit1815bac109437d15902e21da2d84b97678da763c (patch)
tree2bd450434ba08b919dc69ef39c12a6decf10f8ad /sys
parent831285f6342351af2e13b1c7fba741e12a235841 (diff)
downloadFreeBSD-src-1815bac109437d15902e21da2d84b97678da763c.zip
FreeBSD-src-1815bac109437d15902e21da2d84b97678da763c.tar.gz
Allow fibre channel 'bus resets' to go through. Handle Loop Down/Loop Up
events by freezing/unfreezing the simq- nice to have such control at this level! Do bus resets in attach layer (non-CAM defined code).
Diffstat (limited to 'sys')
-rw-r--r--sys/dev/isp/isp_freebsd.c56
1 files changed, 43 insertions, 13 deletions
diff --git a/sys/dev/isp/isp_freebsd.c b/sys/dev/isp/isp_freebsd.c
index affe4f6..ee56cf6 100644
--- a/sys/dev/isp/isp_freebsd.c
+++ b/sys/dev/isp/isp_freebsd.c
@@ -1,5 +1,5 @@
-/* $Id: isp_freebsd.c,v 1.10 1998/12/28 19:22:26 mjacob Exp $ */
-/* release_01_29_99 */
+/* $Id: isp_freebsd.c,v 1.11 1999/01/30 07:29:00 mjacob Exp $ */
+/* release_02_05_99 */
/*
* Platform (FreeBSD) dependent common attachment code for Qlogic adapters.
*
@@ -346,8 +346,10 @@ isp_action(struct cam_sim *sim, union ccb *ccb)
} else {
*dptr &= ~DPARM_SYNC;
}
- IDPRINTF(3, ("%s: target %d new dev_flags 0x%x\n",
- isp->isp_name, tgt,
+ IDPRINTF(3, ("%s: set target %d period %d offset %d "
+ "dev_flags 0x%x\n", isp->isp_name, tgt,
+ sdp->isp_devparam[tgt].sync_period,
+ sdp->isp_devparam[tgt].sync_offset,
sdp->isp_devparam[tgt].dev_flags));
s = splcam();
sdp->isp_devparam[tgt].dev_update = 1;
@@ -450,18 +452,16 @@ isp_action(struct cam_sim *sim, union ccb *ccb)
break;
}
case XPT_RESET_BUS: /* Reset the specified bus */
- if (isp->isp_type & ISP_HA_FC) {
- ccb->ccb_h.status = CAM_REQ_CMP;
- xpt_done(ccb);
- break;
- }
s = splcam();
error = isp_control(isp, ISPCTL_RESET_BUS, NULL);
(void) splx(s);
if (error)
ccb->ccb_h.status = CAM_REQ_CMP_ERR;
- else
+ else {
+ if (isp->isp_path != NULL)
+ xpt_async(AC_BUS_RESET, isp->isp_path, NULL);
ccb->ccb_h.status = CAM_REQ_CMP;
+ }
xpt_done(ccb);
break;
@@ -548,6 +548,10 @@ isp_done(struct ccb_scsiio *sccb)
}
}
if (isp->isp_osinfo.simqfrozen) {
+
+ xpt_print_path(sccb->ccb_h.path);
+ printf("isp_done releasing SIMQ\n");
+
sccb->ccb_h.status |= CAM_RELEASE_SIMQ;
isp->isp_osinfo.simqfrozen = 0;
}
@@ -568,6 +572,29 @@ isp_async(isp, cmd, arg)
{
int rv = 0;
switch (cmd) {
+ case ISPASYNC_LOOP_DOWN:
+ if (isp->isp_path) {
+ /*
+ * We can get multiple LOOP downs, so only count one.
+ */
+ if (isp->isp_osinfo.simqfrozen == 0) {
+ xpt_freeze_simq(isp->isp_sim, 1);
+ isp->isp_osinfo.simqfrozen = 1;
+ xpt_print_path(isp->isp_path);
+ printf("freezing SIMQ until loop comes up\n");
+ }
+ }
+ break;
+ case ISPASYNC_LOOP_UP:
+ if (isp->isp_path) {
+ xpt_print_path(isp->isp_path);
+ if (isp->isp_osinfo.simqfrozen) {
+ isp->isp_osinfo.simqfrozen = 0;
+ printf("releasing frozen SIMQ\n");
+ xpt_release_simq(isp->isp_sim, 1);
+ }
+ }
+ break;
case ISPASYNC_NEW_TGT_PARAMS:
if (isp->isp_type & ISP_HA_SCSI) {
int flags, tgt;
@@ -603,9 +630,9 @@ isp_async(isp, cmd, arg)
neg.valid |= CCB_TRANS_SYNC_RATE_VALID |
CCB_TRANS_SYNC_OFFSET_VALID;
}
- xpt_print_path(tmppath);
- printf("new target params period %d offset %d\n",
- neg.sync_period, neg.sync_offset);
+ IDPRINTF(3, ("%s: new params target %d period %d "
+ "offset %d flags 0x%x\n", isp->isp_name, tgt,
+ neg.sync_period, neg.sync_offset, flags));
xpt_setup_ccb(&neg.ccb_h, tmppath, 1);
xpt_async(AC_TRANSFER_NEG, tmppath, &neg);
xpt_free_path(tmppath);
@@ -662,6 +689,9 @@ isp_attach(struct ispsoftc *isp)
((sdparam *)isp->isp_param)->isp_initiator_id;
scbus->maxtarg = MAX_TARGETS-1;
}
+
+ (void) isp_control(isp, ISPCTL_RESET_BUS, NULL);
+
/*
* Prepare the scsibus_data area for the upperlevel scsi code.
*/
OpenPOWER on IntegriCloud