summaryrefslogtreecommitdiff
path: root/sys/cam
diff options
context:
space:
mode:
Diffstat (limited to 'sys/cam')
-rw-r--r--sys/cam/cam_ccb.h120
-rw-r--r--sys/cam/cam_sim.c13
-rw-r--r--sys/cam/cam_sim.h13
-rw-r--r--sys/cam/cam_xpt.c68
-rw-r--r--sys/cam/scsi/scsi_cd.c35
-rw-r--r--sys/cam/scsi/scsi_da.c13
-rw-r--r--sys/cam/scsi/scsi_pass.c48
-rw-r--r--sys/cam/scsi/scsi_pass.h8
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