If cdrom commands are issued to a scsi drive in most cases the buffer will be
filled via dma. This leads to bad stack corruption on non coherent platforms,
because the buffers are neither cache line aligned nor is the size a multiple
of the cache line size. Using kmalloced buffers avoids this.
Signed-off-by: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
Signed-off-by: Jens Axboe <jens.axboe@oracle.com>
struct media_event_desc *med)
{
struct packet_command cgc;
struct media_event_desc *med)
{
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[1] = 1; /* IMMED */
cgc.cmd[4] = 1 << 4; /* media event */
cgc.cmd[0] = GPCMD_GET_EVENT_STATUS_NOTIFICATION;
cgc.cmd[1] = 1; /* IMMED */
cgc.cmd[4] = 1 << 4; /* media event */
- cgc.cmd[8] = sizeof(buffer);
cgc.quiet = 1;
if (cdi->ops->generic_packet(cdi, &cgc))
cgc.quiet = 1;
if (cdi->ops->generic_packet(cdi, &cgc))
if (be16_to_cpu(eh->data_len) < sizeof(*med))
if (be16_to_cpu(eh->data_len) < sizeof(*med))
if (eh->nea || eh->notification_class != 0x4)
if (eh->nea || eh->notification_class != 0x4)
- memcpy(med, &buffer[sizeof(*eh)], sizeof(*med));
- return 0;
+ memcpy(med, buffer + sizeof(*eh), sizeof(*med));
+ ret = 0;
+err:
+ kfree(buffer);
+ return ret;
static int cdrom_mrw_probe_pc(struct cdrom_device_info *cdi)
{
struct packet_command cgc;
static int cdrom_mrw_probe_pc(struct cdrom_device_info *cdi)
{
struct packet_command cgc;
+ 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.quiet = 1;
if (!cdrom_mode_sense(cdi, &cgc, MRW_MODE_PC, 0)) {
cdi->mrw_mode_page = MRW_MODE_PC;
cgc.timeout = HZ;
cgc.quiet = 1;
if (!cdrom_mode_sense(cdi, &cgc, MRW_MODE_PC, 0)) {
cdi->mrw_mode_page = MRW_MODE_PC;
} else if (!cdrom_mode_sense(cdi, &cgc, MRW_MODE_PC_PRE1, 0)) {
cdi->mrw_mode_page = MRW_MODE_PC_PRE1;
} else if (!cdrom_mode_sense(cdi, &cgc, MRW_MODE_PC_PRE1, 0)) {
cdi->mrw_mode_page = MRW_MODE_PC_PRE1;
+ kfree(buffer);
+ return ret;
}
static int cdrom_is_mrw(struct cdrom_device_info *cdi, int *write)
{
struct packet_command cgc;
struct mrw_feature_desc *mfd;
}
static int cdrom_is_mrw(struct cdrom_device_info *cdi, int *write)
{
struct packet_command cgc;
struct mrw_feature_desc *mfd;
- unsigned char buffer[16];
+ 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[3] = CDF_MRW;
cgc.cmd[0] = GPCMD_GET_CONFIGURATION;
cgc.cmd[3] = CDF_MRW;
- cgc.cmd[8] = sizeof(buffer);
cgc.quiet = 1;
if ((ret = cdi->ops->generic_packet(cdi, &cgc)))
cgc.quiet = 1;
if ((ret = cdi->ops->generic_packet(cdi, &cgc)))
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;
if ((ret = cdrom_mrw_probe_pc(cdi))) {
*write = 0;
*write = mfd->write;
if ((ret = cdrom_mrw_probe_pc(cdi))) {
*write = 0;
+err:
+ kfree(buffer);
+ return ret;
}
static int cdrom_mrw_bgformat(struct cdrom_device_info *cdi, int cont)
{
struct packet_command cgc;
}
static int cdrom_mrw_bgformat(struct cdrom_device_info *cdi, int cont)
{
struct packet_command cgc;
- unsigned char buffer[12];
int ret;
printk(KERN_INFO "cdrom: %sstarting format\n", cont ? "Re" : "");
int ret;
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[1] = (1 << 4) | 1;
cgc.cmd[0] = GPCMD_FORMAT_UNIT;
cgc.cmd[1] = (1 << 4) | 1;
if (ret)
printk(KERN_INFO "cdrom: bgformat failed\n");
if (ret)
printk(KERN_INFO "cdrom: bgformat failed\n");
{
struct packet_command cgc;
struct mode_page_header *mph;
{
struct packet_command cgc;
struct mode_page_header *mph;
- 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)))
mph = (struct mode_page_header *) buffer;
offset = be16_to_cpu(mph->desc_length);
mph = (struct mode_page_header *) buffer;
offset = be16_to_cpu(mph->desc_length);
cgc.buflen = size;
if ((ret = cdrom_mode_select(cdi, &cgc)))
cgc.buflen = size;
if ((ret = cdrom_mode_select(cdi, &cgc)))
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]);
+ ret = 0;
+err:
+ kfree(buffer);
+ return ret;
}
static int cdrom_get_random_writable(struct cdrom_device_info *cdi,
struct rwrt_feature_desc *rfd)
{
struct packet_command cgc;
}
static int cdrom_get_random_writable(struct cdrom_device_info *cdi,
struct rwrt_feature_desc *rfd)
{
struct packet_command cgc;
- 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[3] = CDF_RWRT; /* often 0x0020 */
cgc.cmd[0] = GPCMD_GET_CONFIGURATION; /* often 0x46 */
cgc.cmd[3] = CDF_RWRT; /* often 0x0020 */
- cgc.cmd[8] = sizeof(buffer); /* often 0x18 */
+ cgc.cmd[8] = 24; /* often 0x18 */
cgc.quiet = 1;
if ((ret = cdi->ops->generic_packet(cdi, &cgc)))
cgc.quiet = 1;
if ((ret = cdi->ops->generic_packet(cdi, &cgc)))
memcpy(rfd, &buffer[sizeof(struct feature_header)], sizeof (*rfd));
memcpy(rfd, &buffer[sizeof(struct feature_header)], sizeof (*rfd));
+ ret = 0;
+err:
+ kfree(buffer);
+ return ret;
}
static int cdrom_has_defect_mgt(struct cdrom_device_info *cdi)
{
struct packet_command cgc;
}
static int cdrom_has_defect_mgt(struct cdrom_device_info *cdi)
{
struct packet_command cgc;
__be16 *feature_code;
int ret;
__be16 *feature_code;
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[3] = CDF_HWDM;
cgc.cmd[0] = GPCMD_GET_CONFIGURATION;
cgc.cmd[3] = CDF_HWDM;
- cgc.cmd[8] = sizeof(buffer);
cgc.quiet = 1;
if ((ret = cdi->ops->generic_packet(cdi, &cgc)))
cgc.quiet = 1;
if ((ret = cdi->ops->generic_packet(cdi, &cgc)))
feature_code = (__be16 *) &buffer[sizeof(struct feature_header)];
if (be16_to_cpu(*feature_code) == CDF_HWDM)
feature_code = (__be16 *) &buffer[sizeof(struct feature_header)];
if (be16_to_cpu(*feature_code) == CDF_HWDM)
- return 0;
-
- return 1;
+ ret = 0;
+err:
+ kfree(buffer);
+ return ret;
static int mo_open_write(struct cdrom_device_info *cdi)
{
struct packet_command cgc;
static int mo_open_write(struct cdrom_device_info *cdi)
{
struct packet_command cgc;
- 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);
}
/* drive gave us no info, let the user go ahead */
}
/* drive gave us no info, let the user go ahead */
+ 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)
static void cdrom_mmc3_profile(struct cdrom_device_info *cdi)
{
struct packet_command cgc;
static void cdrom_mmc3_profile(struct cdrom_device_info *cdi)
{
struct packet_command cgc;
- 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[1] = 0;
cgc.cmd[2] = cgc.cmd[3] = 0; /* Starting Feature Number */
cgc.cmd[0] = GPCMD_GET_CONFIGURATION;
cgc.cmd[1] = 0;
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;
if ((ret = cdi->ops->generic_packet(cdi, &cgc)))
cgc.quiet = 1;
if ((ret = cdi->ops->generic_packet(cdi, &cgc)))
mmc3_profile = (buffer[6] << 8) | buffer[7];
cdi->mmc3_profile = mmc3_profile;
mmc3_profile = (buffer[6] << 8) | buffer[7];
cdi->mmc3_profile = mmc3_profile;
}
static int cdrom_is_dvd_rw(struct cdrom_device_info *cdi)
}
static int cdrom_is_dvd_rw(struct cdrom_device_info *cdi)
static int dvd_do_auth(struct cdrom_device_info *cdi, dvd_authinfo *ai)
{
int ret;
static int dvd_do_auth(struct cdrom_device_info *cdi, dvd_authinfo *ai)
{
int ret;
struct packet_command cgc;
struct cdrom_device_ops *cdo = cdi->ops;
struct packet_command cgc;
struct cdrom_device_ops *cdo = cdi->ops;
+ 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);
switch (ai->type) {
init_cdrom_command(&cgc, buf, 0, CGC_DATA_READ);
switch (ai->type) {
setup_report_key(&cgc, ai->lsa.agid, 0);
if ((ret = cdo->generic_packet(cdi, &cgc)))
setup_report_key(&cgc, ai->lsa.agid, 0);
if ((ret = cdo->generic_packet(cdi, &cgc)))
ai->lsa.agid = buf[7] >> 6;
/* Returning data, let host change state */
ai->lsa.agid = buf[7] >> 6;
/* Returning data, let host change state */
setup_report_key(&cgc, ai->lsk.agid, 2);
if ((ret = cdo->generic_packet(cdi, &cgc)))
setup_report_key(&cgc, ai->lsk.agid, 2);
if ((ret = cdo->generic_packet(cdi, &cgc)))
copy_key(ai->lsk.key, &buf[4]);
/* Returning data, let host change state */
copy_key(ai->lsk.key, &buf[4]);
/* Returning data, let host change state */
setup_report_key(&cgc, ai->lsc.agid, 1);
if ((ret = cdo->generic_packet(cdi, &cgc)))
setup_report_key(&cgc, ai->lsc.agid, 1);
if ((ret = cdo->generic_packet(cdi, &cgc)))
copy_chal(ai->lsc.chal, &buf[4]);
/* Returning data, let host change state */
copy_chal(ai->lsc.chal, &buf[4]);
/* Returning data, let host change state */
cgc.cmd[2] = ai->lstk.lba >> 24;
if ((ret = cdo->generic_packet(cdi, &cgc)))
cgc.cmd[2] = ai->lstk.lba >> 24;
if ((ret = cdo->generic_packet(cdi, &cgc)))
ai->lstk.cpm = (buf[4] >> 7) & 1;
ai->lstk.cp_sec = (buf[4] >> 6) & 1;
ai->lstk.cpm = (buf[4] >> 7) & 1;
ai->lstk.cp_sec = (buf[4] >> 6) & 1;
setup_report_key(&cgc, ai->lsasf.agid, 5);
if ((ret = cdo->generic_packet(cdi, &cgc)))
setup_report_key(&cgc, ai->lsasf.agid, 5);
if ((ret = cdo->generic_packet(cdi, &cgc)))
ai->lsasf.asf = buf[7] & 1;
break;
ai->lsasf.asf = buf[7] & 1;
break;
copy_chal(&buf[4], ai->hsc.chal);
if ((ret = cdo->generic_packet(cdi, &cgc)))
copy_chal(&buf[4], ai->hsc.chal);
if ((ret = cdo->generic_packet(cdi, &cgc)))
ai->type = DVD_LU_SEND_KEY1;
break;
ai->type = DVD_LU_SEND_KEY1;
break;
if ((ret = cdo->generic_packet(cdi, &cgc))) {
ai->type = DVD_AUTH_FAILURE;
if ((ret = cdo->generic_packet(cdi, &cgc))) {
ai->type = DVD_AUTH_FAILURE;
}
ai->type = DVD_AUTH_ESTABLISHED;
break;
}
ai->type = DVD_AUTH_ESTABLISHED;
break;
cdinfo(CD_DVD, "entering DVD_INVALIDATE_AGID\n");
setup_report_key(&cgc, ai->lsa.agid, 0x3f);
if ((ret = cdo->generic_packet(cdi, &cgc)))
cdinfo(CD_DVD, "entering DVD_INVALIDATE_AGID\n");
setup_report_key(&cgc, ai->lsa.agid, 0x3f);
if ((ret = cdo->generic_packet(cdi, &cgc)))
break;
/* Get region settings */
case DVD_LU_SEND_RPC_STATE:
cdinfo(CD_DVD, "entering DVD_LU_SEND_RPC_STATE\n");
setup_report_key(&cgc, 0, 8);
break;
/* Get region settings */
case DVD_LU_SEND_RPC_STATE:
cdinfo(CD_DVD, "entering DVD_LU_SEND_RPC_STATE\n");
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)))
- 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;
/* Set region settings */
break;
/* Set region settings */
buf[4] = ai->hrpcs.pdrc;
if ((ret = cdo->generic_packet(cdi, &cgc)))
buf[4] = ai->hrpcs.pdrc;
if ((ret = cdo->generic_packet(cdi, &cgc)))
break;
default:
cdinfo(CD_WARNING, "Invalid DVD key ioctl (%d)\n", ai->type);
break;
default:
cdinfo(CD_WARNING, "Invalid DVD key ioctl (%d)\n", ai->type);
+ ret = -ENOTTY;
+ goto err;
+ 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 packet_command cgc;
struct cdrom_device_ops *cdo = cdi->ops;
struct dvd_layer *layer;
struct packet_command cgc;
struct cdrom_device_ops *cdo = cdi->ops;
if (layer_num >= DVD_LAYERS)
return -EINVAL;
if (layer_num >= DVD_LAYERS)
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[6] = layer_num;
cgc.cmd[7] = s->type;
cgc.cmd[0] = GPCMD_READ_DVD_STRUCTURE;
cgc.cmd[6] = layer_num;
cgc.cmd[7] = s->type;
cgc.quiet = 1;
if ((ret = cdo->generic_packet(cdi, &cgc)))
cgc.quiet = 1;
if ((ret = cdo->generic_packet(cdi, &cgc)))
base = &buf[4];
layer = &s->physical.layer[layer_num];
base = &buf[4];
layer = &s->physical.layer[layer_num];
layer->end_sector_l0 = base[13] << 16 | base[14] << 8 | base[15];
layer->bca = base[16] >> 7;
layer->end_sector_l0 = base[13] << 16 | base[14] << 8 | base[15];
layer->bca = base[16] >> 7;
+ ret = 0;
+err:
+ kfree(buf);
+ return ret;
}
static int dvd_read_copyright(struct cdrom_device_info *cdi, dvd_struct *s)
{
int ret;
}
static int dvd_read_copyright(struct cdrom_device_info *cdi, dvd_struct *s)
{
int ret;
struct packet_command cgc;
struct cdrom_device_ops *cdo = cdi->ops;
struct packet_command cgc;
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[6] = s->copyright.layer_num;
cgc.cmd[7] = s->type;
cgc.cmd[0] = GPCMD_READ_DVD_STRUCTURE;
cgc.cmd[6] = s->copyright.layer_num;
cgc.cmd[7] = s->type;
cgc.cmd[9] = cgc.buflen & 0xff;
if ((ret = cdo->generic_packet(cdi, &cgc)))
cgc.cmd[9] = cgc.buflen & 0xff;
if ((ret = cdo->generic_packet(cdi, &cgc)))
s->copyright.cpst = buf[4];
s->copyright.rmi = buf[5];
s->copyright.cpst = buf[4];
s->copyright.rmi = buf[5];
+ 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)
static int dvd_read_bca(struct cdrom_device_info *cdi, dvd_struct *s)
{
int ret;
static int dvd_read_bca(struct cdrom_device_info *cdi, dvd_struct *s)
{
int ret;
struct packet_command cgc;
struct cdrom_device_ops *cdo = cdi->ops;
struct packet_command cgc;
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[7] = s->type;
cgc.cmd[9] = cgc.buflen & 0xff;
if ((ret = cdo->generic_packet(cdi, &cgc)))
cgc.cmd[0] = GPCMD_READ_DVD_STRUCTURE;
cgc.cmd[7] = s->type;
cgc.cmd[9] = cgc.buflen & 0xff;
if ((ret = cdo->generic_packet(cdi, &cgc)))
s->bca.len = buf[0] << 8 | buf[1];
if (s->bca.len < 12 || s->bca.len > 188) {
cdinfo(CD_WARNING, "Received invalid BCA length (%d)\n", s->bca.len);
s->bca.len = buf[0] << 8 | buf[1];
if (s->bca.len < 12 || s->bca.len > 188) {
cdinfo(CD_WARNING, "Received invalid BCA length (%d)\n", s->bca.len);
+ ret = -EIO;
+ goto err;
}
memcpy(s->bca.value, &buf[4], s->bca.len);
}
memcpy(s->bca.value, &buf[4], s->bca.len);
+ 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)
{
struct cdrom_device_ops *cdo = cdi->ops;
struct packet_command cgc;
{
struct cdrom_device_ops *cdo = cdi->ops;
struct packet_command cgc;
+ buffer = kmalloc(32, GFP_KERNEL);
+ if (!buffer)
+ return -ENOMEM;
+
init_cdrom_command(&cgc, buffer, 16, CGC_DATA_READ);
cgc.cmd[0] = GPCMD_READ_SUBCHANNEL;
cgc.cmd[1] = 2; /* MSF addressing */
init_cdrom_command(&cgc, buffer, 16, CGC_DATA_READ);
cgc.cmd[0] = GPCMD_READ_SUBCHANNEL;
cgc.cmd[1] = 2; /* MSF addressing */
cgc.cmd[8] = 16;
if ((ret = cdo->generic_packet(cdi, &cgc)))
cgc.cmd[8] = 16;
if ((ret = cdo->generic_packet(cdi, &cgc)))
subchnl->cdsc_audiostatus = cgc.buffer[1];
subchnl->cdsc_format = CDROM_MSF;
subchnl->cdsc_audiostatus = cgc.buffer[1];
subchnl->cdsc_format = CDROM_MSF;
subchnl->cdsc_absaddr.msf.second = cgc.buffer[10];
subchnl->cdsc_absaddr.msf.frame = cgc.buffer[11];
subchnl->cdsc_absaddr.msf.second = cgc.buffer[10];
subchnl->cdsc_absaddr.msf.frame = cgc.buffer[11];
+ ret = 0;
+err:
+ kfree(buffer);
+ return ret;