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 overide 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 
114 static int verbose = 0;
115 static int major = PCD_MAJOR;
116 static char *name = PCD_NAME;
117 static int nice = 0;
118 static int disable = 0;
119 
120 static int drive0[6] = { 0, 0, 0, -1, -1, -1 };
121 static int drive1[6] = { 0, 0, 0, -1, -1, -1 };
122 static int drive2[6] = { 0, 0, 0, -1, -1, -1 };
123 static int drive3[6] = { 0, 0, 0, -1, -1, -1 };
124 
125 static int (*drives[4])[6] = {&drive0, &drive1, &drive2, &drive3};
126 static int pcd_drive_count;
127 
128 enum {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/blkdev.h>
141 #include <linux/mutex.h>
142 #include <asm/uaccess.h>
143 
144 static DEFINE_MUTEX(pcd_mutex);
145 static DEFINE_SPINLOCK(pcd_lock);
146 
147 module_param(verbose, int, 0644);
148 module_param(major, int, 0);
149 module_param(name, charp, 0);
150 module_param(nice, int, 0);
151 module_param_array(drive0, int, NULL, 0);
152 module_param_array(drive1, int, NULL, 0);
153 module_param_array(drive2, int, NULL, 0);
154 module_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 
172 static int pcd_open(struct cdrom_device_info *cdi, int purpose);
173 static void pcd_release(struct cdrom_device_info *cdi);
174 static int pcd_drive_status(struct cdrom_device_info *cdi, int slot_nr);
175 static unsigned int pcd_check_events(struct cdrom_device_info *cdi,
176 				     unsigned int clearing, int slot_nr);
177 static int pcd_tray_move(struct cdrom_device_info *cdi, int position);
178 static int pcd_lock_door(struct cdrom_device_info *cdi, int lock);
179 static int pcd_drive_reset(struct cdrom_device_info *cdi);
180 static int pcd_get_mcn(struct cdrom_device_info *cdi, struct cdrom_mcn *mcn);
181 static int pcd_audio_ioctl(struct cdrom_device_info *cdi,
182 			   unsigned int cmd, void *arg);
183 static int pcd_packet(struct cdrom_device_info *cdi,
184 		      struct packet_command *cgc);
185 
186 static int pcd_detect(void);
187 static void pcd_probe_capabilities(void);
188 static void do_pcd_read_drq(void);
189 static void do_pcd_request(struct request_queue * q);
190 static void do_pcd_read(void);
191 
192 struct pcd_unit {
193 	struct pi_adapter pia;	/* interface to paride layer */
194 	struct pi_adapter *pi;
195 	int drive;		/* master/slave */
196 	int last_sense;		/* result of last request sense */
197 	int changed;		/* media change seen */
198 	int present;		/* does this unit exist ? */
199 	char *name;		/* pcd0, pcd1, etc */
200 	struct cdrom_device_info info;	/* uniform cdrom interface */
201 	struct gendisk *disk;
202 };
203 
204 static struct pcd_unit pcd[PCD_UNITS];
205 
206 static char pcd_scratch[64];
207 static char pcd_buffer[2048];	/* raw block buffer */
208 static int pcd_bufblk = -1;	/* block in buffer, in CD units,
209 				   -1 for nothing there. See also
210 				   pd_unit.
211 				 */
212 
213 /* the variables below are used mainly in the I/O request engine, which
214    processes only one request at a time.
215 */
216 
217 static struct pcd_unit *pcd_current; /* current request's drive */
218 static struct request *pcd_req;
219 static int pcd_retries;		/* retries on current request */
220 static int pcd_busy;		/* request being processed ? */
221 static int pcd_sector;		/* address of next requested sector */
222 static int pcd_count;		/* number of blocks still to do */
223 static char *pcd_buf;		/* buffer for request in progress */
224 
225 /* kernel glue structures */
226 
pcd_block_open(struct block_device * bdev,fmode_t mode)227 static int pcd_block_open(struct block_device *bdev, fmode_t mode)
228 {
229 	struct pcd_unit *cd = bdev->bd_disk->private_data;
230 	int ret;
231 
232 	mutex_lock(&pcd_mutex);
233 	ret = cdrom_open(&cd->info, bdev, mode);
234 	mutex_unlock(&pcd_mutex);
235 
236 	return ret;
237 }
238 
pcd_block_release(struct gendisk * disk,fmode_t mode)239 static void pcd_block_release(struct gendisk *disk, fmode_t mode)
240 {
241 	struct pcd_unit *cd = disk->private_data;
242 	mutex_lock(&pcd_mutex);
243 	cdrom_release(&cd->info, mode);
244 	mutex_unlock(&pcd_mutex);
245 }
246 
pcd_block_ioctl(struct block_device * bdev,fmode_t mode,unsigned cmd,unsigned long arg)247 static int pcd_block_ioctl(struct block_device *bdev, fmode_t mode,
248 				unsigned cmd, unsigned long arg)
249 {
250 	struct pcd_unit *cd = bdev->bd_disk->private_data;
251 	int ret;
252 
253 	mutex_lock(&pcd_mutex);
254 	ret = cdrom_ioctl(&cd->info, bdev, mode, cmd, arg);
255 	mutex_unlock(&pcd_mutex);
256 
257 	return ret;
258 }
259 
pcd_block_check_events(struct gendisk * disk,unsigned int clearing)260 static unsigned int pcd_block_check_events(struct gendisk *disk,
261 					   unsigned int clearing)
262 {
263 	struct pcd_unit *cd = disk->private_data;
264 	return cdrom_check_events(&cd->info, clearing);
265 }
266 
267 static const struct block_device_operations pcd_bdops = {
268 	.owner		= THIS_MODULE,
269 	.open		= pcd_block_open,
270 	.release	= pcd_block_release,
271 	.ioctl		= pcd_block_ioctl,
272 	.check_events	= pcd_block_check_events,
273 };
274 
275 static struct cdrom_device_ops pcd_dops = {
276 	.open		= pcd_open,
277 	.release	= pcd_release,
278 	.drive_status	= pcd_drive_status,
279 	.check_events	= pcd_check_events,
280 	.tray_move	= pcd_tray_move,
281 	.lock_door	= pcd_lock_door,
282 	.get_mcn	= pcd_get_mcn,
283 	.reset		= pcd_drive_reset,
284 	.audio_ioctl	= pcd_audio_ioctl,
285 	.generic_packet	= pcd_packet,
286 	.capability	= CDC_CLOSE_TRAY | CDC_OPEN_TRAY | CDC_LOCK |
287 			  CDC_MCN | CDC_MEDIA_CHANGED | CDC_RESET |
288 			  CDC_PLAY_AUDIO | CDC_GENERIC_PACKET | CDC_CD_R |
289 			  CDC_CD_RW,
290 };
291 
pcd_init_units(void)292 static void pcd_init_units(void)
293 {
294 	struct pcd_unit *cd;
295 	int unit;
296 
297 	pcd_drive_count = 0;
298 	for (unit = 0, cd = pcd; unit < PCD_UNITS; unit++, cd++) {
299 		struct gendisk *disk = alloc_disk(1);
300 		if (!disk)
301 			continue;
302 		cd->disk = disk;
303 		cd->pi = &cd->pia;
304 		cd->present = 0;
305 		cd->last_sense = 0;
306 		cd->changed = 1;
307 		cd->drive = (*drives[unit])[D_SLV];
308 		if ((*drives[unit])[D_PRT])
309 			pcd_drive_count++;
310 
311 		cd->name = &cd->info.name[0];
312 		snprintf(cd->name, sizeof(cd->info.name), "%s%d", name, unit);
313 		cd->info.ops = &pcd_dops;
314 		cd->info.handle = cd;
315 		cd->info.speed = 0;
316 		cd->info.capacity = 1;
317 		cd->info.mask = 0;
318 		disk->major = major;
319 		disk->first_minor = unit;
320 		strcpy(disk->disk_name, cd->name);	/* umm... */
321 		disk->fops = &pcd_bdops;
322 		disk->flags = GENHD_FL_BLOCK_EVENTS_ON_EXCL_WRITE;
323 	}
324 }
325 
pcd_open(struct cdrom_device_info * cdi,int purpose)326 static int pcd_open(struct cdrom_device_info *cdi, int purpose)
327 {
328 	struct pcd_unit *cd = cdi->handle;
329 	if (!cd->present)
330 		return -ENODEV;
331 	return 0;
332 }
333 
pcd_release(struct cdrom_device_info * cdi)334 static void pcd_release(struct cdrom_device_info *cdi)
335 {
336 }
337 
status_reg(struct pcd_unit * cd)338 static inline int status_reg(struct pcd_unit *cd)
339 {
340 	return pi_read_regr(cd->pi, 1, 6);
341 }
342 
read_reg(struct pcd_unit * cd,int reg)343 static inline int read_reg(struct pcd_unit *cd, int reg)
344 {
345 	return pi_read_regr(cd->pi, 0, reg);
346 }
347 
write_reg(struct pcd_unit * cd,int reg,int val)348 static inline void write_reg(struct pcd_unit *cd, int reg, int val)
349 {
350 	pi_write_regr(cd->pi, 0, reg, val);
351 }
352 
pcd_wait(struct pcd_unit * cd,int go,int stop,char * fun,char * msg)353 static int pcd_wait(struct pcd_unit *cd, int go, int stop, char *fun, char *msg)
354 {
355 	int j, r, e, s, p;
356 
357 	j = 0;
358 	while ((((r = status_reg(cd)) & go) || (stop && (!(r & stop))))
359 	       && (j++ < PCD_SPIN))
360 		udelay(PCD_DELAY);
361 
362 	if ((r & (IDE_ERR & stop)) || (j > PCD_SPIN)) {
363 		s = read_reg(cd, 7);
364 		e = read_reg(cd, 1);
365 		p = read_reg(cd, 2);
366 		if (j > PCD_SPIN)
367 			e |= 0x100;
368 		if (fun)
369 			printk("%s: %s %s: alt=0x%x stat=0x%x err=0x%x"
370 			       " loop=%d phase=%d\n",
371 			       cd->name, fun, msg, r, s, e, j, p);
372 		return (s << 8) + r;
373 	}
374 	return 0;
375 }
376 
pcd_command(struct pcd_unit * cd,char * cmd,int dlen,char * fun)377 static int pcd_command(struct pcd_unit *cd, char *cmd, int dlen, char *fun)
378 {
379 	pi_connect(cd->pi);
380 
381 	write_reg(cd, 6, 0xa0 + 0x10 * cd->drive);
382 
383 	if (pcd_wait(cd, IDE_BUSY | IDE_DRQ, 0, fun, "before command")) {
384 		pi_disconnect(cd->pi);
385 		return -1;
386 	}
387 
388 	write_reg(cd, 4, dlen % 256);
389 	write_reg(cd, 5, dlen / 256);
390 	write_reg(cd, 7, 0xa0);	/* ATAPI packet command */
391 
392 	if (pcd_wait(cd, IDE_BUSY, IDE_DRQ, fun, "command DRQ")) {
393 		pi_disconnect(cd->pi);
394 		return -1;
395 	}
396 
397 	if (read_reg(cd, 2) != 1) {
398 		printk("%s: %s: command phase error\n", cd->name, fun);
399 		pi_disconnect(cd->pi);
400 		return -1;
401 	}
402 
403 	pi_write_block(cd->pi, cmd, 12);
404 
405 	return 0;
406 }
407 
pcd_completion(struct pcd_unit * cd,char * buf,char * fun)408 static int pcd_completion(struct pcd_unit *cd, char *buf, char *fun)
409 {
410 	int r, d, p, n, k, j;
411 
412 	r = -1;
413 	k = 0;
414 	j = 0;
415 
416 	if (!pcd_wait(cd, IDE_BUSY, IDE_DRQ | IDE_READY | IDE_ERR,
417 		      fun, "completion")) {
418 		r = 0;
419 		while (read_reg(cd, 7) & IDE_DRQ) {
420 			d = read_reg(cd, 4) + 256 * read_reg(cd, 5);
421 			n = (d + 3) & 0xfffc;
422 			p = read_reg(cd, 2) & 3;
423 
424 			if ((p == 2) && (n > 0) && (j == 0)) {
425 				pi_read_block(cd->pi, buf, n);
426 				if (verbose > 1)
427 					printk("%s: %s: Read %d bytes\n",
428 					       cd->name, fun, n);
429 				r = 0;
430 				j++;
431 			} else {
432 				if (verbose > 1)
433 					printk
434 					    ("%s: %s: Unexpected phase %d, d=%d, k=%d\n",
435 					     cd->name, fun, p, d, k);
436 				if (verbose < 2)
437 					printk_once(
438 					    "%s: WARNING: ATAPI phase errors\n",
439 					    cd->name);
440 				mdelay(1);
441 			}
442 			if (k++ > PCD_TMO) {
443 				printk("%s: Stuck DRQ\n", cd->name);
444 				break;
445 			}
446 			if (pcd_wait
447 			    (cd, IDE_BUSY, IDE_DRQ | IDE_READY | IDE_ERR, fun,
448 			     "completion")) {
449 				r = -1;
450 				break;
451 			}
452 		}
453 	}
454 
455 	pi_disconnect(cd->pi);
456 
457 	return r;
458 }
459 
pcd_req_sense(struct pcd_unit * cd,char * fun)460 static void pcd_req_sense(struct pcd_unit *cd, char *fun)
461 {
462 	char rs_cmd[12] = { 0x03, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0 };
463 	char buf[16];
464 	int r, c;
465 
466 	r = pcd_command(cd, rs_cmd, 16, "Request sense");
467 	mdelay(1);
468 	if (!r)
469 		pcd_completion(cd, buf, "Request sense");
470 
471 	cd->last_sense = -1;
472 	c = 2;
473 	if (!r) {
474 		if (fun)
475 			printk("%s: %s: Sense key: %x, ASC: %x, ASQ: %x\n",
476 			       cd->name, fun, buf[2] & 0xf, buf[12], buf[13]);
477 		c = buf[2] & 0xf;
478 		cd->last_sense =
479 		    c | ((buf[12] & 0xff) << 8) | ((buf[13] & 0xff) << 16);
480 	}
481 	if ((c == 2) || (c == 6))
482 		cd->changed = 1;
483 }
484 
pcd_atapi(struct pcd_unit * cd,char * cmd,int dlen,char * buf,char * fun)485 static int pcd_atapi(struct pcd_unit *cd, char *cmd, int dlen, char *buf, char *fun)
486 {
487 	int r;
488 
489 	r = pcd_command(cd, cmd, dlen, fun);
490 	mdelay(1);
491 	if (!r)
492 		r = pcd_completion(cd, buf, fun);
493 	if (r)
494 		pcd_req_sense(cd, fun);
495 
496 	return r;
497 }
498 
pcd_packet(struct cdrom_device_info * cdi,struct packet_command * cgc)499 static int pcd_packet(struct cdrom_device_info *cdi, struct packet_command *cgc)
500 {
501 	return pcd_atapi(cdi->handle, cgc->cmd, cgc->buflen, cgc->buffer,
502 			 "generic packet");
503 }
504 
505 #define DBMSG(msg)	((verbose>1)?(msg):NULL)
506 
pcd_check_events(struct cdrom_device_info * cdi,unsigned int clearing,int slot_nr)507 static unsigned int pcd_check_events(struct cdrom_device_info *cdi,
508 				     unsigned int clearing, int slot_nr)
509 {
510 	struct pcd_unit *cd = cdi->handle;
511 	int res = cd->changed;
512 	if (res)
513 		cd->changed = 0;
514 	return res ? DISK_EVENT_MEDIA_CHANGE : 0;
515 }
516 
pcd_lock_door(struct cdrom_device_info * cdi,int lock)517 static int pcd_lock_door(struct cdrom_device_info *cdi, int lock)
518 {
519 	char un_cmd[12] = { 0x1e, 0, 0, 0, lock, 0, 0, 0, 0, 0, 0, 0 };
520 
521 	return pcd_atapi(cdi->handle, un_cmd, 0, pcd_scratch,
522 			 lock ? "lock door" : "unlock door");
523 }
524 
pcd_tray_move(struct cdrom_device_info * cdi,int position)525 static int pcd_tray_move(struct cdrom_device_info *cdi, int position)
526 {
527 	char ej_cmd[12] = { 0x1b, 0, 0, 0, 3 - position, 0, 0, 0, 0, 0, 0, 0 };
528 
529 	return pcd_atapi(cdi->handle, ej_cmd, 0, pcd_scratch,
530 			 position ? "eject" : "close tray");
531 }
532 
pcd_sleep(int cs)533 static void pcd_sleep(int cs)
534 {
535 	schedule_timeout_interruptible(cs);
536 }
537 
pcd_reset(struct pcd_unit * cd)538 static int pcd_reset(struct pcd_unit *cd)
539 {
540 	int i, k, flg;
541 	int expect[5] = { 1, 1, 1, 0x14, 0xeb };
542 
543 	pi_connect(cd->pi);
544 	write_reg(cd, 6, 0xa0 + 0x10 * cd->drive);
545 	write_reg(cd, 7, 8);
546 
547 	pcd_sleep(20 * HZ / 1000);	/* delay a bit */
548 
549 	k = 0;
550 	while ((k++ < PCD_RESET_TMO) && (status_reg(cd) & IDE_BUSY))
551 		pcd_sleep(HZ / 10);
552 
553 	flg = 1;
554 	for (i = 0; i < 5; i++)
555 		flg &= (read_reg(cd, i + 1) == expect[i]);
556 
557 	if (verbose) {
558 		printk("%s: Reset (%d) signature = ", cd->name, k);
559 		for (i = 0; i < 5; i++)
560 			printk("%3x", read_reg(cd, i + 1));
561 		if (!flg)
562 			printk(" (incorrect)");
563 		printk("\n");
564 	}
565 
566 	pi_disconnect(cd->pi);
567 	return flg - 1;
568 }
569 
pcd_drive_reset(struct cdrom_device_info * cdi)570 static int pcd_drive_reset(struct cdrom_device_info *cdi)
571 {
572 	return pcd_reset(cdi->handle);
573 }
574 
pcd_ready_wait(struct pcd_unit * cd,int tmo)575 static int pcd_ready_wait(struct pcd_unit *cd, int tmo)
576 {
577 	char tr_cmd[12] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
578 	int k, p;
579 
580 	k = 0;
581 	while (k < tmo) {
582 		cd->last_sense = 0;
583 		pcd_atapi(cd, tr_cmd, 0, NULL, DBMSG("test unit ready"));
584 		p = cd->last_sense;
585 		if (!p)
586 			return 0;
587 		if (!(((p & 0xffff) == 0x0402) || ((p & 0xff) == 6)))
588 			return p;
589 		k++;
590 		pcd_sleep(HZ);
591 	}
592 	return 0x000020;	/* timeout */
593 }
594 
pcd_drive_status(struct cdrom_device_info * cdi,int slot_nr)595 static int pcd_drive_status(struct cdrom_device_info *cdi, int slot_nr)
596 {
597 	char rc_cmd[12] = { 0x25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
598 	struct pcd_unit *cd = cdi->handle;
599 
600 	if (pcd_ready_wait(cd, PCD_READY_TMO))
601 		return CDS_DRIVE_NOT_READY;
602 	if (pcd_atapi(cd, rc_cmd, 8, pcd_scratch, DBMSG("check media")))
603 		return CDS_NO_DISC;
604 	return CDS_DISC_OK;
605 }
606 
pcd_identify(struct pcd_unit * cd,char * id)607 static int pcd_identify(struct pcd_unit *cd, char *id)
608 {
609 	int k, s;
610 	char id_cmd[12] = { 0x12, 0, 0, 0, 36, 0, 0, 0, 0, 0, 0, 0 };
611 
612 	pcd_bufblk = -1;
613 
614 	s = pcd_atapi(cd, id_cmd, 36, pcd_buffer, "identify");
615 
616 	if (s)
617 		return -1;
618 	if ((pcd_buffer[0] & 0x1f) != 5) {
619 		if (verbose)
620 			printk("%s: %s is not a CD-ROM\n",
621 			       cd->name, cd->drive ? "Slave" : "Master");
622 		return -1;
623 	}
624 	memcpy(id, pcd_buffer + 16, 16);
625 	id[16] = 0;
626 	k = 16;
627 	while ((k >= 0) && (id[k] <= 0x20)) {
628 		id[k] = 0;
629 		k--;
630 	}
631 
632 	printk("%s: %s: %s\n", cd->name, cd->drive ? "Slave" : "Master", id);
633 
634 	return 0;
635 }
636 
637 /*
638  * returns  0, with id set if drive is detected
639  *	    -1, if drive detection failed
640  */
pcd_probe(struct pcd_unit * cd,int ms,char * id)641 static int pcd_probe(struct pcd_unit *cd, int ms, char *id)
642 {
643 	if (ms == -1) {
644 		for (cd->drive = 0; cd->drive <= 1; cd->drive++)
645 			if (!pcd_reset(cd) && !pcd_identify(cd, id))
646 				return 0;
647 	} else {
648 		cd->drive = ms;
649 		if (!pcd_reset(cd) && !pcd_identify(cd, id))
650 			return 0;
651 	}
652 	return -1;
653 }
654 
pcd_probe_capabilities(void)655 static void pcd_probe_capabilities(void)
656 {
657 	int unit, r;
658 	char buffer[32];
659 	char cmd[12] = { 0x5a, 1 << 3, 0x2a, 0, 0, 0, 0, 18, 0, 0, 0, 0 };
660 	struct pcd_unit *cd;
661 
662 	for (unit = 0, cd = pcd; unit < PCD_UNITS; unit++, cd++) {
663 		if (!cd->present)
664 			continue;
665 		r = pcd_atapi(cd, cmd, 18, buffer, "mode sense capabilities");
666 		if (r)
667 			continue;
668 		/* we should now have the cap page */
669 		if ((buffer[11] & 1) == 0)
670 			cd->info.mask |= CDC_CD_R;
671 		if ((buffer[11] & 2) == 0)
672 			cd->info.mask |= CDC_CD_RW;
673 		if ((buffer[12] & 1) == 0)
674 			cd->info.mask |= CDC_PLAY_AUDIO;
675 		if ((buffer[14] & 1) == 0)
676 			cd->info.mask |= CDC_LOCK;
677 		if ((buffer[14] & 8) == 0)
678 			cd->info.mask |= CDC_OPEN_TRAY;
679 		if ((buffer[14] >> 6) == 0)
680 			cd->info.mask |= CDC_CLOSE_TRAY;
681 	}
682 }
683 
pcd_detect(void)684 static int pcd_detect(void)
685 {
686 	char id[18];
687 	int k, unit;
688 	struct pcd_unit *cd;
689 
690 	printk("%s: %s version %s, major %d, nice %d\n",
691 	       name, name, PCD_VERSION, major, nice);
692 
693 	k = 0;
694 	if (pcd_drive_count == 0) { /* nothing spec'd - so autoprobe for 1 */
695 		cd = pcd;
696 		if (pi_init(cd->pi, 1, -1, -1, -1, -1, -1, pcd_buffer,
697 			    PI_PCD, verbose, cd->name)) {
698 			if (!pcd_probe(cd, -1, id) && cd->disk) {
699 				cd->present = 1;
700 				k++;
701 			} else
702 				pi_release(cd->pi);
703 		}
704 	} else {
705 		for (unit = 0, cd = pcd; unit < PCD_UNITS; unit++, cd++) {
706 			int *conf = *drives[unit];
707 			if (!conf[D_PRT])
708 				continue;
709 			if (!pi_init(cd->pi, 0, conf[D_PRT], conf[D_MOD],
710 				     conf[D_UNI], conf[D_PRO], conf[D_DLY],
711 				     pcd_buffer, PI_PCD, verbose, cd->name))
712 				continue;
713 			if (!pcd_probe(cd, conf[D_SLV], id) && cd->disk) {
714 				cd->present = 1;
715 				k++;
716 			} else
717 				pi_release(cd->pi);
718 		}
719 	}
720 	if (k)
721 		return 0;
722 
723 	printk("%s: No CD-ROM drive found\n", name);
724 	for (unit = 0, cd = pcd; unit < PCD_UNITS; unit++, cd++)
725 		put_disk(cd->disk);
726 	return -1;
727 }
728 
729 /* I/O request processing */
730 static struct request_queue *pcd_queue;
731 
do_pcd_request(struct request_queue * q)732 static void do_pcd_request(struct request_queue * q)
733 {
734 	if (pcd_busy)
735 		return;
736 	while (1) {
737 		if (!pcd_req) {
738 			pcd_req = blk_fetch_request(q);
739 			if (!pcd_req)
740 				return;
741 		}
742 
743 		if (rq_data_dir(pcd_req) == READ) {
744 			struct pcd_unit *cd = pcd_req->rq_disk->private_data;
745 			if (cd != pcd_current)
746 				pcd_bufblk = -1;
747 			pcd_current = cd;
748 			pcd_sector = blk_rq_pos(pcd_req);
749 			pcd_count = blk_rq_cur_sectors(pcd_req);
750 			pcd_buf = bio_data(pcd_req->bio);
751 			pcd_busy = 1;
752 			ps_set_intr(do_pcd_read, NULL, 0, nice);
753 			return;
754 		} else {
755 			__blk_end_request_all(pcd_req, -EIO);
756 			pcd_req = NULL;
757 		}
758 	}
759 }
760 
next_request(int err)761 static inline void next_request(int err)
762 {
763 	unsigned long saved_flags;
764 
765 	spin_lock_irqsave(&pcd_lock, saved_flags);
766 	if (!__blk_end_request_cur(pcd_req, err))
767 		pcd_req = NULL;
768 	pcd_busy = 0;
769 	do_pcd_request(pcd_queue);
770 	spin_unlock_irqrestore(&pcd_lock, saved_flags);
771 }
772 
pcd_ready(void)773 static int pcd_ready(void)
774 {
775 	return (((status_reg(pcd_current) & (IDE_BUSY | IDE_DRQ)) == IDE_DRQ));
776 }
777 
pcd_transfer(void)778 static void pcd_transfer(void)
779 {
780 
781 	while (pcd_count && (pcd_sector / 4 == pcd_bufblk)) {
782 		int o = (pcd_sector % 4) * 512;
783 		memcpy(pcd_buf, pcd_buffer + o, 512);
784 		pcd_count--;
785 		pcd_buf += 512;
786 		pcd_sector++;
787 	}
788 }
789 
pcd_start(void)790 static void pcd_start(void)
791 {
792 	int b, i;
793 	char rd_cmd[12] = { 0xa8, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 };
794 
795 	pcd_bufblk = pcd_sector / 4;
796 	b = pcd_bufblk;
797 	for (i = 0; i < 4; i++) {
798 		rd_cmd[5 - i] = b & 0xff;
799 		b = b >> 8;
800 	}
801 
802 	if (pcd_command(pcd_current, rd_cmd, 2048, "read block")) {
803 		pcd_bufblk = -1;
804 		next_request(-EIO);
805 		return;
806 	}
807 
808 	mdelay(1);
809 
810 	ps_set_intr(do_pcd_read_drq, pcd_ready, PCD_TMO, nice);
811 }
812 
do_pcd_read(void)813 static void do_pcd_read(void)
814 {
815 	pcd_busy = 1;
816 	pcd_retries = 0;
817 	pcd_transfer();
818 	if (!pcd_count) {
819 		next_request(0);
820 		return;
821 	}
822 
823 	pi_do_claimed(pcd_current->pi, pcd_start);
824 }
825 
do_pcd_read_drq(void)826 static void do_pcd_read_drq(void)
827 {
828 	unsigned long saved_flags;
829 
830 	if (pcd_completion(pcd_current, pcd_buffer, "read block")) {
831 		if (pcd_retries < PCD_RETRIES) {
832 			mdelay(1);
833 			pcd_retries++;
834 			pi_do_claimed(pcd_current->pi, pcd_start);
835 			return;
836 		}
837 		pcd_bufblk = -1;
838 		next_request(-EIO);
839 		return;
840 	}
841 
842 	do_pcd_read();
843 	spin_lock_irqsave(&pcd_lock, saved_flags);
844 	do_pcd_request(pcd_queue);
845 	spin_unlock_irqrestore(&pcd_lock, saved_flags);
846 }
847 
848 /* the audio_ioctl stuff is adapted from sr_ioctl.c */
849 
pcd_audio_ioctl(struct cdrom_device_info * cdi,unsigned int cmd,void * arg)850 static int pcd_audio_ioctl(struct cdrom_device_info *cdi, unsigned int cmd, void *arg)
851 {
852 	struct pcd_unit *cd = cdi->handle;
853 
854 	switch (cmd) {
855 
856 	case CDROMREADTOCHDR:
857 
858 		{
859 			char cmd[12] =
860 			    { GPCMD_READ_TOC_PMA_ATIP, 0, 0, 0, 0, 0, 0, 0, 12,
861 			 0, 0, 0 };
862 			struct cdrom_tochdr *tochdr =
863 			    (struct cdrom_tochdr *) arg;
864 			char buffer[32];
865 			int r;
866 
867 			r = pcd_atapi(cd, cmd, 12, buffer, "read toc header");
868 
869 			tochdr->cdth_trk0 = buffer[2];
870 			tochdr->cdth_trk1 = buffer[3];
871 
872 			return r ? -EIO : 0;
873 		}
874 
875 	case CDROMREADTOCENTRY:
876 
877 		{
878 			char cmd[12] =
879 			    { GPCMD_READ_TOC_PMA_ATIP, 0, 0, 0, 0, 0, 0, 0, 12,
880 			 0, 0, 0 };
881 
882 			struct cdrom_tocentry *tocentry =
883 			    (struct cdrom_tocentry *) arg;
884 			unsigned char buffer[32];
885 			int r;
886 
887 			cmd[1] =
888 			    (tocentry->cdte_format == CDROM_MSF ? 0x02 : 0);
889 			cmd[6] = tocentry->cdte_track;
890 
891 			r = pcd_atapi(cd, cmd, 12, buffer, "read toc entry");
892 
893 			tocentry->cdte_ctrl = buffer[5] & 0xf;
894 			tocentry->cdte_adr = buffer[5] >> 4;
895 			tocentry->cdte_datamode =
896 			    (tocentry->cdte_ctrl & 0x04) ? 1 : 0;
897 			if (tocentry->cdte_format == CDROM_MSF) {
898 				tocentry->cdte_addr.msf.minute = buffer[9];
899 				tocentry->cdte_addr.msf.second = buffer[10];
900 				tocentry->cdte_addr.msf.frame = buffer[11];
901 			} else
902 				tocentry->cdte_addr.lba =
903 				    (((((buffer[8] << 8) + buffer[9]) << 8)
904 				      + buffer[10]) << 8) + buffer[11];
905 
906 			return r ? -EIO : 0;
907 		}
908 
909 	default:
910 
911 		return -ENOSYS;
912 	}
913 }
914 
pcd_get_mcn(struct cdrom_device_info * cdi,struct cdrom_mcn * mcn)915 static int pcd_get_mcn(struct cdrom_device_info *cdi, struct cdrom_mcn *mcn)
916 {
917 	char cmd[12] =
918 	    { GPCMD_READ_SUBCHANNEL, 0, 0x40, 2, 0, 0, 0, 0, 24, 0, 0, 0 };
919 	char buffer[32];
920 
921 	if (pcd_atapi(cdi->handle, cmd, 24, buffer, "get mcn"))
922 		return -EIO;
923 
924 	memcpy(mcn->medium_catalog_number, buffer + 9, 13);
925 	mcn->medium_catalog_number[13] = 0;
926 
927 	return 0;
928 }
929 
pcd_init(void)930 static int __init pcd_init(void)
931 {
932 	struct pcd_unit *cd;
933 	int unit;
934 
935 	if (disable)
936 		return -EINVAL;
937 
938 	pcd_init_units();
939 
940 	if (pcd_detect())
941 		return -ENODEV;
942 
943 	/* get the atapi capabilities page */
944 	pcd_probe_capabilities();
945 
946 	if (register_blkdev(major, name)) {
947 		for (unit = 0, cd = pcd; unit < PCD_UNITS; unit++, cd++)
948 			put_disk(cd->disk);
949 		return -EBUSY;
950 	}
951 
952 	pcd_queue = blk_init_queue(do_pcd_request, &pcd_lock);
953 	if (!pcd_queue) {
954 		unregister_blkdev(major, name);
955 		for (unit = 0, cd = pcd; unit < PCD_UNITS; unit++, cd++)
956 			put_disk(cd->disk);
957 		return -ENOMEM;
958 	}
959 
960 	for (unit = 0, cd = pcd; unit < PCD_UNITS; unit++, cd++) {
961 		if (cd->present) {
962 			register_cdrom(&cd->info);
963 			cd->disk->private_data = cd;
964 			cd->disk->queue = pcd_queue;
965 			add_disk(cd->disk);
966 		}
967 	}
968 
969 	return 0;
970 }
971 
pcd_exit(void)972 static void __exit pcd_exit(void)
973 {
974 	struct pcd_unit *cd;
975 	int unit;
976 
977 	for (unit = 0, cd = pcd; unit < PCD_UNITS; unit++, cd++) {
978 		if (cd->present) {
979 			del_gendisk(cd->disk);
980 			pi_release(cd->pi);
981 			unregister_cdrom(&cd->info);
982 		}
983 		put_disk(cd->disk);
984 	}
985 	blk_cleanup_queue(pcd_queue);
986 	unregister_blkdev(major, name);
987 }
988 
989 MODULE_LICENSE("GPL");
990 module_init(pcd_init)
991 module_exit(pcd_exit)
992