cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

sr_ioctl.c (15019B)


      1// SPDX-License-Identifier: GPL-2.0
      2#include <linux/kernel.h>
      3#include <linux/mm.h>
      4#include <linux/fs.h>
      5#include <linux/errno.h>
      6#include <linux/string.h>
      7#include <linux/blkdev.h>
      8#include <linux/module.h>
      9#include <linux/blkpg.h>
     10#include <linux/cdrom.h>
     11#include <linux/delay.h>
     12#include <linux/slab.h>
     13#include <asm/io.h>
     14#include <linux/uaccess.h>
     15
     16#include <scsi/scsi.h>
     17#include <scsi/scsi_dbg.h>
     18#include <scsi/scsi_device.h>
     19#include <scsi/scsi_eh.h>
     20#include <scsi/scsi_host.h>
     21#include <scsi/scsi_ioctl.h>
     22#include <scsi/scsi_cmnd.h>
     23
     24#include "sr.h"
     25
     26#if 0
     27#define DEBUG
     28#endif
     29
     30/* The sr_is_xa() seems to trigger firmware bugs with some drives :-(
     31 * It is off by default and can be turned on with this module parameter */
     32static int xa_test = 0;
     33
     34module_param(xa_test, int, S_IRUGO | S_IWUSR);
     35
     36static int sr_read_tochdr(struct cdrom_device_info *cdi,
     37		struct cdrom_tochdr *tochdr)
     38{
     39	struct scsi_cd *cd = cdi->handle;
     40	struct packet_command cgc;
     41	int result;
     42	unsigned char *buffer;
     43
     44	buffer = kzalloc(32, GFP_KERNEL);
     45	if (!buffer)
     46		return -ENOMEM;
     47
     48	memset(&cgc, 0, sizeof(struct packet_command));
     49	cgc.timeout = IOCTL_TIMEOUT;
     50	cgc.cmd[0] = GPCMD_READ_TOC_PMA_ATIP;
     51	cgc.cmd[8] = 12;		/* LSB of length */
     52	cgc.buffer = buffer;
     53	cgc.buflen = 12;
     54	cgc.quiet = 1;
     55	cgc.data_direction = DMA_FROM_DEVICE;
     56
     57	result = sr_do_ioctl(cd, &cgc);
     58	if (result)
     59		goto err;
     60
     61	tochdr->cdth_trk0 = buffer[2];
     62	tochdr->cdth_trk1 = buffer[3];
     63
     64err:
     65	kfree(buffer);
     66	return result;
     67}
     68
     69static int sr_read_tocentry(struct cdrom_device_info *cdi,
     70		struct cdrom_tocentry *tocentry)
     71{
     72	struct scsi_cd *cd = cdi->handle;
     73	struct packet_command cgc;
     74	int result;
     75	unsigned char *buffer;
     76
     77	buffer = kzalloc(32, GFP_KERNEL);
     78	if (!buffer)
     79		return -ENOMEM;
     80
     81	memset(&cgc, 0, sizeof(struct packet_command));
     82	cgc.timeout = IOCTL_TIMEOUT;
     83	cgc.cmd[0] = GPCMD_READ_TOC_PMA_ATIP;
     84	cgc.cmd[1] |= (tocentry->cdte_format == CDROM_MSF) ? 0x02 : 0;
     85	cgc.cmd[6] = tocentry->cdte_track;
     86	cgc.cmd[8] = 12;		/* LSB of length */
     87	cgc.buffer = buffer;
     88	cgc.buflen = 12;
     89	cgc.data_direction = DMA_FROM_DEVICE;
     90
     91	result = sr_do_ioctl(cd, &cgc);
     92	if (result)
     93		goto err;
     94
     95	tocentry->cdte_ctrl = buffer[5] & 0xf;
     96	tocentry->cdte_adr = buffer[5] >> 4;
     97	tocentry->cdte_datamode = (tocentry->cdte_ctrl & 0x04) ? 1 : 0;
     98	if (tocentry->cdte_format == CDROM_MSF) {
     99		tocentry->cdte_addr.msf.minute = buffer[9];
    100		tocentry->cdte_addr.msf.second = buffer[10];
    101		tocentry->cdte_addr.msf.frame = buffer[11];
    102	} else
    103		tocentry->cdte_addr.lba = (((((buffer[8] << 8) + buffer[9]) << 8)
    104			+ buffer[10]) << 8) + buffer[11];
    105
    106err:
    107	kfree(buffer);
    108	return result;
    109}
    110
    111#define IOCTL_RETRIES 3
    112
    113/* ATAPI drives don't have a SCMD_PLAYAUDIO_TI command.  When these drives
    114   are emulating a SCSI device via the idescsi module, they need to have
    115   CDROMPLAYTRKIND commands translated into CDROMPLAYMSF commands for them */
    116
    117static int sr_fake_playtrkind(struct cdrom_device_info *cdi, struct cdrom_ti *ti)
    118{
    119	struct cdrom_tocentry trk0_te, trk1_te;
    120	struct cdrom_tochdr tochdr;
    121	struct packet_command cgc;
    122	int ntracks, ret;
    123
    124	ret = sr_read_tochdr(cdi, &tochdr);
    125	if (ret)
    126		return ret;
    127
    128	ntracks = tochdr.cdth_trk1 - tochdr.cdth_trk0 + 1;
    129	
    130	if (ti->cdti_trk1 == ntracks) 
    131		ti->cdti_trk1 = CDROM_LEADOUT;
    132	else if (ti->cdti_trk1 != CDROM_LEADOUT)
    133		ti->cdti_trk1 ++;
    134
    135	trk0_te.cdte_track = ti->cdti_trk0;
    136	trk0_te.cdte_format = CDROM_MSF;
    137	trk1_te.cdte_track = ti->cdti_trk1;
    138	trk1_te.cdte_format = CDROM_MSF;
    139	
    140	ret = sr_read_tocentry(cdi, &trk0_te);
    141	if (ret)
    142		return ret;
    143	ret = sr_read_tocentry(cdi, &trk1_te);
    144	if (ret)
    145		return ret;
    146
    147	memset(&cgc, 0, sizeof(struct packet_command));
    148	cgc.cmd[0] = GPCMD_PLAY_AUDIO_MSF;
    149	cgc.cmd[3] = trk0_te.cdte_addr.msf.minute;
    150	cgc.cmd[4] = trk0_te.cdte_addr.msf.second;
    151	cgc.cmd[5] = trk0_te.cdte_addr.msf.frame;
    152	cgc.cmd[6] = trk1_te.cdte_addr.msf.minute;
    153	cgc.cmd[7] = trk1_te.cdte_addr.msf.second;
    154	cgc.cmd[8] = trk1_te.cdte_addr.msf.frame;
    155	cgc.data_direction = DMA_NONE;
    156	cgc.timeout = IOCTL_TIMEOUT;
    157	return sr_do_ioctl(cdi->handle, &cgc);
    158}
    159
    160static int sr_play_trkind(struct cdrom_device_info *cdi,
    161		struct cdrom_ti *ti)
    162
    163{
    164	struct scsi_cd *cd = cdi->handle;
    165	struct packet_command cgc;
    166	int result;
    167
    168	memset(&cgc, 0, sizeof(struct packet_command));
    169	cgc.timeout = IOCTL_TIMEOUT;
    170	cgc.cmd[0] = GPCMD_PLAYAUDIO_TI;
    171	cgc.cmd[4] = ti->cdti_trk0;
    172	cgc.cmd[5] = ti->cdti_ind0;
    173	cgc.cmd[7] = ti->cdti_trk1;
    174	cgc.cmd[8] = ti->cdti_ind1;
    175	cgc.data_direction = DMA_NONE;
    176
    177	result = sr_do_ioctl(cd, &cgc);
    178	if (result == -EDRIVE_CANT_DO_THIS)
    179		result = sr_fake_playtrkind(cdi, ti);
    180
    181	return result;
    182}
    183
    184/* We do our own retries because we want to know what the specific
    185   error code is.  Normally the UNIT_ATTENTION code will automatically
    186   clear after one error */
    187
    188int sr_do_ioctl(Scsi_CD *cd, struct packet_command *cgc)
    189{
    190	struct scsi_device *SDev;
    191	struct scsi_sense_hdr local_sshdr, *sshdr = &local_sshdr;
    192	int result, err = 0, retries = 0;
    193
    194	SDev = cd->device;
    195
    196	if (cgc->sshdr)
    197		sshdr = cgc->sshdr;
    198
    199      retry:
    200	if (!scsi_block_when_processing_errors(SDev)) {
    201		err = -ENODEV;
    202		goto out;
    203	}
    204
    205	result = scsi_execute(SDev, cgc->cmd, cgc->data_direction,
    206			      cgc->buffer, cgc->buflen, NULL, sshdr,
    207			      cgc->timeout, IOCTL_RETRIES, 0, 0, NULL);
    208
    209	/* Minimal error checking.  Ignore cases we know about, and report the rest. */
    210	if (result < 0) {
    211		err = result;
    212		goto out;
    213	}
    214	if (scsi_status_is_check_condition(result)) {
    215		switch (sshdr->sense_key) {
    216		case UNIT_ATTENTION:
    217			SDev->changed = 1;
    218			if (!cgc->quiet)
    219				sr_printk(KERN_INFO, cd,
    220					  "disc change detected.\n");
    221			if (retries++ < 10)
    222				goto retry;
    223			err = -ENOMEDIUM;
    224			break;
    225		case NOT_READY:	/* This happens if there is no disc in drive */
    226			if (sshdr->asc == 0x04 &&
    227			    sshdr->ascq == 0x01) {
    228				/* sense: Logical unit is in process of becoming ready */
    229				if (!cgc->quiet)
    230					sr_printk(KERN_INFO, cd,
    231						  "CDROM not ready yet.\n");
    232				if (retries++ < 10) {
    233					/* sleep 2 sec and try again */
    234					ssleep(2);
    235					goto retry;
    236				} else {
    237					/* 20 secs are enough? */
    238					err = -ENOMEDIUM;
    239					break;
    240				}
    241			}
    242			if (!cgc->quiet)
    243				sr_printk(KERN_INFO, cd,
    244					  "CDROM not ready.  Make sure there "
    245					  "is a disc in the drive.\n");
    246			err = -ENOMEDIUM;
    247			break;
    248		case ILLEGAL_REQUEST:
    249			err = -EIO;
    250			if (sshdr->asc == 0x20 &&
    251			    sshdr->ascq == 0x00)
    252				/* sense: Invalid command operation code */
    253				err = -EDRIVE_CANT_DO_THIS;
    254			break;
    255		default:
    256			err = -EIO;
    257		}
    258	}
    259
    260	/* Wake up a process waiting for device */
    261      out:
    262	cgc->stat = err;
    263	return err;
    264}
    265
    266/* ---------------------------------------------------------------------- */
    267/* interface to cdrom.c                                                   */
    268
    269int sr_tray_move(struct cdrom_device_info *cdi, int pos)
    270{
    271	Scsi_CD *cd = cdi->handle;
    272	struct packet_command cgc;
    273
    274	memset(&cgc, 0, sizeof(struct packet_command));
    275	cgc.cmd[0] = GPCMD_START_STOP_UNIT;
    276	cgc.cmd[4] = (pos == 0) ? 0x03 /* close */ : 0x02 /* eject */ ;
    277	cgc.data_direction = DMA_NONE;
    278	cgc.timeout = IOCTL_TIMEOUT;
    279	return sr_do_ioctl(cd, &cgc);
    280}
    281
    282int sr_lock_door(struct cdrom_device_info *cdi, int lock)
    283{
    284	Scsi_CD *cd = cdi->handle;
    285
    286	return scsi_set_medium_removal(cd->device, lock ?
    287		       SCSI_REMOVAL_PREVENT : SCSI_REMOVAL_ALLOW);
    288}
    289
    290int sr_drive_status(struct cdrom_device_info *cdi, int slot)
    291{
    292	struct scsi_cd *cd = cdi->handle;
    293	struct scsi_sense_hdr sshdr;
    294	struct media_event_desc med;
    295
    296	if (CDSL_CURRENT != slot) {
    297		/* we have no changer support */
    298		return -EINVAL;
    299	}
    300	if (!scsi_test_unit_ready(cd->device, SR_TIMEOUT, MAX_RETRIES, &sshdr))
    301		return CDS_DISC_OK;
    302
    303	/* SK/ASC/ASCQ of 2/4/1 means "unit is becoming ready" */
    304	if (scsi_sense_valid(&sshdr) && sshdr.sense_key == NOT_READY
    305			&& sshdr.asc == 0x04 && sshdr.ascq == 0x01)
    306		return CDS_DRIVE_NOT_READY;
    307
    308	if (!cdrom_get_media_event(cdi, &med)) {
    309		if (med.media_present)
    310			return CDS_DISC_OK;
    311		else if (med.door_open)
    312			return CDS_TRAY_OPEN;
    313		else
    314			return CDS_NO_DISC;
    315	}
    316
    317	/*
    318	 * SK/ASC/ASCQ of 2/4/2 means "initialization required"
    319	 * Using CD_TRAY_OPEN results in an START_STOP_UNIT to close
    320	 * the tray, which resolves the initialization requirement.
    321	 */
    322	if (scsi_sense_valid(&sshdr) && sshdr.sense_key == NOT_READY
    323			&& sshdr.asc == 0x04 && sshdr.ascq == 0x02)
    324		return CDS_TRAY_OPEN;
    325
    326	/*
    327	 * 0x04 is format in progress .. but there must be a disc present!
    328	 */
    329	if (sshdr.sense_key == NOT_READY && sshdr.asc == 0x04)
    330		return CDS_DISC_OK;
    331
    332	/*
    333	 * If not using Mt Fuji extended media tray reports,
    334	 * just return TRAY_OPEN since ATAPI doesn't provide
    335	 * any other way to detect this...
    336	 */
    337	if (scsi_sense_valid(&sshdr) &&
    338	    /* 0x3a is medium not present */
    339	    sshdr.asc == 0x3a)
    340		return CDS_NO_DISC;
    341	else
    342		return CDS_TRAY_OPEN;
    343
    344	return CDS_DRIVE_NOT_READY;
    345}
    346
    347int sr_disk_status(struct cdrom_device_info *cdi)
    348{
    349	Scsi_CD *cd = cdi->handle;
    350	struct cdrom_tochdr toc_h;
    351	struct cdrom_tocentry toc_e;
    352	int i, rc, have_datatracks = 0;
    353
    354	/* look for data tracks */
    355	rc = sr_read_tochdr(cdi, &toc_h);
    356	if (rc)
    357		return (rc == -ENOMEDIUM) ? CDS_NO_DISC : CDS_NO_INFO;
    358
    359	for (i = toc_h.cdth_trk0; i <= toc_h.cdth_trk1; i++) {
    360		toc_e.cdte_track = i;
    361		toc_e.cdte_format = CDROM_LBA;
    362		if (sr_read_tocentry(cdi, &toc_e))
    363			return CDS_NO_INFO;
    364		if (toc_e.cdte_ctrl & CDROM_DATA_TRACK) {
    365			have_datatracks = 1;
    366			break;
    367		}
    368	}
    369	if (!have_datatracks)
    370		return CDS_AUDIO;
    371
    372	if (cd->xa_flag)
    373		return CDS_XA_2_1;
    374	else
    375		return CDS_DATA_1;
    376}
    377
    378int sr_get_last_session(struct cdrom_device_info *cdi,
    379			struct cdrom_multisession *ms_info)
    380{
    381	Scsi_CD *cd = cdi->handle;
    382
    383	ms_info->addr.lba = cd->ms_offset;
    384	ms_info->xa_flag = cd->xa_flag || cd->ms_offset > 0;
    385
    386	return 0;
    387}
    388
    389int sr_get_mcn(struct cdrom_device_info *cdi, struct cdrom_mcn *mcn)
    390{
    391	Scsi_CD *cd = cdi->handle;
    392	struct packet_command cgc;
    393	char *buffer = kzalloc(32, GFP_KERNEL);
    394	int result;
    395
    396	if (!buffer)
    397		return -ENOMEM;
    398
    399	memset(&cgc, 0, sizeof(struct packet_command));
    400	cgc.cmd[0] = GPCMD_READ_SUBCHANNEL;
    401	cgc.cmd[2] = 0x40;	/* I do want the subchannel info */
    402	cgc.cmd[3] = 0x02;	/* Give me medium catalog number info */
    403	cgc.cmd[8] = 24;
    404	cgc.buffer = buffer;
    405	cgc.buflen = 24;
    406	cgc.data_direction = DMA_FROM_DEVICE;
    407	cgc.timeout = IOCTL_TIMEOUT;
    408	result = sr_do_ioctl(cd, &cgc);
    409	if (result)
    410		goto err;
    411
    412	memcpy(mcn->medium_catalog_number, buffer + 9, 13);
    413	mcn->medium_catalog_number[13] = 0;
    414
    415err:
    416	kfree(buffer);
    417	return result;
    418}
    419
    420int sr_reset(struct cdrom_device_info *cdi)
    421{
    422	return 0;
    423}
    424
    425int sr_select_speed(struct cdrom_device_info *cdi, int speed)
    426{
    427	Scsi_CD *cd = cdi->handle;
    428	struct packet_command cgc;
    429
    430	if (speed == 0)
    431		speed = 0xffff;	/* set to max */
    432	else
    433		speed *= 177;	/* Nx to kbyte/s */
    434
    435	memset(&cgc, 0, sizeof(struct packet_command));
    436	cgc.cmd[0] = GPCMD_SET_SPEED;	/* SET CD SPEED */
    437	cgc.cmd[2] = (speed >> 8) & 0xff;	/* MSB for speed (in kbytes/sec) */
    438	cgc.cmd[3] = speed & 0xff;	/* LSB */
    439	cgc.data_direction = DMA_NONE;
    440	cgc.timeout = IOCTL_TIMEOUT;
    441
    442	if (sr_do_ioctl(cd, &cgc))
    443		return -EIO;
    444	return 0;
    445}
    446
    447/* ----------------------------------------------------------------------- */
    448/* this is called by the generic cdrom driver. arg is a _kernel_ pointer,  */
    449/* because the generic cdrom driver does the user access stuff for us.     */
    450/* only cdromreadtochdr and cdromreadtocentry are left - for use with the  */
    451/* sr_disk_status interface for the generic cdrom driver.                  */
    452
    453int sr_audio_ioctl(struct cdrom_device_info *cdi, unsigned int cmd, void *arg)
    454{
    455	switch (cmd) {
    456	case CDROMREADTOCHDR:
    457		return sr_read_tochdr(cdi, arg);
    458	case CDROMREADTOCENTRY:
    459		return sr_read_tocentry(cdi, arg);
    460	case CDROMPLAYTRKIND:
    461		return sr_play_trkind(cdi, arg);
    462	default:
    463		return -EINVAL;
    464	}
    465}
    466
    467/* -----------------------------------------------------------------------
    468 * a function to read all sorts of funny cdrom sectors using the READ_CD
    469 * scsi-3 mmc command
    470 *
    471 * lba:     linear block address
    472 * format:  0 = data (anything)
    473 *          1 = audio
    474 *          2 = data (mode 1)
    475 *          3 = data (mode 2)
    476 *          4 = data (mode 2 form1)
    477 *          5 = data (mode 2 form2)
    478 * blksize: 2048 | 2336 | 2340 | 2352
    479 */
    480
    481static int sr_read_cd(Scsi_CD *cd, unsigned char *dest, int lba, int format, int blksize)
    482{
    483	struct packet_command cgc;
    484
    485#ifdef DEBUG
    486	sr_printk(KERN_INFO, cd, "sr_read_cd lba=%d format=%d blksize=%d\n",
    487		  lba, format, blksize);
    488#endif
    489
    490	memset(&cgc, 0, sizeof(struct packet_command));
    491	cgc.cmd[0] = GPCMD_READ_CD;	/* READ_CD */
    492	cgc.cmd[1] = ((format & 7) << 2);
    493	cgc.cmd[2] = (unsigned char) (lba >> 24) & 0xff;
    494	cgc.cmd[3] = (unsigned char) (lba >> 16) & 0xff;
    495	cgc.cmd[4] = (unsigned char) (lba >> 8) & 0xff;
    496	cgc.cmd[5] = (unsigned char) lba & 0xff;
    497	cgc.cmd[8] = 1;
    498	switch (blksize) {
    499	case 2336:
    500		cgc.cmd[9] = 0x58;
    501		break;
    502	case 2340:
    503		cgc.cmd[9] = 0x78;
    504		break;
    505	case 2352:
    506		cgc.cmd[9] = 0xf8;
    507		break;
    508	default:
    509		cgc.cmd[9] = 0x10;
    510		break;
    511	}
    512	cgc.buffer = dest;
    513	cgc.buflen = blksize;
    514	cgc.data_direction = DMA_FROM_DEVICE;
    515	cgc.timeout = IOCTL_TIMEOUT;
    516	return sr_do_ioctl(cd, &cgc);
    517}
    518
    519/*
    520 * read sectors with blocksizes other than 2048
    521 */
    522
    523static int sr_read_sector(Scsi_CD *cd, int lba, int blksize, unsigned char *dest)
    524{
    525	struct packet_command cgc;
    526	int rc;
    527
    528	/* we try the READ CD command first... */
    529	if (cd->readcd_known) {
    530		rc = sr_read_cd(cd, dest, lba, 0, blksize);
    531		if (-EDRIVE_CANT_DO_THIS != rc)
    532			return rc;
    533		cd->readcd_known = 0;
    534		sr_printk(KERN_INFO, cd,
    535			  "CDROM doesn't support READ CD (0xbe) command\n");
    536		/* fall & retry the other way */
    537	}
    538	/* ... if this fails, we switch the blocksize using MODE SELECT */
    539	if (blksize != cd->device->sector_size) {
    540		if (0 != (rc = sr_set_blocklength(cd, blksize)))
    541			return rc;
    542	}
    543#ifdef DEBUG
    544	sr_printk(KERN_INFO, cd, "sr_read_sector lba=%d blksize=%d\n",
    545		  lba, blksize);
    546#endif
    547
    548	memset(&cgc, 0, sizeof(struct packet_command));
    549	cgc.cmd[0] = GPCMD_READ_10;
    550	cgc.cmd[2] = (unsigned char) (lba >> 24) & 0xff;
    551	cgc.cmd[3] = (unsigned char) (lba >> 16) & 0xff;
    552	cgc.cmd[4] = (unsigned char) (lba >> 8) & 0xff;
    553	cgc.cmd[5] = (unsigned char) lba & 0xff;
    554	cgc.cmd[8] = 1;
    555	cgc.buffer = dest;
    556	cgc.buflen = blksize;
    557	cgc.data_direction = DMA_FROM_DEVICE;
    558	cgc.timeout = IOCTL_TIMEOUT;
    559	rc = sr_do_ioctl(cd, &cgc);
    560
    561	if (blksize != CD_FRAMESIZE)
    562		rc |= sr_set_blocklength(cd, CD_FRAMESIZE);
    563	return rc;
    564}
    565
    566/*
    567 * read a sector in raw mode to check the sector format
    568 * ret: 1 == mode2 (XA), 0 == mode1, <0 == error 
    569 */
    570
    571int sr_is_xa(Scsi_CD *cd)
    572{
    573	unsigned char *raw_sector;
    574	int is_xa;
    575
    576	if (!xa_test)
    577		return 0;
    578
    579	raw_sector = kmalloc(2048, GFP_KERNEL);
    580	if (!raw_sector)
    581		return -ENOMEM;
    582	if (0 == sr_read_sector(cd, cd->ms_offset + 16,
    583				CD_FRAMESIZE_RAW1, raw_sector)) {
    584		is_xa = (raw_sector[3] == 0x02) ? 1 : 0;
    585	} else {
    586		/* read a raw sector failed for some reason. */
    587		is_xa = -1;
    588	}
    589	kfree(raw_sector);
    590#ifdef DEBUG
    591	sr_printk(KERN_INFO, cd, "sr_is_xa: %d\n", is_xa);
    592#endif
    593	return is_xa;
    594}