summaryrefslogtreecommitdiffstats
path: root/sys/dev/amr/amr_cam.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/dev/amr/amr_cam.c')
-rw-r--r--sys/dev/amr/amr_cam.c103
1 files changed, 79 insertions, 24 deletions
diff --git a/sys/dev/amr/amr_cam.c b/sys/dev/amr/amr_cam.c
index b8d7be4..0a6eda8 100644
--- a/sys/dev/amr/amr_cam.c
+++ b/sys/dev/amr/amr_cam.c
@@ -24,6 +24,13 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
+ * 3. The party using or redistributing the source code and binary forms
+ * agrees to the above disclaimer and the terms and conditions set forth
+ * herein.
+ *
+ * Additional Copyright (c) 2002 by Eric Moore under same license.
+ * Additional Copyright (c) 2002 LSI Logic Corporation
+ *
* $FreeBSD$
*/
@@ -119,21 +126,21 @@ amr_cam_attach(struct amr_softc *sc)
* Iterate over our channels, registering them with CAM
*/
for (chn = 0; chn < sc->amr_maxchan; chn++) {
-
+
/* allocate a sim */
if ((sc->amr_cam_sim[chn] = cam_sim_alloc(amr_cam_action,
amr_cam_poll,
"amr",
- sc,
+ sc,
device_get_unit(sc->amr_dev),
- 1,
+ 1,
AMR_MAX_SCSI_CMDS,
devq)) == NULL) {
cam_simq_free(devq);
device_printf(sc->amr_dev, "CAM SIM attach failed\n");
return(ENOMEM);
}
-
+
/* register the bus ID so we can get it later */
if (xpt_bus_register(sc->amr_cam_sim[chn], chn)) {
device_printf(sc->amr_dev, "CAM XPT bus registration failed\n");
@@ -156,7 +163,7 @@ amr_cam_detach(struct amr_softc *sc)
int chn, first;
for (chn = 0, first = 1; chn < sc->amr_maxchan; chn++) {
-
+
/*
* If a sim was allocated for this channel, free it
*/
@@ -259,27 +266,77 @@ amr_cam_action(struct cam_sim *sim, union ccb *ccb)
*/
case XPT_PATH_INQ:
{
- struct ccb_pathinq *cpi = & ccb->cpi;
+ struct ccb_pathinq *cpi = & ccb->cpi;
- cpi->version_num = 1; /* XXX??? */
- cpi->hba_inquiry = PI_SDTR_ABLE;
+ debug(3, "XPT_PATH_INQ");
+ cpi->version_num = 1; /* XXX??? */
+ cpi->hba_inquiry = PI_SDTR_ABLE|PI_TAG_ABLE|PI_WIDE_16;
cpi->target_sprt = 0;
- cpi->hba_misc = 0;
+ cpi->hba_misc = PIM_NOBUSRESET;
cpi->hba_eng_cnt = 0;
cpi->max_target = AMR_MAX_TARGETS;
- cpi->max_lun = AMR_MAX_LUNS;
- cpi->initiator_id = 7; /* XXX variable? */
+ cpi->max_lun = 0 /* AMR_MAX_LUNS*/;
+ cpi->initiator_id = 7; /* XXX variable? */
strncpy(cpi->sim_vid, "FreeBSD", SIM_IDLEN);
- strncpy(cpi->hba_vid, "BSDi", HBA_IDLEN);
+ strncpy(cpi->hba_vid, "LSI", HBA_IDLEN);
strncpy(cpi->dev_name, cam_sim_name(sim), DEV_IDLEN);
cpi->unit_number = cam_sim_unit(sim);
cpi->bus_id = cam_sim_bus(sim);
- cpi->base_transfer_speed = 132 * 1024; /* XXX get from controller? */
+ cpi->base_transfer_speed = 132 * 1024; /* XXX get from controller? */
cpi->ccb_h.status = CAM_REQ_CMP;
break;
}
+ case XPT_RESET_BUS:
+ {
+ struct ccb_pathinq *cpi = & ccb->cpi;
+
+ debug(1, "XPT_RESET_BUS");
+ cpi->ccb_h.status = CAM_REQ_CMP;
+ break;
+ }
+
+ case XPT_RESET_DEV:
+ {
+ debug(1, "XPT_RESET_DEV");
+ ccb->ccb_h.status = CAM_REQ_CMP;
+ break;
+ }
+
+ case XPT_GET_TRAN_SETTINGS:
+ {
+ struct ccb_trans_settings *cts;
+
+ debug(3, "XPT_GET_TRAN_SETTINGS");
+
+ cts = &(ccb->cts);
+
+ if ((cts->flags & CCB_TRANS_USER_SETTINGS) == 0) {
+ ccb->ccb_h.status = CAM_FUNC_NOTAVAIL;
+ break;
+ }
+
+ cts->flags = CCB_TRANS_DISC_ENB|CCB_TRANS_TAG_ENB;
+ cts->bus_width = MSG_EXT_WDTR_BUS_32_BIT;
+ cts->sync_period = 6; /* 40MHz how wide is this bus? */
+ cts->sync_offset = 31; /* How to extract this from board? */
+
+ cts->valid = CCB_TRANS_SYNC_RATE_VALID
+ | CCB_TRANS_SYNC_OFFSET_VALID
+ | CCB_TRANS_BUS_WIDTH_VALID
+ | CCB_TRANS_DISC_VALID
+ | CCB_TRANS_TQ_VALID;
+ ccb->ccb_h.status = CAM_REQ_CMP;
+ break;
+ }
+
+ case XPT_SET_TRAN_SETTINGS:
+ debug(3, "XPT_SET_TRAN_SETTINGS");
+ ccb->ccb_h.status = CAM_FUNC_NOTAVAIL;
+ break;
+
+
/*
* Reject anything else as unsupported.
*/
@@ -314,7 +371,7 @@ amr_cam_command(struct amr_softc *sc, struct amr_command **acp)
bus = csio->ccb_h.sim_priv.entries[0].field;
target = csio->ccb_h.target_id;
- /*
+ /*
* Build a passthrough command.
*/
@@ -331,6 +388,7 @@ amr_cam_command(struct amr_softc *sc, struct amr_command **acp)
ap->ap_scsi_id = target;
ap->ap_logical_drive_no = csio->ccb_h.target_lun;
ap->ap_cdb_length = csio->cdb_len;
+ ap->ap_data_transfer_length = csio->dxfer_len;
if (csio->ccb_h.flags & CAM_CDB_POINTER) {
bcopy(csio->cdb_io.cdb_ptr, ap->ap_cdb, csio->cdb_len);
} else {
@@ -390,21 +448,21 @@ amr_cam_poll(struct cam_sim *sim)
static void
amr_cam_complete(struct amr_command *ac)
{
- struct amr_passthrough *ap = (struct amr_passthrough *)ac->ac_data;
- struct ccb_scsiio *csio = (struct ccb_scsiio *)ac->ac_private;
- struct scsi_inquiry_data *inq = (struct scsi_inquiry_data *)csio->data_ptr;
+ struct amr_passthrough *ap = (struct amr_passthrough *)ac->ac_data;
+ struct ccb_scsiio *csio = (struct ccb_scsiio *)ac->ac_private;
+ struct scsi_inquiry_data *inq = (struct scsi_inquiry_data *)csio->data_ptr;
/* XXX note that we're ignoring ac->ac_status - good idea? */
debug(1, "status 0x%x scsi_status 0x%x", ac->ac_status, ap->ap_scsi_status);
- /*
+ /*
* Hide disks from CAM so that they're not picked up and treated as 'normal' disks.
*
* If the configuration provides a mechanism to mark a disk a "not managed", we
* could add handling for that to allow disks to be selectively visible.
*/
-#if 0
+
if ((ap->ap_cdb[0] == INQUIRY) && (SID_TYPE(inq) == T_DIRECT)) {
bzero(csio->data_ptr, csio->dxfer_len);
if (ap->ap_scsi_status == 0xf0) {
@@ -413,9 +471,6 @@ amr_cam_complete(struct amr_command *ac)
csio->ccb_h.status = CAM_DEV_NOT_THERE;
}
} else {
-#else
- {
-#endif
/* handle passthrough SCSI status */
switch(ap->ap_scsi_status) {
@@ -434,13 +489,13 @@ amr_cam_complete(struct amr_command *ac)
case 0x08:
csio->ccb_h.status = CAM_SCSI_BUSY;
break;
-
+
case 0xf0:
case 0xf4:
default:
csio->ccb_h.status = CAM_REQ_CMP_ERR;
break;
- }
+ }
}
free(ap, M_DEVBUF);
if ((csio->ccb_h.flags & CAM_DIR_MASK) != CAM_DIR_NONE)
OpenPOWER on IntegriCloud