]> bbs.cooldavid.org Git - net-next-2.6.git/blame - drivers/block/paride/pf.c
block: push down BKL into .locked_ioctl
[net-next-2.6.git] / drivers / block / paride / pf.c
CommitLineData
1da177e4
LT
1/*
2 pf.c (c) 1997-8 Grant R. Guenther <grant@torque.net>
3 Under the terms of the GNU General Public License.
4
5 This is the high-level driver for parallel port ATAPI disk
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 disk drive, but if their individual parameters are
10 specified, the driver can handle up to 4 drives.
11
12 The behaviour of the pf 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-7 integers as follows:
18 drive2
19 drive3 <prt>,<pro>,<uni>,<mod>,<slv>,<lun>,<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 CDroms 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 <lun> Some ATAPI devices support multiple LUNs.
47 One example is the ATAPI PD/CD drive from
48 Matshita/Panasonic. This device has a
49 CD drive on LUN 0 and a PD drive on LUN 1.
50 By default, the driver will search for the
51 first LUN with a supported device. Set
52 this parameter to force it to use a specific
53 LUN. (default -1)
54
55 <dly> some parallel ports require the driver to
56 go more slowly. -1 sets a default value that
57 should work with the chosen protocol. Otherwise,
58 set this to a small integer, the larger it is
59 the slower the port i/o. In some cases, setting
60 this to zero will speed up the device. (default -1)
61
62 major You may use this parameter to overide the
63 default major number (47) that this driver
64 will use. Be sure to change the device
65 name as well.
66
67 name This parameter is a character string that
68 contains the name the kernel will use for this
69 device (in /proc output, for instance).
70 (default "pf").
71
72 cluster The driver will attempt to aggregate requests
73 for adjacent blocks into larger multi-block
74 clusters. The maximum cluster size (in 512
75 byte sectors) is set with this parameter.
76 (default 64)
77
78 verbose This parameter controls the amount of logging
79 that the driver will do. Set it to 0 for
80 normal operation, 1 to see autoprobe progress
81 messages, or 2 to see additional debugging
82 output. (default 0)
83
84 nice This parameter controls the driver's use of
85 idle CPU time, at the expense of some speed.
86
87 If this driver is built into the kernel, you can use the
88 following command line parameters, with the same values
89 as the corresponding module parameters listed above:
90
91 pf.drive0
92 pf.drive1
93 pf.drive2
94 pf.drive3
95 pf.cluster
96 pf.nice
97
98 In addition, you can use the parameter pf.disable to disable
99 the driver entirely.
100
101*/
102
103/* Changes:
104
105 1.01 GRG 1998.05.03 Changes for SMP. Eliminate sti().
106 Fix for drives that don't clear STAT_ERR
107 until after next CDB delivered.
108 Small change in pf_completion to round
109 up transfer size.
110 1.02 GRG 1998.06.16 Eliminated an Ugh
111 1.03 GRG 1998.08.16 Use HZ in loop timings, extra debugging
112 1.04 GRG 1998.09.24 Added jumbo support
113
114*/
115
116#define PF_VERSION "1.04"
117#define PF_MAJOR 47
118#define PF_NAME "pf"
119#define PF_UNITS 4
120
121/* Here are things one can override from the insmod command.
122 Most are autoprobed by paride unless set here. Verbose is off
123 by default.
124
125*/
126
127static int verbose = 0;
128static int major = PF_MAJOR;
129static char *name = PF_NAME;
130static int cluster = 64;
131static int nice = 0;
132static int disable = 0;
133
134static int drive0[7] = { 0, 0, 0, -1, -1, -1, -1 };
135static int drive1[7] = { 0, 0, 0, -1, -1, -1, -1 };
136static int drive2[7] = { 0, 0, 0, -1, -1, -1, -1 };
137static int drive3[7] = { 0, 0, 0, -1, -1, -1, -1 };
138
139static int (*drives[4])[7] = {&drive0, &drive1, &drive2, &drive3};
140static int pf_drive_count;
141
142enum {D_PRT, D_PRO, D_UNI, D_MOD, D_SLV, D_LUN, D_DLY};
143
144/* end of parameters */
145
146#include <linux/module.h>
147#include <linux/init.h>
148#include <linux/fs.h>
149#include <linux/delay.h>
150#include <linux/hdreg.h>
151#include <linux/cdrom.h>
152#include <linux/spinlock.h>
153#include <linux/blkdev.h>
154#include <linux/blkpg.h>
8a6cfeb6 155#include <linux/smp_lock.h>
1da177e4
LT
156#include <asm/uaccess.h>
157
671d40f4 158static DEFINE_SPINLOCK(pf_spin_lock);
1da177e4
LT
159
160module_param(verbose, bool, 0644);
161module_param(major, int, 0);
162module_param(name, charp, 0);
163module_param(cluster, int, 0);
164module_param(nice, int, 0);
165module_param_array(drive0, int, NULL, 0);
166module_param_array(drive1, int, NULL, 0);
167module_param_array(drive2, int, NULL, 0);
168module_param_array(drive3, int, NULL, 0);
169
170#include "paride.h"
171#include "pseudo.h"
172
173/* constants for faking geometry numbers */
174
175#define PF_FD_MAX 8192 /* use FD geometry under this size */
176#define PF_FD_HDS 2
177#define PF_FD_SPT 18
178#define PF_HD_HDS 64
179#define PF_HD_SPT 32
180
181#define PF_MAX_RETRIES 5
182#define PF_TMO 800 /* interrupt timeout in jiffies */
183#define PF_SPIN_DEL 50 /* spin delay in micro-seconds */
184
185#define PF_SPIN (1000000*PF_TMO)/(HZ*PF_SPIN_DEL)
186
187#define STAT_ERR 0x00001
188#define STAT_INDEX 0x00002
189#define STAT_ECC 0x00004
190#define STAT_DRQ 0x00008
191#define STAT_SEEK 0x00010
192#define STAT_WRERR 0x00020
193#define STAT_READY 0x00040
194#define STAT_BUSY 0x00080
195
196#define ATAPI_REQ_SENSE 0x03
197#define ATAPI_LOCK 0x1e
198#define ATAPI_DOOR 0x1b
199#define ATAPI_MODE_SENSE 0x5a
200#define ATAPI_CAPACITY 0x25
201#define ATAPI_IDENTIFY 0x12
202#define ATAPI_READ_10 0x28
203#define ATAPI_WRITE_10 0x2a
204
8cfc7ca4 205static int pf_open(struct block_device *bdev, fmode_t mode);
165125e1 206static void do_pf_request(struct request_queue * q);
8cfc7ca4 207static int pf_ioctl(struct block_device *bdev, fmode_t mode,
1da177e4 208 unsigned int cmd, unsigned long arg);
a885c8c4 209static int pf_getgeo(struct block_device *bdev, struct hd_geometry *geo);
1da177e4 210
8cfc7ca4 211static int pf_release(struct gendisk *disk, fmode_t mode);
1da177e4
LT
212
213static int pf_detect(void);
214static void do_pf_read(void);
215static void do_pf_read_start(void);
216static void do_pf_write(void);
217static void do_pf_write_start(void);
218static void do_pf_read_drq(void);
219static void do_pf_write_done(void);
220
221#define PF_NM 0
222#define PF_RO 1
223#define PF_RW 2
224
225#define PF_NAMELEN 8
226
227struct pf_unit {
228 struct pi_adapter pia; /* interface to paride layer */
229 struct pi_adapter *pi;
230 int removable; /* removable media device ? */
231 int media_status; /* media present ? WP ? */
232 int drive; /* drive */
233 int lun;
234 int access; /* count of active opens ... */
235 int present; /* device present ? */
236 char name[PF_NAMELEN]; /* pf0, pf1, ... */
237 struct gendisk *disk;
238};
239
240static struct pf_unit units[PF_UNITS];
241
242static int pf_identify(struct pf_unit *pf);
243static void pf_lock(struct pf_unit *pf, int func);
244static void pf_eject(struct pf_unit *pf);
245static int pf_check_media(struct gendisk *disk);
246
247static char pf_scratch[512]; /* scratch block buffer */
248
249/* the variables below are used mainly in the I/O request engine, which
250 processes only one request at a time.
251*/
252
253static int pf_retries = 0; /* i/o error retry count */
254static int pf_busy = 0; /* request being processed ? */
255static struct request *pf_req; /* current request */
256static int pf_block; /* address of next requested block */
257static int pf_count; /* number of blocks still to do */
258static int pf_run; /* sectors in current cluster */
259static int pf_cmd; /* current command READ/WRITE */
260static struct pf_unit *pf_current;/* unit of current request */
261static int pf_mask; /* stopper for pseudo-int */
262static char *pf_buf; /* buffer for request in progress */
263
264/* kernel glue structures */
265
83d5cde4 266static const struct block_device_operations pf_fops = {
1da177e4 267 .owner = THIS_MODULE,
8cfc7ca4
AV
268 .open = pf_open,
269 .release = pf_release,
8a6cfeb6 270 .ioctl = pf_ioctl,
a885c8c4 271 .getgeo = pf_getgeo,
1da177e4
LT
272 .media_changed = pf_check_media,
273};
274
275static void __init pf_init_units(void)
276{
277 struct pf_unit *pf;
278 int unit;
279
280 pf_drive_count = 0;
281 for (unit = 0, pf = units; unit < PF_UNITS; unit++, pf++) {
282 struct gendisk *disk = alloc_disk(1);
283 if (!disk)
284 continue;
285 pf->disk = disk;
286 pf->pi = &pf->pia;
287 pf->media_status = PF_NM;
288 pf->drive = (*drives[unit])[D_SLV];
289 pf->lun = (*drives[unit])[D_LUN];
290 snprintf(pf->name, PF_NAMELEN, "%s%d", name, unit);
291 disk->major = major;
292 disk->first_minor = unit;
293 strcpy(disk->disk_name, pf->name);
294 disk->fops = &pf_fops;
295 if (!(*drives[unit])[D_PRT])
296 pf_drive_count++;
297 }
298}
299
8cfc7ca4 300static int pf_open(struct block_device *bdev, fmode_t mode)
1da177e4 301{
8cfc7ca4 302 struct pf_unit *pf = bdev->bd_disk->private_data;
1da177e4
LT
303
304 pf_identify(pf);
305
306 if (pf->media_status == PF_NM)
307 return -ENODEV;
308
8cfc7ca4 309 if ((pf->media_status == PF_RO) && (mode & FMODE_WRITE))
1da177e4
LT
310 return -EROFS;
311
312 pf->access++;
313 if (pf->removable)
314 pf_lock(pf, 1);
315
316 return 0;
317}
318
a885c8c4 319static int pf_getgeo(struct block_device *bdev, struct hd_geometry *geo)
1da177e4 320{
a885c8c4
CH
321 struct pf_unit *pf = bdev->bd_disk->private_data;
322 sector_t capacity = get_capacity(pf->disk);
323
1da177e4 324 if (capacity < PF_FD_MAX) {
a885c8c4
CH
325 geo->cylinders = sector_div(capacity, PF_FD_HDS * PF_FD_SPT);
326 geo->heads = PF_FD_HDS;
327 geo->sectors = PF_FD_SPT;
1da177e4 328 } else {
a885c8c4
CH
329 geo->cylinders = sector_div(capacity, PF_HD_HDS * PF_HD_SPT);
330 geo->heads = PF_HD_HDS;
331 geo->sectors = PF_HD_SPT;
1da177e4 332 }
a885c8c4
CH
333
334 return 0;
335}
336
8cfc7ca4 337static int pf_ioctl(struct block_device *bdev, fmode_t mode, unsigned int cmd, unsigned long arg)
a885c8c4 338{
8cfc7ca4 339 struct pf_unit *pf = bdev->bd_disk->private_data;
a885c8c4
CH
340
341 if (cmd != CDROMEJECT)
342 return -EINVAL;
343
344 if (pf->access != 1)
345 return -EBUSY;
8a6cfeb6 346 lock_kernel();
a885c8c4 347 pf_eject(pf);
8a6cfeb6
AB
348 unlock_kernel();
349
1da177e4
LT
350 return 0;
351}
352
8cfc7ca4 353static int pf_release(struct gendisk *disk, fmode_t mode)
1da177e4 354{
8cfc7ca4 355 struct pf_unit *pf = disk->private_data;
1da177e4
LT
356
357 if (pf->access <= 0)
358 return -EINVAL;
359
360 pf->access--;
361
362 if (!pf->access && pf->removable)
363 pf_lock(pf, 0);
364
365 return 0;
366
367}
368
369static int pf_check_media(struct gendisk *disk)
370{
371 return 1;
372}
373
374static inline int status_reg(struct pf_unit *pf)
375{
376 return pi_read_regr(pf->pi, 1, 6);
377}
378
379static inline int read_reg(struct pf_unit *pf, int reg)
380{
381 return pi_read_regr(pf->pi, 0, reg);
382}
383
384static inline void write_reg(struct pf_unit *pf, int reg, int val)
385{
386 pi_write_regr(pf->pi, 0, reg, val);
387}
388
389static int pf_wait(struct pf_unit *pf, int go, int stop, char *fun, char *msg)
390{
391 int j, r, e, s, p;
392
393 j = 0;
394 while ((((r = status_reg(pf)) & go) || (stop && (!(r & stop))))
395 && (j++ < PF_SPIN))
396 udelay(PF_SPIN_DEL);
397
c12ec0a2 398 if ((r & (STAT_ERR & stop)) || (j > PF_SPIN)) {
1da177e4
LT
399 s = read_reg(pf, 7);
400 e = read_reg(pf, 1);
401 p = read_reg(pf, 2);
c12ec0a2 402 if (j > PF_SPIN)
1da177e4
LT
403 e |= 0x100;
404 if (fun)
405 printk("%s: %s %s: alt=0x%x stat=0x%x err=0x%x"
406 " loop=%d phase=%d\n",
407 pf->name, fun, msg, r, s, e, j, p);
408 return (e << 8) + s;
409 }
410 return 0;
411}
412
413static int pf_command(struct pf_unit *pf, char *cmd, int dlen, char *fun)
414{
415 pi_connect(pf->pi);
416
417 write_reg(pf, 6, 0xa0+0x10*pf->drive);
418
419 if (pf_wait(pf, STAT_BUSY | STAT_DRQ, 0, fun, "before command")) {
420 pi_disconnect(pf->pi);
421 return -1;
422 }
423
424 write_reg(pf, 4, dlen % 256);
425 write_reg(pf, 5, dlen / 256);
426 write_reg(pf, 7, 0xa0); /* ATAPI packet command */
427
428 if (pf_wait(pf, STAT_BUSY, STAT_DRQ, fun, "command DRQ")) {
429 pi_disconnect(pf->pi);
430 return -1;
431 }
432
433 if (read_reg(pf, 2) != 1) {
434 printk("%s: %s: command phase error\n", pf->name, fun);
435 pi_disconnect(pf->pi);
436 return -1;
437 }
438
439 pi_write_block(pf->pi, cmd, 12);
440
441 return 0;
442}
443
444static int pf_completion(struct pf_unit *pf, char *buf, char *fun)
445{
446 int r, s, n;
447
448 r = pf_wait(pf, STAT_BUSY, STAT_DRQ | STAT_READY | STAT_ERR,
449 fun, "completion");
450
451 if ((read_reg(pf, 2) & 2) && (read_reg(pf, 7) & STAT_DRQ)) {
452 n = (((read_reg(pf, 4) + 256 * read_reg(pf, 5)) +
453 3) & 0xfffc);
454 pi_read_block(pf->pi, buf, n);
455 }
456
457 s = pf_wait(pf, STAT_BUSY, STAT_READY | STAT_ERR, fun, "data done");
458
459 pi_disconnect(pf->pi);
460
461 return (r ? r : s);
462}
463
464static void pf_req_sense(struct pf_unit *pf, int quiet)
465{
466 char rs_cmd[12] =
467 { ATAPI_REQ_SENSE, pf->lun << 5, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0 };
468 char buf[16];
469 int r;
470
471 r = pf_command(pf, rs_cmd, 16, "Request sense");
472 mdelay(1);
473 if (!r)
474 pf_completion(pf, buf, "Request sense");
475
476 if ((!r) && (!quiet))
477 printk("%s: Sense key: %x, ASC: %x, ASQ: %x\n",
478 pf->name, buf[2] & 0xf, buf[12], buf[13]);
479}
480
481static int pf_atapi(struct pf_unit *pf, char *cmd, int dlen, char *buf, char *fun)
482{
483 int r;
484
485 r = pf_command(pf, cmd, dlen, fun);
486 mdelay(1);
487 if (!r)
488 r = pf_completion(pf, buf, fun);
489 if (r)
490 pf_req_sense(pf, !fun);
491
492 return r;
493}
494
1da177e4
LT
495static void pf_lock(struct pf_unit *pf, int func)
496{
497 char lo_cmd[12] = { ATAPI_LOCK, pf->lun << 5, 0, 0, func, 0, 0, 0, 0, 0, 0, 0 };
498
e62aa046 499 pf_atapi(pf, lo_cmd, 0, pf_scratch, func ? "lock" : "unlock");
1da177e4
LT
500}
501
502static void pf_eject(struct pf_unit *pf)
503{
504 char ej_cmd[12] = { ATAPI_DOOR, pf->lun << 5, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0 };
505
506 pf_lock(pf, 0);
507 pf_atapi(pf, ej_cmd, 0, pf_scratch, "eject");
508}
509
510#define PF_RESET_TMO 30 /* in tenths of a second */
511
512static void pf_sleep(int cs)
513{
86e84862 514 schedule_timeout_interruptible(cs);
1da177e4
LT
515}
516
517/* the ATAPI standard actually specifies the contents of all 7 registers
518 after a reset, but the specification is ambiguous concerning the last
519 two bytes, and different drives interpret the standard differently.
520 */
521
522static int pf_reset(struct pf_unit *pf)
523{
524 int i, k, flg;
525 int expect[5] = { 1, 1, 1, 0x14, 0xeb };
526
527 pi_connect(pf->pi);
528 write_reg(pf, 6, 0xa0+0x10*pf->drive);
529 write_reg(pf, 7, 8);
530
531 pf_sleep(20 * HZ / 1000);
532
533 k = 0;
534 while ((k++ < PF_RESET_TMO) && (status_reg(pf) & STAT_BUSY))
535 pf_sleep(HZ / 10);
536
537 flg = 1;
538 for (i = 0; i < 5; i++)
539 flg &= (read_reg(pf, i + 1) == expect[i]);
540
541 if (verbose) {
542 printk("%s: Reset (%d) signature = ", pf->name, k);
543 for (i = 0; i < 5; i++)
544 printk("%3x", read_reg(pf, i + 1));
545 if (!flg)
546 printk(" (incorrect)");
547 printk("\n");
548 }
549
550 pi_disconnect(pf->pi);
551 return flg - 1;
552}
553
554static void pf_mode_sense(struct pf_unit *pf)
555{
556 char ms_cmd[12] =
557 { ATAPI_MODE_SENSE, pf->lun << 5, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0 };
558 char buf[8];
559
e62aa046 560 pf_atapi(pf, ms_cmd, 8, buf, "mode sense");
1da177e4
LT
561 pf->media_status = PF_RW;
562 if (buf[3] & 0x80)
563 pf->media_status = PF_RO;
564}
565
566static void xs(char *buf, char *targ, int offs, int len)
567{
568 int j, k, l;
569
570 j = 0;
571 l = 0;
572 for (k = 0; k < len; k++)
573 if ((buf[k + offs] != 0x20) || (buf[k + offs] != l))
574 l = targ[j++] = buf[k + offs];
575 if (l == 0x20)
576 j--;
577 targ[j] = 0;
578}
579
580static int xl(char *buf, int offs)
581{
582 int v, k;
583
584 v = 0;
585 for (k = 0; k < 4; k++)
586 v = v * 256 + (buf[k + offs] & 0xff);
587 return v;
588}
589
590static void pf_get_capacity(struct pf_unit *pf)
591{
592 char rc_cmd[12] = { ATAPI_CAPACITY, pf->lun << 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
593 char buf[8];
594 int bs;
595
e62aa046 596 if (pf_atapi(pf, rc_cmd, 8, buf, "get capacity")) {
1da177e4
LT
597 pf->media_status = PF_NM;
598 return;
599 }
600 set_capacity(pf->disk, xl(buf, 0) + 1);
601 bs = xl(buf, 4);
602 if (bs != 512) {
603 set_capacity(pf->disk, 0);
604 if (verbose)
605 printk("%s: Drive %d, LUN %d,"
606 " unsupported block size %d\n",
607 pf->name, pf->drive, pf->lun, bs);
608 }
609}
610
611static int pf_identify(struct pf_unit *pf)
612{
613 int dt, s;
614 char *ms[2] = { "master", "slave" };
615 char mf[10], id[18];
616 char id_cmd[12] =
617 { ATAPI_IDENTIFY, pf->lun << 5, 0, 0, 36, 0, 0, 0, 0, 0, 0, 0 };
618 char buf[36];
619
620 s = pf_atapi(pf, id_cmd, 36, buf, "identify");
621 if (s)
622 return -1;
623
624 dt = buf[0] & 0x1f;
625 if ((dt != 0) && (dt != 7)) {
626 if (verbose)
627 printk("%s: Drive %d, LUN %d, unsupported type %d\n",
628 pf->name, pf->drive, pf->lun, dt);
629 return -1;
630 }
631
632 xs(buf, mf, 8, 8);
633 xs(buf, id, 16, 16);
634
635 pf->removable = (buf[1] & 0x80);
636
637 pf_mode_sense(pf);
638 pf_mode_sense(pf);
639 pf_mode_sense(pf);
640
641 pf_get_capacity(pf);
642
643 printk("%s: %s %s, %s LUN %d, type %d",
644 pf->name, mf, id, ms[pf->drive], pf->lun, dt);
645 if (pf->removable)
646 printk(", removable");
647 if (pf->media_status == PF_NM)
648 printk(", no media\n");
649 else {
650 if (pf->media_status == PF_RO)
651 printk(", RO");
652 printk(", %llu blocks\n",
653 (unsigned long long)get_capacity(pf->disk));
654 }
655 return 0;
656}
657
658/* returns 0, with id set if drive is detected
659 -1, if drive detection failed
660*/
661static int pf_probe(struct pf_unit *pf)
662{
663 if (pf->drive == -1) {
664 for (pf->drive = 0; pf->drive <= 1; pf->drive++)
665 if (!pf_reset(pf)) {
666 if (pf->lun != -1)
667 return pf_identify(pf);
668 else
669 for (pf->lun = 0; pf->lun < 8; pf->lun++)
670 if (!pf_identify(pf))
671 return 0;
672 }
673 } else {
674 if (pf_reset(pf))
675 return -1;
676 if (pf->lun != -1)
677 return pf_identify(pf);
678 for (pf->lun = 0; pf->lun < 8; pf->lun++)
679 if (!pf_identify(pf))
680 return 0;
681 }
682 return -1;
683}
684
685static int pf_detect(void)
686{
687 struct pf_unit *pf = units;
688 int k, unit;
689
690 printk("%s: %s version %s, major %d, cluster %d, nice %d\n",
691 name, name, PF_VERSION, major, cluster, nice);
692
693 k = 0;
694 if (pf_drive_count == 0) {
695 if (pi_init(pf->pi, 1, -1, -1, -1, -1, -1, pf_scratch, PI_PF,
696 verbose, pf->name)) {
697 if (!pf_probe(pf) && pf->disk) {
698 pf->present = 1;
699 k++;
700 } else
701 pi_release(pf->pi);
702 }
703
704 } else
705 for (unit = 0; unit < PF_UNITS; unit++, pf++) {
706 int *conf = *drives[unit];
707 if (!conf[D_PRT])
708 continue;
709 if (pi_init(pf->pi, 0, conf[D_PRT], conf[D_MOD],
710 conf[D_UNI], conf[D_PRO], conf[D_DLY],
711 pf_scratch, PI_PF, verbose, pf->name)) {
8e53cfc8 712 if (pf->disk && !pf_probe(pf)) {
1da177e4
LT
713 pf->present = 1;
714 k++;
715 } else
716 pi_release(pf->pi);
717 }
718 }
719 if (k)
720 return 0;
721
722 printk("%s: No ATAPI disk detected\n", name);
723 for (pf = units, unit = 0; unit < PF_UNITS; pf++, unit++)
724 put_disk(pf->disk);
725 return -1;
726}
727
728/* The i/o request engine */
729
730static int pf_start(struct pf_unit *pf, int cmd, int b, int c)
731{
732 int i;
733 char io_cmd[12] = { cmd, pf->lun << 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
734
735 for (i = 0; i < 4; i++) {
736 io_cmd[5 - i] = b & 0xff;
737 b = b >> 8;
738 }
739
740 io_cmd[8] = c & 0xff;
741 io_cmd[7] = (c >> 8) & 0xff;
742
743 i = pf_command(pf, io_cmd, c * 512, "start i/o");
744
745 mdelay(1);
746
747 return i;
748}
749
750static int pf_ready(void)
751{
752 return (((status_reg(pf_current) & (STAT_BUSY | pf_mask)) == pf_mask));
753}
754
755static struct request_queue *pf_queue;
756
f06d9a2b 757static void pf_end_request(int err)
9564df1f 758{
b12d4f82 759 if (pf_req && !__blk_end_request_cur(pf_req, err))
9564df1f 760 pf_req = NULL;
9564df1f
JA
761}
762
165125e1 763static void do_pf_request(struct request_queue * q)
1da177e4
LT
764{
765 if (pf_busy)
766 return;
767repeat:
b12d4f82 768 if (!pf_req) {
9934c8c0 769 pf_req = blk_fetch_request(q);
b12d4f82
TH
770 if (!pf_req)
771 return;
b12d4f82 772 }
1da177e4
LT
773
774 pf_current = pf_req->rq_disk->private_data;
83096ebf
TH
775 pf_block = blk_rq_pos(pf_req);
776 pf_run = blk_rq_sectors(pf_req);
777 pf_count = blk_rq_cur_sectors(pf_req);
1da177e4
LT
778
779 if (pf_block + pf_count > get_capacity(pf_req->rq_disk)) {
f06d9a2b 780 pf_end_request(-EIO);
1da177e4
LT
781 goto repeat;
782 }
783
784 pf_cmd = rq_data_dir(pf_req);
785 pf_buf = pf_req->buffer;
786 pf_retries = 0;
787
788 pf_busy = 1;
789 if (pf_cmd == READ)
790 pi_do_claimed(pf_current->pi, do_pf_read);
791 else if (pf_cmd == WRITE)
792 pi_do_claimed(pf_current->pi, do_pf_write);
793 else {
794 pf_busy = 0;
f06d9a2b 795 pf_end_request(-EIO);
1da177e4
LT
796 goto repeat;
797 }
798}
799
800static int pf_next_buf(void)
801{
802 unsigned long saved_flags;
803
804 pf_count--;
805 pf_run--;
806 pf_buf += 512;
807 pf_block++;
808 if (!pf_run)
1da177e4 809 return 1;
e62aa046
OZ
810 if (!pf_count) {
811 spin_lock_irqsave(&pf_spin_lock, saved_flags);
f06d9a2b 812 pf_end_request(0);
e62aa046
OZ
813 spin_unlock_irqrestore(&pf_spin_lock, saved_flags);
814 if (!pf_req)
815 return 1;
83096ebf 816 pf_count = blk_rq_cur_sectors(pf_req);
e62aa046
OZ
817 pf_buf = pf_req->buffer;
818 }
819 return 0;
1da177e4
LT
820}
821
f06d9a2b 822static inline void next_request(int err)
1da177e4
LT
823{
824 unsigned long saved_flags;
825
826 spin_lock_irqsave(&pf_spin_lock, saved_flags);
f06d9a2b 827 pf_end_request(err);
1da177e4
LT
828 pf_busy = 0;
829 do_pf_request(pf_queue);
830 spin_unlock_irqrestore(&pf_spin_lock, saved_flags);
831}
832
833/* detach from the calling context - in case the spinlock is held */
834static void do_pf_read(void)
835{
836 ps_set_intr(do_pf_read_start, NULL, 0, nice);
837}
838
839static void do_pf_read_start(void)
840{
841 pf_busy = 1;
842
843 if (pf_start(pf_current, ATAPI_READ_10, pf_block, pf_run)) {
844 pi_disconnect(pf_current->pi);
845 if (pf_retries < PF_MAX_RETRIES) {
846 pf_retries++;
847 pi_do_claimed(pf_current->pi, do_pf_read_start);
848 return;
849 }
f06d9a2b 850 next_request(-EIO);
1da177e4
LT
851 return;
852 }
853 pf_mask = STAT_DRQ;
854 ps_set_intr(do_pf_read_drq, pf_ready, PF_TMO, nice);
855}
856
857static void do_pf_read_drq(void)
858{
859 while (1) {
860 if (pf_wait(pf_current, STAT_BUSY, STAT_DRQ | STAT_ERR,
861 "read block", "completion") & STAT_ERR) {
862 pi_disconnect(pf_current->pi);
863 if (pf_retries < PF_MAX_RETRIES) {
864 pf_req_sense(pf_current, 0);
865 pf_retries++;
866 pi_do_claimed(pf_current->pi, do_pf_read_start);
867 return;
868 }
f06d9a2b 869 next_request(-EIO);
1da177e4
LT
870 return;
871 }
872 pi_read_block(pf_current->pi, pf_buf, 512);
873 if (pf_next_buf())
874 break;
875 }
876 pi_disconnect(pf_current->pi);
f06d9a2b 877 next_request(0);
1da177e4
LT
878}
879
880static void do_pf_write(void)
881{
882 ps_set_intr(do_pf_write_start, NULL, 0, nice);
883}
884
885static void do_pf_write_start(void)
886{
887 pf_busy = 1;
888
889 if (pf_start(pf_current, ATAPI_WRITE_10, pf_block, pf_run)) {
890 pi_disconnect(pf_current->pi);
891 if (pf_retries < PF_MAX_RETRIES) {
892 pf_retries++;
893 pi_do_claimed(pf_current->pi, do_pf_write_start);
894 return;
895 }
f06d9a2b 896 next_request(-EIO);
1da177e4
LT
897 return;
898 }
899
900 while (1) {
901 if (pf_wait(pf_current, STAT_BUSY, STAT_DRQ | STAT_ERR,
902 "write block", "data wait") & STAT_ERR) {
903 pi_disconnect(pf_current->pi);
904 if (pf_retries < PF_MAX_RETRIES) {
905 pf_retries++;
906 pi_do_claimed(pf_current->pi, do_pf_write_start);
907 return;
908 }
f06d9a2b 909 next_request(-EIO);
1da177e4
LT
910 return;
911 }
912 pi_write_block(pf_current->pi, pf_buf, 512);
913 if (pf_next_buf())
914 break;
915 }
916 pf_mask = 0;
917 ps_set_intr(do_pf_write_done, pf_ready, PF_TMO, nice);
918}
919
920static void do_pf_write_done(void)
921{
922 if (pf_wait(pf_current, STAT_BUSY, 0, "write block", "done") & STAT_ERR) {
923 pi_disconnect(pf_current->pi);
924 if (pf_retries < PF_MAX_RETRIES) {
925 pf_retries++;
926 pi_do_claimed(pf_current->pi, do_pf_write_start);
927 return;
928 }
f06d9a2b 929 next_request(-EIO);
1da177e4
LT
930 return;
931 }
932 pi_disconnect(pf_current->pi);
f06d9a2b 933 next_request(0);
1da177e4
LT
934}
935
936static int __init pf_init(void)
937{ /* preliminary initialisation */
938 struct pf_unit *pf;
939 int unit;
940
941 if (disable)
8bca98ca 942 return -EINVAL;
1da177e4
LT
943
944 pf_init_units();
945
946 if (pf_detect())
8bca98ca 947 return -ENODEV;
1da177e4
LT
948 pf_busy = 0;
949
950 if (register_blkdev(major, name)) {
951 for (pf = units, unit = 0; unit < PF_UNITS; pf++, unit++)
952 put_disk(pf->disk);
8bca98ca 953 return -EBUSY;
1da177e4
LT
954 }
955 pf_queue = blk_init_queue(do_pf_request, &pf_spin_lock);
956 if (!pf_queue) {
957 unregister_blkdev(major, name);
958 for (pf = units, unit = 0; unit < PF_UNITS; pf++, unit++)
959 put_disk(pf->disk);
8bca98ca 960 return -ENOMEM;
1da177e4
LT
961 }
962
8a78362c 963 blk_queue_max_segments(pf_queue, cluster);
1da177e4
LT
964
965 for (pf = units, unit = 0; unit < PF_UNITS; pf++, unit++) {
966 struct gendisk *disk = pf->disk;
967
968 if (!pf->present)
969 continue;
970 disk->private_data = pf;
971 disk->queue = pf_queue;
972 add_disk(disk);
973 }
974 return 0;
975}
976
977static void __exit pf_exit(void)
978{
979 struct pf_unit *pf;
980 int unit;
981 unregister_blkdev(major, name);
982 for (pf = units, unit = 0; unit < PF_UNITS; pf++, unit++) {
983 if (!pf->present)
984 continue;
985 del_gendisk(pf->disk);
986 put_disk(pf->disk);
987 pi_release(pf->pi);
988 }
989 blk_cleanup_queue(pf_queue);
990}
991
992MODULE_LICENSE("GPL");
993module_init(pf_init)
994module_exit(pf_exit)