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