OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [rc203soc/] [sw/] [uClinux/] [drivers/] [scsi/] [sr.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1626 jcastillo
/*
2
 *  sr.c Copyright (C) 1992 David Giller
3
 *           Copyright (C) 1993, 1994, 1995 Eric Youngdale
4
 *
5
 *  adapted from:
6
 *      sd.c Copyright (C) 1992 Drew Eckhardt
7
 *      Linux scsi disk driver by
8
 *              Drew Eckhardt <drew@colorado.edu>
9
 *
10
 *      Modified by Eric Youngdale ericy@cais.com to
11
 *      add scatter-gather, multiple outstanding request, and other
12
 *      enhancements.
13
 *
14
 *          Modified by Eric Youngdale eric@aib.com to support loadable
15
 *          low-level scsi drivers.
16
 *
17
 *       Modified by Thomas Quinot thomas@melchior.cuivre.fdn.fr to
18
 *       provide auto-eject.
19
 *
20
 */
21
 
22
#include <linux/module.h>
23
 
24
#include <linux/fs.h>
25
#include <linux/kernel.h>
26
#include <linux/sched.h>
27
#include <linux/mm.h>
28
#include <linux/string.h>
29
#include <linux/errno.h>
30
#include <linux/cdrom.h>
31
#include <linux/interrupt.h>
32
#include <asm/system.h>
33
 
34
#define MAJOR_NR SCSI_CDROM_MAJOR
35
#include <linux/blk.h>
36
#include "scsi.h"
37
#include "hosts.h"
38
#include "sr.h"
39
#include <scsi/scsi_ioctl.h>   /* For the door lock/unlock commands */
40
#include "constants.h"
41
 
42
#define MAX_RETRIES 3
43
#define SR_TIMEOUT (30 * HZ)
44
 
45
static int sr_init(void);
46
static void sr_finish(void);
47
static int sr_attach(Scsi_Device *);
48
static int sr_detect(Scsi_Device *);
49
static void sr_detach(Scsi_Device *);
50
 
51
struct Scsi_Device_Template sr_template = {NULL, "cdrom", "sr", NULL, TYPE_ROM,
52
                                               SCSI_CDROM_MAJOR, 0, 0, 0, 1,
53
                                               sr_detect, sr_init,
54
                                               sr_finish, sr_attach, sr_detach};
55
 
56
Scsi_CD * scsi_CDs = NULL;
57
static int * sr_sizes;
58
 
59
static int * sr_blocksizes;
60
 
61
static int sr_open(struct inode *, struct file *);
62
void get_sectorsize(int);
63
void sr_photocd(struct inode *);
64
 
65
extern int sr_ioctl(struct inode *, struct file *, unsigned int, unsigned long);
66
 
67
void requeue_sr_request (Scsi_Cmnd * SCpnt);
68
static int check_cdrom_media_change(kdev_t);
69
 
70
static void sr_release(struct inode * inode, struct file * file)
71
{
72
        sync_dev(inode->i_rdev);
73
        if(! --scsi_CDs[MINOR(inode->i_rdev)].device->access_count)
74
        {
75
            sr_ioctl(inode, NULL, SCSI_IOCTL_DOORUNLOCK, 0);
76
            if (scsi_CDs[MINOR(inode->i_rdev)].auto_eject)
77
                sr_ioctl(inode, NULL, CDROMEJECT, 0);
78
        }
79
        if (scsi_CDs[MINOR(inode->i_rdev)].device->host->hostt->usage_count)
80
            (*scsi_CDs[MINOR(inode->i_rdev)].device->host->hostt->usage_count)--;
81
        if(sr_template.usage_count) (*sr_template.usage_count)--;
82
}
83
 
84
static struct file_operations sr_fops =
85
{
86
        NULL,                   /* lseek - default */
87
        block_read,             /* read - general block-dev read */
88
        block_write,            /* write - general block-dev write */
89
        NULL,                   /* readdir - bad */
90
        NULL,                   /* select */
91
        sr_ioctl,               /* ioctl */
92
        NULL,                   /* mmap */
93
        sr_open,        /* special open code */
94
        sr_release,             /* release */
95
        NULL,                   /* fsync */
96
        NULL,                   /* fasync */
97
        check_cdrom_media_change,  /* Disk change */
98
        NULL                    /* revalidate */
99
};
100
 
101
/*
102
 * This function checks to see if the media has been changed in the
103
 * CDROM drive.  It is possible that we have already sensed a change,
104
 * or the drive may have sensed one and not yet reported it.  We must
105
 * be ready for either case. This function always reports the current
106
 * value of the changed bit.  If flag is 0, then the changed bit is reset.
107
 * This function could be done as an ioctl, but we would need to have
108
 * an inode for that to work, and we do not always have one.
109
 */
110
 
111
int check_cdrom_media_change(kdev_t full_dev){
112
        int retval, target;
113
        struct inode inode;
114
        int flag = 0;
115
 
116
        target =  MINOR(full_dev);
117
 
118
        if (target >= sr_template.nr_dev) {
119
                printk("CD-ROM request error: invalid device.\n");
120
                return 0;
121
        };
122
 
123
        inode.i_rdev = full_dev;  /* This is all we really need here */
124
        retval = sr_ioctl(&inode, NULL, SCSI_IOCTL_TEST_UNIT_READY, 0);
125
 
126
        if(retval){ /* Unable to test, unit probably not ready.  This usually
127
                 * means there is no disc in the drive.  Mark as changed,
128
                 * and we will figure it out later once the drive is
129
                 * available again.  */
130
 
131
        scsi_CDs[target].device->changed = 1;
132
        return 1; /* This will force a flush, if called from
133
                   * check_disk_change */
134
        };
135
 
136
        retval = scsi_CDs[target].device->changed;
137
        if(!flag) {
138
        scsi_CDs[target].device->changed = 0;
139
        /* If the disk changed, the capacity will now be different,
140
         * so we force a re-read of this information */
141
        if (retval) scsi_CDs[target].needs_sector_size = 1;
142
        };
143
        return retval;
144
}
145
 
146
/*
147
 * rw_intr is the interrupt routine for the device driver.  It will be notified on the
148
 * end of a SCSI read / write, and will take on of several actions based on success or failure.
149
 */
150
 
151
static void rw_intr (Scsi_Cmnd * SCpnt)
152
{
153
        int result = SCpnt->result;
154
        int this_count = SCpnt->this_count;
155
        int good_sectors = (result == 0 ? this_count : 0);
156
        int block_sectors = 0;
157
 
158
#ifdef DEBUG
159
        printk("sr.c done: %x %x\n",result, SCpnt->request.bh->b_data);
160
#endif
161
    /*
162
      Handle MEDIUM ERRORs or VOLUME OVERFLOWs that indicate partial success.
163
      Since this is a relatively rare error condition, no care is taken to
164
      avoid unnecessary additional work such as memcpy's that could be avoided.
165
    */
166
 
167
        if (driver_byte(result) != 0 &&              /* An error occurred */
168
            SCpnt->sense_buffer[0] == 0xF0 &&        /* Sense data is valid */
169
            (SCpnt->sense_buffer[2] == MEDIUM_ERROR ||
170
             SCpnt->sense_buffer[2] == VOLUME_OVERFLOW ||
171
             SCpnt->sense_buffer[2] == ILLEGAL_REQUEST))
172
          {
173
            long error_sector = (SCpnt->sense_buffer[3] << 24) |
174
                                (SCpnt->sense_buffer[4] << 16) |
175
                                (SCpnt->sense_buffer[5] << 8) |
176
                                SCpnt->sense_buffer[6];
177
            int device_nr = DEVICE_NR(SCpnt->request.rq_dev);
178
            if (SCpnt->request.bh != NULL)
179
              block_sectors = SCpnt->request.bh->b_size >> 9;
180
            if (block_sectors < 4) block_sectors = 4;
181
            if (scsi_CDs[device_nr].sector_size == 2048)
182
              error_sector <<= 2;
183
            error_sector &= ~ (block_sectors - 1);
184
            good_sectors = error_sector - SCpnt->request.sector;
185
            if (good_sectors < 0 || good_sectors >= this_count)
186
              good_sectors = 0;
187
            /*
188
              The SCSI specification allows for the value returned by READ
189
              CAPACITY to be up to 75 2K sectors past the last readable
190
              block.  Therefore, if we hit a medium error within the last
191
              75 2K sectors, we decrease the saved size value.
192
            */
193
            if ((error_sector >> 1) < sr_sizes[device_nr] &&
194
                scsi_CDs[device_nr].capacity - error_sector < 4*75)
195
              sr_sizes[device_nr] = error_sector >> 1;
196
          }
197
 
198
        if (good_sectors > 0)
199
    { /* Some sectors were read successfully. */
200
        if (SCpnt->use_sg == 0) {
201
                    if (SCpnt->buffer != SCpnt->request.buffer)
202
            {
203
                int offset;
204
                offset = (SCpnt->request.sector % 4) << 9;
205
                memcpy((char *)SCpnt->request.buffer,
206
                       (char *)SCpnt->buffer + offset,
207
                       good_sectors << 9);
208
                /* Even though we are not using scatter-gather, we look
209
                 * ahead and see if there is a linked request for the
210
                 * other half of this buffer.  If there is, then satisfy
211
                 * it. */
212
                if((offset == 0) && good_sectors == 2 &&
213
                   SCpnt->request.nr_sectors > good_sectors &&
214
                   SCpnt->request.bh &&
215
                   SCpnt->request.bh->b_reqnext &&
216
                   SCpnt->request.bh->b_reqnext->b_size == 1024) {
217
                    memcpy((char *)SCpnt->request.bh->b_reqnext->b_data,
218
                           (char *)SCpnt->buffer + 1024,
219
                           1024);
220
                    good_sectors += 2;
221
                };
222
 
223
                scsi_free(SCpnt->buffer, 2048);
224
            }
225
        } else {
226
                    struct scatterlist * sgpnt;
227
                    int i;
228
                    sgpnt = (struct scatterlist *) SCpnt->buffer;
229
                    for(i=0; i<SCpnt->use_sg; i++) {
230
                if (sgpnt[i].alt_address) {
231
                    if (sgpnt[i].alt_address != sgpnt[i].address) {
232
                        memcpy(sgpnt[i].alt_address, sgpnt[i].address, sgpnt[i].length);
233
                    };
234
                    scsi_free(sgpnt[i].address, sgpnt[i].length);
235
                };
236
                    };
237
                    scsi_free(SCpnt->buffer, SCpnt->sglist_len);  /* Free list of scatter-gather pointers */
238
                    if(SCpnt->request.sector % 4) good_sectors -= 2;
239
            /* See   if there is a padding record at the end that needs to be removed */
240
                    if(good_sectors > SCpnt->request.nr_sectors)
241
                good_sectors -= 2;
242
        };
243
 
244
#ifdef DEBUG
245
                printk("(%x %x %x) ",SCpnt->request.bh, SCpnt->request.nr_sectors,
246
                       good_sectors);
247
#endif
248
                if (SCpnt->request.nr_sectors > this_count)
249
        {
250
                        SCpnt->request.errors = 0;
251
                        if (!SCpnt->request.bh)
252
                            panic("sr.c: linked page request (%lx %x)",
253
                      SCpnt->request.sector, this_count);
254
        }
255
 
256
        SCpnt = end_scsi_request(SCpnt, 1, good_sectors);  /* All done */
257
        if (result == 0)
258
          {
259
            requeue_sr_request(SCpnt);
260
            return;
261
          }
262
    }
263
 
264
    if (good_sectors == 0) {
265
        /* We only come through here if no sectors were read successfully. */
266
 
267
    /* Free up any indirection buffers we allocated for DMA purposes. */
268
        if (SCpnt->use_sg) {
269
        struct scatterlist * sgpnt;
270
        int i;
271
        sgpnt = (struct scatterlist *) SCpnt->buffer;
272
        for(i=0; i<SCpnt->use_sg; i++) {
273
            if (sgpnt[i].alt_address) {
274
                scsi_free(sgpnt[i].address, sgpnt[i].length);
275
            }
276
        }
277
        scsi_free(SCpnt->buffer, SCpnt->sglist_len);  /* Free list of scatter-gather pointers */
278
        } else {
279
        if (SCpnt->buffer != SCpnt->request.buffer)
280
            scsi_free(SCpnt->buffer, SCpnt->bufflen);
281
        }
282
 
283
    }
284
 
285
        if (driver_byte(result) != 0) {
286
                if ((SCpnt->sense_buffer[0] & 0x7f) == 0x70) {
287
                        if ((SCpnt->sense_buffer[2] & 0xf) == UNIT_ATTENTION) {
288
                                /* detected disc change.  set a bit and quietly refuse
289
                                 * further access.      */
290
 
291
                                scsi_CDs[DEVICE_NR(SCpnt->request.rq_dev)].device->changed = 1;
292
                                SCpnt = end_scsi_request(SCpnt, 0, this_count);
293
                                requeue_sr_request(SCpnt);
294
                                return;
295
                        }
296
                }
297
 
298
                if (SCpnt->sense_buffer[2] == ILLEGAL_REQUEST) {
299
                        printk("CD-ROM error: ");
300
                        print_sense("sr", SCpnt);
301
                        printk("command was: ");
302
                        print_command(SCpnt->cmnd);
303
                        if (scsi_CDs[DEVICE_NR(SCpnt->request.rq_dev)].ten) {
304
                                scsi_CDs[DEVICE_NR(SCpnt->request.rq_dev)].ten = 0;
305
                                requeue_sr_request(SCpnt);
306
                                result = 0;
307
                                return;
308
                        } else {
309
                                SCpnt = end_scsi_request(SCpnt, 0, this_count);
310
                                requeue_sr_request(SCpnt); /* Do next request */
311
                                return;
312
                        }
313
 
314
                }
315
 
316
                if (SCpnt->sense_buffer[2] == NOT_READY) {
317
                        printk("CD-ROM not ready.  Make sure you have a disc in the drive.\n");
318
                        SCpnt = end_scsi_request(SCpnt, 0, this_count);
319
                        requeue_sr_request(SCpnt); /* Do next request */
320
                        return;
321
                }
322
 
323
                if (SCpnt->sense_buffer[2] == MEDIUM_ERROR) {
324
                    printk("scsi%d: MEDIUM ERROR on "
325
                           "channel %d, id %d, lun %d, CDB: ",
326
                           SCpnt->host->host_no, (int) SCpnt->channel,
327
                           (int) SCpnt->target, (int) SCpnt->lun);
328
                    print_command(SCpnt->cmnd);
329
                    print_sense("sr", SCpnt);
330
                    SCpnt = end_scsi_request(SCpnt, 0, block_sectors);
331
                    requeue_sr_request(SCpnt);
332
                    return;
333
                }
334
 
335
                if (SCpnt->sense_buffer[2] == VOLUME_OVERFLOW) {
336
                    printk("scsi%d: VOLUME OVERFLOW on "
337
                           "channel %d, id %d, lun %d, CDB: ",
338
                           SCpnt->host->host_no, (int) SCpnt->channel,
339
                           (int) SCpnt->target, (int) SCpnt->lun);
340
                    print_command(SCpnt->cmnd);
341
                    print_sense("sr", SCpnt);
342
                    SCpnt = end_scsi_request(SCpnt, 0, block_sectors);
343
                    requeue_sr_request(SCpnt);
344
                    return;
345
                }
346
    }
347
 
348
        /* We only get this far if we have an error we have not recognized */
349
        if(result) {
350
        printk("SCSI CD error : host %d id %d lun %d return code = %03x\n",
351
               scsi_CDs[DEVICE_NR(SCpnt->request.rq_dev)].device->host->host_no,
352
               scsi_CDs[DEVICE_NR(SCpnt->request.rq_dev)].device->id,
353
               scsi_CDs[DEVICE_NR(SCpnt->request.rq_dev)].device->lun,
354
               result);
355
 
356
        if (status_byte(result) == CHECK_CONDITION)
357
            print_sense("sr", SCpnt);
358
 
359
        SCpnt = end_scsi_request(SCpnt, 0, SCpnt->request.current_nr_sectors);
360
        requeue_sr_request(SCpnt);
361
    }
362
}
363
 
364
/*
365
 * Here I tried to implement support for multisession-CD's
366
 *
367
 * Much of this has do be done with vendor-specific SCSI-commands, because
368
 * multisession is newer than the SCSI-II standard.
369
 * So I have to complete it step by step. Useful information is welcome.
370
 *
371
 * Actually works:
372
 *   - NEC:     Detection and support of multisession CD's. Special handling
373
 *              for XA-disks is not necessary.
374
 *
375
 *   - TOSHIBA: setting density is done here now, mounting PhotoCD's should
376
 *              work now without running the program "set_density"
377
 *              Multisession CD's are supported too.
378
 *
379
 *   Gerd Knorr <kraxel@cs.tu-berlin.de>
380
 */
381
/*
382
 * 19950704 operator@melchior.cuivre.fdn.fr (Thomas Quinot)
383
 *
384
 *   - SONY:    Same as Nec.
385
 *
386
 *   - PIONEER: works with SONY code (may be others too ?)
387
 */
388
 
389
void sr_photocd(struct inode *inode)
390
{
391
    unsigned long   sector,min,sec,frame;
392
    unsigned char   buf[40];    /* the buffer for the ioctl */
393
    unsigned char   *cmd;       /* the scsi-command */
394
    unsigned char   *send;      /* the data we send to the drive ... */
395
    unsigned char   *rec;       /* ... and get back */
396
    int             rc,is_xa,no_multi;
397
 
398
    if (scsi_CDs[MINOR(inode->i_rdev)].xa_flags & 0x02) {
399
#ifdef DEBUG
400
        printk(KERN_DEBUG "sr_photocd: CDROM and/or driver do not support multisession CD's");
401
#endif
402
        return;
403
    }
404
 
405
    if (!suser()) {
406
        /* I'm not the superuser, so SCSI_IOCTL_SEND_COMMAND isn't allowed
407
         * for me. That's why mpcd_sector will be initialized with zero,
408
         * because I'm not able to get the right value. Necessary only if
409
         * access_count is 1, else no disk change happened since the last
410
         * call of this function and we can keep the old value.
411
         */
412
        if (1 == scsi_CDs[MINOR(inode->i_rdev)].device->access_count) {
413
            scsi_CDs[MINOR(inode->i_rdev)].mpcd_sector = 0;
414
            scsi_CDs[MINOR(inode->i_rdev)].xa_flags &= ~0x01;
415
        }
416
        return;
417
    }
418
 
419
    sector   = 0;
420
    is_xa    = 0;
421
    no_multi = 0;
422
    cmd = rec = &buf[8];
423
 
424
    switch(scsi_CDs[MINOR(inode->i_rdev)].device->manufacturer) {
425
 
426
    case SCSI_MAN_NEC:
427
#ifdef DEBUG
428
        printk(KERN_DEBUG "sr_photocd: use NEC code\n");
429
#endif
430
        memset(buf,0,40);
431
        *((unsigned int*)buf)   = 0x0;   /* we send nothing...     */
432
        *((unsigned int*)buf+1) = 0x16;  /* and receive 0x16 bytes */
433
        cmd[0] = 0xde;
434
        cmd[1] = 0x03;
435
        cmd[2] = 0xb0;
436
        rc = kernel_scsi_ioctl(scsi_CDs[MINOR(inode->i_rdev)].device,
437
                           SCSI_IOCTL_SEND_COMMAND, buf);
438
        if (rc != 0) {
439
            if (rc != 0x28000002) /* drop "not ready" */
440
                printk(KERN_WARNING"sr_photocd: ioctl error (NEC): 0x%x\n",rc);
441
            break;
442
        }
443
        if (rec[14] != 0 && rec[14] != 0xb0) {
444
            printk(KERN_INFO"sr_photocd: (NEC) Hmm, seems the CDROM doesn't support multisession CD's\n");
445
            no_multi = 1;
446
            break;
447
        }
448
        min   = (unsigned long) rec[15]/16*10 + (unsigned long) rec[15]%16;
449
        sec   = (unsigned long) rec[16]/16*10 + (unsigned long) rec[16]%16;
450
        frame = (unsigned long) rec[17]/16*10 + (unsigned long) rec[17]%16;
451
        sector = min*CD_SECS*CD_FRAMES + sec*CD_FRAMES + frame;
452
        is_xa  = (rec[14] == 0xb0);
453
#ifdef DEBUG
454
        if (sector) {
455
            printk(KERN_DEBUG "sr_photocd: multisession CD detected. start: %lu\n",sector);
456
        }
457
#endif
458
        break;
459
 
460
    case SCSI_MAN_TOSHIBA:
461
#ifdef DEBUG
462
        printk(KERN_DEBUG "sr_photocd: use TOSHIBA code\n");
463
#endif
464
 
465
        /* we request some disc information (is it a XA-CD ?,
466
         * where starts the last session ?) */
467
        memset(buf,0,40);
468
        *((unsigned int*)buf)   = (unsigned int) 0;
469
        *((unsigned int*)buf+1) = (unsigned int) 4;  /* receive 4 bytes */
470
        cmd[0]                  = (unsigned char) 0x00c7;
471
        cmd[1]                  = (unsigned char) 3;
472
        rc = kernel_scsi_ioctl(scsi_CDs[MINOR(inode->i_rdev)].device,
473
                               SCSI_IOCTL_SEND_COMMAND, buf);
474
        if (rc != 0) {
475
            if (rc == 0x28000002) {
476
                /* Got a "not ready" - error. No chance to find out if this is
477
                 * because there is no CD in the drive or because the drive
478
                 * don't knows multisession CD's. So I need to do an extra
479
                 * check... */
480
                if (!kernel_scsi_ioctl(scsi_CDs[MINOR(inode->i_rdev)].device,
481
                                       SCSI_IOCTL_TEST_UNIT_READY, NULL)) {
482
                    printk(KERN_INFO "sr_photocd: (TOSHIBA) Hmm, seems the CDROM doesn't support multisession CD's\n");
483
                    no_multi = 1;
484
                }
485
            } else
486
                printk(KERN_INFO"sr_photocd: ioctl error (TOSHIBA #1): 0x%x\n",rc);
487
            break; /* if the first ioctl fails, we don't call the second one */
488
        }
489
        is_xa  = (rec[0] == 0x20);
490
        min    = (unsigned long) rec[1]/16*10 + (unsigned long) rec[1]%16;
491
        sec    = (unsigned long) rec[2]/16*10 + (unsigned long) rec[2]%16;
492
        frame  = (unsigned long) rec[3]/16*10 + (unsigned long) rec[3]%16;
493
        sector = min*CD_SECS*CD_FRAMES + sec*CD_FRAMES + frame;
494
        if (sector) {
495
            sector -= CD_BLOCK_OFFSET;
496
#ifdef DEBUG
497
            printk(KERN_DEBUG "sr_photocd: multisession CD detected: start: %lu\n",sector);
498
#endif
499
        }
500
 
501
        /* now we do a get_density... */
502
        memset(buf,0,40);
503
        *((unsigned int*)buf)   = (unsigned int) 0;
504
        *((unsigned int*)buf+1) = (unsigned int) 12;
505
        cmd[0]                  = (unsigned char) MODE_SENSE;
506
        cmd[2]                  = (unsigned char) 1;
507
        cmd[4]                  = (unsigned char) 12;
508
        rc = kernel_scsi_ioctl(scsi_CDs[MINOR(inode->i_rdev)].device,
509
                               SCSI_IOCTL_SEND_COMMAND, buf);
510
        if (rc != 0) {
511
            printk(KERN_WARNING "sr_photocd: ioctl error (TOSHIBA #2): 0x%x\n",rc);
512
            break;
513
        }
514
#ifdef DEBUG
515
        printk(KERN_DEBUG "sr_photocd: get_density: 0x%x\n",rec[4]);
516
#endif
517
 
518
        /* ...and only if necessary a set_density */
519
        if ((rec[4] != 0x81 && is_xa) || (rec[4] != 0 && !is_xa)) {
520
#ifdef DEBUG
521
            printk(KERN_DEBUG "sr_photocd: doing set_density\n");
522
#endif
523
            memset(buf,0,40);
524
            *((unsigned int*)buf)   = (unsigned int) 12;  /* send 12 bytes */
525
            *((unsigned int*)buf+1) = (unsigned int) 0;
526
            cmd[0]                  = (unsigned char) MODE_SELECT;
527
            cmd[1]                  = (unsigned char) (1 << 4);
528
            cmd[4]                  = (unsigned char) 12;
529
            send = &cmd[6];             /* this is a 6-Byte command    */
530
            send[ 3]                = (unsigned char) 0x08; /* data for cmd */
531
            /* density 0x81 for XA, 0 else */
532
            send[ 4]                = (is_xa) ?
533
                                    (unsigned char) 0x81 : (unsigned char) 0;
534
            send[10]                = (unsigned char) 0x08;
535
            rc = kernel_scsi_ioctl(scsi_CDs[MINOR(inode->i_rdev)].device,
536
                                   SCSI_IOCTL_SEND_COMMAND, buf);
537
            if (rc != 0) {
538
                printk(KERN_WARNING "sr_photocd: ioctl error (TOSHIBA #3): 0x%x\n",rc);
539
            }
540
            /* The set_density command may have changed the
541
             * sector size or capacity. */
542
            scsi_CDs[MINOR(inode->i_rdev)].needs_sector_size = 1;
543
        }
544
        break;
545
 
546
    case SCSI_MAN_SONY: /* Thomas QUINOT <thomas@melchior.cuivre.fdn.fr> */
547
    case SCSI_MAN_PIONEER:
548
    case SCSI_MAN_UNKNOWN:
549
#ifdef DEBUG
550
        printk(KERN_DEBUG "sr_photocd: use SONY/PIONEER code\n");
551
#endif
552
        get_sectorsize(MINOR(inode->i_rdev));   /* spinup (avoid timeout) */
553
        memset(buf,0,40);
554
        *((unsigned int*)buf)   = 0x0;   /* we send nothing...     */
555
        *((unsigned int*)buf+1) = 0x0c;  /* and receive 0x0c bytes */
556
        cmd[0] = READ_TOC;
557
        cmd[8] = 0x0c;
558
        cmd[9] = 0x40;
559
        rc = kernel_scsi_ioctl(scsi_CDs[MINOR(inode->i_rdev)].device,
560
                               SCSI_IOCTL_SEND_COMMAND, buf);
561
 
562
        if (rc != 0) {
563
            if (rc != 0x28000002) /* drop "not ready" */
564
                printk(KERN_WARNING "sr_photocd: ioctl error (SONY/PIONEER): 0x%x\n",rc);
565
            break;
566
        }
567
        if ((rec[0] << 8) + rec[1] < 0x0a) {
568
            printk(KERN_INFO "sr_photocd: (SONY/PIONEER) Hmm, seems the CDROM doesn't support multisession CD's\n");
569
            no_multi = 1;
570
            break;
571
        }
572
        sector = rec[11] + (rec[10] << 8) + (rec[9] << 16) + (rec[8] << 24);
573
        is_xa = !!sector;
574
#ifdef DEBUG
575
        if (sector)
576
            printk (KERN_DEBUG "sr_photocd: multisession CD detected. start: %lu\n",sector);
577
#endif
578
        break;
579
 
580
    case SCSI_MAN_NEC_OLDCDR:
581
    default:
582
        sector = 0;
583
        no_multi = 1;
584
        break; }
585
 
586
    scsi_CDs[MINOR(inode->i_rdev)].mpcd_sector = sector;
587
    if (is_xa)
588
        scsi_CDs[MINOR(inode->i_rdev)].xa_flags |= 0x01;
589
    else
590
        scsi_CDs[MINOR(inode->i_rdev)].xa_flags &= ~0x01;
591
    if (no_multi)
592
        scsi_CDs[MINOR(inode->i_rdev)].xa_flags |= 0x02;
593
    return;
594
}
595
 
596
static int sr_open(struct inode * inode, struct file * filp)
597
{
598
    if(MINOR(inode->i_rdev) >= sr_template.nr_dev ||
599
       !scsi_CDs[MINOR(inode->i_rdev)].device) return -ENXIO;   /* No such device */
600
 
601
    if (filp->f_mode & 2)
602
        return -EROFS;
603
 
604
    if(sr_template.usage_count) (*sr_template.usage_count)++;
605
 
606
    sr_ioctl(inode,filp,CDROMCLOSETRAY,0);
607
    check_disk_change(inode->i_rdev);
608
 
609
    if(!scsi_CDs[MINOR(inode->i_rdev)].device->access_count++)
610
        sr_ioctl(inode, NULL, SCSI_IOCTL_DOORLOCK, 0);
611
    if (scsi_CDs[MINOR(inode->i_rdev)].device->host->hostt->usage_count)
612
        (*scsi_CDs[MINOR(inode->i_rdev)].device->host->hostt->usage_count)++;
613
 
614
    sr_photocd(inode);
615
 
616
    /* If this device did not have media in the drive at boot time, then
617
     * we would have been unable to get the sector size.  Check to see if
618
     * this is the case, and try again.
619
     */
620
 
621
    if(scsi_CDs[MINOR(inode->i_rdev)].needs_sector_size)
622
        get_sectorsize(MINOR(inode->i_rdev));
623
 
624
    return 0;
625
}
626
 
627
 
628
/*
629
 * do_sr_request() is the request handler function for the sr driver.
630
 * Its function in life is to take block device requests, and
631
 * translate them to SCSI commands.
632
 */
633
 
634
static void do_sr_request (void)
635
{
636
    Scsi_Cmnd * SCpnt = NULL;
637
    struct request * req = NULL;
638
    Scsi_Device * SDev;
639
    unsigned long flags;
640
    int flag = 0;
641
 
642
    while (1==1){
643
        save_flags(flags);
644
        cli();
645
        if (CURRENT != NULL && CURRENT->rq_status == RQ_INACTIVE) {
646
            restore_flags(flags);
647
            return;
648
        };
649
 
650
        INIT_SCSI_REQUEST;
651
 
652
        SDev = scsi_CDs[DEVICE_NR(CURRENT->rq_dev)].device;
653
 
654
        /*
655
         * I am not sure where the best place to do this is.  We need
656
         * to hook in a place where we are likely to come if in user
657
         * space.
658
         */
659
        if( SDev->was_reset )
660
        {
661
            /*
662
             * We need to relock the door, but we might
663
             * be in an interrupt handler.  Only do this
664
             * from user space, since we do not want to
665
             * sleep from an interrupt.
666
             */
667
            if( SDev->removable && !intr_count )
668
            {
669
                scsi_ioctl(SDev, SCSI_IOCTL_DOORLOCK, 0);
670
            }
671
            SDev->was_reset = 0;
672
        }
673
 
674
        if (flag++ == 0)
675
            SCpnt = allocate_device(&CURRENT,
676
                                    scsi_CDs[DEVICE_NR(CURRENT->rq_dev)].device, 0);
677
        else SCpnt = NULL;
678
        restore_flags(flags);
679
 
680
        /* This is a performance enhancement.  We dig down into the request list and
681
         * try to find a queueable request (i.e. device not busy, and host able to
682
         * accept another command.  If we find one, then we queue it. This can
683
         * make a big difference on systems with more than one disk drive.  We want
684
         * to have the interrupts off when monkeying with the request list, because
685
         * otherwise the kernel might try to slip in a request in between somewhere. */
686
 
687
        if (!SCpnt && sr_template.nr_dev > 1){
688
            struct request *req1;
689
            req1 = NULL;
690
            save_flags(flags);
691
            cli();
692
            req = CURRENT;
693
            while(req){
694
                SCpnt = request_queueable(req,
695
                                          scsi_CDs[DEVICE_NR(req->rq_dev)].device);
696
                if(SCpnt) break;
697
                req1 = req;
698
                req = req->next;
699
            };
700
            if (SCpnt && req->rq_status == RQ_INACTIVE) {
701
                if (req == CURRENT)
702
                    CURRENT = CURRENT->next;
703
                else
704
                    req1->next = req->next;
705
            };
706
            restore_flags(flags);
707
        };
708
 
709
        if (!SCpnt)
710
            return; /* Could not find anything to do */
711
 
712
        wake_up(&wait_for_request);
713
 
714
        /* Queue command */
715
        requeue_sr_request(SCpnt);
716
    };  /* While */
717
}
718
 
719
void requeue_sr_request (Scsi_Cmnd * SCpnt)
720
{
721
        unsigned int dev, block, realcount;
722
        unsigned char cmd[10], *buffer, tries;
723
        int this_count, start, end_rec;
724
 
725
        tries = 2;
726
 
727
 repeat:
728
        if(!SCpnt || SCpnt->request.rq_status == RQ_INACTIVE) {
729
                do_sr_request();
730
                return;
731
        }
732
 
733
        dev =  MINOR(SCpnt->request.rq_dev);
734
        block = SCpnt->request.sector;
735
        buffer = NULL;
736
        this_count = 0;
737
 
738
        if (dev >= sr_template.nr_dev) {
739
                /* printk("CD-ROM request error: invalid device.\n");                   */
740
                SCpnt = end_scsi_request(SCpnt, 0, SCpnt->request.nr_sectors);
741
                tries = 2;
742
                goto repeat;
743
        }
744
 
745
        if (!scsi_CDs[dev].use) {
746
                /* printk("CD-ROM request error: device marked not in use.\n");         */
747
                SCpnt = end_scsi_request(SCpnt, 0, SCpnt->request.nr_sectors);
748
                tries = 2;
749
                goto repeat;
750
        }
751
 
752
        if (scsi_CDs[dev].device->changed) {
753
        /*
754
         * quietly refuse to do anything to a changed disc
755
         * until the changed bit has been reset
756
         */
757
                /* printk("CD-ROM has been changed.  Prohibiting further I/O.\n");      */
758
                SCpnt = end_scsi_request(SCpnt, 0, SCpnt->request.nr_sectors);
759
                tries = 2;
760
                goto repeat;
761
        }
762
 
763
        switch (SCpnt->request.cmd)
764
    {
765
    case WRITE:
766
        SCpnt = end_scsi_request(SCpnt, 0, SCpnt->request.nr_sectors);
767
        goto repeat;
768
        break;
769
    case READ :
770
        cmd[0] = READ_6;
771
        break;
772
    default :
773
        panic ("Unknown sr command %d\n", SCpnt->request.cmd);
774
    }
775
 
776
        cmd[1] = (SCpnt->lun << 5) & 0xe0;
777
 
778
    /*
779
     * Now do the grungy work of figuring out which sectors we need, and
780
     * where in memory we are going to put them.
781
     *
782
     * The variables we need are:
783
     *
784
     * this_count= number of 512 byte sectors being read
785
     * block     = starting cdrom sector to read.
786
     * realcount = # of cdrom sectors to read
787
     *
788
     * The major difference between a scsi disk and a scsi cdrom
789
     * is that we will always use scatter-gather if we can, because we can
790
     * work around the fact that the buffer cache has a block size of 1024,
791
     * and we have 2048 byte sectors.  This code should work for buffers that
792
     * are any multiple of 512 bytes long.
793
     */
794
 
795
        SCpnt->use_sg = 0;
796
 
797
        if (SCpnt->host->sg_tablesize > 0 &&
798
            (!need_isa_buffer ||
799
         dma_free_sectors >= 10)) {
800
        struct buffer_head * bh;
801
        struct scatterlist * sgpnt;
802
        int count, this_count_max;
803
        bh = SCpnt->request.bh;
804
        this_count = 0;
805
        count = 0;
806
        this_count_max = (scsi_CDs[dev].ten ? 0xffff : 0xff) << 4;
807
        /* Calculate how many links we can use.  First see if we need
808
         * a padding record at the start */
809
        this_count = SCpnt->request.sector % 4;
810
        if(this_count) count++;
811
        while(bh && count < SCpnt->host->sg_tablesize) {
812
            if ((this_count + (bh->b_size >> 9)) > this_count_max) break;
813
            this_count += (bh->b_size >> 9);
814
            count++;
815
            bh = bh->b_reqnext;
816
        };
817
        /* Fix up in case of an odd record at the end */
818
        end_rec = 0;
819
        if(this_count % 4) {
820
            if (count < SCpnt->host->sg_tablesize) {
821
                count++;
822
                end_rec = (4 - (this_count % 4)) << 9;
823
                this_count += 4 - (this_count % 4);
824
            } else {
825
                count--;
826
                this_count -= (this_count % 4);
827
            };
828
        };
829
        SCpnt->use_sg = count;  /* Number of chains */
830
        /* scsi_malloc can only allocate in chunks of 512 bytes */
831
        count  = (SCpnt->use_sg * sizeof(struct scatterlist) + 511) & ~511;
832
 
833
        SCpnt->sglist_len = count;
834
        sgpnt = (struct scatterlist * ) scsi_malloc(count);
835
        if (!sgpnt) {
836
            printk("Warning - running *really* short on DMA buffers\n");
837
            SCpnt->use_sg = 0;  /* No memory left - bail out */
838
        } else {
839
            buffer = (unsigned char *) sgpnt;
840
            count = 0;
841
            bh = SCpnt->request.bh;
842
            if(SCpnt->request.sector % 4) {
843
                sgpnt[count].length = (SCpnt->request.sector % 4) << 9;
844
                sgpnt[count].address = (char *) scsi_malloc(sgpnt[count].length);
845
                if(!sgpnt[count].address) panic("SCSI DMA pool exhausted.");
846
                sgpnt[count].alt_address = sgpnt[count].address; /* Flag to delete
847
                                                                    if needed */
848
                count++;
849
            };
850
            for(bh = SCpnt->request.bh; count < SCpnt->use_sg;
851
                count++, bh = bh->b_reqnext) {
852
                if (bh) { /* Need a placeholder at the end of the record? */
853
                    sgpnt[count].address = bh->b_data;
854
                    sgpnt[count].length = bh->b_size;
855
                    sgpnt[count].alt_address = NULL;
856
                } else {
857
                    sgpnt[count].address = (char *) scsi_malloc(end_rec);
858
                    if(!sgpnt[count].address) panic("SCSI DMA pool exhausted.");
859
                    sgpnt[count].length = end_rec;
860
                    sgpnt[count].alt_address = sgpnt[count].address;
861
                    if (count+1 != SCpnt->use_sg) panic("Bad sr request list");
862
                    break;
863
                };
864
                if (((long) sgpnt[count].address) + sgpnt[count].length - 1 >
865
                    ISA_DMA_THRESHOLD && SCpnt->host->unchecked_isa_dma) {
866
                    sgpnt[count].alt_address = sgpnt[count].address;
867
                    /* We try to avoid exhausting the DMA pool, since it is easier
868
                     * to control usage here.  In other places we might have a more
869
                     * pressing need, and we would be screwed if we ran out */
870
                    if(dma_free_sectors < (sgpnt[count].length >> 9) + 5) {
871
                        sgpnt[count].address = NULL;
872
                    } else {
873
                        sgpnt[count].address = (char *) scsi_malloc(sgpnt[count].length);
874
                    };
875
                    /* If we start running low on DMA buffers, we abort the scatter-gather
876
                     * operation, and free all of the memory we have allocated.  We want to
877
                     * ensure that all scsi operations are able to do at least a non-scatter/gather
878
                     * operation */
879
                    if(sgpnt[count].address == NULL){ /* Out of dma memory */
880
                        printk("Warning: Running low on SCSI DMA buffers");
881
                        /* Try switching back to a non scatter-gather operation. */
882
                        while(--count >= 0){
883
                            if(sgpnt[count].alt_address)
884
                                scsi_free(sgpnt[count].address, sgpnt[count].length);
885
                        };
886
                        SCpnt->use_sg = 0;
887
                        scsi_free(buffer, SCpnt->sglist_len);
888
                        break;
889
                    }; /* if address == NULL */
890
                };  /* if need DMA fixup */
891
            };  /* for loop to fill list */
892
#ifdef DEBUG
893
            printk("SR: %d %d %d %d %d *** ",SCpnt->use_sg, SCpnt->request.sector,
894
                   this_count,
895
                   SCpnt->request.current_nr_sectors,
896
                   SCpnt->request.nr_sectors);
897
            for(count=0; count<SCpnt->use_sg; count++)
898
                printk("SGlist: %d %x %x %x\n", count,
899
                       sgpnt[count].address,
900
                       sgpnt[count].alt_address,
901
                       sgpnt[count].length);
902
#endif
903
        };  /* Able to allocate scatter-gather list */
904
        };
905
 
906
        if (SCpnt->use_sg == 0){
907
        /* We cannot use scatter-gather.  Do this the old fashion way */
908
        if (!SCpnt->request.bh)
909
            this_count = SCpnt->request.nr_sectors;
910
        else
911
            this_count = (SCpnt->request.bh->b_size >> 9);
912
 
913
        start = block % 4;
914
        if (start)
915
            {
916
            this_count = ((this_count > 4 - start) ?
917
                          (4 - start) : (this_count));
918
            buffer = (unsigned char *) scsi_malloc(2048);
919
            }
920
        else if (this_count < 4)
921
            {
922
            buffer = (unsigned char *) scsi_malloc(2048);
923
            }
924
        else
925
            {
926
            this_count -= this_count % 4;
927
            buffer = (unsigned char *) SCpnt->request.buffer;
928
            if (((long) buffer) + (this_count << 9) > ISA_DMA_THRESHOLD &&
929
                SCpnt->host->unchecked_isa_dma)
930
                buffer = (unsigned char *) scsi_malloc(this_count << 9);
931
            }
932
        };
933
 
934
        if (scsi_CDs[dev].sector_size == 2048)
935
        block = block >> 2; /* These are the sectors that the cdrom uses */
936
        else
937
        block = block & 0xfffffffc;
938
 
939
        realcount = (this_count + 3) / 4;
940
 
941
        if (scsi_CDs[dev].sector_size == 512) realcount = realcount << 2;
942
 
943
        if (((realcount > 0xff) || (block > 0x1fffff)) && scsi_CDs[dev].ten)
944
    {
945
                if (realcount > 0xffff)
946
        {
947
                        realcount = 0xffff;
948
                        this_count = realcount * (scsi_CDs[dev].sector_size >> 9);
949
        }
950
 
951
                cmd[0] += READ_10 - READ_6 ;
952
                cmd[2] = (unsigned char) (block >> 24) & 0xff;
953
                cmd[3] = (unsigned char) (block >> 16) & 0xff;
954
                cmd[4] = (unsigned char) (block >> 8) & 0xff;
955
                cmd[5] = (unsigned char) block & 0xff;
956
                cmd[6] = cmd[9] = 0;
957
                cmd[7] = (unsigned char) (realcount >> 8) & 0xff;
958
                cmd[8] = (unsigned char) realcount & 0xff;
959
    }
960
        else
961
    {
962
        if (realcount > 0xff)
963
        {
964
            realcount = 0xff;
965
            this_count = realcount * (scsi_CDs[dev].sector_size >> 9);
966
        }
967
 
968
        cmd[1] |= (unsigned char) ((block >> 16) & 0x1f);
969
        cmd[2] = (unsigned char) ((block >> 8) & 0xff);
970
        cmd[3] = (unsigned char) block & 0xff;
971
        cmd[4] = (unsigned char) realcount;
972
        cmd[5] = 0;
973
    }
974
 
975
#ifdef DEBUG
976
    {
977
        int i;
978
        printk("ReadCD: %d %d %d %d\n",block, realcount, buffer, this_count);
979
        printk("Use sg: %d\n", SCpnt->use_sg);
980
        printk("Dumping command: ");
981
        for(i=0; i<12; i++) printk("%2.2x ", cmd[i]);
982
        printk("\n");
983
    };
984
#endif
985
 
986
    /* Some dumb host adapters can speed transfers by knowing the
987
     * minimum transfersize in advance.
988
     *
989
     * We shouldn't disconnect in the middle of a sector, but the cdrom
990
     * sector size can be larger than the size of a buffer and the
991
     * transfer may be split to the size of a buffer.  So it's safe to
992
     * assume that we can at least transfer the minimum of the buffer
993
     * size (1024) and the sector size between each connect / disconnect.
994
     */
995
 
996
    SCpnt->transfersize = (scsi_CDs[dev].sector_size > 1024) ?
997
        1024 : scsi_CDs[dev].sector_size;
998
 
999
        SCpnt->this_count = this_count;
1000
        scsi_do_cmd (SCpnt, (void *) cmd, buffer,
1001
                 realcount * scsi_CDs[dev].sector_size,
1002
                 rw_intr, SR_TIMEOUT, MAX_RETRIES);
1003
}
1004
 
1005
static int sr_detect(Scsi_Device * SDp){
1006
 
1007
    if(SDp->type != TYPE_ROM && SDp->type != TYPE_WORM) return 0;
1008
 
1009
    printk("Detected scsi CD-ROM sr%d at scsi%d, channel %d, id %d, lun %d\n",
1010
           sr_template.dev_noticed++,
1011
           SDp->host->host_no, SDp->channel, SDp->id, SDp->lun);
1012
 
1013
    return 1;
1014
}
1015
 
1016
static int sr_attach(Scsi_Device * SDp){
1017
    Scsi_CD * cpnt;
1018
    int i;
1019
 
1020
    if(SDp->type != TYPE_ROM && SDp->type != TYPE_WORM) return 1;
1021
 
1022
    if (sr_template.nr_dev >= sr_template.dev_max)
1023
    {
1024
        SDp->attached--;
1025
        return 1;
1026
    }
1027
 
1028
    for(cpnt = scsi_CDs, i=0; i<sr_template.dev_max; i++, cpnt++)
1029
        if(!cpnt->device) break;
1030
 
1031
    if(i >= sr_template.dev_max) panic ("scsi_devices corrupt (sr)");
1032
 
1033
    SDp->scsi_request_fn = do_sr_request;
1034
    scsi_CDs[i].device = SDp;
1035
    sr_template.nr_dev++;
1036
    if(sr_template.nr_dev > sr_template.dev_max)
1037
        panic ("scsi_devices corrupt (sr)");
1038
    return 0;
1039
}
1040
 
1041
 
1042
static void sr_init_done (Scsi_Cmnd * SCpnt)
1043
{
1044
    struct request * req;
1045
 
1046
    req = &SCpnt->request;
1047
    req->rq_status = RQ_SCSI_DONE; /* Busy, but indicate request done */
1048
 
1049
    if (req->sem != NULL) {
1050
        up(req->sem);
1051
    }
1052
}
1053
 
1054
void get_sectorsize(int i){
1055
    unsigned char cmd[10];
1056
    unsigned char *buffer;
1057
    int the_result, retries;
1058
    Scsi_Cmnd * SCpnt;
1059
 
1060
    buffer = (unsigned char *) scsi_malloc(512);
1061
    SCpnt = allocate_device(NULL, scsi_CDs[i].device, 1);
1062
 
1063
    retries = 3;
1064
    do {
1065
        cmd[0] = READ_CAPACITY;
1066
        cmd[1] = (scsi_CDs[i].device->lun << 5) & 0xe0;
1067
        memset ((void *) &cmd[2], 0, 8);
1068
        SCpnt->request.rq_status = RQ_SCSI_BUSY;  /* Mark as really busy */
1069
        SCpnt->cmd_len = 0;
1070
 
1071
        memset(buffer, 0, 8);
1072
 
1073
        /* Do the command and wait.. */
1074
        {
1075
            struct semaphore sem = MUTEX_LOCKED;
1076
            SCpnt->request.sem = &sem;
1077
            scsi_do_cmd (SCpnt,
1078
                         (void *) cmd, (void *) buffer,
1079
                         512, sr_init_done,  SR_TIMEOUT,
1080
                         MAX_RETRIES);
1081
            down(&sem);
1082
        }
1083
 
1084
        the_result = SCpnt->result;
1085
        retries--;
1086
 
1087
    } while(the_result && retries);
1088
 
1089
    SCpnt->request.rq_status = RQ_INACTIVE;  /* Mark as not busy */
1090
 
1091
    wake_up(&SCpnt->device->device_wait);
1092
 
1093
    if (the_result) {
1094
        scsi_CDs[i].capacity = 0x1fffff;
1095
        scsi_CDs[i].sector_size = 2048;  /* A guess, just in case */
1096
        scsi_CDs[i].needs_sector_size = 1;
1097
    } else {
1098
        scsi_CDs[i].capacity = 1 + ((buffer[0] << 24) |
1099
                                    (buffer[1] << 16) |
1100
                                    (buffer[2] << 8) |
1101
                                    buffer[3]);
1102
        scsi_CDs[i].sector_size = (buffer[4] << 24) |
1103
            (buffer[5] << 16) | (buffer[6] << 8) | buffer[7];
1104
        switch (scsi_CDs[i].sector_size) {
1105
                /*
1106
                 * HP 4020i CD-Recorder reports 2340 byte sectors
1107
                 * Philips CD-Writers report 2352 byte sectors
1108
                 *
1109
                 * Use 2k sectors for them..
1110
                 */
1111
                case 0: case 2340: case 2352:
1112
                        scsi_CDs[i].sector_size = 2048;
1113
                        /* fall through */
1114
                case 2048:
1115
                        scsi_CDs[i].capacity *= 4;
1116
                        /* fall through */
1117
                case 512:
1118
                        break;
1119
                default:
1120
                        printk ("scd%d : unsupported sector size %d.\n",
1121
                                i, scsi_CDs[i].sector_size);
1122
                        scsi_CDs[i].capacity = 0;
1123
                        scsi_CDs[i].needs_sector_size = 1;
1124
        }
1125
        scsi_CDs[i].needs_sector_size = 0;
1126
        sr_sizes[i] = scsi_CDs[i].capacity >> (BLOCK_SIZE_BITS - 9);
1127
    };
1128
    scsi_free(buffer, 512);
1129
}
1130
 
1131
static int sr_registered = 0;
1132
 
1133
static int sr_init()
1134
{
1135
    int i;
1136
 
1137
    if(sr_template.dev_noticed == 0) return 0;
1138
 
1139
    if(!sr_registered) {
1140
        if (register_blkdev(MAJOR_NR,"sr",&sr_fops)) {
1141
            printk("Unable to get major %d for SCSI-CD\n",MAJOR_NR);
1142
            return 1;
1143
        }
1144
        sr_registered++;
1145
    }
1146
 
1147
 
1148
    if (scsi_CDs) return 0;
1149
    sr_template.dev_max = sr_template.dev_noticed + SR_EXTRA_DEVS;
1150
    scsi_CDs = (Scsi_CD *) scsi_init_malloc(sr_template.dev_max * sizeof(Scsi_CD), GFP_ATOMIC);
1151
    memset(scsi_CDs, 0, sr_template.dev_max * sizeof(Scsi_CD));
1152
 
1153
    sr_sizes = (int *) scsi_init_malloc(sr_template.dev_max * sizeof(int), GFP_ATOMIC);
1154
    memset(sr_sizes, 0, sr_template.dev_max * sizeof(int));
1155
 
1156
    sr_blocksizes = (int *) scsi_init_malloc(sr_template.dev_max *
1157
                                         sizeof(int), GFP_ATOMIC);
1158
    for(i=0;i<sr_template.dev_max;i++) sr_blocksizes[i] = 2048;
1159
    blksize_size[MAJOR_NR] = sr_blocksizes;
1160
    return 0;
1161
}
1162
 
1163
void sr_finish()
1164
{
1165
    int i;
1166
 
1167
    blk_dev[MAJOR_NR].request_fn = DEVICE_REQUEST;
1168
    blk_size[MAJOR_NR] = sr_sizes;
1169
 
1170
    for (i = 0; i < sr_template.nr_dev; ++i)
1171
    {
1172
        /* If we have already seen this, then skip it.  Comes up
1173
         * with loadable modules. */
1174
        if (scsi_CDs[i].capacity) continue;
1175
        scsi_CDs[i].capacity = 0x1fffff;
1176
        scsi_CDs[i].sector_size = 2048;  /* A guess, just in case */
1177
        scsi_CDs[i].needs_sector_size = 1;
1178
#if 0
1179
        /* seems better to leave this for later */
1180
        get_sectorsize(i);
1181
        printk("Scd sectorsize = %d bytes.\n", scsi_CDs[i].sector_size);
1182
#endif
1183
        scsi_CDs[i].use = 1;
1184
        scsi_CDs[i].ten = 1;
1185
        scsi_CDs[i].remap = 1;
1186
        scsi_CDs[i].auto_eject = 0; /* Default is not to eject upon unmount. */
1187
        sr_sizes[i] = scsi_CDs[i].capacity >> (BLOCK_SIZE_BITS - 9);
1188
    }
1189
 
1190
 
1191
    /* If our host adapter is capable of scatter-gather, then we increase
1192
     * the read-ahead to 16 blocks (32 sectors).  If not, we use
1193
     * a two block (4 sector) read ahead. */
1194
    if(scsi_CDs[0].device && scsi_CDs[0].device->host->sg_tablesize)
1195
        read_ahead[MAJOR_NR] = 32;  /* 32 sector read-ahead.  Always removable. */
1196
    else
1197
        read_ahead[MAJOR_NR] = 4;  /* 4 sector read-ahead */
1198
 
1199
    return;
1200
}
1201
 
1202
static void sr_detach(Scsi_Device * SDp)
1203
{
1204
    Scsi_CD * cpnt;
1205
    int i;
1206
 
1207
    for(cpnt = scsi_CDs, i=0; i<sr_template.dev_max; i++, cpnt++)
1208
        if(cpnt->device == SDp) {
1209
            kdev_t devi = MKDEV(MAJOR_NR, i);
1210
 
1211
            /*
1212
             * Since the cdrom is read-only, no need to sync the device.
1213
             * We should be kind to our buffer cache, however.
1214
             */
1215
            invalidate_inodes(devi);
1216
            invalidate_buffers(devi);
1217
 
1218
            /*
1219
             * Reset things back to a sane state so that one can re-load a new
1220
             * driver (perhaps the same one).
1221
             */
1222
            cpnt->device = NULL;
1223
            cpnt->capacity = 0;
1224
            SDp->attached--;
1225
            sr_template.nr_dev--;
1226
            sr_template.dev_noticed--;
1227
            sr_sizes[i] = 0;
1228
            return;
1229
        }
1230
    return;
1231
}
1232
 
1233
 
1234
#ifdef MODULE
1235
 
1236
int init_module(void) {
1237
    sr_template.usage_count = &mod_use_count_;
1238
    return scsi_register_module(MODULE_SCSI_DEV, &sr_template);
1239
}
1240
 
1241
void cleanup_module( void)
1242
{
1243
    scsi_unregister_module(MODULE_SCSI_DEV, &sr_template);
1244
    unregister_blkdev(SCSI_CDROM_MAJOR, "sr");
1245
    sr_registered--;
1246
    if(scsi_CDs != NULL) {
1247
        scsi_init_free((char *) scsi_CDs,
1248
                       (sr_template.dev_noticed + SR_EXTRA_DEVS)
1249
                       * sizeof(Scsi_CD));
1250
 
1251
        scsi_init_free((char *) sr_sizes, sr_template.dev_max * sizeof(int));
1252
        scsi_init_free((char *) sr_blocksizes, sr_template.dev_max * sizeof(int));
1253
    }
1254
 
1255
    blksize_size[MAJOR_NR] = NULL;
1256
    blk_dev[MAJOR_NR].request_fn = NULL;
1257
    blk_size[MAJOR_NR] = NULL;
1258
    read_ahead[MAJOR_NR] = 0;
1259
 
1260
    sr_template.dev_max = 0;
1261
}
1262
#endif /* MODULE */
1263
 
1264
/*
1265
 * Overrides for Emacs so that we follow Linus's tabbing style.
1266
 * Emacs will notice this stuff at the end of the file and automatically
1267
 * adjust the settings for this buffer only.  This must remain at the end
1268
 * of the file.
1269
 * ---------------------------------------------------------------------------
1270
 * Local variables:
1271
 * c-indent-level: 4
1272
 * c-brace-imaginary-offset: 0
1273
 * c-brace-offset: -4
1274
 * c-argdecl-indent: 4
1275
 * c-label-offset: -4
1276
 * c-continued-statement-offset: 4
1277
 * c-continued-brace-offset: 0
1278
 * indent-tabs-mode: nil
1279
 * tab-width: 8
1280
 * End:
1281
 */

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.