aboutsummaryrefslogtreecommitdiff
path: root/sys/cam
diff options
context:
space:
mode:
authorAlexander Motin <mav@FreeBSD.org>2010-02-14 19:44:48 +0000
committerAlexander Motin <mav@FreeBSD.org>2010-02-14 19:44:48 +0000
commit929100472e98ebd8dd087e589443968eec0ec9db (patch)
treec4560811baeecee5da1ccc92c1ae74444a4652d0 /sys/cam
parent50ae5fde8d275e57e290c224f774b1be55d24deb (diff)
Notes
Diffstat (limited to 'sys/cam')
-rw-r--r--sys/cam/ata/ata_xpt.c36
-rw-r--r--sys/cam/cam_ccb.h4
-rw-r--r--sys/cam/cam_xpt.c8
3 files changed, 45 insertions, 3 deletions
diff --git a/sys/cam/ata/ata_xpt.c b/sys/cam/ata/ata_xpt.c
index bff0340b6710..a9d0a87d31f9 100644
--- a/sys/cam/ata/ata_xpt.c
+++ b/sys/cam/ata/ata_xpt.c
@@ -1334,7 +1334,20 @@ ata_device_transport(struct cam_path *path)
cts.protocol = path->device->protocol;
cts.protocol_version = path->device->protocol_version;
cts.proto_specific.valid = 0;
- cts.xport_specific.valid = 0;
+ if (ident_buf) {
+ if (path->device->transport == XPORT_ATA) {
+ cts.xport_specific.ata.atapi =
+ ((ident_buf->config & ATA_PROTO_MASK) == ATA_PROTO_ATAPI_16) ? 16 :
+ ((ident_buf->config & ATA_PROTO_MASK) == ATA_PROTO_ATAPI_12) ? 12 : 0;
+ cts.xport_specific.ata.valid = CTS_ATA_VALID_ATAPI;
+ } else {
+ cts.xport_specific.sata.atapi =
+ ((ident_buf->config & ATA_PROTO_MASK) == ATA_PROTO_ATAPI_16) ? 16 :
+ ((ident_buf->config & ATA_PROTO_MASK) == ATA_PROTO_ATAPI_12) ? 12 : 0;
+ cts.xport_specific.sata.valid = CTS_SATA_VALID_ATAPI;
+ }
+ } else
+ cts.xport_specific.valid = 0;
xpt_action((union ccb *)&cts);
}
@@ -1366,6 +1379,27 @@ ata_action(union ccb *start_ccb)
(*(sim->sim_action))(sim, start_ccb);
break;
}
+ case XPT_SCSI_IO:
+ {
+ struct cam_ed *device;
+ u_int maxlen = 0;
+
+ device = start_ccb->ccb_h.path->device;
+ if (device->protocol == PROTO_SCSI &&
+ (device->flags & CAM_DEV_IDENTIFY_DATA_VALID)) {
+ uint16_t p =
+ device->ident_data.config & ATA_PROTO_MASK;
+
+ maxlen = (p == ATA_PROTO_ATAPI_16) ? 16 :
+ (p == ATA_PROTO_ATAPI_12) ? 12 : 0;
+ }
+ if (start_ccb->csio.cdb_len > maxlen) {
+ start_ccb->ccb_h.status = CAM_REQ_INVALID;
+ xpt_done(start_ccb);
+ break;
+ }
+ /* FALLTHROUGH */
+ }
default:
xpt_action_default(start_ccb);
break;
diff --git a/sys/cam/cam_ccb.h b/sys/cam/cam_ccb.h
index 4c5adba54189..2810c545f71a 100644
--- a/sys/cam/cam_ccb.h
+++ b/sys/cam/cam_ccb.h
@@ -823,8 +823,10 @@ struct ccb_trans_settings_ata {
u_int valid; /* Which fields to honor */
#define CTS_ATA_VALID_MODE 0x01
#define CTS_ATA_VALID_BYTECOUNT 0x02
+#define CTS_ATA_VALID_ATAPI 0x20
int mode; /* Mode */
u_int bytecount; /* Length of PIO transaction */
+ u_int atapi; /* Length of ATAPI CDB */
};
struct ccb_trans_settings_sata {
@@ -834,11 +836,13 @@ struct ccb_trans_settings_sata {
#define CTS_SATA_VALID_REVISION 0x04
#define CTS_SATA_VALID_PM 0x08
#define CTS_SATA_VALID_TAGS 0x10
+#define CTS_SATA_VALID_ATAPI 0x20
int mode; /* Legacy PATA mode */
u_int bytecount; /* Length of PIO transaction */
int revision; /* SATA revision */
u_int pm_present; /* PM is present (XPT->SIM) */
u_int tags; /* Number of allowed tags */
+ u_int atapi; /* Length of ATAPI CDB */
};
/* Get/Set transfer rate/width/disconnection/tag queueing settings */
diff --git a/sys/cam/cam_xpt.c b/sys/cam/cam_xpt.c
index d966a9fb5bd4..3423df97376e 100644
--- a/sys/cam/cam_xpt.c
+++ b/sys/cam/cam_xpt.c
@@ -1201,8 +1201,10 @@ xpt_announce_periph(struct cam_periph *periph, char *announce_string)
printf(" (");
if (ata->valid & CTS_ATA_VALID_MODE)
printf("%s, ", ata_mode2string(ata->mode));
+ if ((ata->valid & CTS_ATA_VALID_ATAPI) && ata->atapi != 0)
+ printf("ATAPI %dbytes, ", ata->atapi);
if (ata->valid & CTS_ATA_VALID_BYTECOUNT)
- printf("PIO size %dbytes", ata->bytecount);
+ printf("PIO %dbytes", ata->bytecount);
printf(")");
}
if (cts.ccb_h.status == CAM_REQ_CMP && cts.transport == XPORT_SATA) {
@@ -1214,8 +1216,10 @@ xpt_announce_periph(struct cam_periph *periph, char *announce_string)
printf("SATA %d.x, ", sata->revision);
if (sata->valid & CTS_SATA_VALID_MODE)
printf("%s, ", ata_mode2string(sata->mode));
+ if ((sata->valid & CTS_ATA_VALID_ATAPI) && sata->atapi != 0)
+ printf("ATAPI %dbytes, ", sata->atapi);
if (sata->valid & CTS_SATA_VALID_BYTECOUNT)
- printf("PIO size %dbytes", sata->bytecount);
+ printf("PIO %dbytes", sata->bytecount);
printf(")");
}
if (path->device->inq_flags & SID_CmdQue