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

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