diff options
author | sos <sos@FreeBSD.org> | 2001-08-30 09:47:17 +0000 |
---|---|---|
committer | sos <sos@FreeBSD.org> | 2001-08-30 09:47:17 +0000 |
commit | 6446a5fe80da2f4a0584db5d3daa9d1bc3d10699 (patch) | |
tree | d98889b095f823a5ed848767f51fa831dcf6357f /sys/dev/ata/ata-all.c | |
parent | 072b9ce451acaee2a7ece2617367d3c3a59caa47 (diff) | |
download | FreeBSD-src-6446a5fe80da2f4a0584db5d3daa9d1bc3d10699.zip FreeBSD-src-6446a5fe80da2f4a0584db5d3daa9d1bc3d10699.tar.gz |
Add support for sending ATAPI commands via ioctl.
Diffstat (limited to 'sys/dev/ata/ata-all.c')
-rw-r--r-- | sys/dev/ata/ata-all.c | 41 |
1 files changed, 41 insertions, 0 deletions
diff --git a/sys/dev/ata/ata-all.c b/sys/dev/ata/ata-all.c index 023f73a..ce29a86 100644 --- a/sys/dev/ata/ata-all.c +++ b/sys/dev/ata/ata-all.c @@ -396,6 +396,47 @@ ataioctl(dev_t dev, u_long cmd, caddr_t addr, int32_t flag, struct proc *p) sizeof(struct ata_params)); return 0; } + + case ATAPICMD: { + struct ata_softc *scp; + struct atapi_softc *atp; + caddr_t buf; + + scp = device_get_softc(device); + if (!scp) + return ENODEV; + + if (!scp->dev_softc[iocmd->device] || + !(scp->devices & + (iocmd->device == 0 ? ATA_ATAPI_MASTER : ATA_ATAPI_SLAVE))) + return ENODEV; + + if (!(buf = malloc(iocmd->u.atapi.count, M_ATA, M_NOWAIT))) + return ENOMEM; + + atp = scp->dev_softc[iocmd->device]; + if (iocmd->u.atapi.flags & ATAPI_CMD_WRITE) { + error = copyin(iocmd->u.atapi.data, buf, iocmd->u.atapi.count); + if (error) + return error; + } + error = atapi_queue_cmd(atp, iocmd->u.atapi.ccb, + buf, iocmd->u.atapi.count, + (iocmd->u.atapi.flags == ATAPI_CMD_READ ? + ATPR_F_READ : 0) | ATPR_F_QUIET, + iocmd->u.atapi.timeout, NULL, NULL); + if (error) { + iocmd->u.atapi.error = error; + bcopy(&atp->sense, iocmd->u.atapi.sense_data, + sizeof(struct atapi_reqsense)); + error = 0; + } + else if (iocmd->u.atapi.flags & ATAPI_CMD_READ) + error = copyout(buf, iocmd->u.atapi.data, iocmd->u.atapi.count); + + free(buf, M_ATA); + return error; + } } return ENOTTY; } |