diff options
Diffstat (limited to 'sys/cam')
-rw-r--r-- | sys/cam/cam_ccb.h | 120 | ||||
-rw-r--r-- | sys/cam/cam_sim.c | 13 | ||||
-rw-r--r-- | sys/cam/cam_sim.h | 13 | ||||
-rw-r--r-- | sys/cam/cam_xpt.c | 68 | ||||
-rw-r--r-- | sys/cam/scsi/scsi_cd.c | 35 | ||||
-rw-r--r-- | sys/cam/scsi/scsi_da.c | 13 | ||||
-rw-r--r-- | sys/cam/scsi/scsi_pass.c | 48 | ||||
-rw-r--r-- | sys/cam/scsi/scsi_pass.h | 8 |
8 files changed, 204 insertions, 114 deletions
diff --git a/sys/cam/cam_ccb.h b/sys/cam/cam_ccb.h index 5c04dfa02634..67b5934e0c68 100644 --- a/sys/cam/cam_ccb.h +++ b/sys/cam/cam_ccb.h @@ -25,7 +25,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: cam_ccb.h,v 1.3 1998/12/10 04:05:49 gibbs Exp $ + * $Id: cam_ccb.h,v 1.4 1999/03/05 23:13:20 gibbs Exp $ */ #ifndef _CAM_CAM_CCB_H @@ -98,61 +98,96 @@ typedef enum { /* XPT Opcodes for xpt_action */ typedef enum { +/* Function code flags are bits greater than 0xff */ + XPT_FC_QUEUED = 0x100, + /* Non-immediate function code */ + XPT_FC_USER_CCB = 0x200, + XPT_FC_XPT_ONLY = 0x400, + /* Only for the transport layer device */ /* Common function commands: 0x00->0x0F */ - XPT_NOOP, /* Execute Nothing */ - XPT_SCSI_IO, /* Execute the requested I/O operation */ - XPT_GDEV_TYPE, /* Get type information for specified device */ - XPT_GDEVLIST, /* Get a list of peripheral devices */ - XPT_PATH_INQ, /* Path routing inquiry */ - XPT_REL_SIMQ, /* Release a frozen SIM queue */ - XPT_SASYNC_CB, /* Set Asynchronous Callback Parameters */ - XPT_SDEV_TYPE, /* Set device type information */ - XPT_SCAN_BUS, /* (Re)Scan the SCSI Bus */ - XPT_DEV_MATCH, /* Get EDT entries matching the given pattern */ - XPT_DEBUG, /* Turn on debugging for a bus, target or lun */ + XPT_NOOP = 0x00, + /* Execute Nothing */ + XPT_SCSI_IO = 0x01 | XPT_FC_QUEUED, + /* Execute the requested I/O operation */ + XPT_GDEV_TYPE = 0x02, + /* Get type information for specified device */ + XPT_GDEVLIST = 0x03, + /* Get a list of peripheral devices */ + XPT_PATH_INQ = 0x04, + /* Path routing inquiry */ + XPT_REL_SIMQ = 0x05, + /* Release a frozen SIM queue */ + XPT_SASYNC_CB = 0x06, + /* Set Asynchronous Callback Parameters */ + XPT_SDEV_TYPE = 0x07, + /* Set device type information */ + XPT_SCAN_BUS = 0x08 | XPT_FC_QUEUED | XPT_FC_USER_CCB + | XPT_FC_XPT_ONLY, + /* (Re)Scan the SCSI Bus */ + XPT_DEV_MATCH = 0x09 | XPT_FC_XPT_ONLY, + /* Get EDT entries matching the given pattern */ + XPT_DEBUG = 0x0a, + /* Turn on debugging for a bus, target or lun */ /* SCSI Control Functions: 0x10->0x1F */ - XPT_ABORT = 0x10, /* Abort the specified CCB */ - XPT_RESET_BUS, /* Reset the specified SCSI bus */ - XPT_RESET_DEV, /* Bus Device Reset the specified SCSI device */ - XPT_TERM_IO, /* Terminate the I/O process */ - XPT_SCAN_LUN, /* Scan Logical Unit */ - XPT_GET_TRAN_SETTINGS, /* + XPT_ABORT = 0x10, + /* Abort the specified CCB */ + XPT_RESET_BUS = 0x11 | XPT_FC_XPT_ONLY, + /* Reset the specified SCSI bus */ + XPT_RESET_DEV = 0x12, + /* Bus Device Reset the specified SCSI device */ + XPT_TERM_IO = 0x13, + /* Terminate the I/O process */ + XPT_SCAN_LUN = 0x14 | XPT_FC_QUEUED | XPT_FC_USER_CCB + | XPT_FC_XPT_ONLY, + /* Scan Logical Unit */ + XPT_GET_TRAN_SETTINGS = 0x15, + /* * Get default/user transfer settings * for the target */ - XPT_SET_TRAN_SETTINGS, /* + XPT_SET_TRAN_SETTINGS = 0x16, + /* * Set transfer rate/width * negotiation settings */ - XPT_CALC_GEOMETRY, /* + XPT_CALC_GEOMETRY = 0x17, + /* * Calculate the geometry parameters for * a device give the sector size and * volume size. */ /* HBA engine commands 0x20->0x2F */ - XPT_ENG_INQ = 0x20, /* HBA engine feature inquiry */ - XPT_ENG_EXEC, /* HBA execute engine request */ + XPT_ENG_INQ = 0x20 | XPT_FC_XPT_ONLY, + /* HBA engine feature inquiry */ + XPT_ENG_EXEC = 0x21 | XPT_FC_QUEUED | XPT_FC_XPT_ONLY, + /* HBA execute engine request */ /* Target mode commands: 0x30->0x3F */ - XPT_EN_LUN = 0x30, /* Enable LUN as a target */ - XPT_TARGET_IO, /* Execute target I/O request */ - XPT_ACCEPT_TARGET_IO, /* Accept Host Target Mode CDB */ - XPT_CONT_TARGET_IO, /* Continue Host Target I/O Connection */ - XPT_IMMED_NOTIFY, /* Notify Host Target driver of event */ - XPT_NOTIFY_ACK, /* Acknowledgement of event */ + XPT_EN_LUN = 0x30, + /* Enable LUN as a target */ + XPT_TARGET_IO = 0x31 | XPT_FC_QUEUED, + /* Execute target I/O request */ + XPT_ACCEPT_TARGET_IO = 0x32 | XPT_FC_QUEUED | XPT_FC_USER_CCB, + /* Accept Host Target Mode CDB */ + XPT_CONT_TARGET_IO = 0x33 | XPT_FC_QUEUED, + /* Continue Host Target I/O Connection */ + XPT_IMMED_NOTIFY = 0x34 | XPT_FC_QUEUED | XPT_FC_USER_CCB, + /* Notify Host Target driver of event */ + XPT_NOTIFY_ACK = 0x35, + /* Acknowledgement of event */ /* Vendor Unique codes: 0x80->0x8F */ - XPT_VUNIQUE = 0x80 + XPT_VUNIQUE = 0x80 } xpt_opcode; -#define XPT_OPCODE_GROUP_MASK 0xF0 -#define XPT_OPCODE_GROUP(op) ((op) & XPT_OPCODE_GROUP_MASK) -#define XPT_OPCODE_GROUP_COMMON 0x00 -#define XPT_OPCODE_GROUP_SCSI_CONTROL 0x10 -#define XPT_OPCODE_GROUP_HBA_ENGINE 0x20 -#define XPT_OPCODE_GROUP_TMODE 0x30 -#define XPT_OPCODE_GROUP_VENDOR_UNIQUE 0x80 +#define XPT_FC_GROUP_MASK 0xF0 +#define XPT_FC_GROUP(op) ((op) & XPT_FC_GROUP_MASK) +#define XPT_FC_GROUP_COMMON 0x00 +#define XPT_FC_GROUP_SCSI_CONTROL 0x10 +#define XPT_FC_GROUP_HBA_ENGINE 0x20 +#define XPT_FC_GROUP_TMODE 0x30 +#define XPT_FC_GROUP_VENDOR_UNIQUE 0x80 typedef union { LIST_ENTRY(ccb_hdr) le; @@ -216,11 +251,11 @@ struct ccb_getdev { * CCBs held by peripheral drivers * for this device */ - u_int8_t maxtags; /* + int maxtags; /* * Boundary conditions for number of * tagged operations */ - u_int8_t mintags; + int mintags; }; @@ -318,11 +353,17 @@ struct periph_match_result { lun_id_t target_lun; }; +typedef enum { + DEV_RESULT_NOFLAG = 0x00, + DEV_RESULT_UNCONFIGURED = 0x01 +} dev_result_flags; + struct device_match_result { path_id_t path_id; target_id_t target_id; lun_id_t target_lun; struct scsi_inquiry_data inq_data; + dev_result_flags flags; }; struct bus_match_result { @@ -396,7 +437,7 @@ struct ccb_dev_match { /* * Definitions for the path inquiry CCB fields. */ -#define CAM_VERSION 0x10 /* Hex value for current version */ +#define CAM_VERSION 0x11 /* Hex value for current version */ typedef enum { PI_MDP_ABLE = 0x80, /* Supports MDP message */ @@ -444,6 +485,7 @@ struct ccb_pathinq { char dev_name[DEV_IDLEN];/* Device name for SIM */ u_int32_t unit_number; /* Unit number for SIM */ u_int32_t bus_id; /* Bus ID for SIM */ + u_int32_t base_transfer_speed;/* Base bus speed in KB/sec */ }; typedef union { diff --git a/sys/cam/cam_sim.c b/sys/cam/cam_sim.c index 70204411f062..feaf9ed69491 100644 --- a/sys/cam/cam_sim.c +++ b/sys/cam/cam_sim.c @@ -25,7 +25,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id$ + * $Id: cam_sim.c,v 1.1 1998/09/15 06:33:23 gibbs Exp $ */ #include <sys/param.h> @@ -54,8 +54,8 @@ cam_simq_free(struct cam_devq *devq) struct cam_sim * cam_sim_alloc(sim_action_func sim_action, sim_poll_func sim_poll, char *sim_name, void *softc, u_int32_t unit, - u_int32_t max_dev_transactions, - u_int32_t max_tagged_dev_transactions, struct cam_devq *queue) + int max_dev_transactions, + int max_tagged_dev_transactions, struct cam_devq *queue) { struct cam_sim *sim; @@ -80,7 +80,6 @@ cam_sim_alloc(sim_action_func sim_action, sim_poll_func sim_poll, sim->path_id = CAM_PATH_ANY; sim->unit_number = unit; sim->bus_id = 0; /* set in xpt_bus_register */ - sim->base_transfer_speed = 3300; /* asynchronous 3300 kB/sec */ sim->max_tagged_dev_openings = max_tagged_dev_transactions; sim->max_dev_openings = max_dev_transactions; sim->flags = 0; @@ -100,12 +99,6 @@ cam_sim_free(struct cam_sim *sim, int free_devq) } void -cam_sim_set_basexfer_speed(struct cam_sim *sim, u_int32_t base_xfer_speed) -{ - sim->base_transfer_speed = base_xfer_speed; -} - -void cam_sim_set_path(struct cam_sim *sim, u_int32_t path_id) { sim->path_id = path_id; diff --git a/sys/cam/cam_sim.h b/sys/cam/cam_sim.h index 183bcedd8213..53e7937b8570 100644 --- a/sys/cam/cam_sim.h +++ b/sys/cam/cam_sim.h @@ -25,7 +25,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id$ + * $Id: cam_sim.h,v 1.1 1998/09/15 06:33:23 gibbs Exp $ */ #ifndef _CAM_CAM_SIM_H @@ -56,14 +56,12 @@ struct cam_sim * cam_sim_alloc(sim_action_func sim_action, char *sim_name, void *softc, u_int32_t unit, - u_int32_t max_dev_transactions, - u_int32_t max_tagged_dev_transactions, + int max_dev_transactions, + int max_tagged_dev_transactions, struct cam_devq *queue); void cam_sim_free(struct cam_sim *sim, int free_devq); /* Optional sim attributes may be set with these. */ -void cam_sim_set_basexfer_speed(struct cam_sim *sim, - u_int32_t base_xfer_speed); void cam_sim_set_path(struct cam_sim *sim, u_int32_t path_id); @@ -95,9 +93,8 @@ struct cam_sim { u_int32_t path_id;/* The Boot device may set this to 0? */ u_int32_t unit_number; u_int32_t bus_id; - u_int32_t base_transfer_speed; /* in kB/s */ - u_int32_t max_tagged_dev_openings; - u_int32_t max_dev_openings; + int max_tagged_dev_openings; + int max_dev_openings; u_int32_t flags; #define CAM_SIM_REL_TIMEOUT_PENDING 0x01 struct callout_handle c_handle; diff --git a/sys/cam/cam_xpt.c b/sys/cam/cam_xpt.c index 59c5883e1e4f..b57bdbf674f3 100644 --- a/sys/cam/cam_xpt.c +++ b/sys/cam/cam_xpt.c @@ -26,7 +26,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: cam_xpt.c,v 1.53 1999/04/21 07:26:24 peter Exp $ + * $Id: cam_xpt.c,v 1.54 1999/04/23 23:25:48 gibbs Exp $ */ #include <sys/param.h> #include <sys/systm.h> @@ -215,8 +215,8 @@ struct xpt_quirk_entry { u_int8_t quirks; #define CAM_QUIRK_NOLUNS 0x01 #define CAM_QUIRK_NOSERIAL 0x02 - u_int8_t mintags; - u_int8_t maxtags; + u_int mintags; + u_int maxtags; }; typedef enum { @@ -942,6 +942,7 @@ xptioctl(dev_t dev, u_long cmd, caddr_t addr, int flag, struct proc *p) } /* FALLTHROUGH */ case XPT_SCAN_LUN: + case XPT_RESET_DEV: case XPT_ENG_INQ: /* XXX not implemented yet */ case XPT_ENG_EXEC: @@ -1449,8 +1450,15 @@ xpt_announce_periph(struct cam_periph *periph, char *announce_string) freq = scsi_calc_syncsrate(cts.sync_period); speed = freq; } else { + struct ccb_pathinq cpi; + + /* Ask the SIM for its base transfer speed */ + xpt_setup_ccb(&cpi.ccb_h, path, /*priority*/1); + cpi.ccb_h.func_code = XPT_PATH_INQ; + xpt_action((union ccb *)&cpi); + + speed = cpi.base_transfer_speed; freq = 0; - speed = path->bus->sim->base_transfer_speed; } if ((cts.valid & CCB_TRANS_BUS_WIDTH_VALID) != 0) speed *= (0x01 << cts.bus_width); @@ -2043,6 +2051,14 @@ xptedtdevicefunc(struct cam_ed *device, void *arg) bcopy(&device->inq_data, &cdm->matches[j].result.device_result.inq_data, sizeof(struct scsi_inquiry_data)); + + /* Let the user know whether this device is unconfigured */ + if (device->flags & CAM_DEV_UNCONFIGURED) + cdm->matches[j].result.device_result.flags = + DEV_RESULT_UNCONFIGURED; + else + cdm->matches[j].result.device_result.flags = + DEV_RESULT_NOFLAG; } /* @@ -4348,16 +4364,7 @@ xpt_done(union ccb *done_ccb) s = splcam(); CAM_DEBUG(done_ccb->ccb_h.path, CAM_DEBUG_TRACE, ("xpt_done\n")); - switch (done_ccb->ccb_h.func_code) { - case XPT_SCSI_IO: - case XPT_ENG_EXEC: - case XPT_TARGET_IO: - case XPT_ACCEPT_TARGET_IO: - case XPT_CONT_TARGET_IO: - case XPT_IMMED_NOTIFY: - case XPT_SCAN_BUS: - case XPT_SCAN_LUN: - { + if ((done_ccb->ccb_h.func_code & XPT_FC_QUEUED) != 0) { /* * Queue up the request for handling by our SWI handler * any of the "non-immediate" type of ccbs. @@ -4376,10 +4383,6 @@ xpt_done(union ccb *done_ccb) setsoftcamnet(); break; } - break; - } - default: - break; } splx(s); } @@ -5517,6 +5520,7 @@ xpt_set_transfer_settings(struct ccb_trans_settings *cts, struct cam_ed *device, if (async_update == FALSE) { struct scsi_inquiry_data *inq_data; struct ccb_pathinq cpi; + struct ccb_trans_settings cur_cts; if (device == NULL) { cts->ccb_h.status = CAM_PATH_INVALID; @@ -5531,8 +5535,28 @@ xpt_set_transfer_settings(struct ccb_trans_settings *cts, struct cam_ed *device, xpt_setup_ccb(&cpi.ccb_h, cts->ccb_h.path, /*priority*/1); cpi.ccb_h.func_code = XPT_PATH_INQ; xpt_action((union ccb *)&cpi); - + xpt_setup_ccb(&cur_cts.ccb_h, cts->ccb_h.path, /*priority*/1); + cur_cts.ccb_h.func_code = XPT_GET_TRAN_SETTINGS; + cur_cts.flags = CCB_TRANS_CURRENT_SETTINGS; + xpt_action((union ccb *)&cur_cts); inq_data = &device->inq_data; + + /* Fill in any gaps in what the user gave us */ + if ((cts->valid & CCB_TRANS_SYNC_RATE_VALID) == 0) + cts->sync_period = cur_cts.sync_period; + if ((cts->valid & CCB_TRANS_SYNC_OFFSET_VALID) == 0) + cts->sync_offset = cur_cts.sync_offset; + if ((cts->valid & CCB_TRANS_BUS_WIDTH_VALID) == 0) + cts->bus_width = cur_cts.bus_width; + if ((cts->valid & CCB_TRANS_DISC_VALID) == 0) { + cts->flags &= ~CCB_TRANS_DISC_ENB; + cts->flags |= cur_cts.flags & CCB_TRANS_DISC_ENB; + } + if ((cts->valid & CCB_TRANS_TQ_VALID) == 0) { + cts->flags &= ~CCB_TRANS_TAG_ENB; + cts->flags |= cur_cts.flags & CCB_TRANS_TAG_ENB; + } + if ((inq_data->flags & SID_Sync) == 0 || (cpi.hba_inquiry & PI_SDTR_ABLE) == 0) { /* Force async */ @@ -5911,6 +5935,7 @@ xptaction(struct cam_sim *sim, union ccb *work_ccb) strncpy(cpi->dev_name, sim->sim_name, DEV_IDLEN); cpi->unit_number = sim->unit_number; cpi->bus_id = sim->bus_id; + cpi->base_transfer_speed = 0; cpi->ccb_h.status = CAM_REQ_CMP; xpt_done(work_ccb); break; @@ -5984,10 +6009,7 @@ camisr(cam_isrq_t *queue) TRUE); } } - if ((ccb_h->func_code != XPT_ACCEPT_TARGET_IO) - && (ccb_h->func_code != XPT_IMMED_NOTIFY) - && (ccb_h->func_code != XPT_SCAN_LUN) - && (ccb_h->func_code != XPT_SCAN_BUS)) { + if ((ccb_h->func_code & XPT_FC_USER_CCB) == 0) { struct cam_ed *dev; dev = ccb_h->path->device; diff --git a/sys/cam/scsi/scsi_cd.c b/sys/cam/scsi/scsi_cd.c index 787abc71e4a3..dc23ab39e7c4 100644 --- a/sys/cam/scsi/scsi_cd.c +++ b/sys/cam/scsi/scsi_cd.c @@ -24,7 +24,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: scsi_cd.c,v 1.16 1999/04/07 22:57:54 gibbs Exp $ + * $Id: scsi_cd.c,v 1.17 1999/04/19 21:26:17 gibbs Exp $ */ /* * Portions of this driver taken from the original FreeBSD cd driver. @@ -126,7 +126,7 @@ typedef enum { struct cd_softc { cam_pinfo pinfo; cd_state state; - cd_flags flags; + volatile cd_flags flags; struct buf_queue_head buf_queue; LIST_HEAD(, ccb_hdr) pending_ccbs; struct cd_params params; @@ -301,7 +301,7 @@ struct cdchanger { struct cd_softc *cur_device; struct callout_handle short_handle; struct callout_handle long_handle; - cd_changer_flags flags; + volatile cd_changer_flags flags; STAILQ_ENTRY(cdchanger) changer_links; STAILQ_HEAD(chdevlist, cd_softc) chluns; }; @@ -1103,7 +1103,8 @@ cdschedule(struct cam_periph *periph, int priority) * bootstrap things. */ if (((softc->changer->flags & CHANGER_TIMEOUT_SCHED)==0) - &&((softc->changer->flags & CHANGER_NEED_TIMEOUT)==0)){ + && ((softc->changer->flags & CHANGER_NEED_TIMEOUT)==0) + && ((softc->changer->flags & CHANGER_SHORT_TMOUT_SCHED)==0)){ softc->changer->flags |= CHANGER_MANUAL_CALL; cdrunchangerqueue(softc->changer); } @@ -1341,7 +1342,7 @@ cdgetccb(struct cam_periph *periph, u_int32_t priority) * This should work the first time this device is woken up, * but just in case it doesn't, we use a while loop. */ - while ((((volatile cd_flags)softc->flags) & CD_FLAG_ACTIVE)==0){ + while ((softc->flags & CD_FLAG_ACTIVE) == 0) { /* * If this changer isn't already queued, queue it up. */ @@ -1352,10 +1353,10 @@ cdgetccb(struct cam_periph *periph, u_int32_t priority) camq_insert(&softc->changer->devq, (cam_pinfo *)softc); } - if (((((volatile cd_changer_flags)softc->changer->flags) - & CHANGER_TIMEOUT_SCHED)==0) - &&((((volatile cd_changer_flags)softc->changer->flags) - & CHANGER_NEED_TIMEOUT)==0)){ + if (((softc->changer->flags & CHANGER_TIMEOUT_SCHED)==0) + && ((softc->changer->flags & CHANGER_NEED_TIMEOUT)==0) + && ((softc->changer->flags + & CHANGER_SHORT_TMOUT_SCHED)==0)) { softc->changer->flags |= CHANGER_MANUAL_CALL; cdrunchangerqueue(softc->changer); } else @@ -1739,18 +1740,12 @@ cddone(struct cam_periph *periph, union ccb *done_ccb) &asc, &ascq); } /* - * With CDROM devices, we expect 0x3a - * (Medium not present) errors, since not - * everyone leaves a CD in the drive. Some - * broken Philips and HP WORM drives return - * 0x04,0x00 (logical unit not ready, cause - * not reportable), so we accept any "not - * ready" type errors as well. If the error - * is anything else, though, we shouldn't - * attach. + * Attach to anything that claims to be a + * CDROM or WORM device, as long as it + * doesn't return a "Logical unit not + * supported" (0x25) error. */ - if ((have_sense) - && ((asc == 0x3a) || (asc == 0x04)) + if ((have_sense) && (asc != 0x25) && (error_code == SSD_CURRENT_ERROR)) snprintf(announce_buf, sizeof(announce_buf), diff --git a/sys/cam/scsi/scsi_da.c b/sys/cam/scsi/scsi_da.c index 388939d5f7dc..b603b173f69a 100644 --- a/sys/cam/scsi/scsi_da.c +++ b/sys/cam/scsi/scsi_da.c @@ -25,7 +25,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: scsi_da.c,v 1.20 1999/02/10 00:03:15 ken Exp $ + * $Id: scsi_da.c,v 1.21 1999/03/05 23:20:20 gibbs Exp $ */ #include "opt_hw_wdog.h" @@ -1381,13 +1381,12 @@ dadone(struct cam_periph *periph, union ccb *done_ccb) &asc, &ascq); } /* - * With removable media devices, we expect - * 0x3a (Medium not present) errors, since not - * everyone leaves a disk in the drive. If - * the error is anything else, though, we - * shouldn't attach. + * Attach to anything that claims to be a + * direct access or optical disk device, + * as long as it doesn't return a "Logical + * unit not supported" (0x25) error. */ - if ((have_sense) && (asc == 0x3a) + if ((have_sense) && (asc != 0x25) && (error_code == SSD_CURRENT_ERROR)) snprintf(announce_buf, sizeof(announce_buf), diff --git a/sys/cam/scsi/scsi_pass.c b/sys/cam/scsi/scsi_pass.c index 927b1b84e64e..2f5d9732eca2 100644 --- a/sys/cam/scsi/scsi_pass.c +++ b/sys/cam/scsi/scsi_pass.c @@ -24,7 +24,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: scsi_pass.c,v 1.5 1998/11/22 23:44:47 ken Exp $ + * $Id: scsi_pass.c,v 1.6 1999/02/10 00:03:15 ken Exp $ */ #include <sys/param.h> @@ -703,13 +703,55 @@ passioctl(dev_t dev, u_long cmd, caddr_t addr, int flag, struct proc *p) { union ccb *inccb; union ccb *ccb; + int ccb_malloced; inccb = (union ccb *)addr; - ccb = cam_periph_getccb(periph, inccb->ccb_h.pinfo.priority); + + /* + * Some CCB types, like scan bus and scan lun can only go + * through the transport layer device. + */ + if (inccb->ccb_h.func_code & XPT_FC_XPT_ONLY) { + xpt_print_path(periph->path); + printf("CCB function code %#x is restricted to the " + "XPT device\n", inccb->ccb_h.func_code); + error = ENODEV; + break; + } + + /* + * Non-immediate CCBs need a CCB from the per-device pool + * of CCBs, which is scheduled by the transport layer. + * Immediate CCBs and user-supplied CCBs should just be + * malloced. + */ + if ((inccb->ccb_h.func_code & XPT_FC_QUEUED) + && ((inccb->ccb_h.func_code & XPT_FC_USER_CCB) == 0)) { + ccb = cam_periph_getccb(periph, + inccb->ccb_h.pinfo.priority); + ccb_malloced = 0; + } else { + ccb = xpt_alloc_ccb(); + + if (ccb != NULL) + xpt_setup_ccb(&ccb->ccb_h, periph->path, + inccb->ccb_h.pinfo.priority); + ccb_malloced = 1; + } + + if (ccb == NULL) { + xpt_print_path(periph->path); + printf("unable to allocate CCB\n"); + error = ENOMEM; + break; + } error = passsendccb(periph, ccb, inccb); - xpt_release_ccb(ccb); + if (ccb_malloced) + xpt_free_ccb(ccb); + else + xpt_release_ccb(ccb); break; } diff --git a/sys/cam/scsi/scsi_pass.h b/sys/cam/scsi/scsi_pass.h index 501598bf5ff9..12ad2e207c8f 100644 --- a/sys/cam/scsi/scsi_pass.h +++ b/sys/cam/scsi/scsi_pass.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997 Kenneth D. Merry. + * Copyright (c) 1997, 1999 Kenneth D. Merry. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -22,7 +22,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id$ + * $Id: scsi_pass.h,v 1.1 1998/09/15 06:36:34 gibbs Exp $ */ #ifndef _SCSI_PASS_H @@ -32,7 +32,7 @@ #include <cam/cam_ccb.h> -#define CAMIOCOMMAND _IOWR('Q', 2, union ccb) -#define CAMGETPASSTHRU _IOWR('Q', 3, union ccb) +#define CAMIOCOMMAND _IOWR(CAM_VERSION, 2, union ccb) +#define CAMGETPASSTHRU _IOWR(CAM_VERSION, 3, union ccb) #endif |