summaryrefslogtreecommitdiffstats
path: root/sys/dev/ata
diff options
context:
space:
mode:
authorsos <sos@FreeBSD.org>2006-03-31 08:09:05 +0000
committersos <sos@FreeBSD.org>2006-03-31 08:09:05 +0000
commit69fb696b657ca9767e91ff4ad17e2aad0822b1d7 (patch)
tree7c4941b618af6a1a0f056695a87cb959f3542b3c /sys/dev/ata
parent32b1878006f50d14c52851c90a362f1012c69f43 (diff)
downloadFreeBSD-src-69fb696b657ca9767e91ff4ad17e2aad0822b1d7.zip
FreeBSD-src-69fb696b657ca9767e91ff4ad17e2aad0822b1d7.tar.gz
Make the ATAPI sense data accessible when using the ioctl interface
MFC candidate.
Diffstat (limited to 'sys/dev/ata')
-rw-r--r--sys/dev/ata/ata-all.c6
-rw-r--r--sys/dev/ata/ata-all.h49
-rw-r--r--sys/dev/ata/ata-disk.c13
-rw-r--r--sys/dev/ata/ata-queue.c63
-rw-r--r--sys/dev/ata/ata-usb.c6
-rw-r--r--sys/dev/ata/atapi-cam.c4
-rw-r--r--sys/dev/ata/atapi-cd.c16
7 files changed, 64 insertions, 93 deletions
diff --git a/sys/dev/ata/ata-all.c b/sys/dev/ata/ata-all.c
index 3b64060..b68cbe9 100644
--- a/sys/dev/ata/ata-all.c
+++ b/sys/dev/ata/ata-all.c
@@ -485,7 +485,11 @@ ata_device_ioctl(device_t dev, u_long cmd, caddr_t data)
if (ioc_request->flags & ATA_CMD_WRITE)
request->flags |= ATA_R_WRITE;
ata_queue_request(request);
- if (!(request->flags & ATA_R_ATAPI)) {
+ if (request->flags & ATA_R_ATAPI) {
+ bcopy(&request->u.atapi.sense, &ioc_request->u.atapi.sense,
+ sizeof(struct atapi_sense));
+ }
+ else {
ioc_request->u.ata.command = request->u.ata.command;
ioc_request->u.ata.feature = request->u.ata.feature;
ioc_request->u.ata.lba = request->u.ata.lba;
diff --git a/sys/dev/ata/ata-all.h b/sys/dev/ata/ata-all.h
index 2bd3e37..8f98589 100644
--- a/sys/dev/ata/ata-all.h
+++ b/sys/dev/ata/ata-all.h
@@ -53,24 +53,7 @@
#define ATA_E_MC 0x20 /* media changed */
#define ATA_E_UNC 0x40 /* uncorrectable data */
#define ATA_E_ICRC 0x80 /* UDMA crc error */
-#define ATA_E_MASK 0x0f /* error mask */
-#define ATA_SK_MASK 0xf0 /* sense key mask */
-#define ATA_SK_NO_SENSE 0x00 /* no specific sense key info */
-#define ATA_SK_RECOVERED_ERROR 0x10 /* command OK, data recovered */
-#define ATA_SK_NOT_READY 0x20 /* no access to drive */
-#define ATA_SK_MEDIUM_ERROR 0x30 /* non-recovered data error */
-#define ATA_SK_HARDWARE_ERROR 0x40 /* non-recoverable HW failure */
-#define ATA_SK_ILLEGAL_REQUEST 0x50 /* invalid command param(s) */
-#define ATA_SK_UNIT_ATTENTION 0x60 /* media changed */
-#define ATA_SK_DATA_PROTECT 0x70 /* write protect */
-#define ATA_SK_BLANK_CHECK 0x80 /* blank check */
-#define ATA_SK_VENDOR_SPECIFIC 0x90 /* vendor specific skey */
-#define ATA_SK_COPY_ABORTED 0xa0 /* copy aborted */
-#define ATA_SK_ABORTED_COMMAND 0xb0 /* command aborted, try again */
-#define ATA_SK_EQUAL 0xc0 /* equal */
-#define ATA_SK_VOLUME_OVERFLOW 0xd0 /* volume overflow */
-#define ATA_SK_MISCOMPARE 0xe0 /* data dont match the medium */
-#define ATA_SK_RESERVED 0xf0
+#define ATA_E_ATAPI_SENSE_MASK 0xf0 /* ATAPI sense key mask */
#define ATA_IREASON 9 /* (R) interrupt reason */
#define ATA_I_CMD 0x01 /* cmd (1) | data (0) */
@@ -284,7 +267,8 @@
#define ATA_PC98_BANKADDR_RID 9
#define ATA_IRQ_RID 0
#define ATA_DEV(device) ((device == ATA_MASTER) ? 0 : 1)
-#define ATA_CFA_MAGIC 0x848A
+#define ATA_CFA_MAGIC1 0x844A
+#define ATA_CFA_MAGIC2 0x848A
#define ATAPI_MAGIC_LSB 0x14
#define ATAPI_MAGIC_MSB 0xeb
#define ATAPI_P_READ (ATA_S_DRQ | ATA_I_IN)
@@ -298,28 +282,6 @@
#define ATA_OP_FINISHED 1
#define ATA_MAX_28BIT_LBA 268435455UL
-/* ATAPI request sense structure */
-struct atapi_sense {
- u_int8_t error_code :7; /* current or deferred errors */
- u_int8_t valid :1; /* follows ATAPI spec */
- u_int8_t segment; /* Segment number */
- u_int8_t sense_key :4; /* sense key */
- u_int8_t reserved2_4 :1; /* reserved */
- u_int8_t ili :1; /* incorrect length indicator */
- u_int8_t eom :1; /* end of medium */
- u_int8_t filemark :1; /* filemark */
- u_int32_t cmd_info __packed; /* cmd information */
- u_int8_t sense_length; /* additional sense len (n-7) */
- u_int32_t cmd_specific_info __packed; /* additional cmd spec info */
- u_int8_t asc; /* additional sense code */
- u_int8_t ascq; /* additional sense code qual */
- u_int8_t replaceable_unit_code; /* replaceable unit code */
- u_int8_t sk_specific :7; /* sense key specific */
- u_int8_t sksv :1; /* sense key specific info OK */
- u_int8_t sk_specific1; /* sense key specific */
- u_int8_t sk_specific2; /* sense key specific */
-};
-
/* structure used for composite atomic operations */
#define MAX_COMPOSITES 32 /* u_int32_t bits */
struct ata_composite {
@@ -348,9 +310,8 @@ struct ata_request {
} ata;
struct {
u_int8_t ccb[16]; /* ATAPI command block */
- struct atapi_sense sense_data; /* ATAPI request sense data */
- u_int8_t sense_key; /* ATAPI request sense key */
- u_int8_t sense_cmd; /* ATAPI saved command */
+ struct atapi_sense sense; /* ATAPI request sense data */
+ u_int8_t saved_cmd; /* ATAPI saved command */
} atapi;
} u;
u_int32_t bytecount; /* bytes to transfer */
diff --git a/sys/dev/ata/ata-disk.c b/sys/dev/ata/ata-disk.c
index fb8942e..6d90b40 100644
--- a/sys/dev/ata/ata-disk.c
+++ b/sys/dev/ata/ata-disk.c
@@ -71,7 +71,8 @@ ad_probe(device_t dev)
struct ata_device *atadev = device_get_softc(dev);
if (!(atadev->param.config & ATA_PROTO_ATAPI) ||
- (atadev->param.config == ATA_CFA_MAGIC))
+ (atadev->param.config == ATA_CFA_MAGIC1) ||
+ (atadev->param.config == ATA_CFA_MAGIC2))
return 0;
else
return ENXIO;
@@ -295,8 +296,14 @@ ad_dump(void *arg, void *virtual, vm_offset_t physical,
struct bio bp;
/* length zero is special and really means flush buffers to media */
- if (!length)
- return ata_controlcmd(dp->d_drv1, ATA_FLUSHCACHE, 0, 0, 0);
+ if (!length) {
+ struct ata_device *atadev = device_get_softc(dp->d_drv1);
+ int error = 0;
+
+ if (atadev->param.support.command2 & ATA_SUPPORT_FLUSHCACHE)
+ error = ata_controlcmd(dp->d_drv1, ATA_FLUSHCACHE, 0, 0, 0);
+ return error;
+ }
bzero(&bp, sizeof(struct bio));
bp.bio_disk = dp;
diff --git a/sys/dev/ata/ata-queue.c b/sys/dev/ata/ata-queue.c
index a3b142e..4957eac 100644
--- a/sys/dev/ata/ata-queue.c
+++ b/sys/dev/ata/ata-queue.c
@@ -51,13 +51,20 @@ static char *ata_skey2str(u_int8_t);
void
ata_queue_request(struct ata_request *request)
{
- struct ata_channel *ch = device_get_softc(device_get_parent(request->dev));
+ struct ata_channel *ch;
- /* mark request as virgin (this might be a ATA_R_REQUEUE) */
+ /* treat request as virgin (this might be an ATA_R_REQUEUE) */
request->result = request->status = request->error = 0;
- request->parent = device_get_parent(request->dev);
- callout_init_mtx(&request->callout, &ch->state_mtx, CALLOUT_RETURNUNLOCKED);
+ /* check that that the device is still valid */
+ if (!(request->parent = device_get_parent(request->dev))) {
+ request->result = ENXIO;
+ if (request->callback)
+ (request->callback)(request);
+ return;
+ }
+ ch = device_get_softc(request->parent);
+ callout_init_mtx(&request->callout, &ch->state_mtx, CALLOUT_RETURNUNLOCKED);
if (!request->callback && !(request->flags & ATA_R_REQUEUE))
sema_init(&request->done, 0, "ATA request done");
@@ -368,16 +375,15 @@ ata_completed(void *context, int dummy)
break;
/* if we have a sensekey -> request sense from device */
- if (request->error & ATA_SK_MASK &&
- request->u.atapi.ccb[0] != ATAPI_REQUEST_SENSE) {
+ if ((request->error & ATA_E_ATAPI_SENSE_MASK) &&
+ (request->u.atapi.ccb[0] != ATAPI_REQUEST_SENSE)) {
static u_int8_t ccb[16] = { ATAPI_REQUEST_SENSE, 0, 0, 0,
sizeof(struct atapi_sense),
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
- request->u.atapi.sense_key = request->error;
- request->u.atapi.sense_cmd = request->u.atapi.ccb[0];
+ request->u.atapi.saved_cmd = request->u.atapi.ccb[0];
bcopy(ccb, request->u.atapi.ccb, 16);
- request->data = (caddr_t)&request->u.atapi.sense_data;
+ request->data = (caddr_t)&request->u.atapi.sense;
request->bytecount = sizeof(struct atapi_sense);
request->donecount = 0;
request->transfersize = sizeof(struct atapi_sense);
@@ -389,21 +395,21 @@ ata_completed(void *context, int dummy)
return;
}
- switch (request->u.atapi.sense_key & ATA_SK_MASK) {
- case ATA_SK_RECOVERED_ERROR:
+ switch (request->u.atapi.sense.key & ATA_SENSE_KEY_MASK) {
+ case ATA_SENSE_RECOVERED_ERROR:
device_printf(request->dev, "WARNING - %s recovered error\n",
ata_cmd2str(request));
/* FALLTHROUGH */
- case ATA_SK_NO_SENSE:
+ case ATA_SENSE_NO_SENSE:
request->result = 0;
break;
- case ATA_SK_NOT_READY:
+ case ATA_SENSE_NOT_READY:
request->result = EBUSY;
break;
- case ATA_SK_UNIT_ATTENTION:
+ case ATA_SENSE_UNIT_ATTENTION:
atadev->flags |= ATA_D_MEDIA_CHANGED;
request->result = EIO;
break;
@@ -416,22 +422,19 @@ ata_completed(void *context, int dummy)
device_printf(request->dev,
"FAILURE - %s %s asc=0x%02x ascq=0x%02x ",
ata_cmd2str(request), ata_skey2str(
- (request->u.atapi.sense_key & ATA_SK_MASK) >> 4),
- request->u.atapi.sense_data.asc,
- request->u.atapi.sense_data.ascq);
- if (request->u.atapi.sense_data.sksv)
- printf("sks=0x%02x 0x%02x 0x%02x ",
- request->u.atapi.sense_data.sk_specific,
- request->u.atapi.sense_data.sk_specific1,
- request->u.atapi.sense_data.sk_specific2);
- printf("error=%b\n",
- (request->u.atapi.sense_key & ATA_E_MASK),
- "\20\4MEDIA_CHANGE_REQUEST\3ABORTED"
- "\2NO_MEDIA\1ILLEGAL_LENGTH");
+ (request->u.atapi.sense.key & ATA_SENSE_KEY_MASK)),
+ request->u.atapi.sense.asc,
+ request->u.atapi.sense.ascq);
+ if (request->u.atapi.sense.specific & ATA_SENSE_SPEC_VALID)
+ printf("sks=0x%02x 0x%02x 0x%02x\n",
+ request->u.atapi.sense.specific & ATA_SENSE_SPEC_MASK,
+ request->u.atapi.sense.specific1,
+ request->u.atapi.sense.specific2);
}
- if ((request->u.atapi.sense_key ?
- request->u.atapi.sense_key : request->error) & ATA_E_MASK)
+ if ((request->u.atapi.sense.key & ATA_SENSE_KEY_MASK ?
+ request->u.atapi.sense.key & ATA_SENSE_KEY_MASK :
+ request->error))
request->result = EIO;
}
@@ -625,8 +628,8 @@ ata_cmd2str(struct ata_request *request)
static char buffer[20];
if (request->flags & ATA_R_ATAPI) {
- switch (request->u.atapi.sense_key ?
- request->u.atapi.sense_cmd : request->u.atapi.ccb[0]) {
+ switch (request->u.atapi.sense.key ?
+ request->u.atapi.saved_cmd : request->u.atapi.ccb[0]) {
case 0x00: return ("TEST_UNIT_READY");
case 0x01: return ("REZERO");
case 0x03: return ("REQUEST_SENSE");
diff --git a/sys/dev/ata/ata-usb.c b/sys/dev/ata/ata-usb.c
index 9f181ef..19d0196 100644
--- a/sys/dev/ata/ata-usb.c
+++ b/sys/dev/ata/ata-usb.c
@@ -683,8 +683,7 @@ atausb_bbb_finish(usbd_xfer_handle xfer, usbd_private_handle priv,
else if (sc->csw.status == CSWSTATUS_FAILED) {
if (atausbdebug)
device_printf(sc->dev, "CSWSTATUS_FAILED\n");
- //request->result = ENODEV;
- request->error = ATA_SK_RESERVED;
+ request->error = ATA_E_ATAPI_SENSE_MASK ;
sc->state = ATAUSB_S_IDLE;
ata_interrupt(device_get_softc(request->parent));
return;
@@ -824,9 +823,6 @@ ata_usbchannel_end_transaction(struct ata_request *request)
*ptr = ntohs(*ptr);
request->result = 0;
}
- if ((request->flags & ATA_R_ATAPI) &&
- (request->u.atapi.ccb[0] == ATAPI_REQUEST_SENSE))
- request->u.atapi.sense_key = request->u.atapi.sense_data.sense_key << 4;
return ATA_OP_FINISHED;
}
diff --git a/sys/dev/ata/atapi-cam.c b/sys/dev/ata/atapi-cam.c
index 386de14..8a24638 100644
--- a/sys/dev/ata/atapi-cam.c
+++ b/sys/dev/ata/atapi-cam.c
@@ -661,7 +661,7 @@ atapi_cb(struct ata_request *request)
csio = &hcb->ccb->csio;
#ifdef CAMDEBUG
-# define err (request->u.atapi.sense_key)
+# define err (request->u.atapi.sense.key)
if (CAM_DEBUGGED(csio->ccb_h.path, CAM_DEBUG_CDB)) {
printf("atapi_cb: hcb@%p error = %02x: (sk = %02x%s%s%s)\n",
hcb, err, err >> 4,
@@ -704,7 +704,7 @@ atapi_cb(struct ata_request *request)
/* The ATA driver has already requested sense for us. */
if (request->error == 0) {
/* The ATA autosense suceeded. */
- bcopy (&request->u.atapi.sense_data, &csio->sense_data, sizeof(struct atapi_sense));
+ bcopy (&request->u.atapi.sense, &csio->sense_data, sizeof(struct atapi_sense));
csio->ccb_h.status |= CAM_AUTOSNS_VALID;
}
#endif
diff --git a/sys/dev/ata/atapi-cd.c b/sys/dev/ata/atapi-cd.c
index cf7d159..bdfa167 100644
--- a/sys/dev/ata/atapi-cd.c
+++ b/sys/dev/ata/atapi-cd.c
@@ -702,10 +702,10 @@ acd_geom_access(struct g_provider *pp, int dr, int dw, int de)
request->timeout = 5;
ata_queue_request(request);
if (!request->error &&
- (request->u.atapi.sense_data.sense_key == 2 ||
- request->u.atapi.sense_data.sense_key == 7) &&
- request->u.atapi.sense_data.asc == 4 &&
- request->u.atapi.sense_data.ascq == 1)
+ (request->u.atapi.sense.key == 2 ||
+ request->u.atapi.sense.key == 7) &&
+ request->u.atapi.sense.asc == 4 &&
+ request->u.atapi.sense.ascq == 1)
tsleep(&timeout, PRIBIO, "acdld", hz / 2);
else
break;
@@ -1008,7 +1008,7 @@ acd_read_toc(device_t dev)
cdp->disk_size, cdp->block_size,
cdp->toc.hdr.ending_track-cdp->toc.hdr.starting_track+1);
if (cdp->toc.tab[0].control & 4)
- printf("%dMB\n", cdp->disk_size / 512);
+ printf("%dMB\n", cdp->disk_size * cdp->block_size / 1048576);
else
printf("%d:%d audio\n",
cdp->disk_size / 75 / 60, cdp->disk_size / 75 % 60);
@@ -1234,9 +1234,9 @@ acd_get_progress(device_t dev, int *finished)
request->flags = ATA_R_ATAPI | ATA_R_READ;
request->timeout = 30;
ata_queue_request(request);
- if (!request->error && request->u.atapi.sense_data.sksv)
- *finished = ((request->u.atapi.sense_data.sk_specific2 |
- (request->u.atapi.sense_data.sk_specific1<<8))*100)/65535;
+ if (!request->error && request->u.atapi.sense.error & ATA_SENSE_VALID)
+ *finished = ((request->u.atapi.sense.specific2 |
+ (request->u.atapi.sense.specific1 << 8)) * 100) / 65535;
else
*finished = 0;
ata_free_request(request);
OpenPOWER on IntegriCloud