]> git.neil.brown.name Git - history.git/commitdiff
[PATCH] (18/25) pcd.c - cleanup, killed used of cdi->dev
authorAlexander Viro <viro@math.psu.edu>
Sat, 7 Sep 2002 10:04:42 +0000 (03:04 -0700)
committerLinus Torvalds <torvalds@home.transmeta.com>
Sat, 7 Sep 2002 10:04:42 +0000 (03:04 -0700)
 pcd.c cleaned up, uses of cdi->dev eliminated, abuse of macros killed
(it used to have
#define PCD pcd[unit]
#define PI PCD.pi
and expected 'unit' to be local variable in each function that used these
(== almost every function in there)).

drivers/block/paride/pcd.c

index 8ac77691fd1da2f6eb6b7843c5d5584e18cd5cfd..de78fa2198b860be5cfafc767f7b2f9a7c3fd199 100644 (file)
@@ -122,18 +122,10 @@ static int drive1[6] = { 0, 0, 0, -1, -1, -1 };
 static int drive2[6] = { 0, 0, 0, -1, -1, -1 };
 static int drive3[6] = { 0, 0, 0, -1, -1, -1 };
 
-static int (*drives[4])[6] = {
-&drive0, &drive1, &drive2, &drive3};
+static int (*drives[4])[6] = {&drive0, &drive1, &drive2, &drive3};
 static int pcd_drive_count;
 
-#define D_PRT   0
-#define D_PRO   1
-#define D_UNI   2
-#define D_MOD   3
-#define D_SLV   4
-#define D_DLY   5
-
-#define DU              (*drives[unit])
+enum {D_PRT, D_PRO, D_UNI, D_MOD, D_SLV, D_DLY};
 
 /* end of parameters */
 
