diff options
author | mav <mav@FreeBSD.org> | 2010-02-02 11:09:28 +0000 |
---|---|---|
committer | mav <mav@FreeBSD.org> | 2010-02-02 11:09:28 +0000 |
commit | b5b6d6b0e0e8523be005d532c4327061249c2a84 (patch) | |
tree | 37197ad5ae0872a11e1bc6a7828374ebc3770e16 /sys/cam/ata | |
parent | 2c76d0e26f4843ec857eaeade022a391227acb85 (diff) | |
download | FreeBSD-src-b5b6d6b0e0e8523be005d532c4327061249c2a84.zip FreeBSD-src-b5b6d6b0e0e8523be005d532c4327061249c2a84.tar.gz |
- Give ATA/SATA SIMs info about ATAPI packet size, supported by device.
- Make ATA XPT to reject longer SCSI CDBs then supported by device, or
any SCSI CDBs, if device doesn't support ATAPI.
Diffstat (limited to 'sys/cam/ata')
-rw-r--r-- | sys/cam/ata/ata_xpt.c | 36 |
1 files changed, 35 insertions, 1 deletions
diff --git a/sys/cam/ata/ata_xpt.c b/sys/cam/ata/ata_xpt.c index bff0340..a9d0a87 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; |