--lDmy9qa7XSrSxqzV Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename="linux-dvd-diff-2.2.7" --- drivers/block/old/ide-cd.c Mon Jul 19 03:06:48 1999 +++ drivers/block/ide-cd.c Mon Jul 19 06:16:22 1999 @@ -2087,6 +2087,329 @@ NULL); } +#define copy_key(dest,src) memcpy ((dest), (src), sizeof(dvd_key)) +#define copy_chal(dest,src) memcpy ((dest), (src), sizeof(dvd_challenge)) + +static void +setup_report_key (struct packet_command *pc, unsigned agid, unsigned type) +{ + pc->c[0] = DVD_REPORT_KEY; + pc->c[10] = type | (agid << 6); +} + +static void +setup_send_key (struct packet_command *pc, unsigned agid, unsigned type) +{ + pc->c[0] = DVD_SEND_KEY; + pc->c[10] = type | (agid << 6); +} + +static int +dvd_do_auth (ide_drive_t *drive, dvd_authinfo *ai) +{ + int rv; + u_char buf[20]; + struct packet_command pc; + + memset (buf, 0, sizeof (buf)); + memset (&pc, 0, sizeof (pc)); + pc.buffer = buf; + + switch (ai->type) { + /* LU data send */ + case DVD_LU_SEND_AGID: + setup_report_key (&pc, 0, 0); + pc.buflen = pc.c[9] = 8; + + rv = cdrom_queue_packet_command (drive, &pc); + if (rv) + return rv; + + ai->lsa.agid = buf[7] >> 6; + /* Returning data, let host change state */ + break; + + case DVD_LU_SEND_KEY1: + setup_report_key (&pc, ai->lsk.agid, 2); + pc.buflen = pc.c[9] = 12; + + rv = cdrom_queue_packet_command (drive, &pc); + if (rv) + return rv; + + copy_key (ai->lsk.key1, &buf[4]); + /* Returning data, let host change state */ + break; + + case DVD_LU_SEND_CHALLENGE: + setup_report_key (&pc, ai->lsc.agid, 1); + pc.buflen = pc.c[9] = 16; + + rv = cdrom_queue_packet_command (drive, &pc); + if (rv) + return rv; + + copy_chal (ai->lsc.chal, &buf[4]); + /* Returning data, let host change state */ + break; + + /* Post-auth key */ + case DVD_LU_SEND_TITLE_KEY: + setup_report_key (&pc, ai->lstk.agid, 4); + pc.c[5] = ai->lstk.lba; + pc.c[4] = ai->lstk.lba >> 8; + pc.c[3] = ai->lstk.lba >> 16; + pc.c[2] = ai->lstk.lba >> 24; + pc.buflen = pc.c[9] = 12; + + rv = cdrom_queue_packet_command (drive, &pc); + if (rv) + return rv; + + ai->lstk.cpm = (buf[3] >> 6) & 1; + ai->lstk.cp_sec = (buf[3] >> 5) & 1; + ai->lstk.cgms = (buf[3] >> 3) & 3; + copy_key (ai->lstk.title_key, &buf[4]); + /* Returning data, let host change state */ + break; + + case DVD_LU_SEND_ASF: + setup_report_key (&pc, ai->lsasf.agid, 5); + pc.buflen = pc.c[9] = 8; + + rv = cdrom_queue_packet_command (drive, &pc); + if (rv) + return rv; + + ai->lsasf.asf = buf[7] & 1; + break; + + /* LU data receive (LU changes state) */ + case DVD_HOST_SEND_CHALLENGE: + setup_send_key (&pc, ai->hsc.agid, 1); + pc.buflen = -(pc.c[9] = 16); + buf[1] = 14; + copy_chal (&buf[4], ai->hsc.chal); + + rv = cdrom_queue_packet_command (drive, &pc); + if (rv) + return rv; + + ai->type = DVD_LU_SEND_KEY1; + break; + + case DVD_HOST_SEND_KEY2: + setup_send_key (&pc, ai->hsk.agid, 3); + pc.buflen = -(pc.c[9] = 12); + buf[1] = 10; + copy_key (&buf[4], ai->hsk.key2); + + rv = cdrom_queue_packet_command (drive, &pc); + if (rv) { + ai->type = DVD_AUTH_FAILURE; + return rv; + } + ai->type = DVD_AUTH_ESTABLISHED; + break; + + /* Misc */ + case DVD_INVALIDATE_AGID: + setup_report_key (&pc, ai->lsa.agid, 0x3f); + + rv = cdrom_queue_packet_command (drive, &pc); + if (rv) + return rv; + break; + + default: +#if VERBOSE_IDE_CD_ERRORS + printk (KERN_WARNING ": Invalid DVD key ioctl (%d)\n", ai->type); +#endif + return -EINVAL; + } + + return 0; +} + +static int +dvd_read_physical (ide_drive_t *drive, dvd_struct *s) +{ + int rv, i; + u_char buf[4 + 4 * 20], *base; + struct dvd_layer *layer; + struct packet_command pc; + + memset (buf, 0, sizeof (buf)); + memset (&pc, 0, sizeof (pc)); + pc.buffer = buf; + pc.c[0] = DVD_READ_STRUCTURE; + pc.c[6] = s->physical.layer_num; + pc.c[7] = s->type; + pc.buflen = pc.c[9] = sizeof (buf); + + rv = cdrom_queue_packet_command (drive, &pc); + if (rv) + return rv; + + base = &buf[4]; + layer = &s->physical.layer[0]; + for (i = 0; i < 4; ++i, base += 20, ++layer) { + memset (layer, 0, sizeof (*layer)); + layer->book_version = base[0] & 0xf; + layer->book_type = base[0] >> 4; + layer->min_rate = base[1] & 0xf; + layer->disc_size = base[1] >> 4; + layer->layer_type = base[2] & 0xf; + layer->track_path = (base[2] >> 4) & 1; + layer->nlayers = (base[2] >> 5) & 3; + layer->track_density = base[3] & 0xf; + layer->linear_density = base[3] >> 4; + layer->start_sector = base[5] << 16 | base[6] << 8 | base[7]; + layer->end_sector = base[9] << 16 | base[10] << 8 | base[11]; + layer->end_sector_l0 = base[13] << 16 | base[14] << 8 | base[15]; + layer->bca = base[16] >> 7; + } + + return 0; +} + +static int +dvd_read_copyright (ide_drive_t *drive, dvd_struct *s) +{ + int rv; + u_char buf[8]; + struct packet_command pc; + + memset (buf, 0, sizeof (buf)); + memset (&pc, 0, sizeof (pc)); + pc.buffer = buf; + pc.c[0] = DVD_READ_STRUCTURE; + pc.c[6] = s->copyright.layer_num; + pc.c[7] = s->type; + pc.buflen = pc.c[9] = sizeof (buf); + + rv = cdrom_queue_packet_command (drive, &pc); + if (rv) + return rv; + + s->copyright.cpst = buf[4]; + s->copyright.rmi = buf[5]; + + return 0; +} + +static int +dvd_read_disckey (ide_drive_t *drive, dvd_struct *s) +{ + int rv; + u_char buf[4 + 2048]; + struct packet_command pc; + + memset (buf, 0, sizeof (buf)); + memset (&pc, 0, sizeof (pc)); + pc.buffer = buf; + pc.c[0] = DVD_READ_STRUCTURE; + pc.c[7] = s->type; + pc.c[10] = s->disckey.agid << 6; + pc.buflen = sizeof (buf); + pc.c[8] = sizeof (buf) >> 8; + pc.c[9] = (char) sizeof (buf); + + rv = cdrom_queue_packet_command (drive, &pc); + if (rv) + return rv; + + memcpy (s->disckey.value, &buf[4], 2048); + + return 0; +} + +static int +dvd_read_bca (ide_drive_t *drive, dvd_struct *s) +{ + int rv; + u_char buf[4 + 188]; + struct packet_command pc; + + memset (buf, 0, sizeof (buf)); + memset (&pc, 0, sizeof (pc)); + pc.buffer = buf; + pc.c[0] = DVD_READ_STRUCTURE; + pc.c[7] = s->type; + pc.buflen = pc.c[9] = sizeof (buf); + + rv = cdrom_queue_packet_command (drive, &pc); + if (rv) + return rv; + + s->bca.len = buf[0] << 8 | buf[1]; + if (s->bca.len < 12 || s->bca.len > 188) { + printk (KERN_DEBUG "Received invalid BCA length (%d)\n", s->bca.len); + return -EIO; + } + memcpy (s->bca.value, &buf[4], s->bca.len); + + return 0; +} + +static int +dvd_read_manufact (ide_drive_t *drive, dvd_struct *s) +{ + int rv; + u_char buf[4 + 2048]; + struct packet_command pc; + + memset (buf, 0, sizeof (buf)); + memset (&pc, 0, sizeof (pc)); + pc.buffer = buf; + pc.c[0] = DVD_READ_STRUCTURE; + pc.c[7] = s->type; + pc.buflen = sizeof (buf); + pc.c[8] = sizeof (buf) >> 8; + pc.c[9] = (char) sizeof (buf); + + rv = cdrom_queue_packet_command (drive, &pc); + if (rv) + return rv; + + s->manufact.len = buf[0] << 8 | buf[1]; + if (s->manufact.len < 0 || s->manufact.len > 2048) { + printk (KERN_DEBUG "Recieved invalid manufacture info length (%d)\n", s->bca.len); + return -EIO; + } + memcpy (s->manufact.value, &buf[4], s->manufact.len); + + return 0; +} + +static int +dvd_read_struct (ide_drive_t *drive, dvd_struct *s) +{ + switch (s->type) { + case DVD_STRUCT_PHYSICAL: + return dvd_read_physical (drive, s); + + case DVD_STRUCT_COPYRIGHT: + return dvd_read_copyright (drive, s); + + case DVD_STRUCT_DISCKEY: + return dvd_read_disckey (drive, s); + + case DVD_STRUCT_BCA: + return dvd_read_bca (drive, s); + + case DVD_STRUCT_MANUFACT: + return dvd_read_manufact (drive, s); + + default: +#if VERBOSE_IDE_CD_ERRORS + printk (KERN_WARNING + ": Invalid DVD structure read requested (%d)\n", + s->type); +#endif + return -EINVAL; + } +} static int ide_cdrom_dev_ioctl (struct cdrom_device_info *cdi, @@ -2303,6 +2626,39 @@ return stat; } #endif + + case DVD_READ_STRUCT: { + int rv; + dvd_struct s; + + if (!CDROM_CONFIG_FLAGS (drive)->dvd) + return -EINVAL; + if (copy_from_user (&s, (void *)arg, sizeof (s))) + return -EFAULT; + if ((rv = dvd_read_struct (drive, &s)) == 0) { + if (copy_to_user ((void *)arg, &s, sizeof (s))) + return -EFAULT; + return 0; + } + return rv; + } + + case DVD_WRITE_STRUCT: { + return -EINVAL; + } + + case DVD_AUTH: { + int rv; + dvd_authinfo ai; + + if (!CDROM_CONFIG_FLAGS (drive)->dvd) + return -EINVAL; + if (copy_from_user (&ai, (void *)arg, sizeof (ai))) + return -EFAULT; + if ((rv = dvd_do_auth (drive, &ai))) + return rv; + return copy_to_user ((void *)arg, &ai, sizeof (ai)); + } default: return -EINVAL; --lDmy9qa7XSrSxqzV Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename="linux-dvd-diff-2.2.7-diff" 1,3c1,2 < diff -ur /usr/src/linux/drivers/block/ide-cd.c linux/drivers/block/ide-cd.c < --- /usr/src/linux/drivers/block/ide-cd.c Tue Mar 23 18:59:35 1999 < +++ linux/drivers/block/ide-cd.c Fri Apr 9 11:03:11 1999 --- > --- drivers/block/old/ide-cd.c Mon Jul 19 03:06:48 1999 > +++ drivers/block/ide-cd.c Mon Jul 19 06:16:22 1999 102c101 < + ai->lsasf.agid = buf[7] & 1; --- > + ai->lsasf.asf = buf[7] & 1; 135c134 < + setup_report_key (&pc, ai->lsasf.agid, 0x7f); --- > + setup_report_key (&pc, ai->lsa.agid, 0x3f); --lDmy9qa7XSrSxqzV--