From 93834f413c7f91e7f12f82e673769c9501f56bca Mon Sep 17 00:00:00 2001 From: mjacob Date: Fri, 14 Jul 2000 19:45:43 +0000 Subject: Pick up some changes from Justin (add tagged queing support, remember to splx(s) if cam_extend_get fails and we return ENXIO, reset ccb flags when we push ATIOs back to the SIM, do some data increment fixes, set priority of command based on whether CAM_DIS_DISCONNECT is set and related changes). Add in some more CAM_DEBUG_PERIPH debug statements and also add in support for TARGIODEBUG which then will enable or disable CAM_DEBUG_PERIPH tracing for an instance. --- sys/cam/scsi/scsi_target.c | 111 +++++++++++++++++++++++++++++++++++++++------ 1 file changed, 96 insertions(+), 15 deletions(-) diff --git a/sys/cam/scsi/scsi_target.c b/sys/cam/scsi/scsi_target.c index 4ad19bf..a1acea0 100644 --- a/sys/cam/scsi/scsi_target.c +++ b/sys/cam/scsi/scsi_target.c @@ -489,7 +489,7 @@ targctor(struct cam_periph *periph, void *arg) softc->inq_data->version = 2; softc->inq_data->response_format = 2; /* SCSI2 Inquiry Format */ softc->inq_data->flags = - cpi->hba_inquiry & (PI_SDTR_ABLE|PI_WIDE_16|PI_WIDE_32); + cpi->hba_inquiry & (PI_SDTR_ABLE|PI_WIDE_16|PI_WIDE_32|PI_TAG_ABLE); softc->inq_data->additional_length = softc->inq_data_len - 4; strncpy(softc->inq_data->vendor, "FreeBSD ", SID_VENDOR_SIZE); strncpy(softc->inq_data->product, "TM-PT ", SID_PRODUCT_SIZE); @@ -548,8 +548,8 @@ targopen(dev_t dev, int flags, int fmt, struct proc *p) s = splsoftcam(); periph = cam_extend_get(targperiphs, unit); if (periph == NULL) { - return (ENXIO); splx(s); + return (ENXIO); } if ((error = cam_periph_lock(periph, PRIBIO | PCATCH)) != 0) { splx(s); @@ -819,6 +819,7 @@ targioctl(dev_t dev, u_long cmd, caddr_t addr, int flag, struct proc *p) TAILQ_REMOVE(&softc->unknown_atio_queue, ccbh, periph_links.tqe); /* Requeue the ATIO back to the controller */ + ccbh->ccb_flags = TARG_CCB_NONE; xpt_action((union ccb *)ccbh); ccbh = TAILQ_FIRST(&softc->unknown_atio_queue); } @@ -889,6 +890,39 @@ targioctl(dev_t dev, u_long cmd, caddr_t addr, int flag, struct proc *p) } break; } +#ifdef CAMDEBUG + case TARGIODEBUG: + { + union ccb ccb; + bzero (&ccb, sizeof ccb); + if (xpt_create_path(&ccb.ccb_h.path, periph, + xpt_path_path_id(periph->path), + xpt_path_target_id(periph->path), + xpt_path_lun_id(periph->path)) != CAM_REQ_CMP) { + error = EINVAL; + break; + } + if (*((int *)addr)) { + ccb.cdbg.flags = CAM_DEBUG_PERIPH; + } else { + ccb.cdbg.flags = CAM_DEBUG_NONE; + } + xpt_setup_ccb(&ccb.ccb_h, ccb.ccb_h.path, 0); + ccb.ccb_h.func_code = XPT_DEBUG; + ccb.ccb_h.path_id = xpt_path_path_id(ccb.ccb_h.path); + ccb.ccb_h.target_id = xpt_path_target_id(ccb.ccb_h.path); + ccb.ccb_h.target_lun = xpt_path_lun_id(ccb.ccb_h.path); + ccb.ccb_h.cbfcnp = targdone; + xpt_action(&ccb); + if ((ccb.ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) { + error = EIO; + } else { + error = 0; + } + xpt_free_path(ccb.ccb_h.path); + break; + } +#endif default: error = ENOTTY; break; @@ -1263,18 +1297,20 @@ targrunqueue(struct cam_periph *periph, struct targ_softc *softc) desc->data = &bp->bio_data[bp->bio_bcount - bp->bio_resid]; desc->data_increment = MIN(desc->data_resid, bp->bio_resid); - desc->data_increment = - MIN(desc->data_increment, 32); } CAM_DEBUG(periph->path, CAM_DEBUG_PERIPH, ("Buffer command: data %p: datacnt %d\n", - (intptr_t)desc->data, desc->data_increment)); + desc->data, desc->data_increment)); TAILQ_INSERT_TAIL(&softc->work_queue, &atio->ccb_h, periph_links.tqe); } - if (TAILQ_FIRST(&softc->work_queue) != NULL) { + atio = (struct ccb_accept_tio *)TAILQ_FIRST(&softc->work_queue); + if (atio != NULL) { + int priority; + + priority = (atio->ccb_h.flags & CAM_DIS_DISCONNECT) ? 0 : 1; splx(s); - xpt_schedule(periph, /*XXX priority*/1); + xpt_schedule(periph, priority); } else splx(s); } @@ -1353,10 +1389,23 @@ targstart(struct cam_periph *periph, union ccb *start_ccb) start_ccb->ccb_h.ccb_flags = TARG_CCB_NONE; start_ccb->ccb_h.ccb_atio = atio; CAM_DEBUG(periph->path, CAM_DEBUG_PERIPH, - ("Sending a CTIO\n")); + ("Sending a CTIO (flags 0x%x)\n", csio->ccb_h.flags)); TAILQ_INSERT_TAIL(&softc->pending_queue, &csio->ccb_h, periph_links.tqe); xpt_action(start_ccb); + /* + * If the queue was frozen waiting for the response + * to this ATIO (for instance disconnection was disallowed), + * then release it now that our response has been queued. + */ + if ((atio->ccb_h.flags & CAM_DEV_QFRZN) != 0) { + cam_release_devq(periph->path, + /*relsim_flags*/0, + /*reduction*/0, + /*timeout*/0, + /*getcount_only*/0); + atio->ccb_h.flags &= ~CAM_DEV_QFRZN; + } s = splbio(); ccbh = TAILQ_FIRST(&softc->work_queue); splx(s); @@ -1378,6 +1427,12 @@ targdone(struct cam_periph *periph, union ccb *done_ccb) return; } + CAM_DEBUG(periph->path, CAM_DEBUG_PERIPH, + ("targdone %x\n", done_ccb->ccb_h.func_code)); + + CAM_DEBUG(periph->path, CAM_DEBUG_PERIPH, + ("targdone %x\n", done_ccb->ccb_h.func_code)); + switch (done_ccb->ccb_h.func_code) { case XPT_ACCEPT_TARGET_IO: { @@ -1385,6 +1440,7 @@ targdone(struct cam_periph *periph, union ccb *done_ccb) struct targ_cmd_desc *descr; struct initiator_state *istate; u_int8_t *cdb; + int priority; atio = &done_ccb->atio; descr = (struct targ_cmd_desc*)atio->ccb_h.ccb_descr; @@ -1398,6 +1454,8 @@ targdone(struct cam_periph *periph, union ccb *done_ccb) } if (atio->sense_len != 0) { + CAM_DEBUG(periph->path, CAM_DEBUG_PERIPH, + ("ATIO with sense_len\n")); /* * We had an error in the reception of @@ -1416,6 +1474,9 @@ targdone(struct cam_periph *periph, union ccb *done_ccb) && istate->pending_ua != 0 && cdb[0] != INQUIRY) { + CAM_DEBUG(periph->path, CAM_DEBUG_PERIPH, + ("pending_ca %d pending_ua %dn", istate->pending_ca, istate->pending_ua)); + /* Pending UA, tell initiator */ /* Direction is always relative to the initator */ atio->ccb_h.flags &= ~CAM_DIR_MASK; @@ -1451,6 +1512,10 @@ targdone(struct cam_periph *periph, union ccb *done_ccb) if (pending_ca == CA_UNIT_ATTN) istate->pending_ua = UA_NONE; + CAM_DEBUG(periph->path, CAM_DEBUG_PERIPH, + ("cdb[..] = %x %x %x %x %x %x\n", + cdb[0], cdb[1], cdb[2], cdb[3], + cdb[4], cdb[5])); /* * Determine the type of incoming command and * setup our buffer for a response. @@ -1518,8 +1583,9 @@ targdone(struct cam_periph *periph, union ccb *done_ccb) atio->ccb_h.flags &= ~CAM_DIR_MASK; atio->ccb_h.flags |= CAM_DIR_IN; descr->data = softc->inq_data; - descr->data_resid = MIN(softc->inq_data_len, - inq->length); + descr->data_resid = + MIN(softc->inq_data_len, + SCSI_CDB6_LEN(inq->length)); descr->data_increment = descr->data_resid; descr->timeout = 5 * 1000; break; @@ -1559,8 +1625,9 @@ targdone(struct cam_periph *periph, union ccb *done_ccb) offsetof(struct scsi_sense_data, extra_len) + sense->extra_len; - descr->data_resid = MIN(descr->data_resid, - rsense->length); + descr->data_resid = + MIN(descr->data_resid, + SCSI_CDB6_LEN(rsense->length)); descr->data_increment = descr->data_resid; descr->timeout = 5 * 1000; descr->status = SCSI_STATUS_OK; @@ -1624,9 +1691,16 @@ targdone(struct cam_periph *periph, union ccb *done_ccb) } /* Queue us up to receive a Continue Target I/O ccb. */ - TAILQ_INSERT_TAIL(&softc->work_queue, &atio->ccb_h, - periph_links.tqe); - xpt_schedule(periph, /*priority*/1); + if ((atio->ccb_h.flags & CAM_DIS_DISCONNECT) != 0) { + TAILQ_INSERT_HEAD(&softc->work_queue, &atio->ccb_h, + periph_links.tqe); + priority = 0; + } else { + TAILQ_INSERT_TAIL(&softc->work_queue, &atio->ccb_h, + periph_links.tqe); + priority = 1; + } + xpt_schedule(periph, priority); break; } case XPT_CONT_TARGET_IO: @@ -1679,6 +1753,8 @@ targdone(struct cam_periph *periph, union ccb *done_ccb) istate->pending_ca = CA_NONE; softc->istate[csio->init_id].pending_ca = CA_NONE; done_ccb->ccb_h.status &= ~CAM_SENT_SENSE; + CAM_DEBUG(periph->path, CAM_DEBUG_PERIPH, + ("Sent Sense\n")); } done_ccb->ccb_h.flags &= ~CAM_SEND_SENSE; @@ -1721,6 +1797,7 @@ targdone(struct cam_periph *periph, union ccb *done_ccb) */ CAM_DEBUG(periph->path, CAM_DEBUG_PERIPH, ("Returning ATIO to target\n")); + atio->ccb_h.ccb_flags = TARG_CCB_NONE; xpt_action((union ccb *)atio); break; } @@ -1785,6 +1862,9 @@ targdone(struct cam_periph *periph, union ccb *done_ccb) /*getcount_only*/0); break; } + case XPT_DEBUG: + wakeup(&done_ccb->ccb_h.cbfcnp); + break; default: panic("targdone: Impossible xpt opcode %x encountered.", done_ccb->ccb_h.func_code); @@ -2172,6 +2252,7 @@ abort_pending_transactions(struct cam_periph *periph, u_int initiator_id, free(atio, M_DEVBUF); } else { /* Return the ATIO back to the controller */ + atio->ccb_h.ccb_flags = TARG_CCB_NONE; xpt_action((union ccb *)atio); } } -- cgit v1.1