root/drivers/scsi/sr.c

/* [previous][next][first][last][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. sr_release
  2. check_cdrom_media_change
  3. rw_intr
  4. sr_photocd_done
  5. sr_photocd
  6. sr_open
  7. do_sr_request
  8. requeue_sr_request
  9. sr_detect
  10. sr_attach
  11. sr_init_done
  12. get_sectorsize
  13. sr_init
  14. sr_finish

   1 /*
   2  *      sr.c Copyright (C) 1992 David Giller
   3  *           Copyright (C) 1993, 1994 Eric Youngdale
   4  *
   5  *      adapted from:
   6  *      sd.c Copyright (C) 1992 Drew Eckhardt 
   7  *      Linux scsi disk driver by
   8  *              Drew Eckhardt 
   9  *
  10  *      <drew@colorado.edu>
  11  *
  12  *       Modified by Eric Youngdale ericy@cais.com to
  13  *       add scatter-gather, multiple outstanding request, and other
  14  *       enhancements.
  15  */
  16 
  17 #include <linux/fs.h>
  18 #include <linux/kernel.h>
  19 #include <linux/sched.h>
  20 #include <linux/string.h>
  21 #include <linux/errno.h>
  22 #include <linux/cdrom.h>
  23 #include <asm/system.h>
  24 
  25 #define MAJOR_NR SCSI_CDROM_MAJOR
  26 #include "../block/blk.h"
  27 #include "scsi.h"
  28 #include "hosts.h"
  29 #include "sr.h"
  30 #include "scsi_ioctl.h"   /* For the door lock/unlock commands */
  31 #include "constants.h"
  32 
  33 #define MAX_RETRIES 3
  34 #define SR_TIMEOUT 5000
  35 
  36 static void sr_init(void);
  37 static void sr_finish(void);
  38 static void sr_attach(Scsi_Device *);
  39 static int sr_detect(Scsi_Device *);
  40 
  41 struct Scsi_Device_Template sr_template = {NULL, "cdrom", "sr", TYPE_ROM, 
  42                                              SCSI_CDROM_MAJOR, 0, 0, 0, 1,
  43                                              sr_detect, sr_init,
  44                                              sr_finish, sr_attach, NULL};
  45 
  46 Scsi_CD * scsi_CDs;
  47 static int * sr_sizes;
  48 
  49 static int * sr_blocksizes;
  50 
  51 static int sr_open(struct inode *, struct file *);
  52 static void get_sectorsize(int);
  53 
  54 extern int sr_ioctl(struct inode *, struct file *, unsigned int, unsigned long);
  55 
  56 void requeue_sr_request (Scsi_Cmnd * SCpnt);
  57 static int check_cdrom_media_change(dev_t);
  58 
  59 static void sr_release(struct inode * inode, struct file * file)
     /* [previous][next][first][last][top][bottom][index][help] */
  60 {
  61         sync_dev(inode->i_rdev);
  62         if(! --scsi_CDs[MINOR(inode->i_rdev)].device->access_count)
  63           sr_ioctl(inode, NULL, SCSI_IOCTL_DOORUNLOCK, 0);
  64 }
  65 
  66 static struct file_operations sr_fops = 
  67 {
  68         NULL,                   /* lseek - default */
  69         block_read,             /* read - general block-dev read */
  70         block_write,            /* write - general block-dev write */
  71         NULL,                   /* readdir - bad */
  72         NULL,                   /* select */
  73         sr_ioctl,               /* ioctl */
  74         NULL,                   /* mmap */
  75         sr_open,                /* special open code */
  76         sr_release,             /* release */
  77         NULL,                   /* fsync */
  78         NULL,                   /* fasync */
  79         check_cdrom_media_change,  /* Disk change */
  80         NULL                    /* revalidate */
  81 };
  82 
  83 /*
  84  * This function checks to see if the media has been changed in the
  85  * CDROM drive.  It is possible that we have already sensed a change,
  86  * or the drive may have sensed one and not yet reported it.  We must
  87  * be ready for either case. This function always reports the current
  88  * value of the changed bit.  If flag is 0, then the changed bit is reset.
  89  * This function could be done as an ioctl, but we would need to have
  90  * an inode for that to work, and we do not always have one.
  91  */
  92 
  93 int check_cdrom_media_change(dev_t full_dev){
     /* [previous][next][first][last][top][bottom][index][help] */
  94         int retval, target;
  95         struct inode inode;
  96         int flag = 0;
  97 
  98         target =  MINOR(full_dev);
  99 
 100         if (target >= sr_template.nr_dev) {
 101                 printk("CD-ROM request error: invalid device.\n");
 102                 return 0;
 103         };
 104 
 105         inode.i_rdev = full_dev;  /* This is all we really need here */
 106         retval = sr_ioctl(&inode, NULL, SCSI_IOCTL_TEST_UNIT_READY, 0);
 107 
 108         if(retval){ /* Unable to test, unit probably not ready.  This usually
 109                      means there is no disc in the drive.  Mark as changed,
 110                      and we will figure it out later once the drive is
 111                      available again.  */
 112 
 113           scsi_CDs[target].device->changed = 1;
 114           return 1; /* This will force a flush, if called from
 115                        check_disk_change */
 116         };
 117 
 118         retval = scsi_CDs[target].device->changed;
 119         if(!flag) {
 120           scsi_CDs[target].device->changed = 0;
 121           /* If the disk changed, the capacity will now be different,
 122              so we force a re-read of this information */
 123           if (retval) scsi_CDs[target].needs_sector_size = 1;
 124         };
 125         return retval;
 126 }
 127 
 128 /*
 129  * rw_intr is the interrupt routine for the device driver.  It will be notified on the 
 130  * end of a SCSI read / write, and will take on of several actions based on success or failure.
 131  */
 132 
 133 static void rw_intr (Scsi_Cmnd * SCpnt)
     /* [previous][next][first][last][top][bottom][index][help] */
 134 {
 135         int result = SCpnt->result;
 136         int this_count = SCpnt->this_count;
 137 
 138 #ifdef DEBUG
 139         printk("sr.c done: %x %x\n",result, SCpnt->request.bh->b_data);
 140 #endif
 141         if (!result)
 142                 { /* No error */
 143                   if (SCpnt->use_sg == 0) {
 144                     if (SCpnt->buffer != SCpnt->request.buffer)
 145                       {
 146                         int offset;
 147                         offset = (SCpnt->request.sector % 4) << 9;
 148                         memcpy((char *)SCpnt->request.buffer, 
 149                                (char *)SCpnt->buffer + offset, 
 150                                this_count << 9);
 151                         /* Even though we are not using scatter-gather, we look
 152                            ahead and see if there is a linked request for the
 153                            other half of this buffer.  If there is, then satisfy
 154                            it. */
 155                         if((offset == 0) && this_count == 2 &&
 156                            SCpnt->request.nr_sectors > this_count && 
 157                            SCpnt->request.bh &&
 158                            SCpnt->request.bh->b_reqnext &&
 159                            SCpnt->request.bh->b_reqnext->b_size == 1024) {
 160                           memcpy((char *)SCpnt->request.bh->b_reqnext->b_data, 
 161                                  (char *)SCpnt->buffer + 1024, 
 162                                  1024);
 163                           this_count += 2;
 164                         };
 165                         
 166                         scsi_free(SCpnt->buffer, 2048);
 167                       }
 168                   } else {
 169                     struct scatterlist * sgpnt;
 170                     int i;
 171                     sgpnt = (struct scatterlist *) SCpnt->buffer;
 172                     for(i=0; i<SCpnt->use_sg; i++) {
 173                       if (sgpnt[i].alt_address) {
 174                         if (sgpnt[i].alt_address != sgpnt[i].address) {
 175                           memcpy(sgpnt[i].alt_address, sgpnt[i].address, sgpnt[i].length);
 176                         };
 177                         scsi_free(sgpnt[i].address, sgpnt[i].length);
 178                       };
 179                     };
 180                     scsi_free(SCpnt->buffer, SCpnt->sglist_len);  /* Free list of scatter-gather pointers */
 181                     if(SCpnt->request.sector % 4) this_count -= 2;
 182 /* See   if there is a padding record at the end that needs to be removed */
 183                     if(this_count > SCpnt->request.nr_sectors)
 184                       this_count -= 2;
 185                   };
 186 
 187 #ifdef DEBUG
 188                 printk("(%x %x %x) ",SCpnt->request.bh, SCpnt->request.nr_sectors, 
 189                        this_count);
 190 #endif
 191                 if (SCpnt->request.nr_sectors > this_count)
 192                         {        
 193                         SCpnt->request.errors = 0;
 194                         if (!SCpnt->request.bh)
 195                             panic("sr.c: linked page request (%lx %x)",
 196                                   SCpnt->request.sector, this_count);
 197                         }
 198 
 199                   SCpnt = end_scsi_request(SCpnt, 1, this_count);  /* All done */
 200                   requeue_sr_request(SCpnt);
 201                   return;
 202                 } /* Normal completion */
 203 
 204         /* We only come through here if we have an error of some kind */
 205 
 206 /* Free up any indirection buffers we allocated for DMA purposes. */
 207         if (SCpnt->use_sg) {
 208           struct scatterlist * sgpnt;
 209           int i;
 210           sgpnt = (struct scatterlist *) SCpnt->buffer;
 211           for(i=0; i<SCpnt->use_sg; i++) {
 212             if (sgpnt[i].alt_address) {
 213               scsi_free(sgpnt[i].address, sgpnt[i].length);
 214             };
 215           };
 216           scsi_free(SCpnt->buffer, SCpnt->sglist_len);  /* Free list of scatter-gather pointers */
 217         } else {
 218           if (SCpnt->buffer != SCpnt->request.buffer)
 219             scsi_free(SCpnt->buffer, SCpnt->bufflen);
 220         };
 221 
 222         if (driver_byte(result) != 0) {
 223                 if ((SCpnt->sense_buffer[0] & 0x7f) == 0x70) {
 224                         if ((SCpnt->sense_buffer[2] & 0xf) == UNIT_ATTENTION) {
 225                                 /* detected disc change.  set a bit and quietly refuse  */
 226                                 /* further access.                                      */
 227                     
 228                                 scsi_CDs[DEVICE_NR(SCpnt->request.dev)].device->changed = 1;
 229                                 SCpnt = end_scsi_request(SCpnt, 0, this_count);
 230                                 requeue_sr_request(SCpnt);
 231                                 return;
 232                         }
 233                 }
 234             
 235                 if (SCpnt->sense_buffer[2] == ILLEGAL_REQUEST) {
 236                         printk("CD-ROM error: Drive reports ILLEGAL REQUEST.\n");
 237                         if (scsi_CDs[DEVICE_NR(SCpnt->request.dev)].ten) {
 238                                 scsi_CDs[DEVICE_NR(SCpnt->request.dev)].ten = 0;
 239                                 requeue_sr_request(SCpnt);
 240                                 result = 0;
 241                                 return;
 242                         } else {
 243                           printk("CD-ROM error: Drive reports %d.\n", SCpnt->sense_buffer[2]);                          
 244                           SCpnt = end_scsi_request(SCpnt, 0, this_count);
 245                           requeue_sr_request(SCpnt); /* Do next request */
 246                           return;
 247                         }
 248 
 249                 }
 250 
 251                 if (SCpnt->sense_buffer[2] == NOT_READY) {
 252                         printk("CDROM not ready.  Make sure you have a disc in the drive.\n");
 253                         SCpnt = end_scsi_request(SCpnt, 0, this_count);
 254                         requeue_sr_request(SCpnt); /* Do next request */
 255                         return;
 256                 };
 257               }
 258         
 259         /* We only get this far if we have an error we have not recognized */
 260         if(result) {
 261           printk("SCSI CD error : host %d id %d lun %d return code = %03x\n", 
 262                  scsi_CDs[DEVICE_NR(SCpnt->request.dev)].device->host->host_no, 
 263                  scsi_CDs[DEVICE_NR(SCpnt->request.dev)].device->id,
 264                  scsi_CDs[DEVICE_NR(SCpnt->request.dev)].device->lun,
 265                  result);
 266             
 267           if (status_byte(result) == CHECK_CONDITION)
 268                   print_sense("sr", SCpnt);
 269           
 270           SCpnt = end_scsi_request(SCpnt, 0, SCpnt->request.current_nr_sectors);
 271           requeue_sr_request(SCpnt);
 272   }
 273 }
 274 
 275 /*
 276  * Here I tried to implement better support for PhotoCD's.
 277  * 
 278  * Much of this has do be done with vendor-specific SCSI-commands.
 279  * So I have to complete it step by step. Useful information is welcome.
 280  *
 281  * Actually works: (should work ;-)
 282  *   - NEC:     Detection and support of multisession CD's. Special handling
 283  *              for XA-disks is not necessary.
 284  *     
 285  *   - TOSHIBA: setting density is done here now, mounting PhotoCD's should
 286  *              work now without running the program "set_density"
 287  *              multisession-CD's are supported too.
 288  *
 289  *   Gerd Knorr  (mailto:kraxel@cs.tu-berlin.de,
 290  *                http://www.cs.tu-berlin.de/~kraxel/)
 291  */
 292 
 293 static void sr_photocd_done(Scsi_Cmnd *SCpnt)
     /* [previous][next][first][last][top][bottom][index][help] */
 294 {
 295   SCpnt->request.dev = 0xfffe;
 296 }
 297 
 298 static void sr_photocd(struct inode *inode)
     /* [previous][next][first][last][top][bottom][index][help] */
 299 {
 300   unsigned long   sector,min,sec,frame;
 301   Scsi_Cmnd       *SCpnt;
 302   unsigned char   scsi_cmd[10];
 303   unsigned char   *buffer;
 304   int             rc;
 305 
 306   switch(scsi_CDs[MINOR(inode->i_rdev)].device->manufacturer) {
 307 
 308   case SCSI_MAN_NEC:
 309     printk("sr_photocd: use NEC code\n");
 310     SCpnt = allocate_device(NULL, scsi_CDs[MINOR(inode->i_rdev)].device,1);
 311     memset(scsi_cmd,0,10);
 312     scsi_cmd[0] = 0xde;
 313     scsi_cmd[1] = ((scsi_CDs[MINOR(inode->i_rdev)].device->lun) << 5) | 0x03;
 314     scsi_cmd[2] = 0xb0;
 315     buffer = (unsigned char*) scsi_malloc(512);
 316     scsi_do_cmd(SCpnt, scsi_cmd, buffer, 0x16,
 317                 sr_photocd_done, SR_TIMEOUT, MAX_RETRIES);
 318     while (SCpnt->request.dev != 0xfffe);
 319     rc = SCpnt->result;
 320     if (driver_byte(rc) != 0) {
 321       printk("sr_photocd: oops, CD-ROM reports an error.\n");
 322       sector = 0; }
 323     else {
 324       min   = (unsigned long)buffer[15]/16*10 + (unsigned long)buffer[15]%16;
 325       sec   = (unsigned long)buffer[16]/16*10 + (unsigned long)buffer[16]%16;
 326       frame = (unsigned long)buffer[17]/16*10 + (unsigned long)buffer[17]%16;
 327       sector = min*60*75 + sec*75 + frame;
 328       if (sector) {
 329         sector -= CD_BLOCK_OFFSET;
 330         printk("sr_photocd: multisession PhotoCD detected\n");
 331       }
 332     }
 333     scsi_free(buffer,512);
 334     SCpnt->request.dev = -1;
 335     break;
 336 
 337   case SCSI_MAN_TOSHIBA:
 338     printk("sr_photocd: use TOSHIBA code\n");
 339 
 340     /* first I do a set_density-call (for reading XA-sectors) ... */
 341     SCpnt = allocate_device(NULL, scsi_CDs[MINOR(inode->i_rdev)].device,1);
 342     memset(scsi_cmd,0,10);
 343     scsi_cmd[0] = 0x15;
 344     scsi_cmd[1] = ((scsi_CDs[MINOR(inode->i_rdev)].device->lun) << 5)|(1 << 4);
 345     scsi_cmd[4] = 12;
 346     buffer = (unsigned char*) scsi_malloc(512);
 347     memset(buffer,0,512);
 348     buffer[ 3] = 0x08;
 349     buffer[ 4] = 0x83;
 350     buffer[10] = 0x08;
 351     scsi_do_cmd(SCpnt, scsi_cmd, buffer, 12,
 352                 sr_photocd_done, SR_TIMEOUT, MAX_RETRIES);
 353     while (SCpnt->request.dev != 0xfffe);
 354     rc = SCpnt->result;
 355     if (driver_byte(rc) != 0) {
 356       printk("sr_photocd: oops, CD-ROM reports an error.\n"); }
 357     scsi_free(buffer,512);
 358     SCpnt->request.dev = -1;
 359 
 360     /* ... and then I ask, if there is a multisession-Disk */
 361     SCpnt = allocate_device(NULL, scsi_CDs[MINOR(inode->i_rdev)].device,1);
 362     memset(scsi_cmd,0,10);
 363     scsi_cmd[0] = 0xc7;
 364     scsi_cmd[1] = ((scsi_CDs[MINOR(inode->i_rdev)].device->lun) << 5) | 3;
 365     buffer = (unsigned char*) scsi_malloc(512);
 366     memset(buffer,0,512);
 367     scsi_do_cmd(SCpnt, scsi_cmd, buffer, 4,
 368                 sr_photocd_done, SR_TIMEOUT, MAX_RETRIES);
 369     while (SCpnt->request.dev != 0xfffe);
 370     rc = SCpnt->result;
 371     if (driver_byte(rc) != 0) {
 372       printk("sr_photocd: oops, CD-ROM reports an error.\n");
 373       sector = 0; }
 374     else {
 375       min   = (unsigned long)buffer[1]/16*10 + (unsigned long)buffer[1]%16;
 376       sec   = (unsigned long)buffer[2]/16*10 + (unsigned long)buffer[2]%16;
 377       frame = (unsigned long)buffer[3]/16*10 + (unsigned long)buffer[3]%16;
 378       sector = min*60*75 + sec*75 + frame;
 379       if (sector) {
 380         sector -= CD_BLOCK_OFFSET;
 381         printk("sr_photocd: multisession PhotoCD detected: %lu\n",sector);
 382       }
 383     }
 384     scsi_free(buffer,512);
 385     SCpnt->request.dev = -1;
 386     break;
 387   case SCSI_MAN_UNKNOWN:
 388   default:
 389     printk("sr_photocd: there is no special photocd-code for this drive\n");
 390     sector = 0;
 391     break; }
 392 
 393   scsi_CDs[MINOR(inode->i_rdev)].mpcd_sector = sector;
 394   return;
 395 }
 396 
 397 static int sr_open(struct inode * inode, struct file * filp)
     /* [previous][next][first][last][top][bottom][index][help] */
 398 {
 399         if(MINOR(inode->i_rdev) >= sr_template.nr_dev || 
 400            !scsi_CDs[MINOR(inode->i_rdev)].device) return -ENXIO;   /* No such device */
 401 
 402         if (filp->f_mode & 2)  
 403             return -EROFS;
 404 
 405         check_disk_change(inode->i_rdev);
 406 
 407         if(!scsi_CDs[MINOR(inode->i_rdev)].device->access_count++)
 408           sr_ioctl(inode, NULL, SCSI_IOCTL_DOORLOCK, 0);
 409 
 410         /* If this device did not have media in the drive at boot time, then
 411            we would have been unable to get the sector size.  Check to see if
 412            this is the case, and try again.
 413            */
 414 
 415         if(scsi_CDs[MINOR(inode->i_rdev)].needs_sector_size)
 416           get_sectorsize(MINOR(inode->i_rdev));
 417 
 418 #if 0   /* don't use for now - it doesn't seem to work for everybody */
 419         sr_photocd(inode);
 420 #endif
 421 
 422         return 0;
 423 }
 424 
 425 
 426 /*
 427  * do_sr_request() is the request handler function for the sr driver.  Its function in life 
 428  * is to take block device requests, and translate them to SCSI commands.
 429  */
 430         
 431 static void do_sr_request (void)
     /* [previous][next][first][last][top][bottom][index][help] */
 432 {
 433   Scsi_Cmnd * SCpnt = NULL;
 434   struct request * req = NULL;
 435   int flag = 0;
 436 
 437   while (1==1){
 438     cli();
 439     if (CURRENT != NULL && CURRENT->dev == -1) {
 440       sti();
 441       return;
 442     };
 443     
 444     INIT_SCSI_REQUEST;
 445 
 446     if (flag++ == 0)
 447       SCpnt = allocate_device(&CURRENT,
 448                               scsi_CDs[DEVICE_NR(MINOR(CURRENT->dev))].device, 0); 
 449     else SCpnt = NULL;
 450     sti();
 451 
 452 /* This is a performance enhancement.  We dig down into the request list and
 453    try and find a queueable request (i.e. device not busy, and host able to
 454    accept another command.  If we find one, then we queue it. This can
 455    make a big difference on systems with more than one disk drive.  We want
 456    to have the interrupts off when monkeying with the request list, because
 457    otherwise the kernel might try and slip in a request in between somewhere. */
 458 
 459     if (!SCpnt && sr_template.nr_dev > 1){
 460       struct request *req1;
 461       req1 = NULL;
 462       cli();
 463       req = CURRENT;
 464       while(req){
 465         SCpnt = request_queueable(req,
 466                                   scsi_CDs[DEVICE_NR(MINOR(req->dev))].device);
 467         if(SCpnt) break;
 468         req1 = req;
 469         req = req->next;
 470       };
 471       if (SCpnt && req->dev == -1) {
 472         if (req == CURRENT) 
 473           CURRENT = CURRENT->next;
 474         else
 475           req1->next = req->next;
 476       };
 477       sti();
 478     };
 479     
 480     if (!SCpnt)
 481       return; /* Could not find anything to do */
 482     
 483   wake_up(&wait_for_request);
 484 
 485 /* Queue command */
 486   requeue_sr_request(SCpnt);
 487   };  /* While */
 488 }    
 489 
 490 void requeue_sr_request (Scsi_Cmnd * SCpnt)
     /* [previous][next][first][last][top][bottom][index][help] */
 491 {
 492         unsigned int dev, block, realcount;
 493         unsigned char cmd[10], *buffer, tries;
 494         int this_count, start, end_rec;
 495 
 496         tries = 2;
 497 
 498       repeat:
 499         if(!SCpnt || SCpnt->request.dev <= 0) {
 500           do_sr_request();
 501           return;
 502         }
 503 
 504         dev =  MINOR(SCpnt->request.dev);
 505         block = SCpnt->request.sector;  
 506         buffer = NULL;
 507         this_count = 0;
 508 
 509         if (dev >= sr_template.nr_dev)
 510                 {
 511                 /* printk("CD-ROM request error: invalid device.\n");                   */
 512                 SCpnt = end_scsi_request(SCpnt, 0, SCpnt->request.nr_sectors);
 513                 tries = 2;
 514                 goto repeat;
 515                 }
 516 
 517         if (!scsi_CDs[dev].use)
 518                 {
 519                 /* printk("CD-ROM request error: device marked not in use.\n");         */
 520                 SCpnt = end_scsi_request(SCpnt, 0, SCpnt->request.nr_sectors);
 521                 tries = 2;
 522                 goto repeat;
 523                 }
 524 
 525         if (scsi_CDs[dev].device->changed)
 526                 {
 527 /* 
 528  * quietly refuse to do anything to a changed disc until the changed bit has been reset
 529  */
 530                 /* printk("CD-ROM has been changed.  Prohibiting further I/O.\n");      */
 531                 SCpnt = end_scsi_request(SCpnt, 0, SCpnt->request.nr_sectors);
 532                 tries = 2;
 533                 goto repeat;
 534                 }
 535         
 536         switch (SCpnt->request.cmd)
 537                 {
 538                 case WRITE:             
 539                         SCpnt = end_scsi_request(SCpnt, 0, SCpnt->request.nr_sectors);
 540                         goto repeat;
 541                         break;
 542                 case READ : 
 543                         cmd[0] = READ_6;
 544                         break;
 545                 default : 
 546                         panic ("Unknown sr command %d\n", SCpnt->request.cmd);
 547                 }
 548         
 549         cmd[1] = (SCpnt->lun << 5) & 0xe0;
 550 
 551 /*
 552            Now do the grungy work of figuring out which sectors we need, and
 553            where in memory we are going to put them.
 554 
 555            The variables we need are:
 556 
 557            this_count= number of 512 byte sectors being read 
 558            block     = starting cdrom sector to read.
 559            realcount = # of cdrom sectors to read
 560 
 561            The major difference between a scsi disk and a scsi cdrom
 562 is that we will always use scatter-gather if we can, because we can
 563 work around the fact that the buffer cache has a block size of 1024,
 564 and we have 2048 byte sectors.  This code should work for buffers that
 565 are any multiple of 512 bytes long.  */
 566 
 567         /* this is for support of multisession-CD's */ 
 568         if (block >= 64 && block < 68) {
 569           block += scsi_CDs[dev].mpcd_sector*4; }
 570 
 571         SCpnt->use_sg = 0;
 572 
 573         if (SCpnt->host->sg_tablesize > 0 &&
 574             (!need_isa_buffer ||
 575             dma_free_sectors >= 10)) {
 576           struct buffer_head * bh;
 577           struct scatterlist * sgpnt;
 578           int count, this_count_max;
 579           bh = SCpnt->request.bh;
 580           this_count = 0;
 581           count = 0;
 582           this_count_max = (scsi_CDs[dev].ten ? 0xffff : 0xff) << 4;
 583           /* Calculate how many links we can use.  First see if we need
 584            a padding record at the start */
 585           this_count = SCpnt->request.sector % 4;
 586           if(this_count) count++;
 587           while(bh && count < SCpnt->host->sg_tablesize) {
 588             if ((this_count + (bh->b_size >> 9)) > this_count_max) break;
 589             this_count += (bh->b_size >> 9);
 590             count++;
 591             bh = bh->b_reqnext;
 592           };
 593           /* Fix up in case of an odd record at the end */
 594           end_rec = 0;
 595           if(this_count % 4) {
 596             if (count < SCpnt->host->sg_tablesize) {
 597               count++;
 598               end_rec = (4 - (this_count % 4)) << 9;
 599               this_count += 4 - (this_count % 4);
 600             } else {
 601               count--;
 602               this_count -= (this_count % 4);
 603             };
 604           };
 605           SCpnt->use_sg = count;  /* Number of chains */
 606           count = 512;/* scsi_malloc can only allocate in chunks of 512 bytes*/
 607           while( count < (SCpnt->use_sg * sizeof(struct scatterlist))) 
 608             count = count << 1;
 609           SCpnt->sglist_len = count;
 610           sgpnt = (struct scatterlist * ) scsi_malloc(count);
 611           if (!sgpnt) {
 612             printk("Warning - running *really* short on DMA buffers\n");
 613             SCpnt->use_sg = 0;  /* No memory left - bail out */
 614           } else {
 615             buffer = (unsigned char *) sgpnt;
 616             count = 0;
 617             bh = SCpnt->request.bh;
 618             if(SCpnt->request.sector % 4) {
 619               sgpnt[count].length = (SCpnt->request.sector % 4) << 9;
 620               sgpnt[count].address = (char *) scsi_malloc(sgpnt[count].length);
 621               if(!sgpnt[count].address) panic("SCSI DMA pool exhausted.");
 622               sgpnt[count].alt_address = sgpnt[count].address; /* Flag to delete
 623                                                                   if needed */
 624               count++;
 625             };
 626             for(bh = SCpnt->request.bh; count < SCpnt->use_sg; 
 627                 count++, bh = bh->b_reqnext) {
 628               if (bh) { /* Need a placeholder at the end of the record? */
 629                 sgpnt[count].address = bh->b_data;
 630                 sgpnt[count].length = bh->b_size;
 631                 sgpnt[count].alt_address = NULL;
 632               } else {
 633                 sgpnt[count].address = (char *) scsi_malloc(end_rec);
 634                 if(!sgpnt[count].address) panic("SCSI DMA pool exhausted.");
 635                 sgpnt[count].length = end_rec;
 636                 sgpnt[count].alt_address = sgpnt[count].address;
 637                 if (count+1 != SCpnt->use_sg) panic("Bad sr request list");
 638                 break;
 639               };
 640               if (((int) sgpnt[count].address) + sgpnt[count].length > 
 641                   ISA_DMA_THRESHOLD & (SCpnt->host->unchecked_isa_dma)) {
 642                 sgpnt[count].alt_address = sgpnt[count].address;
 643                 /* We try and avoid exhausting the DMA pool, since it is easier
 644                    to control usage here.  In other places we might have a more
 645                    pressing need, and we would be screwed if we ran out */
 646                 if(dma_free_sectors < (sgpnt[count].length >> 9) + 5) {
 647                   sgpnt[count].address = NULL;
 648                 } else {
 649                   sgpnt[count].address = (char *) scsi_malloc(sgpnt[count].length);
 650                 };
 651 /* If we start running low on DMA buffers, we abort the scatter-gather
 652    operation, and free all of the memory we have allocated.  We want to
 653    ensure that all scsi operations are able to do at least a non-scatter/gather
 654    operation */
 655                 if(sgpnt[count].address == NULL){ /* Out of dma memory */
 656                   printk("Warning: Running low on SCSI DMA buffers");
 657                   /* Try switching back to a non scatter-gather operation. */
 658                   while(--count >= 0){
 659                     if(sgpnt[count].alt_address) 
 660                       scsi_free(sgpnt[count].address, sgpnt[count].length);
 661                   };
 662                   SCpnt->use_sg = 0;
 663                   scsi_free(buffer, SCpnt->sglist_len);
 664                   break;
 665                 }; /* if address == NULL */
 666               };  /* if need DMA fixup */
 667             };  /* for loop to fill list */
 668 #ifdef DEBUG
 669             printk("SG: %d %d %d %d %d *** ",SCpnt->use_sg, SCpnt->request.sector,
 670                    this_count, 
 671                    SCpnt->request.current_nr_sectors,
 672                    SCpnt->request.nr_sectors);
 673             for(count=0; count<SCpnt->use_sg; count++)
 674               printk("SGlist: %d %x %x %x\n", count,
 675                      sgpnt[count].address, 
 676                      sgpnt[count].alt_address, 
 677                      sgpnt[count].length);
 678 #endif
 679           };  /* Able to allocate scatter-gather list */
 680         };
 681         
 682         if (SCpnt->use_sg == 0){
 683           /* We cannot use scatter-gather.  Do this the old fashion way */
 684           if (!SCpnt->request.bh)       
 685             this_count = SCpnt->request.nr_sectors;
 686           else
 687             this_count = (SCpnt->request.bh->b_size >> 9);
 688           
 689           start = block % 4;
 690           if (start)
 691             {                             
 692               this_count = ((this_count > 4 - start) ? 
 693                             (4 - start) : (this_count));
 694               buffer = (unsigned char *) scsi_malloc(2048);
 695             } 
 696           else if (this_count < 4)
 697             {
 698               buffer = (unsigned char *) scsi_malloc(2048);
 699             }
 700           else
 701             {
 702               this_count -= this_count % 4;
 703               buffer = (unsigned char *) SCpnt->request.buffer;
 704               if (((int) buffer) + (this_count << 9) > ISA_DMA_THRESHOLD & 
 705                   (SCpnt->host->unchecked_isa_dma))
 706                 buffer = (unsigned char *) scsi_malloc(this_count << 9);
 707             }
 708         };
 709 
 710         if (scsi_CDs[dev].sector_size == 2048)
 711           block = block >> 2; /* These are the sectors that the cdrom uses */
 712         else
 713           block = block & 0xfffffffc;
 714 
 715         realcount = (this_count + 3) / 4;
 716 
 717         if (scsi_CDs[dev].sector_size == 512) realcount = realcount << 2;
 718 
 719         if (((realcount > 0xff) || (block > 0x1fffff)) && scsi_CDs[dev].ten) 
 720                 {
 721                 if (realcount > 0xffff)
 722                         {
 723                         realcount = 0xffff;
 724                         this_count = realcount * (scsi_CDs[dev].sector_size >> 9);
 725                         }
 726 
 727                 cmd[0] += READ_10 - READ_6 ;
 728                 cmd[2] = (unsigned char) (block >> 24) & 0xff;
 729                 cmd[3] = (unsigned char) (block >> 16) & 0xff;
 730                 cmd[4] = (unsigned char) (block >> 8) & 0xff;
 731                 cmd[5] = (unsigned char) block & 0xff;
 732                 cmd[6] = cmd[9] = 0;
 733                 cmd[7] = (unsigned char) (realcount >> 8) & 0xff;
 734                 cmd[8] = (unsigned char) realcount & 0xff;
 735                 }
 736         else
 737                 {
 738                   if (realcount > 0xff)
 739                     {
 740                       realcount = 0xff;
 741                       this_count = realcount * (scsi_CDs[dev].sector_size >> 9);
 742                     }
 743                   
 744                   cmd[1] |= (unsigned char) ((block >> 16) & 0x1f);
 745                   cmd[2] = (unsigned char) ((block >> 8) & 0xff);
 746                   cmd[3] = (unsigned char) block & 0xff;
 747                   cmd[4] = (unsigned char) realcount;
 748                   cmd[5] = 0;
 749                 }   
 750 
 751 #ifdef DEBUG
 752         { 
 753           int i;
 754           printk("ReadCD: %d %d %d %d\n",block, realcount, buffer, this_count);
 755           printk("Use sg: %d\n", SCpnt->use_sg);
 756           printk("Dumping command: ");
 757           for(i=0; i<12; i++) printk("%2.2x ", cmd[i]);
 758           printk("\n");
 759         };
 760 #endif
 761 
 762 /* Some dumb host adapters can speed transfers by knowing the
 763  * minimum transfersize in advance.
 764  *
 765  * We shouldn't disconnect in the middle of a sector, but the cdrom
 766  * sector size can be larger than the size of a buffer and the
 767  * transfer may be split to the size of a buffer.  So it's safe to
 768  * assume that we can at least transfer the minimum of the buffer
 769  * size (1024) and the sector size between each connect / disconnect.
 770  */
 771 
 772         SCpnt->transfersize = (scsi_CDs[dev].sector_size > 1024) ?
 773                         1024 : scsi_CDs[dev].sector_size;
 774 
 775         SCpnt->this_count = this_count;
 776         scsi_do_cmd (SCpnt, (void *) cmd, buffer, 
 777                      realcount * scsi_CDs[dev].sector_size, 
 778                      rw_intr, SR_TIMEOUT, MAX_RETRIES);
 779 }
 780 
 781 static int sr_detect(Scsi_Device * SDp){
     /* [previous][next][first][last][top][bottom][index][help] */
 782   
 783   /* We do not support attaching loadable devices yet. */
 784   if(scsi_loadable_module_flag) return 0;
 785   if(SDp->type != TYPE_ROM && SDp->type != TYPE_WORM) return 0;
 786 
 787   printk("Detected scsi CD-ROM sr%d at scsi%d, id %d, lun %d\n", 
 788          sr_template.dev_noticed++,
 789          SDp->host->host_no , SDp->id, SDp->lun); 
 790 
 791          return 1;
 792 }
 793 
 794 static void sr_attach(Scsi_Device * SDp){
     /* [previous][next][first][last][top][bottom][index][help] */
 795   Scsi_CD * cpnt;
 796   int i;
 797   
 798   /* We do not support attaching loadable devices yet. */
 799   
 800   if(scsi_loadable_module_flag) return;
 801   if(SDp->type != TYPE_ROM && SDp->type != TYPE_WORM) return;
 802   
 803   if (sr_template.nr_dev >= sr_template.dev_max)
 804     panic ("scsi_devices corrupt (sr)");
 805   
 806   for(cpnt = scsi_CDs, i=0; i<sr_template.dev_max; i++, cpnt++) 
 807     if(!cpnt->device) break;
 808   
 809   if(i >= sr_template.dev_max) panic ("scsi_devices corrupt (sr)");
 810   
 811   SDp->scsi_request_fn = do_sr_request;
 812   scsi_CDs[i].device = SDp;
 813   sr_template.nr_dev++;
 814   if(sr_template.nr_dev > sr_template.dev_max)
 815     panic ("scsi_devices corrupt (sr)");
 816 }
 817      
 818 
 819 static void sr_init_done (Scsi_Cmnd * SCpnt)
     /* [previous][next][first][last][top][bottom][index][help] */
 820 {
 821   struct request * req;
 822   
 823   req = &SCpnt->request;
 824   req->dev = 0xfffe; /* Busy, but indicate request done */
 825   
 826   if (req->sem != NULL) {
 827     up(req->sem);
 828   }
 829 }
 830 
 831 static void get_sectorsize(int i){
     /* [previous][next][first][last][top][bottom][index][help] */
 832   unsigned char cmd[10];
 833   unsigned char *buffer;
 834   int the_result, retries;
 835   Scsi_Cmnd * SCpnt;
 836   
 837   buffer = (unsigned char *) scsi_malloc(512);
 838   SCpnt = allocate_device(NULL, scsi_CDs[i].device, 1);
 839 
 840   retries = 3;
 841   do {
 842     cmd[0] = READ_CAPACITY;
 843     cmd[1] = (scsi_CDs[i].device->lun << 5) & 0xe0;
 844     memset ((void *) &cmd[2], 0, 8);
 845     SCpnt->request.dev = 0xffff;  /* Mark as really busy */
 846     SCpnt->cmd_len = 0;
 847     
 848     memset(buffer, 0, 8);
 849 
 850     scsi_do_cmd (SCpnt,
 851                  (void *) cmd, (void *) buffer,
 852                  512, sr_init_done,  SR_TIMEOUT,
 853                  MAX_RETRIES);
 854     
 855     if (current == task[0])
 856       while(SCpnt->request.dev != 0xfffe);
 857     else
 858       if (SCpnt->request.dev != 0xfffe){
 859         struct semaphore sem = MUTEX_LOCKED;
 860         SCpnt->request.sem = &sem;
 861         down(&sem);
 862         /* Hmm.. Have to ask about this */
 863         while (SCpnt->request.dev != 0xfffe) schedule();
 864       };
 865     
 866     the_result = SCpnt->result;
 867     retries--;
 868     
 869   } while(the_result && retries);
 870   
 871   SCpnt->request.dev = -1;  /* Mark as not busy */
 872   
 873   wake_up(&SCpnt->device->device_wait); 
 874 
 875   if (the_result) {
 876     scsi_CDs[i].capacity = 0x1fffff;
 877     scsi_CDs[i].sector_size = 2048;  /* A guess, just in case */
 878     scsi_CDs[i].needs_sector_size = 1;
 879   } else {
 880     scsi_CDs[i].capacity = (buffer[0] << 24) |
 881       (buffer[1] << 16) | (buffer[2] << 8) | buffer[3];
 882     scsi_CDs[i].sector_size = (buffer[4] << 24) |
 883       (buffer[5] << 16) | (buffer[6] << 8) | buffer[7];
 884     if(scsi_CDs[i].sector_size == 0) scsi_CDs[i].sector_size = 2048;
 885     if(scsi_CDs[i].sector_size != 2048 && 
 886        scsi_CDs[i].sector_size != 512) {
 887       printk ("scd%d : unsupported sector size %d.\n",
 888               i, scsi_CDs[i].sector_size);
 889       scsi_CDs[i].capacity = 0;
 890       scsi_CDs[i].needs_sector_size = 1;
 891     };
 892     if(scsi_CDs[i].sector_size == 2048)
 893       scsi_CDs[i].capacity *= 4;
 894     scsi_CDs[i].needs_sector_size = 0;
 895   };
 896   scsi_free(buffer, 512);
 897 }
 898 
 899 static void sr_init()
     /* [previous][next][first][last][top][bottom][index][help] */
 900 {
 901         int i;
 902         static int sr_registered = 0;
 903 
 904         if(sr_template.dev_noticed == 0) return;
 905 
 906         if(!sr_registered) {
 907           if (register_blkdev(MAJOR_NR,"sr",&sr_fops)) {
 908             printk("Unable to get major %d for SCSI-CD\n",MAJOR_NR);
 909             return;
 910           }
 911         }
 912 
 913         /* We do not support attaching loadable devices yet. */
 914         if(scsi_loadable_module_flag) return;
 915 
 916         sr_template.dev_max = sr_template.dev_noticed;
 917         scsi_CDs = (Scsi_CD *) scsi_init_malloc(sr_template.dev_max * sizeof(Scsi_CD));
 918         memset(scsi_CDs, 0, sr_template.dev_max * sizeof(Scsi_CD));
 919 
 920         sr_sizes = (int *) scsi_init_malloc(sr_template.dev_max * sizeof(int));
 921         memset(sr_sizes, 0, sr_template.dev_max * sizeof(int));
 922 
 923         sr_blocksizes = (int *) scsi_init_malloc(sr_template.dev_max * 
 924                                                  sizeof(int));
 925         for(i=0;i<sr_template.dev_max;i++) sr_blocksizes[i] = 2048;
 926         blksize_size[MAJOR_NR] = sr_blocksizes;
 927 
 928 }
 929 
 930 void sr_finish()
     /* [previous][next][first][last][top][bottom][index][help] */
 931 {
 932   int i;
 933 
 934         for (i = 0; i < sr_template.nr_dev; ++i)
 935                 {
 936                   get_sectorsize(i);
 937                   printk("Scd sectorsize = %d bytes\n", scsi_CDs[i].sector_size);
 938                   scsi_CDs[i].use = 1;
 939                   scsi_CDs[i].ten = 1;
 940                   scsi_CDs[i].remap = 1;
 941                   sr_sizes[i] = scsi_CDs[i].capacity;
 942                 }
 943 
 944         blk_dev[MAJOR_NR].request_fn = DEVICE_REQUEST;
 945         blk_size[MAJOR_NR] = sr_sizes;  
 946 
 947         /* If our host adapter is capable of scatter-gather, then we increase
 948            the read-ahead to 16 blocks (32 sectors).  If not, we use
 949            a two block (4 sector) read ahead. */
 950         if(scsi_CDs[0].device->host->sg_tablesize)
 951           read_ahead[MAJOR_NR] = 32;  /* 32 sector read-ahead.  Always removable. */
 952         else
 953           read_ahead[MAJOR_NR] = 4;  /* 4 sector read-ahead */
 954 
 955         return;
 956 }       

/* [previous][next][first][last][top][bottom][index][help] */