@@ -236,11 +228,6 @@ struct pcd_unit {
 
 struct pcd_unit pcd[PCD_UNITS];
 
-/*  'unit' must be defined in all functions - either as a local or a param */
-
-#define PCD pcd[unit]
-#define PI PCD.pi
-
 static char pcd_scratch[64];
 static char pcd_buffer[2048];  /* raw block buffer */
 static int pcd_bufblk = -1;    /* block in buffer, in CD units,
@@ -252,14 +239,14 @@ static int pcd_bufblk = -1;       /* block in buffer, in CD units,
    processes only one request at a time.
 */
 
-static int pcd_unit = -1;      /* unit of current request & bufblk */
+static struct pcd_unit *pcd_current; /* current request's drive */
 static int pcd_retries;                /* retries on current request */
-static int pcd_busy = 0;       /* request being processed ? */
+static int pcd_busy;           /* request being processed ? */
 static int pcd_sector;         /* address of next requested sector */
 static int pcd_count;          /* number of blocks still to do */
 static char *pcd_buf;          /* buffer for request in progress */
 
-static int pcd_warned = 0;     /* Have we logged a phase warning ? */
+static int pcd_warned;         /* Have we logged a phase warning ? */
 
 /* kernel glue structures */
 
@@ -290,39 +277,34 @@ static struct cdrom_device_ops pcd_dops = {
 
 static void pcd_init_units(void)
 {
-       int unit, j;
+       struct pcd_unit *cd;
+       int unit;
 
        pcd_drive_count = 0;
-       for (unit = 0; unit < PCD_UNITS; unit++) {
-               PCD.pi = &PCD.pia;
-               PCD.present = 0;
-               PCD.last_sense = 0;
-               PCD.changed = 1;
-               PCD.drive = DU[D_SLV];
-               if (DU[D_PRT])
+       for (unit = 0, cd = pcd; unit < PCD_UNITS; unit++, cd++) {
+               cd->pi = &cd->pia;
+               cd->present = 0;
+               cd->last_sense = 0;
+               cd->changed = 1;
+               cd->drive = (*drives[unit])[D_SLV];
+               if ((*drives[unit])[D_PRT])
                        pcd_drive_count++;
 
-               j = 0;
-               while ((j < (sizeof (PCD.info.name) - 2)) &&
-                      (PCD.info.name[j] = name[j]))
-                       j++;
-               PCD.info.name[j++] = '0' + unit;
-               PCD.info.name[j] = 0;
-               PCD.name = &PCD.info.name[0];
-
-               PCD.info.ops = &pcd_dops;
-               PCD.info.handle = NULL;
-               PCD.info.dev = mk_kdev(major, unit);
-               PCD.info.speed = 0;
-               PCD.info.capacity = 1;
-               PCD.info.mask = 0;
+               cd->name = &cd->info.name[0];
+               snprintf(cd->name, sizeof(cd->info.name), "%s%d", name, unit);
+               cd->info.ops = &pcd_dops;
+               cd->info.handle = cd;
+               cd->info.dev = mk_kdev(major, unit);
+               cd->info.speed = 0;
+               cd->info.capacity = 1;
+               cd->info.mask = 0;
        }
 }
 
 static int pcd_open(struct cdrom_device_info *cdi, int purpose)
 {
-       int unit = DEVICE_NR(cdi->dev);
-       if ((unit >= PCD_UNITS) || (!PCD.present))
+       struct pcd_unit *cd = cdi->handle;
+       if (!cd->present)
                return -ENODEV;
        return 0;
 }
@@ -331,77 +313,77 @@ static void pcd_release(struct cdrom_device_info *cdi)
 {
 }
 
-static inline int status_reg(int unit)
+static inline int status_reg(struct pcd_unit *cd)
 {
-       return pi_read_regr(PI, 1, 6);
+       return pi_read_regr(cd->pi, 1, 6);
 }
 
-static inline int read_reg(int unit, int reg)
+static inline int read_reg(struct pcd_unit *cd, int reg)
 {
-       return pi_read_regr(PI, 0, reg);
+       return pi_read_regr(cd->pi, 0, reg);
 }
 
-static inline void write_reg(int unit, int reg, int val)
+static inline void write_reg(struct pcd_unit *cd, int reg, int val)
 {
-       pi_write_regr(PI, 0, reg, val);
+       pi_write_regr(cd->pi, 0, reg, val);
 }
 
-static int pcd_wait(int unit, int go, int stop, char *fun, char *msg)
+static int pcd_wait(struct pcd_unit *cd, int go, int stop, char *fun, char *msg)
 {
        int j, r, e, s, p;
 
        j = 0;
-       while ((((r = status_reg(unit)) & go) || (stop && (!(r & stop))))
+       while ((((r = status_reg(cd)) & go) || (stop && (!(r & stop))))
               && (j++ < PCD_SPIN))
                udelay(PCD_DELAY);
 
        if ((r & (IDE_ERR & stop)) || (j >= PCD_SPIN)) {
-               s = read_reg(unit, 7);
-               e = read_reg(unit, 1);
-               p = read_reg(unit, 2);
+               s = read_reg(cd, 7);
+               e = read_reg(cd, 1);
+               p = read_reg(cd, 2);
                if (j >= PCD_SPIN)
                        e |= 0x100;
                if (fun)
                        printk("%s: %s %s: alt=0x%x stat=0x%x err=0x%x"
                               " loop=%d phase=%d\n",
-                              PCD.name, fun, msg, r, s, e, j, p);
+                              cd->name, fun, msg, r, s, e, j, p);
                return (s << 8) + r;
        }
        return 0;
 }
 
-static int pcd_command(int unit, char *cmd, int dlen, char *fun)
+static int pcd_command(struct pcd_unit *cd, char *cmd, int dlen, char *fun)
 {
-       pi_connect(PI);
+       pi_connect(cd->pi);
 
-       write_reg(unit, 6, 0xa0 + 0x10 * PCD.drive);
+       write_reg(cd, 6, 0xa0 + 0x10 * cd->drive);
 
-       if (pcd_wait(unit, IDE_BUSY | IDE_DRQ, 0, fun, "before command")) {
-               pi_disconnect(PI);
+       if (pcd_wait(cd, IDE_BUSY | IDE_DRQ, 0, fun, "before command")) {
+               pi_disconnect(cd->pi);
                return -1;
        }
 
-       write_reg(unit, 4, dlen % 256);
-       write_reg(unit, 5, dlen / 256);
-       write_reg(unit, 7, 0xa0);       /* ATAPI packet command */
+       write_reg(cd, 4, dlen % 256);
+       write_reg(cd, 5, dlen / 256);
+       write_reg(cd, 7, 0xa0); /* ATAPI packet command */
 
-       if (pcd_wait(unit, IDE_BUSY, IDE_DRQ, fun, "command DRQ")) {
-               pi_disconnect(PI);
+       if (pcd_wait(cd, IDE_BUSY, IDE_DRQ, fun, "command DRQ")) {
+               pi_disconnect(cd->pi);
                return -1;
        }
 
-       if (read_reg(unit, 2) != 1) {
-               printk("%s: %s: command phase error\n", PCD.name, fun);
-               pi_disconnect(PI);
+       if (read_reg(cd, 2) != 1) {
+               printk("%s: %s: command phase error\n", cd->name, fun);
+               pi_disconnect(cd->pi);
                return -1;
        }
 
-       pi_write_block(PI, cmd, 12);
+       pi_write_block(cd->pi, cmd, 12);
 
        return 0;
 }
 
-static int pcd_completion(int unit, char *buf, char *fun)
+static int pcd_completion(struct pcd_unit *cd, char *buf, char *fun)
 {
        int r, d, p, n, k, j;
 
@@ -409,40 +391,40 @@ static int pcd_completion(int unit, char *buf, char *fun)
        k = 0;
        j = 0;
 
-       if (!pcd_wait(unit, IDE_BUSY, IDE_DRQ | IDE_READY | IDE_ERR,
+       if (!pcd_wait(cd, IDE_BUSY, IDE_DRQ | IDE_READY | IDE_ERR,
                      fun, "completion")) {
                r = 0;
-               while (read_reg(unit, 7) & IDE_DRQ) {
-                       d = (read_reg(unit, 4) + 256 * read_reg(unit, 5));
-                       n = ((d + 3) & 0xfffc);
-                       p = read_reg(unit, 2) & 3;
+               while (read_reg(cd, 7) & IDE_DRQ) {
+                       d = read_reg(cd, 4) + 256 * read_reg(cd, 5);
+                       n = (d + 3) & 0xfffc;
+                       p = read_reg(cd, 2) & 3;
 
                        if ((p == 2) && (n > 0) && (j == 0)) {
-                               pi_read_block(PI, buf, n);
+                               pi_read_block(cd->pi, buf, n);
                                if (verbose > 1)
                                        printk("%s: %s: Read %d bytes\n",
-                                              PCD.name, fun, n);
+                                              cd->name, fun, n);
                                r = 0;
                                j++;
                        } else {
                                if (verbose > 1)
                                        printk
                                            ("%s: %s: Unexpected phase %d, d=%d, k=%d\n",
-                                            PCD.name, fun, p, d, k);
+                                            cd->name, fun, p, d, k);
                                if ((verbose < 2) && !pcd_warned) {
                                        pcd_warned = 1;
                                        printk
                                            ("%s: WARNING: ATAPI phase errors\n",
-                                            PCD.name);
+                                            cd->name);
                                }
                                mdelay(1);
                        }
                        if (k++ > PCD_TMO) {
-                               printk("%s: Stuck DRQ\n", PCD.name);
+                               printk("%s: Stuck DRQ\n", cd->name);
                                break;
                        }
                        if (pcd_wait
-                           (unit, IDE_BUSY, IDE_DRQ | IDE_READY | IDE_ERR, fun,
+                           (cd, IDE_BUSY, IDE_DRQ | IDE_READY | IDE_ERR, fun,
                             "completion")) {
                                r = -1;
                                break;
@@ -450,57 +432,53 @@ static int pcd_completion(int unit, char *buf, char *fun)
                }
        }
 
-       pi_disconnect(PI);
+       pi_disconnect(cd->pi);
 
        return r;
 }
 
-static void pcd_req_sense(int unit, char *fun)
+static void pcd_req_sense(struct pcd_unit *cd, char *fun)
 {
        char rs_cmd[12] = { 0x03, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0 };
        char buf[16];
        int r, c;
 
-       r = pcd_command(unit, rs_cmd, 16, "Request sense");
+       r = pcd_command(cd, rs_cmd, 16, "Request sense");
        mdelay(1);
        if (!r)
-               pcd_completion(unit, buf, "Request sense");
+               pcd_completion(cd, buf, "Request sense");
 
-       PCD.last_sense = -1;
+       cd->last_sense = -1;
        c = 2;
        if (!r) {
                if (fun)
                        printk("%s: %s: Sense key: %x, ASC: %x, ASQ: %x\n",
-                              PCD.name, fun, buf[2] & 0xf, buf[12], buf[13]);
+                              cd->name, fun, buf[2] & 0xf, buf[12], buf[13]);
                c = buf[2] & 0xf;
-               PCD.last_sense =
+               cd->last_sense =
                    c | ((buf[12] & 0xff) << 8) | ((buf[13] & 0xff) << 16);
        }
        if ((c == 2) || (c == 6))
-               PCD.changed = 1;
+               cd->changed = 1;
 }
 
-static int pcd_atapi(int unit, char *cmd, int dlen, char *buf, char *fun)
+static int pcd_atapi(struct pcd_unit *cd, char *cmd, int dlen, char *buf, char *fun)
 {
        int r;
 
-       r = pcd_command(unit, cmd, dlen, fun);
+       r = pcd_command(cd, cmd, dlen, fun);
        mdelay(1);
        if (!r)
-               r = pcd_completion(unit, buf, fun);
+               r = pcd_completion(cd, buf, fun);
        if (r)
-               pcd_req_sense(unit, fun);
+               pcd_req_sense(cd, fun);
 
        return r;
 }
 
 static int pcd_packet(struct cdrom_device_info *cdi, struct cdrom_generic_command *cgc)
 {
-       char *un_cmd;
-       int unit = DEVICE_NR(cdi->dev);
-
-       un_cmd = cgc->cmd;
-       return pcd_atapi(unit, un_cmd, cgc->buflen, cgc->buffer,
+       return pcd_atapi(cdi->handle, cgc->cmd, cgc->buflen, cgc->buffer,
                         "generic packet");
 }
 
@@ -508,30 +486,26 @@ static int pcd_packet(struct cdrom_device_info *cdi, struct cdrom_generic_comman
 
 static int pcd_media_changed(struct cdrom_device_info *cdi, int slot_nr)
 {
-       int r;
-       int unit = DEVICE_NR(cdi->dev);
-
-       r = PCD.changed;
-       PCD.changed = 0;
-
-       return r;
+       struct pcd_unit *cd = cdi->handle;
+       int res = cd->changed;
+       if (res)
+               cd->changed = 0;
+       return res;
 }
 
 static int pcd_lock_door(struct cdrom_device_info *cdi, int lock)
 {
        char un_cmd[12] = { 0x1e, 0, 0, 0, lock, 0, 0, 0, 0, 0, 0, 0 };
-       int unit = DEVICE_NR(cdi->dev);
 
-       return pcd_atapi(unit, un_cmd, 0, pcd_scratch,
+       return pcd_atapi(cdi->handle, un_cmd, 0, pcd_scratch,
                         lock ? "lock door" : "unlock door");
 }
 
 static int pcd_tray_move(struct cdrom_device_info *cdi, int position)
 {
        char ej_cmd[12] = { 0x1b, 0, 0, 0, 3 - position, 0, 0, 0, 0, 0, 0, 0 };
-       int unit = DEVICE_NR(cdi->dev);
 
-       return pcd_atapi(unit, ej_cmd, 0, pcd_scratch,
+       return pcd_atapi(cdi->handle, ej_cmd, 0, pcd_scratch,
                         position ? "eject" : "close tray");
 }
 
@@ -541,53 +515,53 @@ static void pcd_sleep(int cs)
        schedule_timeout(cs);
 }
 
-static int pcd_reset(int unit)
+static int pcd_reset(struct pcd_unit *cd)
 {
        int i, k, flg;
        int expect[5] = { 1, 1, 1, 0x14, 0xeb };
 
-       pi_connect(PI);
-       write_reg(unit, 6, 0xa0 + 0x10 * PCD.drive);
-       write_reg(unit, 7, 8);
+       pi_connect(cd->pi);
+       write_reg(cd, 6, 0xa0 + 0x10 * cd->drive);
+       write_reg(cd, 7, 8);
 
        pcd_sleep(20 * HZ / 1000);      /* delay a bit */
 
        k = 0;
-       while ((k++ < PCD_RESET_TMO) && (status_reg(unit) & IDE_BUSY))
+       while ((k++ < PCD_RESET_TMO) && (status_reg(cd) & IDE_BUSY))
                pcd_sleep(HZ / 10);
 
        flg = 1;
        for (i = 0; i < 5; i++)
-               flg &= (read_reg(unit, i + 1) == expect[i]);
+               flg &= (read_reg(cd, i + 1) == expect[i]);
 
        if (verbose) {
-               printk("%s: Reset (%d) signature = ", PCD.name, k);
+               printk("%s: Reset (%d) signature = ", cd->name, k);
                for (i = 0; i < 5; i++)
-                       printk("%3x", read_reg(unit, i + 1));
+                       printk("%3x", read_reg(cd, i + 1));
                if (!flg)
                        printk(" (incorrect)");
                printk("\n");
        }
 
-       pi_disconnect(PI);
+       pi_disconnect(cd->pi);
        return flg - 1;
 }
 
 static int pcd_drive_reset(struct cdrom_device_info *cdi)
 {
-       return pcd_reset(DEVICE_NR(cdi->dev));
+       return pcd_reset(cdi->handle);
 }
 
-static int pcd_ready_wait(int unit, int tmo)
+static int pcd_ready_wait(struct pcd_unit *cd, int tmo)
 {
        char tr_cmd[12] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
        int k, p;
 
        k = 0;
        while (k < tmo) {
-               PCD.last_sense = 0;
-               pcd_atapi(unit, tr_cmd, 0, NULL, DBMSG("test unit ready"));
-               p = PCD.last_sense;
+               cd->last_sense = 0;
+               pcd_atapi(cd, tr_cmd, 0, NULL, DBMSG("test unit ready"));
+               p = cd->last_sense;
                if (!p)
                        return 0;
                if (!(((p & 0xffff) == 0x0402) || ((p & 0xff) == 6)))
@@ -601,34 +575,33 @@ static int pcd_ready_wait(int unit, int tmo)
 static int pcd_drive_status(struct cdrom_device_info *cdi, int slot_nr)
 {
        char rc_cmd[12] = { 0x25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
-       int unit = DEVICE_NR(cdi->dev);
+       struct pcd_unit *cd = cdi->handle;
 
-       if (pcd_ready_wait(unit, PCD_READY_TMO))
+       if (pcd_ready_wait(cd, PCD_READY_TMO))
                return CDS_DRIVE_NOT_READY;
-       if (pcd_atapi(unit, rc_cmd, 8, pcd_scratch, DBMSG("check media")))
+       if (pcd_atapi(cd, rc_cmd, 8, pcd_scratch, DBMSG("check media")))
                return CDS_NO_DISC;
        return CDS_DISC_OK;
 }
 
-static int pcd_identify(int unit, char *id)
+static int pcd_identify(struct pcd_unit *cd, char *id)
 {
        int k, s;
        char id_cmd[12] = { 0x12, 0, 0, 0, 36, 0, 0, 0, 0, 0, 0, 0 };
 
        pcd_bufblk = -1;
 
-       s = pcd_atapi(unit, id_cmd, 36, pcd_buffer, "identify");
+       s = pcd_atapi(cd, id_cmd, 36, pcd_buffer, "identify");
 
        if (s)
                return -1;
        if ((pcd_buffer[0] & 0x1f) != 5) {
                if (verbose)
                        printk("%s: %s is not a CD-ROM\n",
-                              PCD.name, PCD.drive ? "Slave" : "Master");
+                              cd->name, cd->drive ? "Slave" : "Master");
                return -1;
        }
-       for (k = 0; k < 16; k++)
-               id[k] = pcd_buffer[16 + k];
+       memcpy(id, pcd_buffer + 16, 16);
        id[16] = 0;
        k = 16;
        while ((k >= 0) && (id[k] <= 0x20)) {
@@ -636,7 +609,7 @@ static int pcd_identify(int unit, char *id)
                k--;
        }
 
-       printk("%s: %s: %s\n", PCD.name, PCD.drive ? "Slave" : "Master", id);
+       printk("%s: %s: %s\n", cd->name, cd->drive ? "Slave" : "Master", id);
 
        return 0;
 }
@@ -645,15 +618,15 @@ static int pcd_identify(int unit, char *id)
  * returns  0, with id set if drive is detected
  *         -1, if drive detection failed
  */
-static int pcd_probe(int unit, int ms, char *id)
+static int pcd_probe(struct pcd_unit *cd, int ms, char *id)
 {
        if (ms == -1) {
-               for (PCD.drive = 0; PCD.drive <= 1; PCD.drive++)
-                       if (!pcd_reset(unit) && !pcd_identify(unit, id))
+               for (cd->drive = 0; cd->drive <= 1; cd->drive++)
+                       if (!pcd_reset(cd) && !pcd_identify(cd, id))
                                return 0;
        } else {
-               PCD.drive = ms;
-               if (!pcd_reset(unit) && !pcd_identify(unit, id))
+               cd->drive = ms;
+               if (!pcd_reset(cd) && !pcd_identify(cd, id))
                        return 0;
        }
        return -1;
@@ -664,26 +637,27 @@ static void pcd_probe_capabilities(void)
        int unit, r;
        char buffer[32];
        char cmd[12] = { 0x5a, 1 << 3, 0x2a, 0, 0, 0, 0, 18, 0, 0, 0, 0 };
+       struct pcd_unit *cd;
 
-       for (unit = 0; unit < PCD_UNITS; unit++) {
-               if (!PCD.present)
+       for (unit = 0, cd = pcd; unit < PCD_UNITS; unit++, cd++) {
+               if (!cd->present)
                        continue;
-               r = pcd_atapi(unit, cmd, 18, buffer, "mode sense capabilities");
+               r = pcd_atapi(cd, cmd, 18, buffer, "mode sense capabilities");
                if (r)
                        continue;
                /* we should now have the cap page */
                if ((buffer[11] & 1) == 0)
-                       PCD.info.mask |= CDC_CD_R;
+                       cd->info.mask |= CDC_CD_R;
                if ((buffer[11] & 2) == 0)
-                       PCD.info.mask |= CDC_CD_RW;
+                       cd->info.mask |= CDC_CD_RW;
                if ((buffer[12] & 1) == 0)
-                       PCD.info.mask |= CDC_PLAY_AUDIO;
+                       cd->info.mask |= CDC_PLAY_AUDIO;
                if ((buffer[14] & 1) == 0)
-                       PCD.info.mask |= CDC_LOCK;
+                       cd->info.mask |= CDC_LOCK;
                if ((buffer[14] & 8) == 0)
-                       PCD.info.mask |= CDC_OPEN_TRAY;
+                       cd->info.mask |= CDC_OPEN_TRAY;
                if ((buffer[14] >> 6) == 0)
-                       PCD.info.mask |= CDC_CLOSE_TRAY;
+                       cd->info.mask |= CDC_CLOSE_TRAY;
        }
 }
 
@@ -691,36 +665,38 @@ static int pcd_detect(void)
 {
        char id[18];
        int k, unit;
+       struct pcd_unit *cd;
 
        printk("%s: %s version %s, major %d, nice %d\n",
               name, name, PCD_VERSION, major, nice);
 
        k = 0;
-       if (pcd_drive_count == 0) {     /* nothing spec'd - so autoprobe for 1 */
-               unit = 0;
-               if (pi_init(PI, 1, -1, -1, -1, -1, -1, pcd_buffer,
-                           PI_PCD, verbose, PCD.name)) {
-                       if (!pcd_probe(unit, -1, id)) {
-                               PCD.present = 1;
+       if (pcd_drive_count == 0) { /* nothing spec'd - so autoprobe for 1 */
+               cd = pcd;
+               if (pi_init(cd->pi, 1, -1, -1, -1, -1, -1, pcd_buffer,
+                           PI_PCD, verbose, cd->name)) {
+                       if (!pcd_probe(cd, -1, id)) {
+                               cd->present = 1;
                                k++;
                        } else
-                               pi_release(PI);
+                               pi_release(cd->pi);
                }
-
-       } else
-               for (unit = 0; unit < PCD_UNITS; unit++)
-                       if (DU[D_PRT])
-                               if (pi_init
-                                   (PI, 0, DU[D_PRT], DU[D_MOD], DU[D_UNI],
-                                    DU[D_PRO], DU[D_DLY], pcd_buffer, PI_PCD,
-                                    verbose, PCD.name)) {
-                                       if (!pcd_probe(unit, DU[D_SLV], id)) {
-                                               PCD.present = 1;
-                                               k++;
-                                       } else
-                                               pi_release(PI);
-                               }
-
+       } else {
+               for (unit = 0, cd = pcd; unit < PCD_UNITS; unit++, cd++) {
+                       int *conf = *drives[unit];
+                       if (!conf[D_PRT])
+                               continue;
+                       if (!pi_init(cd->pi, 0, conf[D_PRT], conf[D_MOD],
+                                    conf[D_UNI], conf[D_PRO], conf[D_DLY],
+                                    pcd_buffer, PI_PCD, verbose, cd->name)) 
+                               continue;
+                       if (!pcd_probe(cd, conf[D_SLV], id)) {
+                               cd->present = 1;
+                               k++;
+                       } else
+                               pi_release(cd->pi);
+               }
+       }
        if (k)
                return 0;
 
@@ -732,46 +708,40 @@ static int pcd_detect(void)
 
 static void do_pcd_request(request_queue_t * q)
 {
-       int unit;
-
        if (pcd_busy)
                return;
        while (1) {
+               struct request *req;
                if (blk_queue_empty(QUEUE))
                        return;
-
-               if (rq_data_dir(CURRENT) == READ) {
-                       unit = minor(CURRENT->rq_dev);
-                       if (unit != pcd_unit) {
+               req = CURRENT;
+               if (rq_data_dir(req) == READ) {
+                       struct pcd_unit *cd = pcd + minor(req->rq_dev);
+                       if (cd != pcd_current)
                                pcd_bufblk = -1;
-                               pcd_unit = unit;
-                       }
-                       pcd_sector = CURRENT->sector;
-                       pcd_count = CURRENT->current_nr_sectors;
-                       pcd_buf = CURRENT->buffer;
+                       pcd_current = cd;
+                       pcd_sector = req->sector;
+                       pcd_count = req->current_nr_sectors;
+                       pcd_buf = req->buffer;
                        pcd_busy = 1;
                        ps_set_intr(do_pcd_read, 0, 0, nice);
                        return;
                } else
-                       end_request(CURRENT, 0);
+                       end_request(req, 0);
        }
 }
 
 static int pcd_ready(void)
 {
-       int unit = pcd_unit;
-
-       return (((status_reg(unit) & (IDE_BUSY | IDE_DRQ)) == IDE_DRQ));
+       return (((status_reg(pcd_current) & (IDE_BUSY | IDE_DRQ)) == IDE_DRQ));
 }
 
 static void pcd_transfer(void)
 {
-       int k, o;
 
        while (pcd_count && (pcd_sector / 4 == pcd_bufblk)) {
-               o = (pcd_sector % 4) * 512;
-               for (k = 0; k < 512; k++)
-                       pcd_buf[k] = pcd_buffer[o + k];
+               int o = (pcd_sector % 4) * 512;
+               memcpy(pcd_buf, pcd_buffer + o, 512);
                pcd_count--;
                pcd_buf += 512;
                pcd_sector++;
@@ -780,7 +750,6 @@ static void pcd_transfer(void)
 
 static void pcd_start(void)
 {
-       int unit = pcd_unit;
        int b, i;
        char rd_cmd[12] = { 0xa8, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 };
        long saved_flags;
@@ -792,7 +761,7 @@ static void pcd_start(void)
                b = b >> 8;
        }
 
-       if (pcd_command(unit, rd_cmd, 2048, "read block")) {
+       if (pcd_command(pcd_current, rd_cmd, 2048, "read block")) {
                pcd_bufblk = -1;
                spin_lock_irqsave(&pcd_lock, saved_flags);
                pcd_busy = 0;
@@ -805,18 +774,15 @@ static void pcd_start(void)
        mdelay(1);
 
        ps_set_intr(do_pcd_read_drq, pcd_ready, PCD_TMO, nice);
-
 }
 
 static void do_pcd_read(void)
 {
-       int unit = pcd_unit;
-       long saved_flags;
-
        pcd_busy = 1;
        pcd_retries = 0;
        pcd_transfer();
        if (!pcd_count) {
+               long saved_flags;
                spin_lock_irqsave(&pcd_lock, saved_flags);
                end_request(CURRENT, 1);
                pcd_busy = 0;
@@ -825,19 +791,18 @@ static void do_pcd_read(void)
                return;
        }
 
-       pi_do_claimed(PI, pcd_start);
+       pi_do_claimed(pcd_current->pi, pcd_start);
 }
 
 static void do_pcd_read_drq(void)
 {
-       int unit = pcd_unit;
        long saved_flags;
 
-       if (pcd_completion(unit, pcd_buffer, "read block")) {
+       if (pcd_completion(pcd_current, pcd_buffer, "read block")) {
                if (pcd_retries < PCD_RETRIES) {
                        mdelay(1);
                        pcd_retries++;
-                       pi_do_claimed(PI, pcd_start);
+                       pi_do_claimed(pcd_current->pi, pcd_start);
                        return;
                }
                spin_lock_irqsave(&pcd_lock, saved_flags);
@@ -859,7 +824,7 @@ static void do_pcd_read_drq(void)
 
 static int pcd_audio_ioctl(struct cdrom_device_info *cdi, unsigned int cmd, void *arg)
 {
-       int unit = DEVICE_NR(cdi->dev);
+       struct pcd_unit *cd = cdi->handle;
 
        switch (cmd) {
 
@@ -874,12 +839,12 @@ static int pcd_audio_ioctl(struct cdrom_device_info *cdi, unsigned int cmd, void
                        char buffer[32];
                        int r;
 
-                       r = pcd_atapi(unit, cmd, 12, buffer, "read toc header");
+                       r = pcd_atapi(cd, cmd, 12, buffer, "read toc header");
 
                        tochdr->cdth_trk0 = buffer[2];
                        tochdr->cdth_trk1 = buffer[3];
 
-                       return r * EIO;
+                       return r ? -EIO : 0;
                }
 
        case CDROMREADTOCENTRY:
@@ -898,7 +863,7 @@ static int pcd_audio_ioctl(struct cdrom_device_info *cdi, unsigned int cmd, void
                            (tocentry->cdte_format == CDROM_MSF ? 0x02 : 0);
                        cmd[6] = tocentry->cdte_track;
 
-                       r = pcd_atapi(unit, cmd, 12, buffer, "read toc entry");
+                       r = pcd_atapi(cd, cmd, 12, buffer, "read toc entry");
 
                        tocentry->cdte_ctrl = buffer[5] & 0xf;
                        tocentry->cdte_adr = buffer[5] >> 4;
@@ -913,7 +878,7 @@ static int pcd_audio_ioctl(struct cdrom_device_info *cdi, unsigned int cmd, void
                                    (((((buffer[8] << 8) + buffer[9]) << 8)
                                      + buffer[10]) << 8) + buffer[11];
 
-                       return r * EIO;
+                       return r ? -EIO : 0;
                }
 
        default:
@@ -927,14 +892,11 @@ static int pcd_get_mcn(struct cdrom_device_info *cdi, struct cdrom_mcn *mcn)
        char cmd[12] =
            { GPCMD_READ_SUBCHANNEL, 0, 0x40, 2, 0, 0, 0, 0, 24, 0, 0, 0 };
        char buffer[32];
-       int k;
-       int unit = DEVICE_NR(cdi->dev);
 
-       if (pcd_atapi(unit, cmd, 24, buffer, "get mcn"))
+       if (pcd_atapi(cdi->handle, cmd, 24, buffer, "get mcn"))
                return -EIO;
 
-       for (k = 0; k < 13; k++)
-               mcn->medium_catalog_number[k] = buffer[k + 9];
+       memcpy(mcn->medium_catalog_number, buffer + 9, 13);
        mcn->medium_catalog_number[13] = 0;
 
        return 0;
@@ -942,6 +904,7 @@ static int pcd_get_mcn(struct cdrom_device_info *cdi, struct cdrom_mcn *mcn)
 
 static int __init pcd_init(void)
 {
+       struct pcd_unit *cd;
        int unit;
 
        if (disable)
@@ -960,10 +923,10 @@ static int __init pcd_init(void)
                return -1;
        }
 
-       for (unit = 0; unit < PCD_UNITS; unit++) {
-               if (PCD.present) {
-                       register_cdrom(&PCD.info);
-                       devfs_plain_cdrom(&PCD.info, &pcd_bdops);
+       for (unit = 0, cd = pcd; unit < PCD_UNITS; unit++, cd++) {
+               if (cd->present) {
+                       register_cdrom(&cd->info);
+                       devfs_plain_cdrom(&cd->info, &pcd_bdops);
                }
        }
 
@@ -974,12 +937,15 @@ static int __init pcd_init(void)
 
 static void __exit pcd_exit(void)
 {
+       struct pcd_unit *cd;
        int unit;
-       for (unit = 0; unit < PCD_UNITS; unit++)
-               if (PCD.present) {
-                       pi_release(PI);
-                       unregister_cdrom(&PCD.info);
+
+       for (unit = 0, cd = pcd; unit < PCD_UNITS; unit++, cd++) {
+               if (cd->present) {
+                       pi_release(cd->pi);
+                       unregister_cdrom(&cd->info);
                }
+       }
        unregister_blkdev(MAJOR_NR, name);
 }