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