diff options
| author | Søren Schmidt <sos@FreeBSD.org> | 1999-12-07 22:25:28 +0000 |
|---|---|---|
| committer | Søren Schmidt <sos@FreeBSD.org> | 1999-12-07 22:25:28 +0000 |
| commit | cb2a8dffa0a79ce0096335ff68f3dabd716626d5 (patch) | |
| tree | 48f106ba8968fa5430d241fce1358592ea458176 /sys/dev/ata | |
| parent | f3a2511a25ce33bae3166c730959a167b94fa0eb (diff) | |
Notes
Diffstat (limited to 'sys/dev/ata')
| -rw-r--r-- | sys/dev/ata/atapi-all.c | 3 | ||||
| -rw-r--r-- | sys/dev/ata/atapi-all.h | 3 | ||||
| -rw-r--r-- | sys/dev/ata/atapi-cd.c | 278 | ||||
| -rw-r--r-- | sys/dev/ata/atapi-fd.c | 6 |
4 files changed, 285 insertions, 5 deletions
diff --git a/sys/dev/ata/atapi-all.c b/sys/dev/ata/atapi-all.c index 2992e2a355426..8b8643a4ffc0f 100644 --- a/sys/dev/ata/atapi-all.c +++ b/sys/dev/ata/atapi-all.c @@ -706,7 +706,10 @@ atapi_cmd2str(u_int8_t cmd) case 0x4b: return ("PAUSE"); case 0x48: return ("PLAY_TRACK"); case 0xa1: return ("BLANK_CMD"); + case 0xa3: return ("SEND_KEY"); + case 0xa4: return ("REPORT_KEY"); case 0xa5: return ("PLAY_BIG"); + case 0xad: return ("READ_DVD_STRUCTURE"); case 0xb4: return ("PLAY_CD"); case 0xbd: return ("MECH_STATUS"); case 0xbe: return ("READ_CD"); diff --git a/sys/dev/ata/atapi-all.h b/sys/dev/ata/atapi-all.h index 7fa123acb31c3..a8c7b9382408e 100644 --- a/sys/dev/ata/atapi-all.h +++ b/sys/dev/ata/atapi-all.h @@ -99,8 +99,11 @@ #define ATAPI_MODE_SENSE_BIG 0x5a /* get device parameters */ #define ATAPI_CLOSE_TRACK 0x5b /* close track/session */ #define ATAPI_BLANK 0xa1 /* blank the media */ +#define ATAPI_SEND_KEY 0xa3 +#define ATAPI_REPORT_KEY 0xa4 #define ATAPI_PLAY_BIG 0xa5 /* play by lba */ #define ATAPI_LOAD_UNLOAD 0xa6 /* changer control command */ +#define ATAPI_READ_STRUCTURE 0xad #define ATAPI_PLAY_CD 0xb4 /* universal play command */ #define ATAPI_SET_SPEED 0xbb /* set drive speed */ #define ATAPI_MECH_STATUS 0xbd /* get changer status */ diff --git a/sys/dev/ata/atapi-cd.c b/sys/dev/ata/atapi-cd.c index cc18ecfbc340d..9dedf7c6e771b 100644 --- a/sys/dev/ata/atapi-cd.c +++ b/sys/dev/ata/atapi-cd.c @@ -39,6 +39,7 @@ #include <sys/devicestat.h> #include <sys/cdio.h> #include <sys/wormio.h> +#include <sys/dvdio.h> #include <sys/fcntl.h> #include <sys/conf.h> #include <sys/stat.h> @@ -87,6 +88,9 @@ static int32_t acd_open_track(struct acd_softc *, struct wormio_prepare_track *) static int32_t acd_close_track(struct acd_softc *); static int32_t acd_close_disk(struct acd_softc *); static int32_t acd_read_track_info(struct acd_softc *, int32_t, struct acd_track_info*); +static int acd_report_key(struct acd_softc *, struct dvd_authinfo *); +static int acd_send_key(struct acd_softc *, struct dvd_authinfo *); +static int acd_read_structure(struct acd_softc *, struct dvd_struct *); static int32_t acd_eject(struct acd_softc *, int32_t); static int32_t acd_blank(struct acd_softc *); static int32_t acd_prevent_allow(struct acd_softc *, int32_t); @@ -279,7 +283,11 @@ acd_describe(struct acd_softc *cdp) printf("%s CD-RW", comma ? "," : ""); comma = 1; } if (cdp->cap.cd_da) { - printf("%s CD-DA", comma ? "," : ""); comma = 1; + if (cdp->cap.cd_da_stream) + printf("%s CD-DA stream", comma ? "," : ""); + else + printf("%s CD-DA", comma ? "," : ""); + comma = 1; } if (cdp->cap.read_dvdrom) { printf("%s DVD-ROM", comma ? "," : ""); comma = 1; @@ -984,6 +992,27 @@ acdioctl(dev_t dev, u_long cmd, caddr_t addr, int32_t flag, struct proc *p) error = acd_blank(cdp); break; + case DVDIOCREPORTKEY: + if (!cdp->cap.read_dvdrom) + error = EINVAL; + else + error = acd_report_key(cdp, (struct dvd_authinfo *)addr); + break; + + case DVDIOCSENDKEY: + if (!cdp->cap.read_dvdrom) + error = EINVAL; + else + error = acd_send_key(cdp, (struct dvd_authinfo *)addr); + break; + + case DVDIOCREADSTRUCTURE: + if (!cdp->cap.read_dvdrom) + error = EINVAL; + else + error = acd_read_structure(cdp, (struct dvd_struct *)addr); + break; + default: error = ENOTTY; } @@ -1380,6 +1409,252 @@ acd_read_track_info(struct acd_softc *cdp, return 0; } +static int +acd_report_key(struct acd_softc *cdp, struct dvd_authinfo *ai) +{ + struct { + u_int16_t length; + u_char reserved[2]; + u_char data[12]; + } d; + u_int32_t lba = 0; + int32_t error; + int16_t length; + int8_t ccb[16]; + + printf("dvd_report_key: format=0x%x\n", ai->format); + + switch (ai->format) { + case DVD_REPORT_AGID: + case DVD_REPORT_ASF: + case DVD_REPORT_RPC: + length = 8; + break; + case DVD_REPORT_KEY1: + length = 12; + break; + case DVD_REPORT_TITLE_KEY: + length = 12; + lba = ai->lba; + break; + case DVD_REPORT_CHALLENGE: + length = 16; + break; + case DVD_INVALIDATE_AGID: + length = 0; + break; + default: + return EINVAL; + } + + bzero(ccb, sizeof(ccb)); + ccb[0] = ATAPI_REPORT_KEY; + ccb[2] = (lba >> 24) & 0xff; + ccb[3] = (lba >> 16) & 0xff; + ccb[4] = (lba >> 8) & 0xff; + ccb[5] = lba & 0xff; + ccb[8] = (length >> 8) & 0xff; + ccb[9] = length & 0xff; + ccb[10] = (ai->agid << 6) | ai->format; + bzero(&d, sizeof(d)); + d.length = htons(length - 2); + error = atapi_queue_cmd(cdp->atp, ccb, &d, length, + (ai->format == DVD_INVALIDATE_AGID) ? 0 : A_READ, + 10, NULL, NULL, NULL); + if (error) + return error; + + switch (ai->format) { + case DVD_REPORT_AGID: + ai->agid = d.data[3] >> 6; + break; + + case DVD_REPORT_CHALLENGE: + bcopy(&d.data[0], &ai->keychal[0], 10); + break; + + case DVD_REPORT_KEY1: + bcopy(&d.data[0], &ai->keychal[0], 5); + break; + + case DVD_REPORT_TITLE_KEY: + ai->cpm = (d.data[0] >> 7); + ai->cp_sec = (d.data[0] >> 6) & 0x1; + ai->cgms = (d.data[0] >> 4) & 0x3; + bcopy(&d.data[1], &ai->keychal[0], 5); + break; + + case DVD_REPORT_ASF: + ai->asf = d.data[3] & 1; + break; + + case DVD_REPORT_RPC: + ai->reg_type = (d.data[0] >> 6); + ai->vend_rsts = (d.data[0] >> 3) & 0x7; + ai->user_rsts = d.data[0] & 0x7; + break; + + case DVD_INVALIDATE_AGID: + break; + + default: + return EINVAL; + } + return 0; +} + +static int +acd_send_key(struct acd_softc *cdp, struct dvd_authinfo *ai) +{ + struct { + u_int16_t length; + u_char reserved[2]; + u_char data[12]; + } d; + int16_t length; + int8_t ccb[16]; + + printf("dvd_send_key: format=0x%x\n", ai->format); + + bzero(&d, sizeof(d)); + + switch (ai->format) { + case DVD_SEND_CHALLENGE: + length = 16; + bcopy(ai->keychal, &d.data[0], 10); + break; + + case DVD_SEND_KEY2: + length = 12; + bcopy(&ai->keychal[0], &d.data[0], 5); + break; + + case DVD_SEND_RPC: + length = 8; + break; + + default: + return EINVAL; + } + + bzero(ccb, sizeof(ccb)); + ccb[0] = ATAPI_SEND_KEY; + ccb[8] = (length >> 8) & 0xff; + ccb[9] = length & 0xff; + ccb[10] = (ai->agid << 6) | ai->format; + d.length = htons(length - 2); + return atapi_queue_cmd(cdp->atp, ccb, &d, length, 0, 10, NULL, NULL, NULL); +} + +static int +acd_read_structure(struct acd_softc *cdp, struct dvd_struct *s) +{ + struct { + u_int16_t length; + u_char reserved[2]; + u_char data[2048]; + } d; + u_int16_t length; + int32_t error = 0; + int8_t ccb[16]; + + printf("dvd_read_structure: format=0x%x\n", s->format); + + bzero(&d, sizeof(d)); + + switch(s->format) { + case DVD_STRUCT_PHYSICAL: + length = 21; + break; + + case DVD_STRUCT_COPYRIGHT: + length = 8; + break; + + case DVD_STRUCT_DISCKEY: + length = 2052; + break; + + case DVD_STRUCT_BCA: + length = 192; + break; + + case DVD_STRUCT_MANUFACT: + length = 2052; + break; + + case DVD_STRUCT_DDS: + case DVD_STRUCT_PRERECORDED: + case DVD_STRUCT_UNIQUEID: + case DVD_STRUCT_LIST: + case DVD_STRUCT_CMI: + case DVD_STRUCT_RMD_LAST: + case DVD_STRUCT_RMD_RMA: + case DVD_STRUCT_DCB: + return ENOSYS; + + default: + return EINVAL; + } + + bzero(ccb, sizeof(ccb)); + ccb[0] = ATAPI_READ_STRUCTURE; + ccb[6] = s->layer_num; + ccb[7] = s->format; + ccb[8] = (length >> 8) & 0xff; + ccb[9] = length & 0xff; + ccb[10] = s->agid << 6; + d.length = htons(length - 2); + error = atapi_queue_cmd(cdp->atp, ccb, &d, length, A_READ, 30, + NULL, NULL, NULL); + if (error) + return error; + + switch (s->format) { + case DVD_STRUCT_PHYSICAL: { + struct dvd_layer *layer = (struct dvd_layer *)&s->data[0]; + + layer->book_type = d.data[0] >> 4; + layer->book_version = d.data[0] & 0xf; + layer->disc_size = d.data[1] >> 4; + layer->max_rate = d.data[1] & 0xf; + layer->nlayers = (d.data[2] >> 5) & 3; + layer->track_path = (d.data[2] >> 4) & 1; + layer->layer_type = d.data[2] & 0xf; + layer->linear_density = d.data[3] >> 4; + layer->track_density = d.data[3] & 0xf; + layer->start_sector = d.data[5] << 16 | d.data[6] << 8 | d.data[7]; + layer->end_sector = d.data[9] << 16 | d.data[10] << 8 | d.data[11]; + layer->end_sector_l0 = d.data[13] << 16 | d.data[14] << 8 | d.data[15]; + layer->bca = d.data[16] >> 7; + break; + } + + case DVD_STRUCT_COPYRIGHT: + s->cpst = d.data[0]; + s->rmi = d.data[0]; + break; + + case DVD_STRUCT_DISCKEY: + bcopy(&d.data[0], &s->data[0], 2048); + break; + + case DVD_STRUCT_BCA: + s->length = ntohs(d.length); + bcopy(&d.data[0], &s->data[0], s->length); + break; + + case DVD_STRUCT_MANUFACT: + s->length = ntohs(d.length); + bcopy(&d.data[0], &s->data[0], s->length); + break; + + default: + return EINVAL; + } + return 0; +} + static int32_t acd_eject(struct acd_softc *cdp, int32_t close) { @@ -1485,3 +1760,4 @@ acd_set_speed(struct acd_softc *cdp, int32_t speed) return atapi_queue_cmd(cdp->atp, ccb, NULL, 0, 0, 30, NULL, NULL, NULL); } + diff --git a/sys/dev/ata/atapi-fd.c b/sys/dev/ata/atapi-fd.c index 3872b54be182b..3fbdfd5b1305b 100644 --- a/sys/dev/ata/atapi-fd.c +++ b/sys/dev/ata/atapi-fd.c @@ -142,7 +142,7 @@ afd_sense(struct afd_softc *fdp) if (error) return error; bcopy(buffer, &fdp->header, sizeof(struct afd_header)); - bcopy(buffer+sizeof(struct afd_header), &fdp->cap, + bcopy(buffer + sizeof(struct afd_header), &fdp->cap, sizeof(struct afd_cappage)); if (fdp->cap.page_code != ATAPI_REWRITEABLE_CAP_PAGE) return 1; @@ -207,16 +207,14 @@ afdopen(dev_t dev, int32_t flags, int32_t fmt, struct proc *p) if (afd_sense(fdp)) printf("afd%d: sense media type failed\n", fdp->lun); - /* build disklabel and initilize slice tables */ label = &fdp->disk.d_label; bzero(label, sizeof *label); label->d_secsize = fdp->cap.sector_size; label->d_nsectors = fdp->cap.sectors; label->d_ntracks = fdp->cap.heads; label->d_ncylinders = fdp->cap.cylinders; - label->d_secpercyl = fdp->cap.heads * fdp->cap.sectors; + label->d_secpercyl = fdp->cap.sectors * fdp->cap.heads; label->d_secperunit = label->d_secpercyl * fdp->cap.cylinders; - return 0; } |
