brintos

brintos / linux-shallow public Read only

0
0
Text · 14.9 KiB · 0896530 Raw
601 lines · c
1// SPDX-License-Identifier: GPL-2.02#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 027#define DEBUG28#endif29 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	} else103		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 3112 113/* ATAPI drives don't have a SCMD_PLAYAUDIO_TI command.  When these drives114   are emulating a SCSI device via the idescsi module, they need to have115   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 specific185   error code is.  Normally the UNIT_ATTENTION code will automatically186   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;192	int result, err = 0, retries = 0;193	const struct scsi_exec_args exec_args = {194		.sshdr = cgc->sshdr ? : &local_sshdr,195	};196 197	SDev = cd->device;198 199	sshdr = exec_args.sshdr;200 201      retry:202	if (!scsi_block_when_processing_errors(SDev)) {203		err = -ENODEV;204		goto out;205	}206 207	result = scsi_execute_cmd(SDev, cgc->cmd,208				  cgc->data_direction == DMA_TO_DEVICE ?209				  REQ_OP_DRV_OUT : REQ_OP_DRV_IN, cgc->buffer,210				  cgc->buflen, cgc->timeout, IOCTL_RETRIES,211				  &exec_args);212	/* Minimal error checking.  Ignore cases we know about, and report the rest. */213	if (result < 0) {214		err = result;215		goto out;216	}217	if (scsi_status_is_check_condition(result)) {218		switch (sshdr->sense_key) {219		case UNIT_ATTENTION:220			SDev->changed = 1;221			if (!cgc->quiet)222				sr_printk(KERN_INFO, cd,223					  "disc change detected.\n");224			if (retries++ < 10)225				goto retry;226			err = -ENOMEDIUM;227			break;228		case NOT_READY:	/* This happens if there is no disc in drive */229			if (sshdr->asc == 0x04 &&230			    sshdr->ascq == 0x01) {231				/* sense: Logical unit is in process of becoming ready */232				if (!cgc->quiet)233					sr_printk(KERN_INFO, cd,234						  "CDROM not ready yet.\n");235				if (retries++ < 10) {236					/* sleep 2 sec and try again */237					ssleep(2);238					goto retry;239				} else {240					/* 20 secs are enough? */241					err = -ENOMEDIUM;242					break;243				}244			}245			if (!cgc->quiet)246				sr_printk(KERN_INFO, cd,247					  "CDROM not ready.  Make sure there "248					  "is a disc in the drive.\n");249			err = -ENOMEDIUM;250			break;251		case ILLEGAL_REQUEST:252			err = -EIO;253			if (sshdr->asc == 0x20 &&254			    sshdr->ascq == 0x00)255				/* sense: Invalid command operation code */256				err = -EDRIVE_CANT_DO_THIS;257			break;258		default:259			err = -EIO;260		}261	}262 263	/* Wake up a process waiting for device */264      out:265	cgc->stat = err;266	return err;267}268 269/* ---------------------------------------------------------------------- */270/* interface to cdrom.c                                                   */271 272int sr_tray_move(struct cdrom_device_info *cdi, int pos)273{274	Scsi_CD *cd = cdi->handle;275	struct packet_command cgc;276 277	memset(&cgc, 0, sizeof(struct packet_command));278	cgc.cmd[0] = GPCMD_START_STOP_UNIT;279	cgc.cmd[4] = (pos == 0) ? 0x03 /* close */ : 0x02 /* eject */ ;280	cgc.data_direction = DMA_NONE;281	cgc.timeout = IOCTL_TIMEOUT;282	return sr_do_ioctl(cd, &cgc);283}284 285int sr_lock_door(struct cdrom_device_info *cdi, int lock)286{287	Scsi_CD *cd = cdi->handle;288 289	return scsi_set_medium_removal(cd->device, lock ?290		       SCSI_REMOVAL_PREVENT : SCSI_REMOVAL_ALLOW);291}292 293int sr_drive_status(struct cdrom_device_info *cdi, int slot)294{295	struct scsi_cd *cd = cdi->handle;296	struct scsi_sense_hdr sshdr;297	struct media_event_desc med;298 299	if (CDSL_CURRENT != slot) {300		/* we have no changer support */301		return -EINVAL;302	}303	if (!scsi_test_unit_ready(cd->device, SR_TIMEOUT, MAX_RETRIES, &sshdr))304		return CDS_DISC_OK;305 306	/* SK/ASC/ASCQ of 2/4/1 means "unit is becoming ready" */307	if (scsi_sense_valid(&sshdr) && sshdr.sense_key == NOT_READY308			&& sshdr.asc == 0x04 && sshdr.ascq == 0x01)309		return CDS_DRIVE_NOT_READY;310 311	if (!cdrom_get_media_event(cdi, &med)) {312		if (med.media_present)313			return CDS_DISC_OK;314		else if (med.door_open)315			return CDS_TRAY_OPEN;316		else317			return CDS_NO_DISC;318	}319 320	/*321	 * SK/ASC/ASCQ of 2/4/2 means "initialization required"322	 * Using CD_TRAY_OPEN results in an START_STOP_UNIT to close323	 * the tray, which resolves the initialization requirement.324	 */325	if (scsi_sense_valid(&sshdr) && sshdr.sense_key == NOT_READY326			&& sshdr.asc == 0x04 && sshdr.ascq == 0x02)327		return CDS_TRAY_OPEN;328 329	/*330	 * 0x04 is format in progress .. but there must be a disc present!331	 */332	if (sshdr.sense_key == NOT_READY && sshdr.asc == 0x04)333		return CDS_DISC_OK;334 335	/*336	 * If not using Mt Fuji extended media tray reports,337	 * just return TRAY_OPEN since ATAPI doesn't provide338	 * any other way to detect this...339	 */340	if (scsi_sense_valid(&sshdr) &&341	    /* 0x3a is medium not present */342	    sshdr.asc == 0x3a)343		return CDS_NO_DISC;344	else345		return CDS_TRAY_OPEN;346 347	return CDS_DRIVE_NOT_READY;348}349 350int sr_disk_status(struct cdrom_device_info *cdi)351{352	Scsi_CD *cd = cdi->handle;353	struct cdrom_tochdr toc_h;354	struct cdrom_tocentry toc_e;355	int i, rc, have_datatracks = 0;356 357	/* look for data tracks */358	rc = sr_read_tochdr(cdi, &toc_h);359	if (rc)360		return (rc == -ENOMEDIUM) ? CDS_NO_DISC : CDS_NO_INFO;361 362	for (i = toc_h.cdth_trk0; i <= toc_h.cdth_trk1; i++) {363		toc_e.cdte_track = i;364		toc_e.cdte_format = CDROM_LBA;365		if (sr_read_tocentry(cdi, &toc_e))366			return CDS_NO_INFO;367		if (toc_e.cdte_ctrl & CDROM_DATA_TRACK) {368			have_datatracks = 1;369			break;370		}371	}372	if (!have_datatracks)373		return CDS_AUDIO;374 375	if (cd->xa_flag)376		return CDS_XA_2_1;377	else378		return CDS_DATA_1;379}380 381int sr_get_last_session(struct cdrom_device_info *cdi,382			struct cdrom_multisession *ms_info)383{384	Scsi_CD *cd = cdi->handle;385 386	ms_info->addr.lba = cd->ms_offset;387	ms_info->xa_flag = cd->xa_flag || cd->ms_offset > 0;388 389	return 0;390}391 392int sr_get_mcn(struct cdrom_device_info *cdi, struct cdrom_mcn *mcn)393{394	Scsi_CD *cd = cdi->handle;395	struct packet_command cgc;396	char *buffer = kzalloc(32, GFP_KERNEL);397	int result;398 399	if (!buffer)400		return -ENOMEM;401 402	memset(&cgc, 0, sizeof(struct packet_command));403	cgc.cmd[0] = GPCMD_READ_SUBCHANNEL;404	cgc.cmd[2] = 0x40;	/* I do want the subchannel info */405	cgc.cmd[3] = 0x02;	/* Give me medium catalog number info */406	cgc.cmd[8] = 24;407	cgc.buffer = buffer;408	cgc.buflen = 24;409	cgc.data_direction = DMA_FROM_DEVICE;410	cgc.timeout = IOCTL_TIMEOUT;411	result = sr_do_ioctl(cd, &cgc);412	if (result)413		goto err;414 415	memcpy(mcn->medium_catalog_number, buffer + 9, 13);416	mcn->medium_catalog_number[13] = 0;417 418err:419	kfree(buffer);420	return result;421}422 423int sr_reset(struct cdrom_device_info *cdi)424{425	return 0;426}427 428int sr_select_speed(struct cdrom_device_info *cdi, unsigned long speed)429{430	Scsi_CD *cd = cdi->handle;431	struct packet_command cgc;432 433	/* avoid exceeding the max speed or overflowing integer bounds */434	speed = clamp(speed, 0, 0xffff / 177);435 436	if (speed == 0)437		speed = 0xffff;	/* set to max */438	else439		speed *= 177;	/* Nx to kbyte/s */440 441	memset(&cgc, 0, sizeof(struct packet_command));442	cgc.cmd[0] = GPCMD_SET_SPEED;	/* SET CD SPEED */443	cgc.cmd[2] = (speed >> 8) & 0xff;	/* MSB for speed (in kbytes/sec) */444	cgc.cmd[3] = speed & 0xff;	/* LSB */445	cgc.data_direction = DMA_NONE;446	cgc.timeout = IOCTL_TIMEOUT;447 448	if (sr_do_ioctl(cd, &cgc))449		return -EIO;450	return 0;451}452 453/* ----------------------------------------------------------------------- */454/* this is called by the generic cdrom driver. arg is a _kernel_ pointer,  */455/* because the generic cdrom driver does the user access stuff for us.     */456/* only cdromreadtochdr and cdromreadtocentry are left - for use with the  */457/* sr_disk_status interface for the generic cdrom driver.                  */458 459int sr_audio_ioctl(struct cdrom_device_info *cdi, unsigned int cmd, void *arg)460{461	switch (cmd) {462	case CDROMREADTOCHDR:463		return sr_read_tochdr(cdi, arg);464	case CDROMREADTOCENTRY:465		return sr_read_tocentry(cdi, arg);466	case CDROMPLAYTRKIND:467		return sr_play_trkind(cdi, arg);468	default:469		return -EINVAL;470	}471}472 473/* -----------------------------------------------------------------------474 * a function to read all sorts of funny cdrom sectors using the READ_CD475 * scsi-3 mmc command476 *477 * lba:     linear block address478 * format:  0 = data (anything)479 *          1 = audio480 *          2 = data (mode 1)481 *          3 = data (mode 2)482 *          4 = data (mode 2 form1)483 *          5 = data (mode 2 form2)484 * blksize: 2048 | 2336 | 2340 | 2352485 */486 487static int sr_read_cd(Scsi_CD *cd, unsigned char *dest, int lba, int format, int blksize)488{489	struct packet_command cgc;490 491#ifdef DEBUG492	sr_printk(KERN_INFO, cd, "sr_read_cd lba=%d format=%d blksize=%d\n",493		  lba, format, blksize);494#endif495 496	memset(&cgc, 0, sizeof(struct packet_command));497	cgc.cmd[0] = GPCMD_READ_CD;	/* READ_CD */498	cgc.cmd[1] = ((format & 7) << 2);499	cgc.cmd[2] = (unsigned char) (lba >> 24) & 0xff;500	cgc.cmd[3] = (unsigned char) (lba >> 16) & 0xff;501	cgc.cmd[4] = (unsigned char) (lba >> 8) & 0xff;502	cgc.cmd[5] = (unsigned char) lba & 0xff;503	cgc.cmd[8] = 1;504	switch (blksize) {505	case 2336:506		cgc.cmd[9] = 0x58;507		break;508	case 2340:509		cgc.cmd[9] = 0x78;510		break;511	case 2352:512		cgc.cmd[9] = 0xf8;513		break;514	default:515		cgc.cmd[9] = 0x10;516		break;517	}518	cgc.buffer = dest;519	cgc.buflen = blksize;520	cgc.data_direction = DMA_FROM_DEVICE;521	cgc.timeout = IOCTL_TIMEOUT;522	return sr_do_ioctl(cd, &cgc);523}524 525/*526 * read sectors with blocksizes other than 2048527 */528 529static int sr_read_sector(Scsi_CD *cd, int lba, int blksize, unsigned char *dest)530{531	struct packet_command cgc;532	int rc;533 534	/* we try the READ CD command first... */535	if (cd->readcd_known) {536		rc = sr_read_cd(cd, dest, lba, 0, blksize);537		if (-EDRIVE_CANT_DO_THIS != rc)538			return rc;539		cd->readcd_known = 0;540		sr_printk(KERN_INFO, cd,541			  "CDROM doesn't support READ CD (0xbe) command\n");542		/* fall & retry the other way */543	}544	/* ... if this fails, we switch the blocksize using MODE SELECT */545	if (blksize != cd->device->sector_size) {546		if (0 != (rc = sr_set_blocklength(cd, blksize)))547			return rc;548	}549#ifdef DEBUG550	sr_printk(KERN_INFO, cd, "sr_read_sector lba=%d blksize=%d\n",551		  lba, blksize);552#endif553 554	memset(&cgc, 0, sizeof(struct packet_command));555	cgc.cmd[0] = GPCMD_READ_10;556	cgc.cmd[2] = (unsigned char) (lba >> 24) & 0xff;557	cgc.cmd[3] = (unsigned char) (lba >> 16) & 0xff;558	cgc.cmd[4] = (unsigned char) (lba >> 8) & 0xff;559	cgc.cmd[5] = (unsigned char) lba & 0xff;560	cgc.cmd[8] = 1;561	cgc.buffer = dest;562	cgc.buflen = blksize;563	cgc.data_direction = DMA_FROM_DEVICE;564	cgc.timeout = IOCTL_TIMEOUT;565	rc = sr_do_ioctl(cd, &cgc);566 567	if (blksize != CD_FRAMESIZE)568		rc |= sr_set_blocklength(cd, CD_FRAMESIZE);569	return rc;570}571 572/*573 * read a sector in raw mode to check the sector format574 * ret: 1 == mode2 (XA), 0 == mode1, <0 == error 575 */576 577int sr_is_xa(Scsi_CD *cd)578{579	unsigned char *raw_sector;580	int is_xa;581 582	if (!xa_test)583		return 0;584 585	raw_sector = kmalloc(2048, GFP_KERNEL);586	if (!raw_sector)587		return -ENOMEM;588	if (0 == sr_read_sector(cd, cd->ms_offset + 16,589				CD_FRAMESIZE_RAW1, raw_sector)) {590		is_xa = (raw_sector[3] == 0x02) ? 1 : 0;591	} else {592		/* read a raw sector failed for some reason. */593		is_xa = -1;594	}595	kfree(raw_sector);596#ifdef DEBUG597	sr_printk(KERN_INFO, cd, "sr_is_xa: %d\n", is_xa);598#endif599	return is_xa;600}601