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_open
  5. do_sr_request
  6. requeue_sr_request
  7. sr_detect
  8. sr_attach
  9. sr_init_done
  10. get_sectorsize
  11. sr_init
  12. 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                   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                                 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                           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                         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           end_scsi_request(SCpnt, 0, SCpnt->request.current_nr_sectors);
 270           requeue_sr_request(SCpnt);
 271   }
 272 }
 273 
 274 static int sr_open(struct inode * inode, struct file * filp)
     /* [previous][next][first][last][top][bottom][index][help] */
 275 {
 276         if(MINOR(inode->i_rdev) >= sr_template.nr_dev || 
 277            !scsi_CDs[MINOR(inode->i_rdev)].device) return -ENXIO;   /* No such device */
 278 
 279         if (filp->f_mode & 2)  
 280             return -EROFS;
 281 
 282         check_disk_change(inode->i_rdev);
 283 
 284         if(!scsi_CDs[MINOR(inode->i_rdev)].device->access_count++)
 285           sr_ioctl(inode, NULL, SCSI_IOCTL_DOORLOCK, 0);
 286 
 287         /* If this device did not have media in the drive at boot time, then
 288            we would have been unable to get the sector size.  Check to see if
 289            this is the case, and try again.
 290            */
 291 
 292         if(scsi_CDs[MINOR(inode->i_rdev)].needs_sector_size)
 293           get_sectorsize(MINOR(inode->i_rdev));
 294 
 295         return 0;
 296 }
 297 
 298 
 299 /*
 300  * do_sr_request() is the request handler function for the sr driver.  Its function in life 
 301  * is to take block device requests, and translate them to SCSI commands.
 302  */
 303         
 304 static void do_sr_request (void)
     /* [previous][next][first][last][top][bottom][index][help] */
 305 {
 306   Scsi_Cmnd * SCpnt = NULL;
 307   struct request * req = NULL;
 308   int flag = 0;
 309 
 310   while (1==1){
 311     cli();
 312     if (CURRENT != NULL && CURRENT->dev == -1) {
 313       sti();
 314       return;
 315     };
 316     
 317     INIT_SCSI_REQUEST;
 318 
 319     if (flag++ == 0)
 320       SCpnt = allocate_device(&CURRENT,
 321                               scsi_CDs[DEVICE_NR(MINOR(CURRENT->dev))].device, 0); 
 322     else SCpnt = NULL;
 323     sti();
 324 
 325 /* This is a performance enhancement.  We dig down into the request list and
 326    try and find a queueable request (i.e. device not busy, and host able to
 327    accept another command.  If we find one, then we queue it. This can
 328    make a big difference on systems with more than one disk drive.  We want
 329    to have the interrupts off when monkeying with the request list, because
 330    otherwise the kernel might try and slip in a request in between somewhere. */
 331 
 332     if (!SCpnt && sr_template.nr_dev > 1){
 333       struct request *req1;
 334       req1 = NULL;
 335       cli();
 336       req = CURRENT;
 337       while(req){
 338         SCpnt = request_queueable(req,
 339                                   scsi_CDs[DEVICE_NR(MINOR(req->dev))].device);
 340         if(SCpnt) break;
 341         req1 = req;
 342         req = req->next;
 343       };
 344       if (SCpnt && req->dev == -1) {
 345         if (req == CURRENT) 
 346           CURRENT = CURRENT->next;
 347         else
 348           req1->next = req->next;
 349       };
 350       sti();
 351     };
 352     
 353     if (!SCpnt)
 354       return; /* Could not find anything to do */
 355     
 356   wake_up(&wait_for_request);
 357 
 358 /* Queue command */
 359   requeue_sr_request(SCpnt);
 360   };  /* While */
 361 }    
 362 
 363 void requeue_sr_request (Scsi_Cmnd * SCpnt)
     /* [previous][next][first][last][top][bottom][index][help] */
 364 {
 365         unsigned int dev, block, realcount;
 366         unsigned char cmd[10], *buffer, tries;
 367         int this_count, start, end_rec;
 368 
 369         tries = 2;
 370 
 371       repeat:
 372         if(SCpnt->request.dev <= 0) {
 373           do_sr_request();
 374           return;
 375         }
 376 
 377         dev =  MINOR(SCpnt->request.dev);
 378         block = SCpnt->request.sector;  
 379         buffer = NULL;
 380         this_count = 0;
 381 
 382         if (dev >= sr_template.nr_dev)
 383                 {
 384                 /* printk("CD-ROM request error: invalid device.\n");                   */
 385                 end_scsi_request(SCpnt, 0, SCpnt->request.nr_sectors);
 386                 tries = 2;
 387                 goto repeat;
 388                 }
 389 
 390         if (!scsi_CDs[dev].use)
 391                 {
 392                 /* printk("CD-ROM request error: device marked not in use.\n");         */
 393                 end_scsi_request(SCpnt, 0, SCpnt->request.nr_sectors);
 394                 tries = 2;
 395                 goto repeat;
 396                 }
 397 
 398         if (scsi_CDs[dev].device->changed)
 399                 {
 400 /* 
 401  * quietly refuse to do anything to a changed disc until the changed bit has been reset
 402  */
 403                 /* printk("CD-ROM has been changed.  Prohibiting further I/O.\n");      */
 404                 end_scsi_request(SCpnt, 0, SCpnt->request.nr_sectors);
 405                 tries = 2;
 406                 goto repeat;
 407                 }
 408         
 409         switch (SCpnt->request.cmd)
 410                 {
 411                 case WRITE:             
 412                         end_scsi_request(SCpnt, 0, SCpnt->request.nr_sectors);
 413                         goto repeat;
 414                         break;
 415                 case READ : 
 416                         cmd[0] = READ_6;
 417                         break;
 418                 default : 
 419                         panic ("Unknown sr command %d\n", SCpnt->request.cmd);
 420                 }
 421         
 422         cmd[1] = (SCpnt->lun << 5) & 0xe0;
 423 
 424 /*
 425            Now do the grungy work of figuring out which sectors we need, and
 426            where in memory we are going to put them.
 427 
 428            The variables we need are:
 429 
 430            this_count= number of 512 byte sectors being read 
 431            block     = starting cdrom sector to read.
 432            realcount = # of cdrom sectors to read
 433 
 434            The major difference between a scsi disk and a scsi cdrom
 435 is that we will always use scatter-gather if we can, because we can
 436 work around the fact that the buffer cache has a block size of 1024,
 437 and we have 2048 byte sectors.  This code should work for buffers that
 438 are any multiple of 512 bytes long.  */
 439 
 440         SCpnt->use_sg = 0;
 441 
 442         if (SCpnt->host->sg_tablesize > 0 &&
 443             (!need_isa_buffer ||
 444             dma_free_sectors >= 10)) {
 445           struct buffer_head * bh;
 446           struct scatterlist * sgpnt;
 447           int count, this_count_max;
 448           bh = SCpnt->request.bh;
 449           this_count = 0;
 450           count = 0;
 451           this_count_max = (scsi_CDs[dev].ten ? 0xffff : 0xff) << 4;
 452           /* Calculate how many links we can use.  First see if we need
 453            a padding record at the start */
 454           this_count = SCpnt->request.sector % 4;
 455           if(this_count) count++;
 456           while(bh && count < SCpnt->host->sg_tablesize) {
 457             if ((this_count + (bh->b_size >> 9)) > this_count_max) break;
 458             this_count += (bh->b_size >> 9);
 459             count++;
 460             bh = bh->b_reqnext;
 461           };
 462           /* Fix up in case of an odd record at the end */
 463           end_rec = 0;
 464           if(this_count % 4) {
 465             if (count < SCpnt->host->sg_tablesize) {
 466               count++;
 467               end_rec = (4 - (this_count % 4)) << 9;
 468               this_count += 4 - (this_count % 4);
 469             } else {
 470               count--;
 471               this_count -= (this_count % 4);
 472             };
 473           };
 474           SCpnt->use_sg = count;  /* Number of chains */
 475           count = 512;/* scsi_malloc can only allocate in chunks of 512 bytes*/
 476           while( count < (SCpnt->use_sg * sizeof(struct scatterlist))) 
 477             count = count << 1;
 478           SCpnt->sglist_len = count;
 479           sgpnt = (struct scatterlist * ) scsi_malloc(count);
 480           if (!sgpnt) {
 481             printk("Warning - running *really* short on DMA buffers\n");
 482             SCpnt->use_sg = 0;  /* No memory left - bail out */
 483           } else {
 484             buffer = (unsigned char *) sgpnt;
 485             count = 0;
 486             bh = SCpnt->request.bh;
 487             if(SCpnt->request.sector % 4) {
 488               sgpnt[count].length = (SCpnt->request.sector % 4) << 9;
 489               sgpnt[count].address = (char *) scsi_malloc(sgpnt[count].length);
 490               if(!sgpnt[count].address) panic("SCSI DMA pool exhausted.");
 491               sgpnt[count].alt_address = sgpnt[count].address; /* Flag to delete
 492                                                                   if needed */
 493               count++;
 494             };
 495             for(bh = SCpnt->request.bh; count < SCpnt->use_sg; 
 496                 count++, bh = bh->b_reqnext) {
 497               if (bh) { /* Need a placeholder at the end of the record? */
 498                 sgpnt[count].address = bh->b_data;
 499                 sgpnt[count].length = bh->b_size;
 500                 sgpnt[count].alt_address = NULL;
 501               } else {
 502                 sgpnt[count].address = (char *) scsi_malloc(end_rec);
 503                 if(!sgpnt[count].address) panic("SCSI DMA pool exhausted.");
 504                 sgpnt[count].length = end_rec;
 505                 sgpnt[count].alt_address = sgpnt[count].address;
 506                 if (count+1 != SCpnt->use_sg) panic("Bad sr request list");
 507                 break;
 508               };
 509               if (((int) sgpnt[count].address) + sgpnt[count].length > 
 510                   ISA_DMA_THRESHOLD & (SCpnt->host->unchecked_isa_dma)) {
 511                 sgpnt[count].alt_address = sgpnt[count].address;
 512                 /* We try and avoid exhausting the DMA pool, since it is easier
 513                    to control usage here.  In other places we might have a more
 514                    pressing need, and we would be screwed if we ran out */
 515                 if(dma_free_sectors < (sgpnt[count].length >> 9) + 5) {
 516                   sgpnt[count].address = NULL;
 517                 } else {
 518                   sgpnt[count].address = (char *) scsi_malloc(sgpnt[count].length);
 519                 };
 520 /* If we start running low on DMA buffers, we abort the scatter-gather
 521    operation, and free all of the memory we have allocated.  We want to
 522    ensure that all scsi operations are able to do at least a non-scatter/gather
 523    operation */
 524                 if(sgpnt[count].address == NULL){ /* Out of dma memory */
 525                   printk("Warning: Running low on SCSI DMA buffers");
 526                   /* Try switching back to a non scatter-gather operation. */
 527                   while(--count >= 0){
 528                     if(sgpnt[count].alt_address) 
 529                       scsi_free(sgpnt[count].address, sgpnt[count].length);
 530                   };
 531                   SCpnt->use_sg = 0;
 532                   scsi_free(buffer, SCpnt->sglist_len);
 533                   break;
 534                 }; /* if address == NULL */
 535               };  /* if need DMA fixup */
 536             };  /* for loop to fill list */
 537 #ifdef DEBUG
 538             printk("SG: %d %d %d %d %d *** ",SCpnt->use_sg, SCpnt->request.sector,
 539                    this_count, 
 540                    SCpnt->request.current_nr_sectors,
 541                    SCpnt->request.nr_sectors);
 542             for(count=0; count<SCpnt->use_sg; count++)
 543               printk("SGlist: %d %x %x %x\n", count,
 544                      sgpnt[count].address, 
 545                      sgpnt[count].alt_address, 
 546                      sgpnt[count].length);
 547 #endif
 548           };  /* Able to allocate scatter-gather list */
 549         };
 550         
 551         if (SCpnt->use_sg == 0){
 552           /* We cannot use scatter-gather.  Do this the old fashion way */
 553           if (!SCpnt->request.bh)       
 554             this_count = SCpnt->request.nr_sectors;
 555           else
 556             this_count = (SCpnt->request.bh->b_size >> 9);
 557           
 558           start = block % 4;
 559           if (start)
 560             {                             
 561               this_count = ((this_count > 4 - start) ? 
 562                             (4 - start) : (this_count));
 563               buffer = (unsigned char *) scsi_malloc(2048);
 564             } 
 565           else if (this_count < 4)
 566             {
 567               buffer = (unsigned char *) scsi_malloc(2048);
 568             }
 569           else
 570             {
 571               this_count -= this_count % 4;
 572               buffer = (unsigned char *) SCpnt->request.buffer;
 573               if (((int) buffer) + (this_count << 9) > ISA_DMA_THRESHOLD & 
 574                   (SCpnt->host->unchecked_isa_dma))
 575                 buffer = (unsigned char *) scsi_malloc(this_count << 9);
 576             }
 577         };
 578 
 579         if (scsi_CDs[dev].sector_size == 2048)
 580           block = block >> 2; /* These are the sectors that the cdrom uses */
 581         else
 582           block = block & 0xfffffffc;
 583 
 584         realcount = (this_count + 3) / 4;
 585 
 586         if (scsi_CDs[dev].sector_size == 512) realcount = realcount << 2;
 587 
 588         if (((realcount > 0xff) || (block > 0x1fffff)) && scsi_CDs[dev].ten) 
 589                 {
 590                 if (realcount > 0xffff)
 591                         {
 592                         realcount = 0xffff;
 593                         this_count = realcount * (scsi_CDs[dev].sector_size >> 9);
 594                         }
 595 
 596                 cmd[0] += READ_10 - READ_6 ;
 597                 cmd[2] = (unsigned char) (block >> 24) & 0xff;
 598                 cmd[3] = (unsigned char) (block >> 16) & 0xff;
 599                 cmd[4] = (unsigned char) (block >> 8) & 0xff;
 600                 cmd[5] = (unsigned char) block & 0xff;
 601                 cmd[6] = cmd[9] = 0;
 602                 cmd[7] = (unsigned char) (realcount >> 8) & 0xff;
 603                 cmd[8] = (unsigned char) realcount & 0xff;
 604                 }
 605         else
 606                 {
 607                   if (realcount > 0xff)
 608                     {
 609                       realcount = 0xff;
 610                       this_count = realcount * (scsi_CDs[dev].sector_size >> 9);
 611                     }
 612                   
 613                   cmd[1] |= (unsigned char) ((block >> 16) & 0x1f);
 614                   cmd[2] = (unsigned char) ((block >> 8) & 0xff);
 615                   cmd[3] = (unsigned char) block & 0xff;
 616                   cmd[4] = (unsigned char) realcount;
 617                   cmd[5] = 0;
 618                 }   
 619 
 620 #ifdef DEBUG
 621         { 
 622           int i;
 623           printk("ReadCD: %d %d %d %d\n",block, realcount, buffer, this_count);
 624           printk("Use sg: %d\n", SCpnt->use_sg);
 625           printk("Dumping command: ");
 626           for(i=0; i<12; i++) printk("%2.2x ", cmd[i]);
 627           printk("\n");
 628         };
 629 #endif
 630 
 631 /* Some dumb host adapters can speed transfers by knowing the
 632  * minimum transfersize in advance.
 633  *
 634  * We shouldn't disconnect in the middle of a sector, but the cdrom
 635  * sector size can be larger than the size of a buffer and the
 636  * transfer may be split to the size of a buffer.  So it's safe to
 637  * assume that we can at least transfer the minimum of the buffer
 638  * size (1024) and the sector size between each connect / disconnect.
 639  */
 640 
 641         SCpnt->transfersize = (scsi_CDs[dev].sector_size > 1024) ?
 642                         1024 : scsi_CDs[dev].sector_size;
 643 
 644         SCpnt->this_count = this_count;
 645         scsi_do_cmd (SCpnt, (void *) cmd, buffer, 
 646                      realcount * scsi_CDs[dev].sector_size, 
 647                      rw_intr, SR_TIMEOUT, MAX_RETRIES);
 648 }
 649 
 650 static int sr_detect(Scsi_Device * SDp){
     /* [previous][next][first][last][top][bottom][index][help] */
 651   
 652   /* We do not support attaching loadable devices yet. */
 653   if(scsi_loadable_module_flag) return 0;
 654   if(SDp->type != TYPE_ROM && SDp->type != TYPE_WORM) return 0;
 655 
 656   printk("Detected scsi CD-ROM sr%d at scsi%d, id %d, lun %d\n", 
 657          sr_template.dev_noticed++,
 658          SDp->host->host_no , SDp->id, SDp->lun); 
 659 
 660          return 1;
 661 }
 662 
 663 static void sr_attach(Scsi_Device * SDp){
     /* [previous][next][first][last][top][bottom][index][help] */
 664   Scsi_CD * cpnt;
 665   int i;
 666   
 667   /* We do not support attaching loadable devices yet. */
 668   
 669   if(scsi_loadable_module_flag) return;
 670   if(SDp->type != TYPE_ROM && SDp->type != TYPE_WORM) return;
 671   
 672   if (sr_template.nr_dev >= sr_template.dev_max)
 673     panic ("scsi_devices corrupt (sr)");
 674   
 675   for(cpnt = scsi_CDs, i=0; i<sr_template.dev_max; i++, cpnt++) 
 676     if(!cpnt->device) break;
 677   
 678   if(i >= sr_template.dev_max) panic ("scsi_devices corrupt (sr)");
 679   
 680   SDp->scsi_request_fn = do_sr_request;
 681   scsi_CDs[i].device = SDp;
 682   sr_template.nr_dev++;
 683   if(sr_template.nr_dev > sr_template.dev_max)
 684     panic ("scsi_devices corrupt (sr)");
 685 }
 686      
 687 
 688 static void sr_init_done (Scsi_Cmnd * SCpnt)
     /* [previous][next][first][last][top][bottom][index][help] */
 689 {
 690   struct request * req;
 691   
 692   req = &SCpnt->request;
 693   req->dev = 0xfffe; /* Busy, but indicate request done */
 694   
 695   if (req->sem != NULL) {
 696     up(req->sem);
 697   }
 698 }
 699 
 700 static void get_sectorsize(int i){
     /* [previous][next][first][last][top][bottom][index][help] */
 701   unsigned char cmd[10];
 702   unsigned char buffer[513];
 703   int the_result, retries;
 704   Scsi_Cmnd * SCpnt;
 705   
 706   SCpnt = allocate_device(NULL, scsi_CDs[i].device, 1);
 707 
 708   retries = 3;
 709   do {
 710     cmd[0] = READ_CAPACITY;
 711     cmd[1] = (scsi_CDs[i].device->lun << 5) & 0xe0;
 712     memset ((void *) &cmd[2], 0, 8);
 713     SCpnt->request.dev = 0xffff;  /* Mark as really busy */
 714     
 715     memset(buffer, 0, 8);
 716 
 717     scsi_do_cmd (SCpnt,
 718                  (void *) cmd, (void *) buffer,
 719                  512, sr_init_done,  SR_TIMEOUT,
 720                  MAX_RETRIES);
 721     
 722     if (current == task[0])
 723       while(SCpnt->request.dev != 0xfffe);
 724     else
 725       if (SCpnt->request.dev != 0xfffe){
 726         struct semaphore sem = MUTEX_LOCKED;
 727         SCpnt->request.sem = &sem;
 728         down(&sem);
 729         /* Hmm.. Have to ask about this */
 730         while (SCpnt->request.dev != 0xfffe) schedule();
 731       };
 732     
 733     the_result = SCpnt->result;
 734     retries--;
 735     
 736   } while(the_result && retries);
 737   
 738   SCpnt->request.dev = -1;  /* Mark as not busy */
 739   
 740   wake_up(&SCpnt->device->device_wait); 
 741 
 742   if (the_result) {
 743     scsi_CDs[i].capacity = 0x1fffff;
 744     scsi_CDs[i].sector_size = 2048;  /* A guess, just in case */
 745     scsi_CDs[i].needs_sector_size = 1;
 746   } else {
 747     scsi_CDs[i].capacity = (buffer[0] << 24) |
 748       (buffer[1] << 16) | (buffer[2] << 8) | buffer[3];
 749     scsi_CDs[i].sector_size = (buffer[4] << 24) |
 750       (buffer[5] << 16) | (buffer[6] << 8) | buffer[7];
 751     if(scsi_CDs[i].sector_size == 0) scsi_CDs[i].sector_size = 2048;
 752     if(scsi_CDs[i].sector_size != 2048 && 
 753        scsi_CDs[i].sector_size != 512) {
 754       printk ("scd%d : unsupported sector size %d.\n",
 755               i, scsi_CDs[i].sector_size);
 756       scsi_CDs[i].capacity = 0;
 757       scsi_CDs[i].needs_sector_size = 1;
 758     };
 759     if(scsi_CDs[i].sector_size == 2048)
 760       scsi_CDs[i].capacity *= 4;
 761     scsi_CDs[i].needs_sector_size = 0;
 762   };
 763 }
 764 
 765 static void sr_init()
     /* [previous][next][first][last][top][bottom][index][help] */
 766 {
 767         int i;
 768         static int sr_registered = 0;
 769 
 770         if(sr_template.dev_noticed == 0) return;
 771 
 772         if(!sr_registered) {
 773           if (register_blkdev(MAJOR_NR,"sr",&sr_fops)) {
 774             printk("Unable to get major %d for SCSI-CD\n",MAJOR_NR);
 775             return;
 776           }
 777         }
 778 
 779         /* We do not support attaching loadable devices yet. */
 780         if(scsi_loadable_module_flag) return;
 781 
 782         sr_template.dev_max = sr_template.dev_noticed;
 783         scsi_CDs = (Scsi_CD *) scsi_init_malloc(sr_template.dev_max * sizeof(Scsi_CD));
 784         memset(scsi_CDs, 0, sr_template.dev_max * sizeof(Scsi_CD));
 785 
 786         sr_sizes = (int *) scsi_init_malloc(sr_template.dev_max * sizeof(int));
 787         memset(sr_sizes, 0, sr_template.dev_max * sizeof(int));
 788 
 789         sr_blocksizes = (int *) scsi_init_malloc(sr_template.dev_max * 
 790                                                  sizeof(int));
 791         for(i=0;i<sr_template.dev_max;i++) sr_blocksizes[i] = 2048;
 792         blksize_size[MAJOR_NR] = sr_blocksizes;
 793 
 794 }
 795 
 796 void sr_finish()
     /* [previous][next][first][last][top][bottom][index][help] */
 797 {
 798   int i;
 799 
 800         for (i = 0; i < sr_template.nr_dev; ++i)
 801                 {
 802                   get_sectorsize(i);
 803                   printk("Scd sectorsize = %d bytes\n", scsi_CDs[i].sector_size);
 804                   scsi_CDs[i].use = 1;
 805                   scsi_CDs[i].ten = 1;
 806                   scsi_CDs[i].remap = 1;
 807                   sr_sizes[i] = scsi_CDs[i].capacity;
 808                 }
 809 
 810         blk_dev[MAJOR_NR].request_fn = DEVICE_REQUEST;
 811         blk_size[MAJOR_NR] = sr_sizes;  
 812 
 813         /* If our host adapter is capable of scatter-gather, then we increase
 814            the read-ahead to 16 blocks (32 sectors).  If not, we use
 815            a two block (4 sector) read ahead. */
 816         if(scsi_CDs[0].device->host->sg_tablesize)
 817           read_ahead[MAJOR_NR] = 32;  /* 32 sector read-ahead.  Always removable. */
 818         else
 819           read_ahead[MAJOR_NR] = 4;  /* 4 sector read-ahead */
 820 
 821         return;
 822 }       

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