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

pcd.c (26144B)


      1/* 
      2	pcd.c	(c) 1997-8  Grant R. Guenther <grant@torque.net>
      3		            Under the terms of the GNU General Public License.
      4
      5	This is a high-level driver for parallel port ATAPI CD-ROM
      6        drives based on chips supported by the paride module.
      7
      8        By default, the driver will autoprobe for a single parallel
      9        port ATAPI CD-ROM drive, but if their individual parameters are
     10        specified, the driver can handle up to 4 drives.
     11
     12        The behaviour of the pcd driver can be altered by setting
     13        some parameters from the insmod command line.  The following
     14        parameters are adjustable:
     15
     16            drive0      These four arguments can be arrays of       
     17            drive1      1-6 integers as follows:
     18            drive2
     19            drive3      <prt>,<pro>,<uni>,<mod>,<slv>,<dly>
     20
     21                        Where,
     22
     23                <prt>   is the base of the parallel port address for
     24                        the corresponding drive.  (required)
     25
     26                <pro>   is the protocol number for the adapter that
     27                        supports this drive.  These numbers are
     28                        logged by 'paride' when the protocol modules
     29                        are initialised.  (0 if not given)
     30
     31                <uni>   for those adapters that support chained
     32                        devices, this is the unit selector for the
     33                        chain of devices on the given port.  It should
     34                        be zero for devices that don't support chaining.
     35                        (0 if not given)
     36
     37                <mod>   this can be -1 to choose the best mode, or one
     38                        of the mode numbers supported by the adapter.
     39                        (-1 if not given)
     40
     41		<slv>   ATAPI CD-ROMs can be jumpered to master or slave.
     42			Set this to 0 to choose the master drive, 1 to
     43                        choose the slave, -1 (the default) to choose the
     44			first drive found.
     45
     46                <dly>   some parallel ports require the driver to 
     47                        go more slowly.  -1 sets a default value that
     48                        should work with the chosen protocol.  Otherwise,
     49                        set this to a small integer, the larger it is
     50                        the slower the port i/o.  In some cases, setting
     51                        this to zero will speed up the device. (default -1)
     52                        
     53            major       You may use this parameter to override the
     54                        default major number (46) that this driver
     55                        will use.  Be sure to change the device
     56                        name as well.
     57
     58            name        This parameter is a character string that
     59                        contains the name the kernel will use for this
     60                        device (in /proc output, for instance).
     61                        (default "pcd")
     62
     63            verbose     This parameter controls the amount of logging
     64                        that the driver will do.  Set it to 0 for
     65                        normal operation, 1 to see autoprobe progress
     66                        messages, or 2 to see additional debugging
     67                        output.  (default 0)
     68  
     69            nice        This parameter controls the driver's use of
     70                        idle CPU time, at the expense of some speed.
     71 
     72	If this driver is built into the kernel, you can use the
     73        following kernel command line parameters, with the same values
     74        as the corresponding module parameters listed above:
     75
     76	    pcd.drive0
     77	    pcd.drive1
     78	    pcd.drive2
     79	    pcd.drive3
     80	    pcd.nice
     81
     82        In addition, you can use the parameter pcd.disable to disable
     83        the driver entirely.
     84
     85*/
     86
     87/* Changes:
     88
     89	1.01	GRG 1998.01.24	Added test unit ready support
     90	1.02    GRG 1998.05.06  Changes to pcd_completion, ready_wait,
     91				and loosen interpretation of ATAPI
     92			        standard for clearing error status.
     93				Use spinlocks. Eliminate sti().
     94	1.03    GRG 1998.06.16  Eliminated an Ugh
     95	1.04	GRG 1998.08.15  Added extra debugging, improvements to
     96				pcd_completion, use HZ in loop timing
     97	1.05	GRG 1998.08.16	Conformed to "Uniform CD-ROM" standard
     98	1.06    GRG 1998.08.19  Added audio ioctl support
     99	1.07    GRG 1998.09.24  Increased reset timeout, added jumbo support
    100
    101*/
    102
    103#define	PCD_VERSION	"1.07"
    104#define PCD_MAJOR	46
    105#define PCD_NAME	"pcd"
    106#define PCD_UNITS	4
    107
    108/* Here are things one can override from the insmod command.
    109   Most are autoprobed by paride unless set here.  Verbose is off
    110   by default.
    111
    112*/
    113
    114static int verbose = 0;
    115static int major = PCD_MAJOR;
    116static char *name = PCD_NAME;
    117static int nice = 0;
    118static int disable = 0;
    119
    120static int drive0[6] = { 0, 0, 0, -1, -1, -1 };
    121static int drive1[6] = { 0, 0, 0, -1, -1, -1 };
    122static int drive2[6] = { 0, 0, 0, -1, -1, -1 };
    123static int drive3[6] = { 0, 0, 0, -1, -1, -1 };
    124
    125static int (*drives[4])[6] = {&drive0, &drive1, &drive2, &drive3};
    126static int pcd_drive_count;
    127
    128enum {D_PRT, D_PRO, D_UNI, D_MOD, D_SLV, D_DLY};
    129
    130/* end of parameters */
    131
    132#include <linux/module.h>
    133#include <linux/init.h>
    134#include <linux/errno.h>
    135#include <linux/fs.h>
    136#include <linux/kernel.h>
    137#include <linux/delay.h>
    138#include <linux/cdrom.h>
    139#include <linux/spinlock.h>
    140#include <linux/blk-mq.h>
    141#include <linux/mutex.h>
    142#include <linux/uaccess.h>
    143
    144static DEFINE_MUTEX(pcd_mutex);
    145static DEFINE_SPINLOCK(pcd_lock);
    146
    147module_param(verbose, int, 0644);
    148module_param(major, int, 0);
    149module_param(name, charp, 0);
    150module_param(nice, int, 0);
    151module_param_array(drive0, int, NULL, 0);
    152module_param_array(drive1, int, NULL, 0);
    153module_param_array(drive2, int, NULL, 0);
    154module_param_array(drive3, int, NULL, 0);
    155
    156#include "paride.h"
    157#include "pseudo.h"
    158
    159#define PCD_RETRIES	     5
    160#define PCD_TMO		   800	/* timeout in jiffies */
    161#define PCD_DELAY           50	/* spin delay in uS */
    162#define PCD_READY_TMO	    20	/* in seconds */
    163#define PCD_RESET_TMO	   100	/* in tenths of a second */
    164
    165#define PCD_SPIN	(1000000*PCD_TMO)/(HZ*PCD_DELAY)
    166
    167#define IDE_ERR		0x01
    168#define IDE_DRQ         0x08
    169#define IDE_READY       0x40
    170#define IDE_BUSY        0x80
    171
    172static int pcd_open(struct cdrom_device_info *cdi, int purpose);
    173static void pcd_release(struct cdrom_device_info *cdi);
    174static int pcd_drive_status(struct cdrom_device_info *cdi, int slot_nr);
    175static unsigned int pcd_check_events(struct cdrom_device_info *cdi,
    176				     unsigned int clearing, int slot_nr);
    177static int pcd_tray_move(struct cdrom_device_info *cdi, int position);
    178static int pcd_lock_door(struct cdrom_device_info *cdi, int lock);
    179static int pcd_drive_reset(struct cdrom_device_info *cdi);
    180static int pcd_get_mcn(struct cdrom_device_info *cdi, struct cdrom_mcn *mcn);
    181static int pcd_audio_ioctl(struct cdrom_device_info *cdi,
    182			   unsigned int cmd, void *arg);
    183static int pcd_packet(struct cdrom_device_info *cdi,
    184		      struct packet_command *cgc);
    185
    186static void do_pcd_read_drq(void);
    187static blk_status_t pcd_queue_rq(struct blk_mq_hw_ctx *hctx,
    188				 const struct blk_mq_queue_data *bd);
    189static void do_pcd_read(void);
    190
    191struct pcd_unit {
    192	struct pi_adapter pia;	/* interface to paride layer */
    193	struct pi_adapter *pi;
    194	int drive;		/* master/slave */
    195	int last_sense;		/* result of last request sense */
    196	int changed;		/* media change seen */
    197	int present;		/* does this unit exist ? */
    198	char *name;		/* pcd0, pcd1, etc */
    199	struct cdrom_device_info info;	/* uniform cdrom interface */
    200	struct gendisk *disk;
    201	struct blk_mq_tag_set tag_set;
    202	struct list_head rq_list;
    203};
    204
    205static struct pcd_unit pcd[PCD_UNITS];
    206
    207static char pcd_scratch[64];
    208static char pcd_buffer[2048];	/* raw block buffer */
    209static int pcd_bufblk = -1;	/* block in buffer, in CD units,
    210				   -1 for nothing there. See also
    211				   pd_unit.
    212				 */
    213
    214/* the variables below are used mainly in the I/O request engine, which
    215   processes only one request at a time.
    216*/
    217
    218static struct pcd_unit *pcd_current; /* current request's drive */
    219static struct request *pcd_req;
    220static int pcd_retries;		/* retries on current request */
    221static int pcd_busy;		/* request being processed ? */
    222static int pcd_sector;		/* address of next requested sector */
    223static int pcd_count;		/* number of blocks still to do */
    224static char *pcd_buf;		/* buffer for request in progress */
    225static void *par_drv;		/* reference of parport driver */
    226
    227/* kernel glue structures */
    228
    229static int pcd_block_open(struct block_device *bdev, fmode_t mode)
    230{
    231	struct pcd_unit *cd = bdev->bd_disk->private_data;
    232	int ret;
    233
    234	bdev_check_media_change(bdev);
    235
    236	mutex_lock(&pcd_mutex);
    237	ret = cdrom_open(&cd->info, bdev, mode);
    238	mutex_unlock(&pcd_mutex);
    239
    240	return ret;
    241}
    242
    243static void pcd_block_release(struct gendisk *disk, fmode_t mode)
    244{
    245	struct pcd_unit *cd = disk->private_data;
    246	mutex_lock(&pcd_mutex);
    247	cdrom_release(&cd->info, mode);
    248	mutex_unlock(&pcd_mutex);
    249}
    250
    251static int pcd_block_ioctl(struct block_device *bdev, fmode_t mode,
    252				unsigned cmd, unsigned long arg)
    253{
    254	struct pcd_unit *cd = bdev->bd_disk->private_data;
    255	int ret;
    256
    257	mutex_lock(&pcd_mutex);
    258	ret = cdrom_ioctl(&cd->info, bdev, mode, cmd, arg);
    259	mutex_unlock(&pcd_mutex);
    260
    261	return ret;
    262}
    263
    264static unsigned int pcd_block_check_events(struct gendisk *disk,
    265					   unsigned int clearing)
    266{
    267	struct pcd_unit *cd = disk->private_data;
    268	return cdrom_check_events(&cd->info, clearing);
    269}
    270
    271static const struct block_device_operations pcd_bdops = {
    272	.owner		= THIS_MODULE,
    273	.open		= pcd_block_open,
    274	.release	= pcd_block_release,
    275	.ioctl		= pcd_block_ioctl,
    276#ifdef CONFIG_COMPAT
    277	.compat_ioctl	= blkdev_compat_ptr_ioctl,
    278#endif
    279	.check_events	= pcd_block_check_events,
    280};
    281
    282static const struct cdrom_device_ops pcd_dops = {
    283	.open		= pcd_open,
    284	.release	= pcd_release,
    285	.drive_status	= pcd_drive_status,
    286	.check_events	= pcd_check_events,
    287	.tray_move	= pcd_tray_move,
    288	.lock_door	= pcd_lock_door,
    289	.get_mcn	= pcd_get_mcn,
    290	.reset		= pcd_drive_reset,
    291	.audio_ioctl	= pcd_audio_ioctl,
    292	.generic_packet	= pcd_packet,
    293	.capability	= CDC_CLOSE_TRAY | CDC_OPEN_TRAY | CDC_LOCK |
    294			  CDC_MCN | CDC_MEDIA_CHANGED | CDC_RESET |
    295			  CDC_PLAY_AUDIO | CDC_GENERIC_PACKET | CDC_CD_R |
    296			  CDC_CD_RW,
    297};
    298
    299static const struct blk_mq_ops pcd_mq_ops = {
    300	.queue_rq	= pcd_queue_rq,
    301};
    302
    303static int pcd_open(struct cdrom_device_info *cdi, int purpose)
    304{
    305	struct pcd_unit *cd = cdi->handle;
    306	if (!cd->present)
    307		return -ENODEV;
    308	return 0;
    309}
    310
    311static void pcd_release(struct cdrom_device_info *cdi)
    312{
    313}
    314
    315static inline int status_reg(struct pcd_unit *cd)
    316{
    317	return pi_read_regr(cd->pi, 1, 6);
    318}
    319
    320static inline int read_reg(struct pcd_unit *cd, int reg)
    321{
    322	return pi_read_regr(cd->pi, 0, reg);
    323}
    324
    325static inline void write_reg(struct pcd_unit *cd, int reg, int val)
    326{
    327	pi_write_regr(cd->pi, 0, reg, val);
    328}
    329
    330static int pcd_wait(struct pcd_unit *cd, int go, int stop, char *fun, char *msg)
    331{
    332	int j, r, e, s, p;
    333
    334	j = 0;
    335	while ((((r = status_reg(cd)) & go) || (stop && (!(r & stop))))
    336	       && (j++ < PCD_SPIN))
    337		udelay(PCD_DELAY);
    338
    339	if ((r & (IDE_ERR & stop)) || (j > PCD_SPIN)) {
    340		s = read_reg(cd, 7);
    341		e = read_reg(cd, 1);
    342		p = read_reg(cd, 2);
    343		if (j > PCD_SPIN)
    344			e |= 0x100;
    345		if (fun)
    346			printk("%s: %s %s: alt=0x%x stat=0x%x err=0x%x"
    347			       " loop=%d phase=%d\n",
    348			       cd->name, fun, msg, r, s, e, j, p);
    349		return (s << 8) + r;
    350	}
    351	return 0;
    352}
    353
    354static int pcd_command(struct pcd_unit *cd, char *cmd, int dlen, char *fun)
    355{
    356	pi_connect(cd->pi);
    357
    358	write_reg(cd, 6, 0xa0 + 0x10 * cd->drive);
    359
    360	if (pcd_wait(cd, IDE_BUSY | IDE_DRQ, 0, fun, "before command")) {
    361		pi_disconnect(cd->pi);
    362		return -1;
    363	}
    364
    365	write_reg(cd, 4, dlen % 256);
    366	write_reg(cd, 5, dlen / 256);
    367	write_reg(cd, 7, 0xa0);	/* ATAPI packet command */
    368
    369	if (pcd_wait(cd, IDE_BUSY, IDE_DRQ, fun, "command DRQ")) {
    370		pi_disconnect(cd->pi);
    371		return -1;
    372	}
    373
    374	if (read_reg(cd, 2) != 1) {
    375		printk("%s: %s: command phase error\n", cd->name, fun);
    376		pi_disconnect(cd->pi);
    377		return -1;
    378	}
    379
    380	pi_write_block(cd->pi, cmd, 12);
    381
    382	return 0;
    383}
    384
    385static int pcd_completion(struct pcd_unit *cd, char *buf, char *fun)
    386{
    387	int r, d, p, n, k, j;
    388
    389	r = -1;
    390	k = 0;
    391	j = 0;
    392
    393	if (!pcd_wait(cd, IDE_BUSY, IDE_DRQ | IDE_READY | IDE_ERR,
    394		      fun, "completion")) {
    395		r = 0;
    396		while (read_reg(cd, 7) & IDE_DRQ) {
    397			d = read_reg(cd, 4) + 256 * read_reg(cd, 5);
    398			n = (d + 3) & 0xfffc;
    399			p = read_reg(cd, 2) & 3;
    400
    401			if ((p == 2) && (n > 0) && (j == 0)) {
    402				pi_read_block(cd->pi, buf, n);
    403				if (verbose > 1)
    404					printk("%s: %s: Read %d bytes\n",
    405					       cd->name, fun, n);
    406				r = 0;
    407				j++;
    408			} else {
    409				if (verbose > 1)
    410					printk
    411					    ("%s: %s: Unexpected phase %d, d=%d, k=%d\n",
    412					     cd->name, fun, p, d, k);
    413				if (verbose < 2)
    414					printk_once(
    415					    "%s: WARNING: ATAPI phase errors\n",
    416					    cd->name);
    417				mdelay(1);
    418			}
    419			if (k++ > PCD_TMO) {
    420				printk("%s: Stuck DRQ\n", cd->name);
    421				break;
    422			}
    423			if (pcd_wait
    424			    (cd, IDE_BUSY, IDE_DRQ | IDE_READY | IDE_ERR, fun,
    425			     "completion")) {
    426				r = -1;
    427				break;
    428			}
    429		}
    430	}
    431
    432	pi_disconnect(cd->pi);
    433
    434	return r;
    435}
    436
    437static void pcd_req_sense(struct pcd_unit *cd, char *fun)
    438{
    439	char rs_cmd[12] = { 0x03, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0 };
    440	char buf[16];
    441	int r, c;
    442
    443	r = pcd_command(cd, rs_cmd, 16, "Request sense");
    444	mdelay(1);
    445	if (!r)
    446		pcd_completion(cd, buf, "Request sense");
    447
    448	cd->last_sense = -1;
    449	c = 2;
    450	if (!r) {
    451		if (fun)
    452			printk("%s: %s: Sense key: %x, ASC: %x, ASQ: %x\n",
    453			       cd->name, fun, buf[2] & 0xf, buf[12], buf[13]);
    454		c = buf[2] & 0xf;
    455		cd->last_sense =
    456		    c | ((buf[12] & 0xff) << 8) | ((buf[13] & 0xff) << 16);
    457	}
    458	if ((c == 2) || (c == 6))
    459		cd->changed = 1;
    460}
    461
    462static int pcd_atapi(struct pcd_unit *cd, char *cmd, int dlen, char *buf, char *fun)
    463{
    464	int r;
    465
    466	r = pcd_command(cd, cmd, dlen, fun);
    467	mdelay(1);
    468	if (!r)
    469		r = pcd_completion(cd, buf, fun);
    470	if (r)
    471		pcd_req_sense(cd, fun);
    472
    473	return r;
    474}
    475
    476static int pcd_packet(struct cdrom_device_info *cdi, struct packet_command *cgc)
    477{
    478	return pcd_atapi(cdi->handle, cgc->cmd, cgc->buflen, cgc->buffer,
    479			 "generic packet");
    480}
    481
    482#define DBMSG(msg)	((verbose>1)?(msg):NULL)
    483
    484static unsigned int pcd_check_events(struct cdrom_device_info *cdi,
    485				     unsigned int clearing, int slot_nr)
    486{
    487	struct pcd_unit *cd = cdi->handle;
    488	int res = cd->changed;
    489	if (res)
    490		cd->changed = 0;
    491	return res ? DISK_EVENT_MEDIA_CHANGE : 0;
    492}
    493
    494static int pcd_lock_door(struct cdrom_device_info *cdi, int lock)
    495{
    496	char un_cmd[12] = { 0x1e, 0, 0, 0, lock, 0, 0, 0, 0, 0, 0, 0 };
    497
    498	return pcd_atapi(cdi->handle, un_cmd, 0, pcd_scratch,
    499			 lock ? "lock door" : "unlock door");
    500}
    501
    502static int pcd_tray_move(struct cdrom_device_info *cdi, int position)
    503{
    504	char ej_cmd[12] = { 0x1b, 0, 0, 0, 3 - position, 0, 0, 0, 0, 0, 0, 0 };
    505
    506	return pcd_atapi(cdi->handle, ej_cmd, 0, pcd_scratch,
    507			 position ? "eject" : "close tray");
    508}
    509
    510static void pcd_sleep(int cs)
    511{
    512	schedule_timeout_interruptible(cs);
    513}
    514
    515static int pcd_reset(struct pcd_unit *cd)
    516{
    517	int i, k, flg;
    518	int expect[5] = { 1, 1, 1, 0x14, 0xeb };
    519
    520	pi_connect(cd->pi);
    521	write_reg(cd, 6, 0xa0 + 0x10 * cd->drive);
    522	write_reg(cd, 7, 8);
    523
    524	pcd_sleep(20 * HZ / 1000);	/* delay a bit */
    525
    526	k = 0;
    527	while ((k++ < PCD_RESET_TMO) && (status_reg(cd) & IDE_BUSY))
    528		pcd_sleep(HZ / 10);
    529
    530	flg = 1;
    531	for (i = 0; i < 5; i++)
    532		flg &= (read_reg(cd, i + 1) == expect[i]);
    533
    534	if (verbose) {
    535		printk("%s: Reset (%d) signature = ", cd->name, k);
    536		for (i = 0; i < 5; i++)
    537			printk("%3x", read_reg(cd, i + 1));
    538		if (!flg)
    539			printk(" (incorrect)");
    540		printk("\n");
    541	}
    542
    543	pi_disconnect(cd->pi);
    544	return flg - 1;
    545}
    546
    547static int pcd_drive_reset(struct cdrom_device_info *cdi)
    548{
    549	return pcd_reset(cdi->handle);
    550}
    551
    552static int pcd_ready_wait(struct pcd_unit *cd, int tmo)
    553{
    554	char tr_cmd[12] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
    555	int k, p;
    556
    557	k = 0;
    558	while (k < tmo) {
    559		cd->last_sense = 0;
    560		pcd_atapi(cd, tr_cmd, 0, NULL, DBMSG("test unit ready"));
    561		p = cd->last_sense;
    562		if (!p)
    563			return 0;
    564		if (!(((p & 0xffff) == 0x0402) || ((p & 0xff) == 6)))
    565			return p;
    566		k++;
    567		pcd_sleep(HZ);
    568	}
    569	return 0x000020;	/* timeout */
    570}
    571
    572static int pcd_drive_status(struct cdrom_device_info *cdi, int slot_nr)
    573{
    574	char rc_cmd[12] = { 0x25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
    575	struct pcd_unit *cd = cdi->handle;
    576
    577	if (pcd_ready_wait(cd, PCD_READY_TMO))
    578		return CDS_DRIVE_NOT_READY;
    579	if (pcd_atapi(cd, rc_cmd, 8, pcd_scratch, DBMSG("check media")))
    580		return CDS_NO_DISC;
    581	return CDS_DISC_OK;
    582}
    583
    584static int pcd_identify(struct pcd_unit *cd)
    585{
    586	char id_cmd[12] = { 0x12, 0, 0, 0, 36, 0, 0, 0, 0, 0, 0, 0 };
    587	char id[18];
    588	int k, s;
    589
    590	pcd_bufblk = -1;
    591
    592	s = pcd_atapi(cd, id_cmd, 36, pcd_buffer, "identify");
    593
    594	if (s)
    595		return -1;
    596	if ((pcd_buffer[0] & 0x1f) != 5) {
    597		if (verbose)
    598			printk("%s: %s is not a CD-ROM\n",
    599			       cd->name, cd->drive ? "Slave" : "Master");
    600		return -1;
    601	}
    602	memcpy(id, pcd_buffer + 16, 16);
    603	id[16] = 0;
    604	k = 16;
    605	while ((k >= 0) && (id[k] <= 0x20)) {
    606		id[k] = 0;
    607		k--;
    608	}
    609
    610	printk("%s: %s: %s\n", cd->name, cd->drive ? "Slave" : "Master", id);
    611
    612	return 0;
    613}
    614
    615/*
    616 * returns 0, with id set if drive is detected, otherwise an error code.
    617 */
    618static int pcd_probe(struct pcd_unit *cd, int ms)
    619{
    620	if (ms == -1) {
    621		for (cd->drive = 0; cd->drive <= 1; cd->drive++)
    622			if (!pcd_reset(cd) && !pcd_identify(cd))
    623				return 0;
    624	} else {
    625		cd->drive = ms;
    626		if (!pcd_reset(cd) && !pcd_identify(cd))
    627			return 0;
    628	}
    629	return -ENODEV;
    630}
    631
    632static int pcd_probe_capabilities(struct pcd_unit *cd)
    633{
    634	char cmd[12] = { 0x5a, 1 << 3, 0x2a, 0, 0, 0, 0, 18, 0, 0, 0, 0 };
    635	char buffer[32];
    636	int ret;
    637
    638	ret = pcd_atapi(cd, cmd, 18, buffer, "mode sense capabilities");
    639	if (ret)
    640		return ret;
    641
    642	/* we should now have the cap page */
    643	if ((buffer[11] & 1) == 0)
    644		cd->info.mask |= CDC_CD_R;
    645	if ((buffer[11] & 2) == 0)
    646		cd->info.mask |= CDC_CD_RW;
    647	if ((buffer[12] & 1) == 0)
    648		cd->info.mask |= CDC_PLAY_AUDIO;
    649	if ((buffer[14] & 1) == 0)
    650		cd->info.mask |= CDC_LOCK;
    651	if ((buffer[14] & 8) == 0)
    652		cd->info.mask |= CDC_OPEN_TRAY;
    653	if ((buffer[14] >> 6) == 0)
    654		cd->info.mask |= CDC_CLOSE_TRAY;
    655
    656	return 0;
    657}
    658
    659/* I/O request processing */
    660static int pcd_queue;
    661
    662static int set_next_request(void)
    663{
    664	struct pcd_unit *cd;
    665	int old_pos = pcd_queue;
    666
    667	do {
    668		cd = &pcd[pcd_queue];
    669		if (++pcd_queue == PCD_UNITS)
    670			pcd_queue = 0;
    671		if (cd->present && !list_empty(&cd->rq_list)) {
    672			pcd_req = list_first_entry(&cd->rq_list, struct request,
    673							queuelist);
    674			list_del_init(&pcd_req->queuelist);
    675			blk_mq_start_request(pcd_req);
    676			break;
    677		}
    678	} while (pcd_queue != old_pos);
    679
    680	return pcd_req != NULL;
    681}
    682
    683static void pcd_request(void)
    684{
    685	struct pcd_unit *cd;
    686
    687	if (pcd_busy)
    688		return;
    689
    690	if (!pcd_req && !set_next_request())
    691		return;
    692
    693	cd = pcd_req->q->disk->private_data;
    694	if (cd != pcd_current)
    695		pcd_bufblk = -1;
    696	pcd_current = cd;
    697	pcd_sector = blk_rq_pos(pcd_req);
    698	pcd_count = blk_rq_cur_sectors(pcd_req);
    699	pcd_buf = bio_data(pcd_req->bio);
    700	pcd_busy = 1;
    701	ps_set_intr(do_pcd_read, NULL, 0, nice);
    702}
    703
    704static blk_status_t pcd_queue_rq(struct blk_mq_hw_ctx *hctx,
    705				 const struct blk_mq_queue_data *bd)
    706{
    707	struct pcd_unit *cd = hctx->queue->queuedata;
    708
    709	if (rq_data_dir(bd->rq) != READ) {
    710		blk_mq_start_request(bd->rq);
    711		return BLK_STS_IOERR;
    712	}
    713
    714	spin_lock_irq(&pcd_lock);
    715	list_add_tail(&bd->rq->queuelist, &cd->rq_list);
    716	pcd_request();
    717	spin_unlock_irq(&pcd_lock);
    718
    719	return BLK_STS_OK;
    720}
    721
    722static inline void next_request(blk_status_t err)
    723{
    724	unsigned long saved_flags;
    725
    726	spin_lock_irqsave(&pcd_lock, saved_flags);
    727	if (!blk_update_request(pcd_req, err, blk_rq_cur_bytes(pcd_req))) {
    728		__blk_mq_end_request(pcd_req, err);
    729		pcd_req = NULL;
    730	}
    731	pcd_busy = 0;
    732	pcd_request();
    733	spin_unlock_irqrestore(&pcd_lock, saved_flags);
    734}
    735
    736static int pcd_ready(void)
    737{
    738	return (((status_reg(pcd_current) & (IDE_BUSY | IDE_DRQ)) == IDE_DRQ));
    739}
    740
    741static void pcd_transfer(void)
    742{
    743
    744	while (pcd_count && (pcd_sector / 4 == pcd_bufblk)) {
    745		int o = (pcd_sector % 4) * 512;
    746		memcpy(pcd_buf, pcd_buffer + o, 512);
    747		pcd_count--;
    748		pcd_buf += 512;
    749		pcd_sector++;
    750	}
    751}
    752
    753static void pcd_start(void)
    754{
    755	int b, i;
    756	char rd_cmd[12] = { 0xa8, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 };
    757
    758	pcd_bufblk = pcd_sector / 4;
    759	b = pcd_bufblk;
    760	for (i = 0; i < 4; i++) {
    761		rd_cmd[5 - i] = b & 0xff;
    762		b = b >> 8;
    763	}
    764
    765	if (pcd_command(pcd_current, rd_cmd, 2048, "read block")) {
    766		pcd_bufblk = -1;
    767		next_request(BLK_STS_IOERR);
    768		return;
    769	}
    770
    771	mdelay(1);
    772
    773	ps_set_intr(do_pcd_read_drq, pcd_ready, PCD_TMO, nice);
    774}
    775
    776static void do_pcd_read(void)
    777{
    778	pcd_busy = 1;
    779	pcd_retries = 0;
    780	pcd_transfer();
    781	if (!pcd_count) {
    782		next_request(0);
    783		return;
    784	}
    785
    786	pi_do_claimed(pcd_current->pi, pcd_start);
    787}
    788
    789static void do_pcd_read_drq(void)
    790{
    791	unsigned long saved_flags;
    792
    793	if (pcd_completion(pcd_current, pcd_buffer, "read block")) {
    794		if (pcd_retries < PCD_RETRIES) {
    795			mdelay(1);
    796			pcd_retries++;
    797			pi_do_claimed(pcd_current->pi, pcd_start);
    798			return;
    799		}
    800		pcd_bufblk = -1;
    801		next_request(BLK_STS_IOERR);
    802		return;
    803	}
    804
    805	do_pcd_read();
    806	spin_lock_irqsave(&pcd_lock, saved_flags);
    807	pcd_request();
    808	spin_unlock_irqrestore(&pcd_lock, saved_flags);
    809}
    810
    811/* the audio_ioctl stuff is adapted from sr_ioctl.c */
    812
    813static int pcd_audio_ioctl(struct cdrom_device_info *cdi, unsigned int cmd, void *arg)
    814{
    815	struct pcd_unit *cd = cdi->handle;
    816
    817	switch (cmd) {
    818
    819	case CDROMREADTOCHDR:
    820
    821		{
    822			char cmd[12] =
    823			    { GPCMD_READ_TOC_PMA_ATIP, 0, 0, 0, 0, 0, 0, 0, 12,
    824			 0, 0, 0 };
    825			struct cdrom_tochdr *tochdr =
    826			    (struct cdrom_tochdr *) arg;
    827			char buffer[32];
    828			int r;
    829
    830			r = pcd_atapi(cd, cmd, 12, buffer, "read toc header");
    831
    832			tochdr->cdth_trk0 = buffer[2];
    833			tochdr->cdth_trk1 = buffer[3];
    834
    835			return r ? -EIO : 0;
    836		}
    837
    838	case CDROMREADTOCENTRY:
    839
    840		{
    841			char cmd[12] =
    842			    { GPCMD_READ_TOC_PMA_ATIP, 0, 0, 0, 0, 0, 0, 0, 12,
    843			 0, 0, 0 };
    844
    845			struct cdrom_tocentry *tocentry =
    846			    (struct cdrom_tocentry *) arg;
    847			unsigned char buffer[32];
    848			int r;
    849
    850			cmd[1] =
    851			    (tocentry->cdte_format == CDROM_MSF ? 0x02 : 0);
    852			cmd[6] = tocentry->cdte_track;
    853
    854			r = pcd_atapi(cd, cmd, 12, buffer, "read toc entry");
    855
    856			tocentry->cdte_ctrl = buffer[5] & 0xf;
    857			tocentry->cdte_adr = buffer[5] >> 4;
    858			tocentry->cdte_datamode =
    859			    (tocentry->cdte_ctrl & 0x04) ? 1 : 0;
    860			if (tocentry->cdte_format == CDROM_MSF) {
    861				tocentry->cdte_addr.msf.minute = buffer[9];
    862				tocentry->cdte_addr.msf.second = buffer[10];
    863				tocentry->cdte_addr.msf.frame = buffer[11];
    864			} else
    865				tocentry->cdte_addr.lba =
    866				    (((((buffer[8] << 8) + buffer[9]) << 8)
    867				      + buffer[10]) << 8) + buffer[11];
    868
    869			return r ? -EIO : 0;
    870		}
    871
    872	default:
    873
    874		return -ENOSYS;
    875	}
    876}
    877
    878static int pcd_get_mcn(struct cdrom_device_info *cdi, struct cdrom_mcn *mcn)
    879{
    880	char cmd[12] =
    881	    { GPCMD_READ_SUBCHANNEL, 0, 0x40, 2, 0, 0, 0, 0, 24, 0, 0, 0 };
    882	char buffer[32];
    883
    884	if (pcd_atapi(cdi->handle, cmd, 24, buffer, "get mcn"))
    885		return -EIO;
    886
    887	memcpy(mcn->medium_catalog_number, buffer + 9, 13);
    888	mcn->medium_catalog_number[13] = 0;
    889
    890	return 0;
    891}
    892
    893static int pcd_init_unit(struct pcd_unit *cd, bool autoprobe, int port,
    894		int mode, int unit, int protocol, int delay, int ms)
    895{
    896	struct gendisk *disk;
    897	int ret;
    898
    899	ret = blk_mq_alloc_sq_tag_set(&cd->tag_set, &pcd_mq_ops, 1,
    900				      BLK_MQ_F_SHOULD_MERGE);
    901	if (ret)
    902		return ret;
    903
    904	disk = blk_mq_alloc_disk(&cd->tag_set, cd);
    905	if (IS_ERR(disk)) {
    906		ret = PTR_ERR(disk);
    907		goto out_free_tag_set;
    908	}
    909
    910	INIT_LIST_HEAD(&cd->rq_list);
    911	blk_queue_bounce_limit(disk->queue, BLK_BOUNCE_HIGH);
    912	cd->disk = disk;
    913	cd->pi = &cd->pia;
    914	cd->present = 0;
    915	cd->last_sense = 0;
    916	cd->changed = 1;
    917	cd->drive = (*drives[cd - pcd])[D_SLV];
    918
    919	cd->name = &cd->info.name[0];
    920	snprintf(cd->name, sizeof(cd->info.name), "%s%d", name, unit);
    921	cd->info.ops = &pcd_dops;
    922	cd->info.handle = cd;
    923	cd->info.speed = 0;
    924	cd->info.capacity = 1;
    925	cd->info.mask = 0;
    926	disk->major = major;
    927	disk->first_minor = unit;
    928	disk->minors = 1;
    929	strcpy(disk->disk_name, cd->name);	/* umm... */
    930	disk->fops = &pcd_bdops;
    931	disk->flags |= GENHD_FL_NO_PART;
    932	disk->events = DISK_EVENT_MEDIA_CHANGE;
    933	disk->event_flags = DISK_EVENT_FLAG_BLOCK_ON_EXCL_WRITE;
    934
    935	if (!pi_init(cd->pi, autoprobe, port, mode, unit, protocol, delay,
    936			pcd_buffer, PI_PCD, verbose, cd->name)) {
    937		ret = -ENODEV;
    938		goto out_free_disk;
    939	}
    940	ret = pcd_probe(cd, ms);
    941	if (ret)
    942		goto out_pi_release;
    943
    944	cd->present = 1;
    945	pcd_probe_capabilities(cd);
    946	ret = register_cdrom(cd->disk, &cd->info);
    947	if (ret)
    948		goto out_pi_release;
    949	ret = add_disk(cd->disk);
    950	if (ret)
    951		goto out_unreg_cdrom;
    952	return 0;
    953
    954out_unreg_cdrom:
    955	unregister_cdrom(&cd->info);
    956out_pi_release:
    957	pi_release(cd->pi);
    958out_free_disk:
    959	blk_cleanup_disk(cd->disk);
    960out_free_tag_set:
    961	blk_mq_free_tag_set(&cd->tag_set);
    962	return ret;
    963}
    964
    965static int __init pcd_init(void)
    966{
    967	int found = 0, unit;
    968
    969	if (disable)
    970		return -EINVAL;
    971
    972	if (register_blkdev(major, name))
    973		return -EBUSY;
    974
    975	pr_info("%s: %s version %s, major %d, nice %d\n",
    976		name, name, PCD_VERSION, major, nice);
    977
    978	par_drv = pi_register_driver(name);
    979	if (!par_drv) {
    980		pr_err("failed to register %s driver\n", name);
    981		goto out_unregister_blkdev;
    982	}
    983
    984	for (unit = 0; unit < PCD_UNITS; unit++) {
    985		if ((*drives[unit])[D_PRT])
    986			pcd_drive_count++;
    987	}
    988
    989	if (pcd_drive_count == 0) { /* nothing spec'd - so autoprobe for 1 */
    990		if (!pcd_init_unit(pcd, 1, -1, -1, -1, -1, -1, -1))
    991			found++;
    992	} else {
    993		for (unit = 0; unit < PCD_UNITS; unit++) {
    994			struct pcd_unit *cd = &pcd[unit];
    995			int *conf = *drives[unit];
    996
    997			if (!conf[D_PRT])
    998				continue;
    999			if (!pcd_init_unit(cd, 0, conf[D_PRT], conf[D_MOD],
   1000					conf[D_UNI], conf[D_PRO], conf[D_DLY],
   1001					conf[D_SLV]))
   1002				found++;
   1003		}
   1004	}
   1005
   1006	if (!found) {
   1007		pr_info("%s: No CD-ROM drive found\n", name);
   1008		goto out_unregister_pi_driver;
   1009	}
   1010
   1011	return 0;
   1012
   1013out_unregister_pi_driver:
   1014	pi_unregister_driver(par_drv);
   1015out_unregister_blkdev:
   1016	unregister_blkdev(major, name);
   1017	return -ENODEV;
   1018}
   1019
   1020static void __exit pcd_exit(void)
   1021{
   1022	struct pcd_unit *cd;
   1023	int unit;
   1024
   1025	for (unit = 0, cd = pcd; unit < PCD_UNITS; unit++, cd++) {
   1026		if (!cd->present)
   1027			continue;
   1028
   1029		unregister_cdrom(&cd->info);
   1030		del_gendisk(cd->disk);
   1031		pi_release(cd->pi);
   1032		blk_cleanup_disk(cd->disk);
   1033
   1034		blk_mq_free_tag_set(&cd->tag_set);
   1035	}
   1036	pi_unregister_driver(par_drv);
   1037	unregister_blkdev(major, name);
   1038}
   1039
   1040MODULE_LICENSE("GPL");
   1041module_init(pcd_init)
   1042module_exit(pcd_exit)