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