|
@@ -461,27 +461,37 @@ int cdrom_get_media_event(struct cdrom_device_info *cdi,
|
|
struct media_event_desc *med)
|
|
struct media_event_desc *med)
|
|
{
|
|
{
|
|
struct packet_command cgc;
|
|
struct packet_command cgc;
|
|
- unsigned char buffer[8];
|
|
|
|
- struct event_header *eh = (struct event_header *) buffer;
|
|
|
|
|
|
+ unsigned char *buffer;
|
|
|
|
+ struct event_header *eh;
|
|
|
|
+ int ret = 1;
|
|
|
|
+
|
|
|
|
+ buffer = kmalloc(8, GFP_KERNEL);
|
|
|
|
+ if (!buffer)
|
|
|
|
+ return -ENOMEM;
|
|
|
|
|
|
- init_cdrom_command(&cgc, buffer, sizeof(buffer), CGC_DATA_READ);
|
|
|
|
|
|
+ eh = (struct event_header *)buffer;
|
|
|
|
+
|
|
|
|
+ init_cdrom_command(&cgc, buffer, 8, CGC_DATA_READ);
|
|
cgc.cmd[0] = GPCMD_GET_EVENT_STATUS_NOTIFICATION;
|
|
cgc.cmd[0] = GPCMD_GET_EVENT_STATUS_NOTIFICATION;
|
|
cgc.cmd[1] = 1; /* IMMED */
|
|
cgc.cmd[1] = 1; /* IMMED */
|
|
cgc.cmd[4] = 1 << 4; /* media event */
|
|
cgc.cmd[4] = 1 << 4; /* media event */
|
|
- cgc.cmd[8] = sizeof(buffer);
|
|
|
|
|
|
+ cgc.cmd[8] = 8;
|
|
cgc.quiet = 1;
|
|
cgc.quiet = 1;
|
|
|
|
|
|
if (cdi->ops->generic_packet(cdi, &cgc))
|
|
if (cdi->ops->generic_packet(cdi, &cgc))
|
|
- return 1;
|
|
|
|
|
|
+ goto err;
|
|
|
|
|
|
if (be16_to_cpu(eh->data_len) < sizeof(*med))
|
|
if (be16_to_cpu(eh->data_len) < sizeof(*med))
|
|
- return 1;
|
|
|
|
|
|
+ goto err;
|
|
|
|
|
|
if (eh->nea || eh->notification_class != 0x4)
|
|
if (eh->nea || eh->notification_class != 0x4)
|
|
- return 1;
|
|
|
|
|
|
+ goto err;
|
|
|
|
|
|
- memcpy(med, &buffer[sizeof(*eh)], sizeof(*med));
|
|
|
|
- return 0;
|
|
|
|
|
|
+ memcpy(med, buffer + sizeof(*eh), sizeof(*med));
|
|
|
|
+ ret = 0;
|
|
|
|
+err:
|
|
|
|
+ kfree(buffer);
|
|
|
|
+ return ret;
|
|
}
|
|
}
|
|
|
|
|
|
/*
|
|
/*
|
|
@@ -491,68 +501,82 @@ int cdrom_get_media_event(struct cdrom_device_info *cdi,
|
|
static int cdrom_mrw_probe_pc(struct cdrom_device_info *cdi)
|
|
static int cdrom_mrw_probe_pc(struct cdrom_device_info *cdi)
|
|
{
|
|
{
|
|
struct packet_command cgc;
|
|
struct packet_command cgc;
|
|
- char buffer[16];
|
|
|
|
|
|
+ char *buffer;
|
|
|
|
+ int ret = 1;
|
|
|
|
+
|
|
|
|
+ buffer = kmalloc(16, GFP_KERNEL);
|
|
|
|
+ if (!buffer)
|
|
|
|
+ return -ENOMEM;
|
|
|
|
|
|
- init_cdrom_command(&cgc, buffer, sizeof(buffer), CGC_DATA_READ);
|
|
|
|
|
|
+ init_cdrom_command(&cgc, buffer, 16, CGC_DATA_READ);
|
|
|
|
|
|
cgc.timeout = HZ;
|
|
cgc.timeout = HZ;
|
|
cgc.quiet = 1;
|
|
cgc.quiet = 1;
|
|
|
|
|
|
if (!cdrom_mode_sense(cdi, &cgc, MRW_MODE_PC, 0)) {
|
|
if (!cdrom_mode_sense(cdi, &cgc, MRW_MODE_PC, 0)) {
|
|
cdi->mrw_mode_page = MRW_MODE_PC;
|
|
cdi->mrw_mode_page = MRW_MODE_PC;
|
|
- return 0;
|
|
|
|
|
|
+ ret = 0;
|
|
} else if (!cdrom_mode_sense(cdi, &cgc, MRW_MODE_PC_PRE1, 0)) {
|
|
} else if (!cdrom_mode_sense(cdi, &cgc, MRW_MODE_PC_PRE1, 0)) {
|
|
cdi->mrw_mode_page = MRW_MODE_PC_PRE1;
|
|
cdi->mrw_mode_page = MRW_MODE_PC_PRE1;
|
|
- return 0;
|
|
|
|
|
|
+ ret = 0;
|
|
}
|
|
}
|
|
-
|
|
|
|
- return 1;
|
|
|
|
|
|
+ kfree(buffer);
|
|
|
|
+ return ret;
|
|
}
|
|
}
|
|
|
|
|
|
static int cdrom_is_mrw(struct cdrom_device_info *cdi, int *write)
|
|
static int cdrom_is_mrw(struct cdrom_device_info *cdi, int *write)
|
|
{
|
|
{
|
|
struct packet_command cgc;
|
|
struct packet_command cgc;
|
|
struct mrw_feature_desc *mfd;
|
|
struct mrw_feature_desc *mfd;
|
|
- unsigned char buffer[16];
|
|
|
|
|
|
+ unsigned char *buffer;
|
|
int ret;
|
|
int ret;
|
|
|
|
|
|
*write = 0;
|
|
*write = 0;
|
|
|
|
+ buffer = kmalloc(16, GFP_KERNEL);
|
|
|
|
+ if (!buffer)
|
|
|
|
+ return -ENOMEM;
|
|
|
|
|
|
- init_cdrom_command(&cgc, buffer, sizeof(buffer), CGC_DATA_READ);
|
|
|
|
|
|
+ init_cdrom_command(&cgc, buffer, 16, CGC_DATA_READ);
|
|
|
|
|
|
cgc.cmd[0] = GPCMD_GET_CONFIGURATION;
|
|
cgc.cmd[0] = GPCMD_GET_CONFIGURATION;
|
|
cgc.cmd[3] = CDF_MRW;
|
|
cgc.cmd[3] = CDF_MRW;
|
|
- cgc.cmd[8] = sizeof(buffer);
|
|
|
|
|
|
+ cgc.cmd[8] = 16;
|
|
cgc.quiet = 1;
|
|
cgc.quiet = 1;
|
|
|
|
|
|
if ((ret = cdi->ops->generic_packet(cdi, &cgc)))
|
|
if ((ret = cdi->ops->generic_packet(cdi, &cgc)))
|
|
- return ret;
|
|
|
|
|
|
+ goto err;
|
|
|
|
|
|
mfd = (struct mrw_feature_desc *)&buffer[sizeof(struct feature_header)];
|
|
mfd = (struct mrw_feature_desc *)&buffer[sizeof(struct feature_header)];
|
|
- if (be16_to_cpu(mfd->feature_code) != CDF_MRW)
|
|
|
|
- return 1;
|
|
|
|
|
|
+ if (be16_to_cpu(mfd->feature_code) != CDF_MRW) {
|
|
|
|
+ ret = 1;
|
|
|
|
+ goto err;
|
|
|
|
+ }
|
|
*write = mfd->write;
|
|
*write = mfd->write;
|
|
|
|
|
|
if ((ret = cdrom_mrw_probe_pc(cdi))) {
|
|
if ((ret = cdrom_mrw_probe_pc(cdi))) {
|
|
*write = 0;
|
|
*write = 0;
|
|
- return ret;
|
|
|
|
}
|
|
}
|
|
-
|
|
|
|
- return 0;
|
|
|
|
|
|
+err:
|
|
|
|
+ kfree(buffer);
|
|
|
|
+ return ret;
|
|
}
|
|
}
|
|
|
|
|
|
static int cdrom_mrw_bgformat(struct cdrom_device_info *cdi, int cont)
|
|
static int cdrom_mrw_bgformat(struct cdrom_device_info *cdi, int cont)
|
|
{
|
|
{
|
|
struct packet_command cgc;
|
|
struct packet_command cgc;
|
|
- unsigned char buffer[12];
|
|
|
|
|
|
+ unsigned char *buffer;
|
|
int ret;
|
|
int ret;
|
|
|
|
|
|
printk(KERN_INFO "cdrom: %sstarting format\n", cont ? "Re" : "");
|
|
printk(KERN_INFO "cdrom: %sstarting format\n", cont ? "Re" : "");
|
|
|
|
|
|
|
|
+ buffer = kmalloc(12, GFP_KERNEL);
|
|
|
|
+ if (!buffer)
|
|
|
|
+ return -ENOMEM;
|
|
|
|
+
|
|
/*
|
|
/*
|
|
* FmtData bit set (bit 4), format type is 1
|
|
* FmtData bit set (bit 4), format type is 1
|
|
*/
|
|
*/
|
|
- init_cdrom_command(&cgc, buffer, sizeof(buffer), CGC_DATA_WRITE);
|
|
|
|
|
|
+ init_cdrom_command(&cgc, buffer, 12, CGC_DATA_WRITE);
|
|
cgc.cmd[0] = GPCMD_FORMAT_UNIT;
|
|
cgc.cmd[0] = GPCMD_FORMAT_UNIT;
|
|
cgc.cmd[1] = (1 << 4) | 1;
|
|
cgc.cmd[1] = (1 << 4) | 1;
|
|
|
|
|
|
@@ -579,6 +603,7 @@ static int cdrom_mrw_bgformat(struct cdrom_device_info *cdi, int cont)
|
|
if (ret)
|
|
if (ret)
|
|
printk(KERN_INFO "cdrom: bgformat failed\n");
|
|
printk(KERN_INFO "cdrom: bgformat failed\n");
|
|
|
|
|
|
|
|
+ kfree(buffer);
|
|
return ret;
|
|
return ret;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -638,16 +663,17 @@ static int cdrom_mrw_set_lba_space(struct cdrom_device_info *cdi, int space)
|
|
{
|
|
{
|
|
struct packet_command cgc;
|
|
struct packet_command cgc;
|
|
struct mode_page_header *mph;
|
|
struct mode_page_header *mph;
|
|
- char buffer[16];
|
|
|
|
|
|
+ char *buffer;
|
|
int ret, offset, size;
|
|
int ret, offset, size;
|
|
|
|
|
|
- init_cdrom_command(&cgc, buffer, sizeof(buffer), CGC_DATA_READ);
|
|
|
|
|
|
+ buffer = kmalloc(16, GFP_KERNEL);
|
|
|
|
+ if (!buffer)
|
|
|
|
+ return -ENOMEM;
|
|
|
|
|
|
- cgc.buffer = buffer;
|
|
|
|
- cgc.buflen = sizeof(buffer);
|
|
|
|
|
|
+ init_cdrom_command(&cgc, buffer, 16, CGC_DATA_READ);
|
|
|
|
|
|
if ((ret = cdrom_mode_sense(cdi, &cgc, cdi->mrw_mode_page, 0)))
|
|
if ((ret = cdrom_mode_sense(cdi, &cgc, cdi->mrw_mode_page, 0)))
|
|
- return ret;
|
|
|
|
|
|
+ goto err;
|
|
|
|
|
|
mph = (struct mode_page_header *) buffer;
|
|
mph = (struct mode_page_header *) buffer;
|
|
offset = be16_to_cpu(mph->desc_length);
|
|
offset = be16_to_cpu(mph->desc_length);
|
|
@@ -657,55 +683,70 @@ static int cdrom_mrw_set_lba_space(struct cdrom_device_info *cdi, int space)
|
|
cgc.buflen = size;
|
|
cgc.buflen = size;
|
|
|
|
|
|
if ((ret = cdrom_mode_select(cdi, &cgc)))
|
|
if ((ret = cdrom_mode_select(cdi, &cgc)))
|
|
- return ret;
|
|
|
|
|
|
+ goto err;
|
|
|
|
|
|
printk(KERN_INFO "cdrom: %s: mrw address space %s selected\n", cdi->name, mrw_address_space[space]);
|
|
printk(KERN_INFO "cdrom: %s: mrw address space %s selected\n", cdi->name, mrw_address_space[space]);
|
|
- return 0;
|
|
|
|
|
|
+ ret = 0;
|
|
|
|
+err:
|
|
|
|
+ kfree(buffer);
|
|
|
|
+ return ret;
|
|
}
|
|
}
|
|
|
|
|
|
static int cdrom_get_random_writable(struct cdrom_device_info *cdi,
|
|
static int cdrom_get_random_writable(struct cdrom_device_info *cdi,
|
|
struct rwrt_feature_desc *rfd)
|
|
struct rwrt_feature_desc *rfd)
|
|
{
|
|
{
|
|
struct packet_command cgc;
|
|
struct packet_command cgc;
|
|
- char buffer[24];
|
|
|
|
|
|
+ char *buffer;
|
|
int ret;
|
|
int ret;
|
|
|
|
|
|
- init_cdrom_command(&cgc, buffer, sizeof(buffer), CGC_DATA_READ);
|
|
|
|
|
|
+ buffer = kmalloc(24, GFP_KERNEL);
|
|
|
|
+ if (!buffer)
|
|
|
|
+ return -ENOMEM;
|
|
|
|
+
|
|
|
|
+ init_cdrom_command(&cgc, buffer, 24, CGC_DATA_READ);
|
|
|
|
|
|
cgc.cmd[0] = GPCMD_GET_CONFIGURATION; /* often 0x46 */
|
|
cgc.cmd[0] = GPCMD_GET_CONFIGURATION; /* often 0x46 */
|
|
cgc.cmd[3] = CDF_RWRT; /* often 0x0020 */
|
|
cgc.cmd[3] = CDF_RWRT; /* often 0x0020 */
|
|
- cgc.cmd[8] = sizeof(buffer); /* often 0x18 */
|
|
|
|
|
|
+ cgc.cmd[8] = 24; /* often 0x18 */
|
|
cgc.quiet = 1;
|
|
cgc.quiet = 1;
|
|
|
|
|
|
if ((ret = cdi->ops->generic_packet(cdi, &cgc)))
|
|
if ((ret = cdi->ops->generic_packet(cdi, &cgc)))
|
|
- return ret;
|
|
|
|
|
|
+ goto err;
|
|
|
|
|
|
memcpy(rfd, &buffer[sizeof(struct feature_header)], sizeof (*rfd));
|
|
memcpy(rfd, &buffer[sizeof(struct feature_header)], sizeof (*rfd));
|
|
- return 0;
|
|
|
|
|
|
+ ret = 0;
|
|
|
|
+err:
|
|
|
|
+ kfree(buffer);
|
|
|
|
+ return ret;
|
|
}
|
|
}
|
|
|
|
|
|
static int cdrom_has_defect_mgt(struct cdrom_device_info *cdi)
|
|
static int cdrom_has_defect_mgt(struct cdrom_device_info *cdi)
|
|
{
|
|
{
|
|
struct packet_command cgc;
|
|
struct packet_command cgc;
|
|
- char buffer[16];
|
|
|
|
|
|
+ char *buffer;
|
|
__be16 *feature_code;
|
|
__be16 *feature_code;
|
|
int ret;
|
|
int ret;
|
|
|
|
|
|
- init_cdrom_command(&cgc, buffer, sizeof(buffer), CGC_DATA_READ);
|
|
|
|
|
|
+ buffer = kmalloc(16, GFP_KERNEL);
|
|
|
|
+ if (!buffer)
|
|
|
|
+ return -ENOMEM;
|
|
|
|
+
|
|
|
|
+ init_cdrom_command(&cgc, buffer, 16, CGC_DATA_READ);
|
|
|
|
|
|
cgc.cmd[0] = GPCMD_GET_CONFIGURATION;
|
|
cgc.cmd[0] = GPCMD_GET_CONFIGURATION;
|
|
cgc.cmd[3] = CDF_HWDM;
|
|
cgc.cmd[3] = CDF_HWDM;
|
|
- cgc.cmd[8] = sizeof(buffer);
|
|
|
|
|
|
+ cgc.cmd[8] = 16;
|
|
cgc.quiet = 1;
|
|
cgc.quiet = 1;
|
|
|
|
|
|
if ((ret = cdi->ops->generic_packet(cdi, &cgc)))
|
|
if ((ret = cdi->ops->generic_packet(cdi, &cgc)))
|
|
- return ret;
|
|
|
|
|
|
+ goto err;
|
|
|
|
|
|
feature_code = (__be16 *) &buffer[sizeof(struct feature_header)];
|
|
feature_code = (__be16 *) &buffer[sizeof(struct feature_header)];
|
|
if (be16_to_cpu(*feature_code) == CDF_HWDM)
|
|
if (be16_to_cpu(*feature_code) == CDF_HWDM)
|
|
- return 0;
|
|
|
|
-
|
|
|
|
- return 1;
|
|
|
|
|
|
+ ret = 0;
|
|
|
|
+err:
|
|
|
|
+ kfree(buffer);
|
|
|
|
+ return ret;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -796,10 +837,14 @@ static int cdrom_mrw_open_write(struct cdrom_device_info *cdi)
|
|
static int mo_open_write(struct cdrom_device_info *cdi)
|
|
static int mo_open_write(struct cdrom_device_info *cdi)
|
|
{
|
|
{
|
|
struct packet_command cgc;
|
|
struct packet_command cgc;
|
|
- char buffer[255];
|
|
|
|
|
|
+ char *buffer;
|
|
int ret;
|
|
int ret;
|
|
|
|
|
|
- init_cdrom_command(&cgc, &buffer, 4, CGC_DATA_READ);
|
|
|
|
|
|
+ buffer = kmalloc(255, GFP_KERNEL);
|
|
|
|
+ if (!buffer)
|
|
|
|
+ return -ENOMEM;
|
|
|
|
+
|
|
|
|
+ init_cdrom_command(&cgc, buffer, 4, CGC_DATA_READ);
|
|
cgc.quiet = 1;
|
|
cgc.quiet = 1;
|
|
|
|
|
|
/*
|
|
/*
|
|
@@ -816,10 +861,15 @@ static int mo_open_write(struct cdrom_device_info *cdi)
|
|
}
|
|
}
|
|
|
|
|
|
/* drive gave us no info, let the user go ahead */
|
|
/* drive gave us no info, let the user go ahead */
|
|
- if (ret)
|
|
|
|
- return 0;
|
|
|
|
|
|
+ if (ret) {
|
|
|
|
+ ret = 0;
|
|
|
|
+ goto err;
|
|
|
|
+ }
|
|
|
|
|
|
- return buffer[3] & 0x80;
|
|
|
|
|
|
+ ret = buffer[3] & 0x80;
|
|
|
|
+err:
|
|
|
|
+ kfree(buffer);
|
|
|
|
+ return ret;
|
|
}
|
|
}
|
|
|
|
|
|
static int cdrom_ram_open_write(struct cdrom_device_info *cdi)
|
|
static int cdrom_ram_open_write(struct cdrom_device_info *cdi)
|
|
@@ -842,15 +892,19 @@ static int cdrom_ram_open_write(struct cdrom_device_info *cdi)
|
|
static void cdrom_mmc3_profile(struct cdrom_device_info *cdi)
|
|
static void cdrom_mmc3_profile(struct cdrom_device_info *cdi)
|
|
{
|
|
{
|
|
struct packet_command cgc;
|
|
struct packet_command cgc;
|
|
- char buffer[32];
|
|
|
|
|
|
+ char *buffer;
|
|
int ret, mmc3_profile;
|
|
int ret, mmc3_profile;
|
|
|
|
|
|
- init_cdrom_command(&cgc, buffer, sizeof(buffer), CGC_DATA_READ);
|
|
|
|
|
|
+ buffer = kmalloc(32, GFP_KERNEL);
|
|
|
|
+ if (!buffer)
|
|
|
|
+ return;
|
|
|
|
+
|
|
|
|
+ init_cdrom_command(&cgc, buffer, 32, CGC_DATA_READ);
|
|
|
|
|
|
cgc.cmd[0] = GPCMD_GET_CONFIGURATION;
|
|
cgc.cmd[0] = GPCMD_GET_CONFIGURATION;
|
|
cgc.cmd[1] = 0;
|
|
cgc.cmd[1] = 0;
|
|
cgc.cmd[2] = cgc.cmd[3] = 0; /* Starting Feature Number */
|
|
cgc.cmd[2] = cgc.cmd[3] = 0; /* Starting Feature Number */
|
|
- cgc.cmd[8] = sizeof(buffer); /* Allocation Length */
|
|
|
|
|
|
+ cgc.cmd[8] = 32; /* Allocation Length */
|
|
cgc.quiet = 1;
|
|
cgc.quiet = 1;
|
|
|
|
|
|
if ((ret = cdi->ops->generic_packet(cdi, &cgc)))
|
|
if ((ret = cdi->ops->generic_packet(cdi, &cgc)))
|
|
@@ -859,6 +913,7 @@ static void cdrom_mmc3_profile(struct cdrom_device_info *cdi)
|
|
mmc3_profile = (buffer[6] << 8) | buffer[7];
|
|
mmc3_profile = (buffer[6] << 8) | buffer[7];
|
|
|
|
|
|
cdi->mmc3_profile = mmc3_profile;
|
|
cdi->mmc3_profile = mmc3_profile;
|
|
|
|
+ kfree(buffer);
|
|
}
|
|
}
|
|
|
|
|
|
static int cdrom_is_dvd_rw(struct cdrom_device_info *cdi)
|
|
static int cdrom_is_dvd_rw(struct cdrom_device_info *cdi)
|
|
@@ -1573,12 +1628,15 @@ static void setup_send_key(struct packet_command *cgc, unsigned agid, unsigned t
|
|
static int dvd_do_auth(struct cdrom_device_info *cdi, dvd_authinfo *ai)
|
|
static int dvd_do_auth(struct cdrom_device_info *cdi, dvd_authinfo *ai)
|
|
{
|
|
{
|
|
int ret;
|
|
int ret;
|
|
- u_char buf[20];
|
|
|
|
|
|
+ u_char *buf;
|
|
struct packet_command cgc;
|
|
struct packet_command cgc;
|
|
struct cdrom_device_ops *cdo = cdi->ops;
|
|
struct cdrom_device_ops *cdo = cdi->ops;
|
|
- rpc_state_t rpc_state;
|
|
|
|
|
|
+ rpc_state_t *rpc_state;
|
|
|
|
+
|
|
|
|
+ buf = kzalloc(20, GFP_KERNEL);
|
|
|
|
+ if (!buf)
|
|
|
|
+ return -ENOMEM;
|
|
|
|
|
|
- memset(buf, 0, sizeof(buf));
|
|
|
|
init_cdrom_command(&cgc, buf, 0, CGC_DATA_READ);
|
|
init_cdrom_command(&cgc, buf, 0, CGC_DATA_READ);
|
|
|
|
|
|
switch (ai->type) {
|
|
switch (ai->type) {
|
|
@@ -1589,7 +1647,7 @@ static int dvd_do_auth(struct cdrom_device_info *cdi, dvd_authinfo *ai)
|
|
setup_report_key(&cgc, ai->lsa.agid, 0);
|
|
setup_report_key(&cgc, ai->lsa.agid, 0);
|
|
|
|
|
|
if ((ret = cdo->generic_packet(cdi, &cgc)))
|
|
if ((ret = cdo->generic_packet(cdi, &cgc)))
|
|
- return ret;
|
|
|
|
|
|
+ goto err;
|
|
|
|
|
|
ai->lsa.agid = buf[7] >> 6;
|
|
ai->lsa.agid = buf[7] >> 6;
|
|
/* Returning data, let host change state */
|
|
/* Returning data, let host change state */
|
|
@@ -1600,7 +1658,7 @@ static int dvd_do_auth(struct cdrom_device_info *cdi, dvd_authinfo *ai)
|
|
setup_report_key(&cgc, ai->lsk.agid, 2);
|
|
setup_report_key(&cgc, ai->lsk.agid, 2);
|
|
|
|
|
|
if ((ret = cdo->generic_packet(cdi, &cgc)))
|
|
if ((ret = cdo->generic_packet(cdi, &cgc)))
|
|
- return ret;
|
|
|
|
|
|
+ goto err;
|
|
|
|
|
|
copy_key(ai->lsk.key, &buf[4]);
|
|
copy_key(ai->lsk.key, &buf[4]);
|
|
/* Returning data, let host change state */
|
|
/* Returning data, let host change state */
|
|
@@ -1611,7 +1669,7 @@ static int dvd_do_auth(struct cdrom_device_info *cdi, dvd_authinfo *ai)
|
|
setup_report_key(&cgc, ai->lsc.agid, 1);
|
|
setup_report_key(&cgc, ai->lsc.agid, 1);
|
|
|
|
|
|
if ((ret = cdo->generic_packet(cdi, &cgc)))
|
|
if ((ret = cdo->generic_packet(cdi, &cgc)))
|
|
- return ret;
|
|
|
|
|
|
+ goto err;
|
|
|
|
|
|
copy_chal(ai->lsc.chal, &buf[4]);
|
|
copy_chal(ai->lsc.chal, &buf[4]);
|
|
/* Returning data, let host change state */
|
|
/* Returning data, let host change state */
|
|
@@ -1628,7 +1686,7 @@ static int dvd_do_auth(struct cdrom_device_info *cdi, dvd_authinfo *ai)
|
|
cgc.cmd[2] = ai->lstk.lba >> 24;
|
|
cgc.cmd[2] = ai->lstk.lba >> 24;
|
|
|
|
|
|
if ((ret = cdo->generic_packet(cdi, &cgc)))
|
|
if ((ret = cdo->generic_packet(cdi, &cgc)))
|
|
- return ret;
|
|
|
|
|
|
+ goto err;
|
|
|
|
|
|
ai->lstk.cpm = (buf[4] >> 7) & 1;
|
|
ai->lstk.cpm = (buf[4] >> 7) & 1;
|
|
ai->lstk.cp_sec = (buf[4] >> 6) & 1;
|
|
ai->lstk.cp_sec = (buf[4] >> 6) & 1;
|
|
@@ -1642,7 +1700,7 @@ static int dvd_do_auth(struct cdrom_device_info *cdi, dvd_authinfo *ai)
|
|
setup_report_key(&cgc, ai->lsasf.agid, 5);
|
|
setup_report_key(&cgc, ai->lsasf.agid, 5);
|
|
|
|
|
|
if ((ret = cdo->generic_packet(cdi, &cgc)))
|
|
if ((ret = cdo->generic_packet(cdi, &cgc)))
|
|
- return ret;
|
|
|
|
|
|
+ goto err;
|
|
|
|
|
|
ai->lsasf.asf = buf[7] & 1;
|
|
ai->lsasf.asf = buf[7] & 1;
|
|
break;
|
|
break;
|
|
@@ -1655,7 +1713,7 @@ static int dvd_do_auth(struct cdrom_device_info *cdi, dvd_authinfo *ai)
|
|
copy_chal(&buf[4], ai->hsc.chal);
|
|
copy_chal(&buf[4], ai->hsc.chal);
|
|
|
|
|
|
if ((ret = cdo->generic_packet(cdi, &cgc)))
|
|
if ((ret = cdo->generic_packet(cdi, &cgc)))
|
|
- return ret;
|
|
|
|
|
|
+ goto err;
|
|
|
|
|
|
ai->type = DVD_LU_SEND_KEY1;
|
|
ai->type = DVD_LU_SEND_KEY1;
|
|
break;
|
|
break;
|
|
@@ -1668,7 +1726,7 @@ static int dvd_do_auth(struct cdrom_device_info *cdi, dvd_authinfo *ai)
|
|
|
|
|
|
if ((ret = cdo->generic_packet(cdi, &cgc))) {
|
|
if ((ret = cdo->generic_packet(cdi, &cgc))) {
|
|
ai->type = DVD_AUTH_FAILURE;
|
|
ai->type = DVD_AUTH_FAILURE;
|
|
- return ret;
|
|
|
|
|
|
+ goto err;
|
|
}
|
|
}
|
|
ai->type = DVD_AUTH_ESTABLISHED;
|
|
ai->type = DVD_AUTH_ESTABLISHED;
|
|
break;
|
|
break;
|
|
@@ -1679,24 +1737,23 @@ static int dvd_do_auth(struct cdrom_device_info *cdi, dvd_authinfo *ai)
|
|
cdinfo(CD_DVD, "entering DVD_INVALIDATE_AGID\n");
|
|
cdinfo(CD_DVD, "entering DVD_INVALIDATE_AGID\n");
|
|
setup_report_key(&cgc, ai->lsa.agid, 0x3f);
|
|
setup_report_key(&cgc, ai->lsa.agid, 0x3f);
|
|
if ((ret = cdo->generic_packet(cdi, &cgc)))
|
|
if ((ret = cdo->generic_packet(cdi, &cgc)))
|
|
- return ret;
|
|
|
|
|
|
+ goto err;
|
|
break;
|
|
break;
|
|
|
|
|
|
/* Get region settings */
|
|
/* Get region settings */
|
|
case DVD_LU_SEND_RPC_STATE:
|
|
case DVD_LU_SEND_RPC_STATE:
|
|
cdinfo(CD_DVD, "entering DVD_LU_SEND_RPC_STATE\n");
|
|
cdinfo(CD_DVD, "entering DVD_LU_SEND_RPC_STATE\n");
|
|
setup_report_key(&cgc, 0, 8);
|
|
setup_report_key(&cgc, 0, 8);
|
|
- memset(&rpc_state, 0, sizeof(rpc_state_t));
|
|
|
|
- cgc.buffer = (char *) &rpc_state;
|
|
|
|
|
|
|
|
if ((ret = cdo->generic_packet(cdi, &cgc)))
|
|
if ((ret = cdo->generic_packet(cdi, &cgc)))
|
|
- return ret;
|
|
|
|
|
|
+ goto err;
|
|
|
|
|
|
- ai->lrpcs.type = rpc_state.type_code;
|
|
|
|
- ai->lrpcs.vra = rpc_state.vra;
|
|
|
|
- ai->lrpcs.ucca = rpc_state.ucca;
|
|
|
|
- ai->lrpcs.region_mask = rpc_state.region_mask;
|
|
|
|
- ai->lrpcs.rpc_scheme = rpc_state.rpc_scheme;
|
|
|
|
|
|
+ rpc_state = (rpc_state_t *)buf;
|
|
|
|
+ ai->lrpcs.type = rpc_state->type_code;
|
|
|
|
+ ai->lrpcs.vra = rpc_state->vra;
|
|
|
|
+ ai->lrpcs.ucca = rpc_state->ucca;
|
|
|
|
+ ai->lrpcs.region_mask = rpc_state->region_mask;
|
|
|
|
+ ai->lrpcs.rpc_scheme = rpc_state->rpc_scheme;
|
|
break;
|
|
break;
|
|
|
|
|
|
/* Set region settings */
|
|
/* Set region settings */
|
|
@@ -1707,20 +1764,23 @@ static int dvd_do_auth(struct cdrom_device_info *cdi, dvd_authinfo *ai)
|
|
buf[4] = ai->hrpcs.pdrc;
|
|
buf[4] = ai->hrpcs.pdrc;
|
|
|
|
|
|
if ((ret = cdo->generic_packet(cdi, &cgc)))
|
|
if ((ret = cdo->generic_packet(cdi, &cgc)))
|
|
- return ret;
|
|
|
|
|
|
+ goto err;
|
|
break;
|
|
break;
|
|
|
|
|
|
default:
|
|
default:
|
|
cdinfo(CD_WARNING, "Invalid DVD key ioctl (%d)\n", ai->type);
|
|
cdinfo(CD_WARNING, "Invalid DVD key ioctl (%d)\n", ai->type);
|
|
- return -ENOTTY;
|
|
|
|
|
|
+ ret = -ENOTTY;
|
|
|
|
+ goto err;
|
|
}
|
|
}
|
|
-
|
|
|
|
- return 0;
|
|
|
|
|
|
+ ret = 0;
|
|
|
|
+err:
|
|
|
|
+ kfree(buf);
|
|
|
|
+ return ret;
|
|
}
|
|
}
|
|
|
|
|
|
static int dvd_read_physical(struct cdrom_device_info *cdi, dvd_struct *s)
|
|
static int dvd_read_physical(struct cdrom_device_info *cdi, dvd_struct *s)
|
|
{
|
|
{
|
|
- unsigned char buf[21], *base;
|
|
|
|
|
|
+ unsigned char *buf, *base;
|
|
struct dvd_layer *layer;
|
|
struct dvd_layer *layer;
|
|
struct packet_command cgc;
|
|
struct packet_command cgc;
|
|
struct cdrom_device_ops *cdo = cdi->ops;
|
|
struct cdrom_device_ops *cdo = cdi->ops;
|
|
@@ -1729,7 +1789,11 @@ static int dvd_read_physical(struct cdrom_device_info *cdi, dvd_struct *s)
|
|
if (layer_num >= DVD_LAYERS)
|
|
if (layer_num >= DVD_LAYERS)
|
|
return -EINVAL;
|
|
return -EINVAL;
|
|
|
|
|
|
- init_cdrom_command(&cgc, buf, sizeof(buf), CGC_DATA_READ);
|
|
|
|
|
|
+ buf = kmalloc(21, GFP_KERNEL);
|
|
|
|
+ if (!buf)
|
|
|
|
+ return -ENOMEM;
|
|
|
|
+
|
|
|
|
+ init_cdrom_command(&cgc, buf, 21, CGC_DATA_READ);
|
|
cgc.cmd[0] = GPCMD_READ_DVD_STRUCTURE;
|
|
cgc.cmd[0] = GPCMD_READ_DVD_STRUCTURE;
|
|
cgc.cmd[6] = layer_num;
|
|
cgc.cmd[6] = layer_num;
|
|
cgc.cmd[7] = s->type;
|
|
cgc.cmd[7] = s->type;
|
|
@@ -1741,7 +1805,7 @@ static int dvd_read_physical(struct cdrom_device_info *cdi, dvd_struct *s)
|
|
cgc.quiet = 1;
|
|
cgc.quiet = 1;
|
|
|
|
|
|
if ((ret = cdo->generic_packet(cdi, &cgc)))
|
|
if ((ret = cdo->generic_packet(cdi, &cgc)))
|
|
- return ret;
|
|
|
|
|
|
+ goto err;
|
|
|
|
|
|
base = &buf[4];
|
|
base = &buf[4];
|
|
layer = &s->physical.layer[layer_num];
|
|
layer = &s->physical.layer[layer_num];
|
|
@@ -1765,17 +1829,24 @@ static int dvd_read_physical(struct cdrom_device_info *cdi, dvd_struct *s)
|
|
layer->end_sector_l0 = base[13] << 16 | base[14] << 8 | base[15];
|
|
layer->end_sector_l0 = base[13] << 16 | base[14] << 8 | base[15];
|
|
layer->bca = base[16] >> 7;
|
|
layer->bca = base[16] >> 7;
|
|
|
|
|
|
- return 0;
|
|
|
|
|
|
+ ret = 0;
|
|
|
|
+err:
|
|
|
|
+ kfree(buf);
|
|
|
|
+ return ret;
|
|
}
|
|
}
|
|
|
|
|
|
static int dvd_read_copyright(struct cdrom_device_info *cdi, dvd_struct *s)
|
|
static int dvd_read_copyright(struct cdrom_device_info *cdi, dvd_struct *s)
|
|
{
|
|
{
|
|
int ret;
|
|
int ret;
|
|
- u_char buf[8];
|
|
|
|
|
|
+ u_char *buf;
|
|
struct packet_command cgc;
|
|
struct packet_command cgc;
|
|
struct cdrom_device_ops *cdo = cdi->ops;
|
|
struct cdrom_device_ops *cdo = cdi->ops;
|
|
|
|
|
|
- init_cdrom_command(&cgc, buf, sizeof(buf), CGC_DATA_READ);
|
|
|
|
|
|
+ buf = kmalloc(8, GFP_KERNEL);
|
|
|
|
+ if (!buf)
|
|
|
|
+ return -ENOMEM;
|
|
|
|
+
|
|
|
|
+ init_cdrom_command(&cgc, buf, 8, CGC_DATA_READ);
|
|
cgc.cmd[0] = GPCMD_READ_DVD_STRUCTURE;
|
|
cgc.cmd[0] = GPCMD_READ_DVD_STRUCTURE;
|
|
cgc.cmd[6] = s->copyright.layer_num;
|
|
cgc.cmd[6] = s->copyright.layer_num;
|
|
cgc.cmd[7] = s->type;
|
|
cgc.cmd[7] = s->type;
|
|
@@ -1783,12 +1854,15 @@ static int dvd_read_copyright(struct cdrom_device_info *cdi, dvd_struct *s)
|
|
cgc.cmd[9] = cgc.buflen & 0xff;
|
|
cgc.cmd[9] = cgc.buflen & 0xff;
|
|
|
|
|
|
if ((ret = cdo->generic_packet(cdi, &cgc)))
|
|
if ((ret = cdo->generic_packet(cdi, &cgc)))
|
|
- return ret;
|
|
|
|
|
|
+ goto err;
|
|
|
|
|
|
s->copyright.cpst = buf[4];
|
|
s->copyright.cpst = buf[4];
|
|
s->copyright.rmi = buf[5];
|
|
s->copyright.rmi = buf[5];
|
|
|
|
|
|
- return 0;
|
|
|
|
|
|
+ ret = 0;
|
|
|
|
+err:
|
|
|
|
+ kfree(buf);
|
|
|
|
+ return ret;
|
|
}
|
|
}
|
|
|
|
|
|
static int dvd_read_disckey(struct cdrom_device_info *cdi, dvd_struct *s)
|
|
static int dvd_read_disckey(struct cdrom_device_info *cdi, dvd_struct *s)
|
|
@@ -1820,26 +1894,33 @@ static int dvd_read_disckey(struct cdrom_device_info *cdi, dvd_struct *s)
|
|
static int dvd_read_bca(struct cdrom_device_info *cdi, dvd_struct *s)
|
|
static int dvd_read_bca(struct cdrom_device_info *cdi, dvd_struct *s)
|
|
{
|
|
{
|
|
int ret;
|
|
int ret;
|
|
- u_char buf[4 + 188];
|
|
|
|
|
|
+ u_char *buf;
|
|
struct packet_command cgc;
|
|
struct packet_command cgc;
|
|
struct cdrom_device_ops *cdo = cdi->ops;
|
|
struct cdrom_device_ops *cdo = cdi->ops;
|
|
|
|
|
|
- init_cdrom_command(&cgc, buf, sizeof(buf), CGC_DATA_READ);
|
|
|
|
|
|
+ buf = kmalloc(4 + 188, GFP_KERNEL);
|
|
|
|
+ if (!buf)
|
|
|
|
+ return -ENOMEM;
|
|
|
|
+
|
|
|
|
+ init_cdrom_command(&cgc, buf, 4 + 188, CGC_DATA_READ);
|
|
cgc.cmd[0] = GPCMD_READ_DVD_STRUCTURE;
|
|
cgc.cmd[0] = GPCMD_READ_DVD_STRUCTURE;
|
|
cgc.cmd[7] = s->type;
|
|
cgc.cmd[7] = s->type;
|
|
cgc.cmd[9] = cgc.buflen & 0xff;
|
|
cgc.cmd[9] = cgc.buflen & 0xff;
|
|
|
|
|
|
if ((ret = cdo->generic_packet(cdi, &cgc)))
|
|
if ((ret = cdo->generic_packet(cdi, &cgc)))
|
|
- return ret;
|
|
|
|
|
|
+ goto err;
|
|
|
|
|
|
s->bca.len = buf[0] << 8 | buf[1];
|
|
s->bca.len = buf[0] << 8 | buf[1];
|
|
if (s->bca.len < 12 || s->bca.len > 188) {
|
|
if (s->bca.len < 12 || s->bca.len > 188) {
|
|
cdinfo(CD_WARNING, "Received invalid BCA length (%d)\n", s->bca.len);
|
|
cdinfo(CD_WARNING, "Received invalid BCA length (%d)\n", s->bca.len);
|
|
- return -EIO;
|
|
|
|
|
|
+ ret = -EIO;
|
|
|
|
+ goto err;
|
|
}
|
|
}
|
|
memcpy(s->bca.value, &buf[4], s->bca.len);
|
|
memcpy(s->bca.value, &buf[4], s->bca.len);
|
|
-
|
|
|
|
- return 0;
|
|
|
|
|
|
+ ret = 0;
|
|
|
|
+err:
|
|
|
|
+ kfree(buf);
|
|
|
|
+ return ret;
|
|
}
|
|
}
|
|
|
|
|
|
static int dvd_read_manufact(struct cdrom_device_info *cdi, dvd_struct *s)
|
|
static int dvd_read_manufact(struct cdrom_device_info *cdi, dvd_struct *s)
|
|
@@ -1939,9 +2020,13 @@ static int cdrom_read_subchannel(struct cdrom_device_info *cdi,
|
|
{
|
|
{
|
|
struct cdrom_device_ops *cdo = cdi->ops;
|
|
struct cdrom_device_ops *cdo = cdi->ops;
|
|
struct packet_command cgc;
|
|
struct packet_command cgc;
|
|
- char buffer[32];
|
|
|
|
|
|
+ char *buffer;
|
|
int ret;
|
|
int ret;
|
|
|
|
|
|
|
|
+ buffer = kmalloc(32, GFP_KERNEL);
|
|
|
|
+ if (!buffer)
|
|
|
|
+ return -ENOMEM;
|
|
|
|
+
|
|
init_cdrom_command(&cgc, buffer, 16, CGC_DATA_READ);
|
|
init_cdrom_command(&cgc, buffer, 16, CGC_DATA_READ);
|
|
cgc.cmd[0] = GPCMD_READ_SUBCHANNEL;
|
|
cgc.cmd[0] = GPCMD_READ_SUBCHANNEL;
|
|
cgc.cmd[1] = 2; /* MSF addressing */
|
|
cgc.cmd[1] = 2; /* MSF addressing */
|
|
@@ -1950,7 +2035,7 @@ static int cdrom_read_subchannel(struct cdrom_device_info *cdi,
|
|
cgc.cmd[8] = 16;
|
|
cgc.cmd[8] = 16;
|
|
|
|
|
|
if ((ret = cdo->generic_packet(cdi, &cgc)))
|
|
if ((ret = cdo->generic_packet(cdi, &cgc)))
|
|
- return ret;
|
|
|
|
|
|
+ goto err;
|
|
|
|
|
|
subchnl->cdsc_audiostatus = cgc.buffer[1];
|
|
subchnl->cdsc_audiostatus = cgc.buffer[1];
|
|
subchnl->cdsc_format = CDROM_MSF;
|
|
subchnl->cdsc_format = CDROM_MSF;
|
|
@@ -1965,7 +2050,10 @@ static int cdrom_read_subchannel(struct cdrom_device_info *cdi,
|
|
subchnl->cdsc_absaddr.msf.second = cgc.buffer[10];
|
|
subchnl->cdsc_absaddr.msf.second = cgc.buffer[10];
|
|
subchnl->cdsc_absaddr.msf.frame = cgc.buffer[11];
|
|
subchnl->cdsc_absaddr.msf.frame = cgc.buffer[11];
|
|
|
|
|
|
- return 0;
|
|
|
|
|
|
+ ret = 0;
|
|
|
|
+err:
|
|
|
|
+ kfree(buffer);
|
|
|
|
+ return ret;
|
|
}
|
|
}
|
|
|
|
|
|
/*
|
|
/*
|