static int sr_read_tochdr(struct cdrom_device_info *cdi, struct cdrom_tochdr *tochdr) { struct scsi_cd *cd = cdi->handle; struct packet_command cgc; int result; unsigned char *buffer; buffer = kmalloc(32, GFP_KERNEL | SR_GFP_DMA(cd)); if (!buffer) return -ENOMEM; memset(&cgc, 0, sizeof(struct packet_command)); cgc.timeout = IOCTL_TIMEOUT; cgc.cmd[0] = GPCMD_READ_TOC_PMA_ATIP; cgc.cmd[8] = 12; /* LSB of length */ cgc.buffer = buffer; cgc.buflen = 12; cgc.quiet = 1; cgc.data_direction = DMA_FROM_DEVICE; result = sr_do_ioctl(cd, &cgc); tochdr->cdth_trk0 = buffer[2]; tochdr->cdth_trk1 = buffer[3]; kfree(buffer); return result; }
int sr_get_mcn(struct cdrom_device_info *cdi, struct cdrom_mcn *mcn) { Scsi_CD *cd = cdi->handle; struct packet_command cgc; char *buffer = kmalloc(32, GFP_KERNEL | SR_GFP_DMA(cd)); int result; if (!buffer) return -ENOMEM; memset(&cgc, 0, sizeof(struct packet_command)); cgc.cmd[0] = GPCMD_READ_SUBCHANNEL; cgc.cmd[2] = 0x40; /* I do want the subchannel info */ cgc.cmd[3] = 0x02; /* Give me medium catalog number info */ cgc.cmd[8] = 24; cgc.buffer = buffer; cgc.buflen = 24; cgc.data_direction = DMA_FROM_DEVICE; cgc.timeout = IOCTL_TIMEOUT; result = sr_do_ioctl(cd, &cgc); memcpy(mcn->medium_catalog_number, buffer + 9, 13); mcn->medium_catalog_number[13] = 0; kfree(buffer); return result; }
static int sr_read_tocentry(struct cdrom_device_info *cdi, struct cdrom_tocentry *tocentry) { struct scsi_cd *cd = cdi->handle; struct packet_command cgc; int result; unsigned char *buffer; buffer = kmalloc(32, GFP_KERNEL | SR_GFP_DMA(cd)); if (!buffer) return -ENOMEM; memset(&cgc, 0, sizeof(struct packet_command)); cgc.timeout = IOCTL_TIMEOUT; cgc.cmd[0] = GPCMD_READ_TOC_PMA_ATIP; cgc.cmd[1] |= (tocentry->cdte_format == CDROM_MSF) ? 0x02 : 0; cgc.cmd[6] = tocentry->cdte_track; cgc.cmd[8] = 12; /* LSB of length */ cgc.buffer = buffer; cgc.buflen = 12; cgc.data_direction = DMA_FROM_DEVICE; result = sr_do_ioctl(cd, &cgc); tocentry->cdte_ctrl = buffer[5] & 0xf; tocentry->cdte_adr = buffer[5] >> 4; tocentry->cdte_datamode = (tocentry->cdte_ctrl & 0x04) ? 1 : 0; if (tocentry->cdte_format == CDROM_MSF) { tocentry->cdte_addr.msf.minute = buffer[9]; tocentry->cdte_addr.msf.second = buffer[10]; tocentry->cdte_addr.msf.frame = buffer[11]; } else tocentry->cdte_addr.lba = (((((buffer[8] << 8) + buffer[9]) << 8) + buffer[10]) << 8) + buffer[11]; kfree(buffer); return result; }
int sr_is_xa(Scsi_CD *cd) { unsigned char *raw_sector; int is_xa; if (!xa_test) return 0; raw_sector = kmalloc(2048, GFP_KERNEL | SR_GFP_DMA(cd)); if (!raw_sector) return -ENOMEM; if (0 == sr_read_sector(cd, cd->ms_offset + 16, CD_FRAMESIZE_RAW1, raw_sector)) { is_xa = (raw_sector[3] == 0x02) ? 1 : 0; } else { /* read a raw sector failed for some reason. */ is_xa = -1; } kfree(raw_sector); #ifdef DEBUG sr_printk(KERN_INFO, cd, "sr_is_xa: %d\n", is_xa); #endif return is_xa; }
int sr_audio_ioctl(struct cdrom_device_info *cdi, unsigned int cmd, void *arg) { Scsi_CD *cd = cdi->handle; struct packet_command cgc; int result; unsigned char *buffer = kmalloc(32, GFP_KERNEL | SR_GFP_DMA(cd)); if (!buffer) return -ENOMEM; memset(&cgc, 0, sizeof(struct packet_command)); cgc.timeout = IOCTL_TIMEOUT; switch (cmd) { case CDROMREADTOCHDR: { struct cdrom_tochdr *tochdr = (struct cdrom_tochdr *) arg; cgc.cmd[0] = GPCMD_READ_TOC_PMA_ATIP; cgc.cmd[8] = 12; /* LSB of length */ cgc.buffer = buffer; cgc.buflen = 12; cgc.quiet = 1; cgc.data_direction = DMA_FROM_DEVICE; result = sr_do_ioctl(cd, &cgc); tochdr->cdth_trk0 = buffer[2]; tochdr->cdth_trk1 = buffer[3]; break; } case CDROMREADTOCENTRY: { struct cdrom_tocentry *tocentry = (struct cdrom_tocentry *) arg; cgc.cmd[0] = GPCMD_READ_TOC_PMA_ATIP; cgc.cmd[1] |= (tocentry->cdte_format == CDROM_MSF) ? 0x02 : 0; cgc.cmd[6] = tocentry->cdte_track; cgc.cmd[8] = 12; /* LSB of length */ cgc.buffer = buffer; cgc.buflen = 12; cgc.data_direction = DMA_FROM_DEVICE; result = sr_do_ioctl(cd, &cgc); tocentry->cdte_ctrl = buffer[5] & 0xf; tocentry->cdte_adr = buffer[5] >> 4; tocentry->cdte_datamode = (tocentry->cdte_ctrl & 0x04) ? 1 : 0; if (tocentry->cdte_format == CDROM_MSF) { tocentry->cdte_addr.msf.minute = buffer[9]; tocentry->cdte_addr.msf.second = buffer[10]; tocentry->cdte_addr.msf.frame = buffer[11]; } else tocentry->cdte_addr.lba = (((((buffer[8] << 8) + buffer[9]) << 8) + buffer[10]) << 8) + buffer[11]; break; } case CDROMPLAYTRKIND: { struct cdrom_ti* ti = (struct cdrom_ti*)arg; cgc.cmd[0] = GPCMD_PLAYAUDIO_TI; cgc.cmd[4] = ti->cdti_trk0; cgc.cmd[5] = ti->cdti_ind0; cgc.cmd[7] = ti->cdti_trk1; cgc.cmd[8] = ti->cdti_ind1; cgc.data_direction = DMA_NONE; result = sr_do_ioctl(cd, &cgc); if (result == -EDRIVE_CANT_DO_THIS) result = sr_fake_playtrkind(cdi, ti); break; } default: result = -EINVAL; } #if 0 if (result) printk("DEBUG: sr_audio: result for ioctl %x: %x\n", cmd, result); #endif kfree(buffer); return result; }