diff options
author | ken <ken@FreeBSD.org> | 1999-05-06 20:16:39 +0000 |
---|---|---|
committer | ken <ken@FreeBSD.org> | 1999-05-06 20:16:39 +0000 |
commit | 2bb789d7a3f2adcda33230cdaeda95918cf54a8d (patch) | |
tree | 73c8cd7f798e8bccec0dbcf97e5d0e4447a4ec4e /sys/cam | |
parent | f57a01ebfcda8effff50ce6f1c90b572e76d8cd2 (diff) | |
download | FreeBSD-src-2bb789d7a3f2adcda33230cdaeda95918cf54a8d.zip FreeBSD-src-2bb789d7a3f2adcda33230cdaeda95918cf54a8d.tar.gz |
Add a number of interrelated CAM feature enhancements and bug fixes.
NOTE: These changes will require recompilation of any userland
applications, like cdrecord, xmcd, etc., that use the CAM passthrough
interface. A make world is recommended.
camcontrol.[c8]:
- We now support two new commands, "tags" and "negotiate".
- The tags commands allows users to view the number of tagged
openings for a device as well as a number of other related
parameters, and it allows users to set tagged openings for
a device.
- The negotiate command allows users to enable and disable
disconnection and tagged queueing, set sync rates, offsets
and bus width. Note that not all of those features are
available for all controllers. Only the adv, ahc, and ncr
drivers fully support all of the features at this point.
Some cards do not allow the setting of sync rates, offsets and
the like, and some of the drivers don't have any facilities to
do so. Some drivers, like the adw driver, only support enabling
or disabling sync negotiation, but do not support setting sync
rates.
- new description in the camcontrol man page of how to format a disk
- cleanup of the camcontrol inquiry command
- add support in the 'devlist' command for skipping unconfigured devices if
-v was not specified on the command line.
- make use of the new base_transfer_speed in the path inquiry CCB.
- fix CCB bzero cases
cam_xpt.c, cam_sim.[ch], cam_ccb.h:
- new flags on many CCB function codes to designate whether they're
non-immediate, use a user-supplied CCB, and can only be passed from
userland programs via the xpt device. Use these flags in the transport
layer and pass driver to categorize CCBs.
- new flag in the transport layer device matching code for device nodes
that indicates whether a device is unconfigured
- bump the CAM version from 0x10 to 0x11
- Change the CAM ioctls to use the version as their group code, so we can
force users to recompile code even when the CCB size doesn't change.
- add + fill in a new value in the path inquiry CCB, base_transfer_speed.
Remove a corresponding field from the cam_sim structure, and add code to
every SIM to set this field to the proper value.
- Fix the set transfer settings code in the transport layer.
scsi_cd.c:
- make some variables volatile instead of just casting them in various
places
- fix a race condition in the changer code
- attach unless we get a "logical unit not supported" error. This should
fix all of the cases where people have devices that return weird errors
when they don't have media in the drive.
scsi_da.c:
- attach unless we get a "logical unit not supported" error
scsi_pass.c:
- for immediate CCBs, just malloc a CCB to send the user request in. This
gets rid of the 'held' count problem in camcontrol tags.
scsi_pass.h:
- change the CAM ioctls to use the CAM version as their group code.
adv driver:
- Allow changing the sync rate and offset separately.
adw driver
- Allow changing the sync rate and offset separately.
aha driver:
- Don't return CAM_REQ_CMP for SET_TRAN_SETTINGS CCBs.
ahc driver:
- Allow setting offset and sync rate separately
bt driver:
- Don't return CAM_REQ_CMP for SET_TRAN_SETTINGS CCBs.
NCR driver:
- Fix the ultra/ultra 2 negotiation bug
- allow setting both the sync rate and offset separately
Other HBA drivers:
- Put code in to set the base_transfer_speed field for
XPT_GET_TRAN_SETTINGS CCBs.
Reviewed by: gibbs, mjacob (isp), imp (aha)
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 5c04dfa..67b5934 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 7020441..feaf9ed 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 183bced..53e7937 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 59c5883..b57bdbf 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 787abc7..dc23ab3 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 388939d..b603b17 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 927b1b8..2f5d973 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 501598b..12ad2e2 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 |