diff options
author | Ralf Baechle <ralf@linux-mips.org> | 1999-10-09 00:00:47 +0000 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 1999-10-09 00:00:47 +0000 |
commit | d6434e1042f3b0a6dfe1b1f615af369486f9b1fa (patch) | |
tree | e2be02f33984c48ec019c654051d27964e42c441 /drivers/scsi/sd.c | |
parent | 609d1e803baf519487233b765eb487f9ec227a18 (diff) |
Merge with 2.3.19.
Diffstat (limited to 'drivers/scsi/sd.c')
-rw-r--r-- | drivers/scsi/sd.c | 2971 |
1 files changed, 1452 insertions, 1519 deletions
diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c index 0a83f14b2..a2876d17c 100644 --- a/drivers/scsi/sd.c +++ b/drivers/scsi/sd.c @@ -18,7 +18,7 @@ * Modified by Jirka Hanika geo@ff.cuni.cz to support more * scsi disks using eight major numbers. */ - + #include <linux/module.h> #ifdef MODULE /* @@ -29,7 +29,7 @@ #define MODULE_FLAG 1 #else #define MODULE_FLAG scsi_loadable_module_flag -#endif /* MODULE */ +#endif /* MODULE */ #include <linux/fs.h> #include <linux/kernel.h> @@ -57,9 +57,9 @@ /* * static const char RCSid[] = "$Header:"; */ - + #define SD_MAJOR(i) (!(i) ? SCSI_DISK0_MAJOR : SCSI_DISK1_MAJOR-1+(i)) - + #define SCSI_DISKS_PER_MAJOR 16 #define SD_MAJOR_NUMBER(i) SD_MAJOR((i) >> 8) #define SD_MINOR_NUMBER(i) ((i) & 255) @@ -74,18 +74,18 @@ * Time out in seconds for disks and Magneto-opticals (which are slower). */ -#define SD_TIMEOUT (15 * HZ) +#define SD_TIMEOUT (30 * HZ) #define SD_MOD_TIMEOUT (75 * HZ) #define CLUSTERABLE_DEVICE(SC) (SC->host->use_clustering && \ SC->device->type != TYPE_MOD) -struct hd_struct * sd; +struct hd_struct *sd; -Scsi_Disk * rscsi_disks = NULL; -static int * sd_sizes; -static int * sd_blocksizes; -static int * sd_hardsizes; /* Hardware sector size */ +Scsi_Disk *rscsi_disks = NULL; +static int *sd_sizes; +static int *sd_blocksizes; +static int *sd_hardsizes; /* Hardware sector size */ extern int sd_ioctl(struct inode *, struct file *, unsigned int, unsigned long); @@ -94,7 +94,7 @@ static int fop_revalidate_scsidisk(kdev_t); static int sd_init_onedisk(int); -static void requeue_sd_request (Scsi_Cmnd * SCpnt); +static void requeue_sd_request(Scsi_Cmnd * SCpnt); static int sd_init(void); static void sd_finish(void); @@ -102,175 +102,171 @@ static int sd_attach(Scsi_Device *); static int sd_detect(Scsi_Device *); static void sd_detach(Scsi_Device *); -static void sd_devname(unsigned int disknum, char * buffer) +static void sd_devname(unsigned int disknum, char *buffer) { - if( disknum < 26 ) - sprintf(buffer, "sd%c", 'a' + disknum); - else { - unsigned int min1; - unsigned int min2; - /* - * For larger numbers of disks, we need to go to a new - * naming scheme. - */ - min1 = disknum / 26; - min2 = disknum % 26; - sprintf(buffer, "sd%c%c", 'a' + min1 - 1, 'a' + min2); - } + if (disknum < 26) + sprintf(buffer, "sd%c", 'a' + disknum); + else { + unsigned int min1; + unsigned int min2; + /* + * For larger numbers of disks, we need to go to a new + * naming scheme. + */ + min1 = disknum / 26; + min2 = disknum % 26; + sprintf(buffer, "sd%c%c", 'a' + min1 - 1, 'a' + min2); + } } struct Scsi_Device_Template sd_template = -{ NULL, "disk", "sd", NULL, TYPE_DISK, - SCSI_DISK0_MAJOR, 0, 0, 0, 1, - sd_detect, sd_init, - sd_finish, sd_attach, sd_detach +{NULL, "disk", "sd", NULL, TYPE_DISK, + SCSI_DISK0_MAJOR, 0, 0, 0, 1, + sd_detect, sd_init, + sd_finish, sd_attach, sd_detach }; -static int sd_open(struct inode * inode, struct file * filp) +static int sd_open(struct inode *inode, struct file *filp) { - int target; - target = DEVICE_NR(inode->i_rdev); - - SCSI_LOG_HLQUEUE(1,printk("target=%d, max=%d\n", target, sd_template.dev_max)); - - if(target >= sd_template.dev_max || !rscsi_disks[target].device) - return -ENXIO; /* No such device */ - - /* - * If the device is in error recovery, wait until it is done. - * If the device is offline, then disallow any access to it. - */ - if( !scsi_block_when_processing_errors(rscsi_disks[target].device) ) - { - return -ENXIO; - } - - /* - * Make sure that only one process can do a check_change_disk at one time. - * This is also used to lock out further access when the partition table - * is being re-read. - */ - - while (rscsi_disks[target].device->busy) - barrier(); - if(rscsi_disks[target].device->removable) { - check_disk_change(inode->i_rdev); + int target; + target = DEVICE_NR(inode->i_rdev); + + SCSI_LOG_HLQUEUE(1, printk("target=%d, max=%d\n", target, sd_template.dev_max)); + + if (target >= sd_template.dev_max || !rscsi_disks[target].device) + return -ENXIO; /* No such device */ /* - * If the drive is empty, just let the open fail. + * If the device is in error recovery, wait until it is done. + * If the device is offline, then disallow any access to it. + */ + if (!scsi_block_when_processing_errors(rscsi_disks[target].device)) { + return -ENXIO; + } + /* + * Make sure that only one process can do a check_change_disk at one time. + * This is also used to lock out further access when the partition table + * is being re-read. */ - if ( !rscsi_disks[target].ready ) - return -ENXIO; + while (rscsi_disks[target].device->busy) + barrier(); + if (rscsi_disks[target].device->removable) { + check_disk_change(inode->i_rdev); + + /* + * If the drive is empty, just let the open fail. + */ + if (!rscsi_disks[target].ready) + return -ENXIO; + + /* + * Similarly, if the device has the write protect tab set, + * have the open fail if the user expects to be able to write + * to the thing. + */ + if ((rscsi_disks[target].write_prot) && (filp->f_mode & 2)) + return -EROFS; + } /* - * Similarly, if the device has the write protect tab set, - * have the open fail if the user expects to be able to write - * to the thing. + * It is possible that the disk changing stuff resulted in the device being taken + * offline. If this is the case, report this to the user, and don't pretend that + * the open actually succeeded. */ - if ( (rscsi_disks[target].write_prot) && (filp->f_mode & 2) ) - return -EROFS; - } - - /* - * It is possible that the disk changing stuff resulted in the device being taken - * offline. If this is the case, report this to the user, and don't pretend that - * the open actually succeeded. - */ - if( !rscsi_disks[target].device->online ) - { - return -ENXIO; - } - - /* - * See if we are requesting a non-existent partition. Do this - * after checking for disk change. - */ - if(sd_sizes[SD_PARTITION(inode->i_rdev)] == 0) - return -ENXIO; - - if(rscsi_disks[target].device->removable) - if(!rscsi_disks[target].device->access_count) - sd_ioctl(inode, NULL, SCSI_IOCTL_DOORLOCK, 0); - - rscsi_disks[target].device->access_count++; - if (rscsi_disks[target].device->host->hostt->module) - __MOD_INC_USE_COUNT(rscsi_disks[target].device->host->hostt->module); - if(sd_template.module) - __MOD_INC_USE_COUNT(sd_template.module); - return 0; + if (!rscsi_disks[target].device->online) { + return -ENXIO; + } + /* + * See if we are requesting a non-existent partition. Do this + * after checking for disk change. + */ + if (sd_sizes[SD_PARTITION(inode->i_rdev)] == 0) + return -ENXIO; + + if (rscsi_disks[target].device->removable) + if (!rscsi_disks[target].device->access_count) + sd_ioctl(inode, NULL, SCSI_IOCTL_DOORLOCK, 0); + + rscsi_disks[target].device->access_count++; + if (rscsi_disks[target].device->host->hostt->module) + __MOD_INC_USE_COUNT(rscsi_disks[target].device->host->hostt->module); + if (sd_template.module) + __MOD_INC_USE_COUNT(sd_template.module); + return 0; } -static int sd_release(struct inode * inode, struct file * file) +static int sd_release(struct inode *inode, struct file *file) { - int target; - fsync_dev(inode->i_rdev); - - target = DEVICE_NR(inode->i_rdev); + int target; + fsync_dev(inode->i_rdev); - rscsi_disks[target].device->access_count--; + target = DEVICE_NR(inode->i_rdev); - if(rscsi_disks[target].device->removable) { - if(!rscsi_disks[target].device->access_count) - sd_ioctl(inode, NULL, SCSI_IOCTL_DOORUNLOCK, 0); - } + rscsi_disks[target].device->access_count--; - if(rscsi_disks[target].device->host->hostt->module) - __MOD_DEC_USE_COUNT(rscsi_disks[target].device->host->hostt->module); - if(sd_template.module) - __MOD_DEC_USE_COUNT(sd_template.module); - return 0; + if (rscsi_disks[target].device->removable) { + if (!rscsi_disks[target].device->access_count) + sd_ioctl(inode, NULL, SCSI_IOCTL_DOORUNLOCK, 0); + } + if (rscsi_disks[target].device->host->hostt->module) + __MOD_DEC_USE_COUNT(rscsi_disks[target].device->host->hostt->module); + if (sd_template.module) + __MOD_DEC_USE_COUNT(sd_template.module); + return 0; } static void sd_geninit(struct gendisk *); -static struct file_operations sd_fops = { - NULL, /* lseek - default */ - block_read, /* read - general block-dev read */ - block_write, /* write - general block-dev write */ - NULL, /* readdir - bad */ - NULL, /* select */ - sd_ioctl, /* ioctl */ - NULL, /* mmap */ - sd_open, /* open code */ - NULL, /* flush */ - sd_release, /* release */ - block_fsync, /* fsync */ - NULL, /* fasync */ - check_scsidisk_media_change, /* Disk change */ - fop_revalidate_scsidisk /* revalidate */ +static struct file_operations sd_fops = +{ + NULL, /* lseek - default */ + block_read, /* read - general block-dev read */ + block_write, /* write - general block-dev write */ + NULL, /* readdir - bad */ + NULL, /* select */ + sd_ioctl, /* ioctl */ + NULL, /* mmap */ + sd_open, /* open code */ + NULL, /* flush */ + sd_release, /* release */ + block_fsync, /* fsync */ + NULL, /* fasync */ + check_scsidisk_media_change, /* Disk change */ + fop_revalidate_scsidisk /* revalidate */ }; /* - * If we need more than one SCSI disk major (i.e. more than - * 16 SCSI disks), we'll have to kmalloc() more gendisks later. + * If we need more than one SCSI disk major (i.e. more than + * 16 SCSI disks), we'll have to kmalloc() more gendisks later. */ -static struct gendisk sd_gendisk = { - SCSI_DISK0_MAJOR, /* Major number */ - "sd", /* Major name */ - 4, /* Bits to shift to get real from partition */ - 1 << 4, /* Number of partitions per real */ - 0, /* maximum number of real */ - sd_geninit, /* init function */ - NULL, /* hd struct */ - NULL, /* block sizes */ - 0, /* number */ - NULL, /* internal */ - NULL /* next */ -}; +static struct gendisk sd_gendisk = +{ + SCSI_DISK0_MAJOR, /* Major number */ + "sd", /* Major name */ + 4, /* Bits to shift to get real from partition */ + 1 << 4, /* Number of partitions per real */ + 0, /* maximum number of real */ + sd_geninit, /* init function */ + NULL, /* hd struct */ + NULL, /* block sizes */ + 0, /* number */ + NULL, /* internal */ + NULL /* next */ +}; static struct gendisk *sd_gendisks = &sd_gendisk; #define SD_GENDISK(i) sd_gendisks[(i) / SCSI_DISKS_PER_MAJOR] #define LAST_SD_GENDISK sd_gendisks[N_USED_SD_MAJORS - 1] -static void sd_geninit (struct gendisk *ignored) +static void sd_geninit(struct gendisk *ignored) { - int i; + int i; - for (i = 0; i < sd_template.dev_max; ++i) - if(rscsi_disks[i].device) - sd[i << 4].nr_sects = rscsi_disks[i].capacity; + for (i = 0; i < sd_template.dev_max; ++i) + if (rscsi_disks[i].device) + sd[i << 4].nr_sects = rscsi_disks[i].capacity; } /* @@ -279,1208 +275,1144 @@ static void sd_geninit (struct gendisk *ignored) * will take one of several actions based on success or failure. */ -static void rw_intr (Scsi_Cmnd *SCpnt) +static void rw_intr(Scsi_Cmnd * SCpnt) { - int result = SCpnt->result; - char nbuff[6]; - int this_count = SCpnt->bufflen >> 9; - int good_sectors = (result == 0 ? this_count : 0); - int block_sectors = 1; - - sd_devname(DEVICE_NR(SCpnt->request.rq_dev), nbuff); - - SCSI_LOG_HLCOMPLETE(1,printk("%s : rw_intr(%d, %x [%x %x])\n", nbuff, - SCpnt->host->host_no, - result, - SCpnt->sense_buffer[0], - SCpnt->sense_buffer[2])); - - /* - Handle MEDIUM ERRORs that indicate partial success. Since this is a - relatively rare error condition, no care is taken to avoid unnecessary - additional work such as memcpy's that could be avoided. - */ - - if (driver_byte(result) != 0 && /* An error occurred */ - SCpnt->sense_buffer[0] == 0xF0 && /* Sense data is valid */ - SCpnt->sense_buffer[2] == MEDIUM_ERROR) - { - long error_sector = (SCpnt->sense_buffer[3] << 24) | - (SCpnt->sense_buffer[4] << 16) | - (SCpnt->sense_buffer[5] << 8) | - SCpnt->sense_buffer[6]; - int sector_size = - rscsi_disks[DEVICE_NR(SCpnt->request.rq_dev)].sector_size; - if (SCpnt->request.bh != NULL) - block_sectors = SCpnt->request.bh->b_size >> 9; - if (sector_size == 1024) - { - error_sector <<= 1; - if (block_sectors < 2) block_sectors = 2; - } - else if (sector_size == 2048) - { - error_sector <<= 2; - if (block_sectors < 4) block_sectors = 4; - } - else if (sector_size == 256) - error_sector >>= 1; - error_sector -= sd[SD_PARTITION(SCpnt->request.rq_dev)].start_sect; - error_sector &= ~ (block_sectors - 1); - good_sectors = error_sector - SCpnt->request.sector; - if (good_sectors < 0 || good_sectors >= this_count) - good_sectors = 0; - } - - /* - * First case : we assume that the command succeeded. One of two things - * will happen here. Either we will be finished, or there will be more - * sectors that we were unable to read last time. - */ - - if (good_sectors > 0) { - - SCSI_LOG_HLCOMPLETE(1,printk("%s : %ld sectors remain.\n", nbuff, - SCpnt->request.nr_sectors)); - SCSI_LOG_HLCOMPLETE(1,printk("use_sg is %d\n ",SCpnt->use_sg)); - - if (SCpnt->use_sg) { - struct scatterlist * sgpnt; - int i; - sgpnt = (struct scatterlist *) SCpnt->buffer; - for(i=0; i<SCpnt->use_sg; i++) { + int result = SCpnt->result; + char nbuff[6]; + int this_count = SCpnt->bufflen >> 9; + int good_sectors = (result == 0 ? this_count : 0); + int block_sectors = 1; -#if 0 - SCSI_LOG_HLCOMPLETE(3,printk(":%p %p %d\n",sgpnt[i].alt_address, sgpnt[i].address, - sgpnt[i].length)); -#endif + sd_devname(DEVICE_NR(SCpnt->request.rq_dev), nbuff); - if (sgpnt[i].alt_address) { - if (SCpnt->request.cmd == READ) - memcpy(sgpnt[i].alt_address, sgpnt[i].address, - sgpnt[i].length); - scsi_free(sgpnt[i].address, sgpnt[i].length); - } - } + SCSI_LOG_HLCOMPLETE(1, printk("%s : rw_intr(%d, %x [%x %x])\n", nbuff, + SCpnt->host->host_no, + result, + SCpnt->sense_buffer[0], + SCpnt->sense_buffer[2])); - /* Free list of scatter-gather pointers */ - scsi_free(SCpnt->buffer, SCpnt->sglist_len); - } else { - if (SCpnt->buffer != SCpnt->request.buffer) { - SCSI_LOG_HLCOMPLETE(3,printk("nosg: %p %p %d\n", - SCpnt->request.buffer, SCpnt->buffer, - SCpnt->bufflen)); - - if (SCpnt->request.cmd == READ) - memcpy(SCpnt->request.buffer, SCpnt->buffer, - SCpnt->bufflen); - scsi_free(SCpnt->buffer, SCpnt->bufflen); - } + /* + Handle MEDIUM ERRORs that indicate partial success. Since this is a + relatively rare error condition, no care is taken to avoid unnecessary + additional work such as memcpy's that could be avoided. + */ + + if (driver_byte(result) != 0 && /* An error occurred */ + SCpnt->sense_buffer[0] == 0xF0 && /* Sense data is valid */ + SCpnt->sense_buffer[2] == MEDIUM_ERROR) { + long error_sector = (SCpnt->sense_buffer[3] << 24) | + (SCpnt->sense_buffer[4] << 16) | + (SCpnt->sense_buffer[5] << 8) | + SCpnt->sense_buffer[6]; + int sector_size = + rscsi_disks[DEVICE_NR(SCpnt->request.rq_dev)].sector_size; + if (SCpnt->request.bh != NULL) + block_sectors = SCpnt->request.bh->b_size >> 9; + if (sector_size == 1024) { + error_sector <<= 1; + if (block_sectors < 2) + block_sectors = 2; + } else if (sector_size == 2048) { + error_sector <<= 2; + if (block_sectors < 4) + block_sectors = 4; + } else if (sector_size == 256) + error_sector >>= 1; + error_sector -= sd[SD_PARTITION(SCpnt->request.rq_dev)].start_sect; + error_sector &= ~(block_sectors - 1); + good_sectors = error_sector - SCpnt->request.sector; + if (good_sectors < 0 || good_sectors >= this_count) + good_sectors = 0; } /* - * If multiple sectors are requested in one buffer, then - * they will have been finished off by the first command. - * If not, then we have a multi-buffer command. + * First case : we assume that the command succeeded. One of two things + * will happen here. Either we will be finished, or there will be more + * sectors that we were unable to read last time. */ - if (SCpnt->request.nr_sectors > this_count) - { - SCpnt->request.errors = 0; - if (!SCpnt->request.bh) - { - SCSI_LOG_HLCOMPLETE(2,printk("%s : handling page request, no buffer\n", - nbuff)); + if (good_sectors > 0) { + + SCSI_LOG_HLCOMPLETE(1, printk("%s : %ld sectors remain.\n", nbuff, + SCpnt->request.nr_sectors)); + SCSI_LOG_HLCOMPLETE(1, printk("use_sg is %d\n ", SCpnt->use_sg)); + + if (SCpnt->use_sg) { + struct scatterlist *sgpnt; + int i; + sgpnt = (struct scatterlist *) SCpnt->buffer; + for (i = 0; i < SCpnt->use_sg; i++) { + +#if 0 + SCSI_LOG_HLCOMPLETE(3, printk(":%p %p %d\n", sgpnt[i].alt_address, sgpnt[i].address, + sgpnt[i].length)); +#endif + if (sgpnt[i].alt_address) { + if (SCpnt->request.cmd == READ) + memcpy(sgpnt[i].alt_address, sgpnt[i].address, + sgpnt[i].length); + scsi_free(sgpnt[i].address, sgpnt[i].length); + } + } + + /* Free list of scatter-gather pointers */ + scsi_free(SCpnt->buffer, SCpnt->sglist_len); + } else { + if (SCpnt->buffer != SCpnt->request.buffer) { + SCSI_LOG_HLCOMPLETE(3, printk("nosg: %p %p %d\n", + SCpnt->request.buffer, SCpnt->buffer, + SCpnt->bufflen)); + + if (SCpnt->request.cmd == READ) + memcpy(SCpnt->request.buffer, SCpnt->buffer, + SCpnt->bufflen); + scsi_free(SCpnt->buffer, SCpnt->bufflen); + } + } /* - * The SCpnt->request.nr_sectors field is always done in - * 512 byte sectors, even if this really isn't the case. + * If multiple sectors are requested in one buffer, then + * they will have been finished off by the first command. + * If not, then we have a multi-buffer command. */ - panic("sd.c: linked page request (%lx %x)", - SCpnt->request.sector, this_count); - } + if (SCpnt->request.nr_sectors > this_count) { + SCpnt->request.errors = 0; + + if (!SCpnt->request.bh) { + SCSI_LOG_HLCOMPLETE(2, printk("%s : handling page request, no buffer\n", + nbuff)); + + /* + * The SCpnt->request.nr_sectors field is always done in + * 512 byte sectors, even if this really isn't the case. + */ + panic("sd.c: linked page request (%lx %x)", + SCpnt->request.sector, this_count); + } + } + SCpnt = end_scsi_request(SCpnt, 1, good_sectors); + if (result == 0) { + requeue_sd_request(SCpnt); + return; + } } - SCpnt = end_scsi_request(SCpnt, 1, good_sectors); - if (result == 0) - { - requeue_sd_request(SCpnt); - return; - } - } - - if (good_sectors == 0) { - - /* Free up any indirection buffers we allocated for DMA purposes. */ - if (SCpnt->use_sg) { - struct scatterlist * sgpnt; - int i; - sgpnt = (struct scatterlist *) SCpnt->buffer; - for(i=0; i<SCpnt->use_sg; i++) { - SCSI_LOG_HLCOMPLETE(3,printk("err: %p %p %d\n", - SCpnt->request.buffer, SCpnt->buffer, - SCpnt->bufflen)); - if (sgpnt[i].alt_address) { - scsi_free(sgpnt[i].address, sgpnt[i].length); - } + if (good_sectors == 0) { + + /* Free up any indirection buffers we allocated for DMA purposes. */ + if (SCpnt->use_sg) { + struct scatterlist *sgpnt; + int i; + sgpnt = (struct scatterlist *) SCpnt->buffer; + for (i = 0; i < SCpnt->use_sg; i++) { + SCSI_LOG_HLCOMPLETE(3, printk("err: %p %p %d\n", + SCpnt->request.buffer, SCpnt->buffer, + SCpnt->bufflen)); + if (sgpnt[i].alt_address) { + scsi_free(sgpnt[i].address, sgpnt[i].length); + } + } + scsi_free(SCpnt->buffer, SCpnt->sglist_len); /* Free list of scatter-gather pointers */ + } else { + SCSI_LOG_HLCOMPLETE(2, printk("nosgerr: %p %p %d\n", + SCpnt->request.buffer, SCpnt->buffer, + SCpnt->bufflen)); + if (SCpnt->buffer != SCpnt->request.buffer) + scsi_free(SCpnt->buffer, SCpnt->bufflen); + } } - scsi_free(SCpnt->buffer, SCpnt->sglist_len); /* Free list of scatter-gather pointers */ - } else { - SCSI_LOG_HLCOMPLETE(2,printk("nosgerr: %p %p %d\n", - SCpnt->request.buffer, SCpnt->buffer, - SCpnt->bufflen)); - if (SCpnt->buffer != SCpnt->request.buffer) - scsi_free(SCpnt->buffer, SCpnt->bufflen); - } - } - - /* - * Now, if we were good little boys and girls, Santa left us a request - * sense buffer. We can extract information from this, so we - * can choose a block to remap, etc. - */ - - if (driver_byte(result) != 0) { - if (suggestion(result) == SUGGEST_REMAP) { + /* + * Now, if we were good little boys and girls, Santa left us a request + * sense buffer. We can extract information from this, so we + * can choose a block to remap, etc. + */ + + if (driver_byte(result) != 0) { + if (suggestion(result) == SUGGEST_REMAP) { #ifdef REMAP - /* - * Not yet implemented. A read will fail after being remapped, - * a write will call the strategy routine again. - */ - if rscsi_disks[DEVICE_NR(SCpnt->request.rq_dev)].remap - { - result = 0; - } - else + /* + * Not yet implemented. A read will fail after being remapped, + * a write will call the strategy routine again. + */ + if rscsi_disks + [DEVICE_NR(SCpnt->request.rq_dev)].remap + { + result = 0; + } #endif - } - - if ((SCpnt->sense_buffer[0] & 0x7f) == 0x70) { - if ((SCpnt->sense_buffer[2] & 0xf) == UNIT_ATTENTION) { - if(rscsi_disks[DEVICE_NR(SCpnt->request.rq_dev)].device->removable) { - /* detected disc change. set a bit and quietly refuse - * further access. - */ - rscsi_disks[DEVICE_NR(SCpnt->request.rq_dev)].device->changed = 1; - SCpnt = end_scsi_request(SCpnt, 0, this_count); - requeue_sd_request(SCpnt); - return; } - else - { - /* - * Must have been a power glitch, or a bus reset. - * Could not have been a media change, so we just retry - * the request and see what happens. - */ - requeue_sd_request(SCpnt); - return; - } - } - } - - - /* If we had an ILLEGAL REQUEST returned, then we may have - * performed an unsupported command. The only thing this should be - * would be a ten byte read where only a six byte read was supported. - * Also, on a system where READ CAPACITY failed, we have have read - * past the end of the disk. - */ + if ((SCpnt->sense_buffer[0] & 0x7f) == 0x70) { + if ((SCpnt->sense_buffer[2] & 0xf) == UNIT_ATTENTION) { + if (rscsi_disks[DEVICE_NR(SCpnt->request.rq_dev)].device->removable) { + /* detected disc change. set a bit and quietly refuse + * further access. + */ + rscsi_disks[DEVICE_NR(SCpnt->request.rq_dev)].device->changed = 1; + SCpnt = end_scsi_request(SCpnt, 0, this_count); + requeue_sd_request(SCpnt); + return; + } else { + /* + * Must have been a power glitch, or a bus reset. + * Could not have been a media change, so we just retry + * the request and see what happens. + */ + requeue_sd_request(SCpnt); + return; + } + } + } + /* If we had an ILLEGAL REQUEST returned, then we may have + * performed an unsupported command. The only thing this should be + * would be a ten byte read where only a six byte read was supported. + * Also, on a system where READ CAPACITY failed, we have have read + * past the end of the disk. + */ - if (SCpnt->sense_buffer[2] == ILLEGAL_REQUEST) { - if (rscsi_disks[DEVICE_NR(SCpnt->request.rq_dev)].ten) { - rscsi_disks[DEVICE_NR(SCpnt->request.rq_dev)].ten = 0; + if (SCpnt->sense_buffer[2] == ILLEGAL_REQUEST) { + if (rscsi_disks[DEVICE_NR(SCpnt->request.rq_dev)].ten) { + rscsi_disks[DEVICE_NR(SCpnt->request.rq_dev)].ten = 0; + requeue_sd_request(SCpnt); + result = 0; + } else { + /* ???? */ + } + } + if (SCpnt->sense_buffer[2] == MEDIUM_ERROR) { + printk("scsi%d: MEDIUM ERROR on channel %d, id %d, lun %d, CDB: ", + SCpnt->host->host_no, (int) SCpnt->channel, + (int) SCpnt->target, (int) SCpnt->lun); + print_command(SCpnt->cmnd); + print_sense("sd", SCpnt); + SCpnt = end_scsi_request(SCpnt, 0, block_sectors); + requeue_sd_request(SCpnt); + return; + } + } /* driver byte != 0 */ + if (result) { + printk("SCSI disk error : host %d channel %d id %d lun %d return code = %x\n", + rscsi_disks[DEVICE_NR(SCpnt->request.rq_dev)].device->host->host_no, + rscsi_disks[DEVICE_NR(SCpnt->request.rq_dev)].device->channel, + rscsi_disks[DEVICE_NR(SCpnt->request.rq_dev)].device->id, + rscsi_disks[DEVICE_NR(SCpnt->request.rq_dev)].device->lun, result); + + if (driver_byte(result) & DRIVER_SENSE) + print_sense("sd", SCpnt); + SCpnt = end_scsi_request(SCpnt, 0, SCpnt->request.current_nr_sectors); requeue_sd_request(SCpnt); - result = 0; - } else { - /* ???? */ - } + return; } - - if (SCpnt->sense_buffer[2] == MEDIUM_ERROR) { - printk("scsi%d: MEDIUM ERROR on channel %d, id %d, lun %d, CDB: ", - SCpnt->host->host_no, (int) SCpnt->channel, - (int) SCpnt->target, (int) SCpnt->lun); - print_command(SCpnt->cmnd); - print_sense("sd", SCpnt); - SCpnt = end_scsi_request(SCpnt, 0, block_sectors); - requeue_sd_request(SCpnt); - return; - } - } /* driver byte != 0 */ - if (result) { - printk("SCSI disk error : host %d channel %d id %d lun %d return code = %x\n", - rscsi_disks[DEVICE_NR(SCpnt->request.rq_dev)].device->host->host_no, - rscsi_disks[DEVICE_NR(SCpnt->request.rq_dev)].device->channel, - rscsi_disks[DEVICE_NR(SCpnt->request.rq_dev)].device->id, - rscsi_disks[DEVICE_NR(SCpnt->request.rq_dev)].device->lun, result); - - if (driver_byte(result) & DRIVER_SENSE) - print_sense("sd", SCpnt); - SCpnt = end_scsi_request(SCpnt, 0, SCpnt->request.current_nr_sectors); - requeue_sd_request(SCpnt); - return; - } } - /* * requeue_sd_request() is the request handler function for the sd driver. * Its function in life is to take block device requests, and translate * them to SCSI commands. */ -static void do_sd_request (void) +static void do_sd_request(void) { - Scsi_Cmnd * SCpnt = NULL; - Scsi_Device * SDev; - struct request * req = NULL; - int flag = 0; - - while (1==1){ - if (CURRENT != NULL && CURRENT->rq_status == RQ_INACTIVE) { - return; - } - - INIT_SCSI_REQUEST; - SDev = rscsi_disks[CURRENT_DEV].device; - - /* - * If the host for this device is in error recovery mode, don't - * do anything at all here. When the host leaves error recovery - * mode, it will automatically restart things and start queueing - * commands again. - */ - if( SDev->host->in_recovery ) - { - return; - } - - /* - * I am not sure where the best place to do this is. We need - * to hook in a place where we are likely to come if in user - * space. - */ - if( SDev->was_reset ) - { - /* - * We need to relock the door, but we might - * be in an interrupt handler. Only do this - * from user space, since we do not want to - * sleep from an interrupt. FIXME(eric) - do this - * from the kernel error handling thred. - */ - if( SDev->removable && !in_interrupt() ) - { - spin_unlock_irq(&io_request_lock); /* FIXME!!!! */ - scsi_ioctl(SDev, SCSI_IOCTL_DOORLOCK, 0); - /* scsi_ioctl may allow CURRENT to change, so start over. */ - SDev->was_reset = 0; - spin_lock_irq(&io_request_lock); /* FIXME!!!! */ - continue; - } - SDev->was_reset = 0; - } - - /* We have to be careful here. scsi_allocate_device will get a free pointer, - * but there is no guarantee that it is queueable. In normal usage, - * we want to call this, because other types of devices may have the - * host all tied up, and we want to make sure that we have at least - * one request pending for this type of device. We can also come - * through here while servicing an interrupt, because of the need to - * start another command. If we call scsi_allocate_device more than once, - * then the system can wedge if the command is not queueable. The - * scsi_request_queueable function is safe because it checks to make sure - * that the host is able to take another command before it returns - * a pointer. - */ - - if (flag++ == 0) - SCpnt = scsi_allocate_device(&CURRENT, - rscsi_disks[CURRENT_DEV].device, 0); - else SCpnt = NULL; + Scsi_Cmnd *SCpnt = NULL; + Scsi_Device *SDev; + struct request *req = NULL; + int flag = 0; + + while (1 == 1) { + if (CURRENT != NULL && CURRENT->rq_status == RQ_INACTIVE) { + return; + } + INIT_SCSI_REQUEST; + SDev = rscsi_disks[CURRENT_DEV].device; - /* - * The following restore_flags leads to latency problems. FIXME. - * Using a "sti()" gets rid of the latency problems but causes - * race conditions and crashes. - */ + /* + * If the host for this device is in error recovery mode, don't + * do anything at all here. When the host leaves error recovery + * mode, it will automatically restart things and start queueing + * commands again. + */ + if (SDev->host->in_recovery) { + return; + } + /* + * I am not sure where the best place to do this is. We need + * to hook in a place where we are likely to come if in user + * space. + */ + if (SDev->was_reset) { + /* + * We need to relock the door, but we might + * be in an interrupt handler. Only do this + * from user space, since we do not want to + * sleep from an interrupt. FIXME(eric) - do this + * from the kernel error handling thred. + */ + if (SDev->removable && !in_interrupt()) { + spin_unlock_irq(&io_request_lock); /* FIXME!!!! */ + scsi_ioctl(SDev, SCSI_IOCTL_DOORLOCK, 0); + /* scsi_ioctl may allow CURRENT to change, so start over. */ + SDev->was_reset = 0; + spin_lock_irq(&io_request_lock); /* FIXME!!!! */ + continue; + } + SDev->was_reset = 0; + } + /* We have to be careful here. scsi_allocate_device will get a free pointer, + * but there is no guarantee that it is queueable. In normal usage, + * we want to call this, because other types of devices may have the + * host all tied up, and we want to make sure that we have at least + * one request pending for this type of device. We can also come + * through here while servicing an interrupt, because of the need to + * start another command. If we call scsi_allocate_device more than once, + * then the system can wedge if the command is not queueable. The + * scsi_request_queueable function is safe because it checks to make sure + * that the host is able to take another command before it returns + * a pointer. + */ - /* This is a performance enhancement. We dig down into the request - * list and try to find a queueable request (i.e. device not busy, - * and host able to accept another command. If we find one, then we - * queue it. This can make a big difference on systems with more than - * one disk drive. We want to have the interrupts off when monkeying - * with the request list, because otherwise the kernel might try to - * slip in a request in between somewhere. - * - * FIXME(eric) - this doesn't belong at this level. The device code in - * ll_rw_blk.c should know how to dig down into the device queue to - * figure out what it can deal with, and what it can't. Consider - * possibility of pulling entire queue down into scsi layer. - */ - if (!SCpnt && sd_template.nr_dev > 1){ - struct request *req1; - req1 = NULL; - req = CURRENT; - while(req){ - SCpnt = scsi_request_queueable(req, - rscsi_disks[DEVICE_NR(req->rq_dev)].device); - if(SCpnt) break; - req1 = req; - req = req->next; - } - if (SCpnt && req->rq_status == RQ_INACTIVE) { - if (req == CURRENT) - CURRENT = CURRENT->next; + if (flag++ == 0) + SCpnt = scsi_allocate_device(&CURRENT, + rscsi_disks[CURRENT_DEV].device, 0); else - req1->next = req->next; - } - } + SCpnt = NULL; + + /* + * The following restore_flags leads to latency problems. FIXME. + * Using a "sti()" gets rid of the latency problems but causes + * race conditions and crashes. + */ - if (!SCpnt) return; /* Could not find anything to do */ + /* This is a performance enhancement. We dig down into the request + * list and try to find a queueable request (i.e. device not busy, + * and host able to accept another command. If we find one, then we + * queue it. This can make a big difference on systems with more than + * one disk drive. We want to have the interrupts off when monkeying + * with the request list, because otherwise the kernel might try to + * slip in a request in between somewhere. + * + * FIXME(eric) - this doesn't belong at this level. The device code in + * ll_rw_blk.c should know how to dig down into the device queue to + * figure out what it can deal with, and what it can't. Consider + * possibility of pulling entire queue down into scsi layer. + */ + if (!SCpnt && sd_template.nr_dev > 1) { + struct request *req1; + req1 = NULL; + req = CURRENT; + while (req) { + SCpnt = scsi_request_queueable(req, + rscsi_disks[DEVICE_NR(req->rq_dev)].device); + if (SCpnt) + break; + req1 = req; + req = req->next; + } + if (SCpnt && req->rq_status == RQ_INACTIVE) { + if (req == CURRENT) + CURRENT = CURRENT->next; + else + req1->next = req->next; + } + } + if (!SCpnt) + return; /* Could not find anything to do */ - /* Queue command */ - requeue_sd_request(SCpnt); - } /* While */ + /* Queue command */ + requeue_sd_request(SCpnt); + } /* While */ } -static void requeue_sd_request (Scsi_Cmnd * SCpnt) +static void requeue_sd_request(Scsi_Cmnd * SCpnt) { - int dev, devm, block, this_count; - unsigned char cmd[10]; - char nbuff[6]; - int bounce_size, contiguous; - int max_sg; - struct buffer_head * bh, *bhp; - char * buff, *bounce_buffer; - - repeat: - - if(!SCpnt || SCpnt->request.rq_status == RQ_INACTIVE) { - do_sd_request(); - return; - } - - devm = SD_PARTITION(SCpnt->request.rq_dev); - dev = DEVICE_NR(SCpnt->request.rq_dev); + int dev, devm, block, this_count; + unsigned char cmd[10]; + char nbuff[6]; + int bounce_size, contiguous; + int max_sg; + struct buffer_head *bh, *bhp; + char *buff, *bounce_buffer; + +repeat: + + if (!SCpnt || SCpnt->request.rq_status == RQ_INACTIVE) { + do_sd_request(); + return; + } + devm = SD_PARTITION(SCpnt->request.rq_dev); + dev = DEVICE_NR(SCpnt->request.rq_dev); - block = SCpnt->request.sector; - this_count = 0; + block = SCpnt->request.sector; + this_count = 0; - SCSI_LOG_HLQUEUE(1,printk("Doing sd request, dev = %d, block = %d\n", devm, block)); + SCSI_LOG_HLQUEUE(1, printk("Doing sd request, dev = %d, block = %d\n", devm, block)); - if (devm >= (sd_template.dev_max << 4) || - !rscsi_disks[dev].device || - !rscsi_disks[dev].device->online || - block + SCpnt->request.nr_sectors > sd[devm].nr_sects) - { - SCSI_LOG_HLQUEUE(2,printk("Finishing %ld sectors\n", SCpnt->request.nr_sectors)); - SCpnt = end_scsi_request(SCpnt, 0, SCpnt->request.nr_sectors); - SCSI_LOG_HLQUEUE(2,printk("Retry with 0x%p\n", SCpnt)); - goto repeat; - } + if (devm >= (sd_template.dev_max << 4) || + !rscsi_disks[dev].device || + !rscsi_disks[dev].device->online || + block + SCpnt->request.nr_sectors > sd[devm].nr_sects) { + SCSI_LOG_HLQUEUE(2, printk("Finishing %ld sectors\n", SCpnt->request.nr_sectors)); + SCpnt = end_scsi_request(SCpnt, 0, SCpnt->request.nr_sectors); + SCSI_LOG_HLQUEUE(2, printk("Retry with 0x%p\n", SCpnt)); + goto repeat; + } + block += sd[devm].start_sect; - block += sd[devm].start_sect; + if (rscsi_disks[dev].device->changed) { + /* + * quietly refuse to do anything to a changed disc until the changed + * bit has been reset + */ + /* printk("SCSI disk has been changed. Prohibiting further I/O.\n"); */ + SCpnt = end_scsi_request(SCpnt, 0, SCpnt->request.nr_sectors); + goto repeat; + } + sd_devname(devm >> 4, nbuff); + SCSI_LOG_HLQUEUE(2, printk("%s : real dev = /dev/%d, block = %d\n", + nbuff, dev, block)); - if (rscsi_disks[dev].device->changed) - { /* - * quietly refuse to do anything to a changed disc until the changed - * bit has been reset + * If we have a 1K hardware sectorsize, prevent access to single + * 512 byte sectors. In theory we could handle this - in fact + * the scsi cdrom driver must be able to handle this because + * we typically use 1K blocksizes, and cdroms typically have + * 2K hardware sectorsizes. Of course, things are simpler + * with the cdrom, since it is read-only. For performance + * reasons, the filesystems should be able to handle this + * and not force the scsi disk driver to use bounce buffers + * for this. */ - /* printk("SCSI disk has been changed. Prohibiting further I/O.\n"); */ - SCpnt = end_scsi_request(SCpnt, 0, SCpnt->request.nr_sectors); - goto repeat; - } - - sd_devname(devm >> 4, nbuff); - SCSI_LOG_HLQUEUE(2,printk("%s : real dev = /dev/%d, block = %d\n", - nbuff, dev, block)); - - /* - * If we have a 1K hardware sectorsize, prevent access to single - * 512 byte sectors. In theory we could handle this - in fact - * the scsi cdrom driver must be able to handle this because - * we typically use 1K blocksizes, and cdroms typically have - * 2K hardware sectorsizes. Of course, things are simpler - * with the cdrom, since it is read-only. For performance - * reasons, the filesystems should be able to handle this - * and not force the scsi disk driver to use bounce buffers - * for this. - */ - if (rscsi_disks[dev].sector_size == 1024) - if((block & 1) || (SCpnt->request.nr_sectors & 1)) { - printk("sd.c:Bad block number/count requested"); - SCpnt = end_scsi_request(SCpnt, 0, SCpnt->request.nr_sectors); - goto repeat; - } - - if (rscsi_disks[dev].sector_size == 2048) - if((block & 3) || (SCpnt->request.nr_sectors & 3)) { - printk("sd.c:Bad block number/count requested"); - SCpnt = end_scsi_request(SCpnt, 0, SCpnt->request.nr_sectors); - goto repeat; - } - if (rscsi_disks[dev].sector_size == 4096) - if((block & 7) || (SCpnt->request.nr_sectors & 7)) { - printk("sd.cBad block number/count requested"); - SCpnt = end_scsi_request(SCpnt, 0, SCpnt->request.nr_sectors); - goto repeat; - } - - switch (SCpnt->request.cmd) - { - case WRITE : - if (!rscsi_disks[dev].device->writeable) - { - SCpnt = end_scsi_request(SCpnt, 0, SCpnt->request.nr_sectors); - goto repeat; - } - cmd[0] = WRITE_6; - break; - case READ : - cmd[0] = READ_6; - break; - default : - panic ("Unknown sd command %d\n", SCpnt->request.cmd); - } - - SCpnt->this_count = 0; - - /* If the host adapter can deal with very large scatter-gather - * requests, it is a waste of time to cluster - */ - contiguous = (!CLUSTERABLE_DEVICE(SCpnt) ? 0 :1); - bounce_buffer = NULL; - bounce_size = (SCpnt->request.nr_sectors << 9); - - /* First see if we need a bounce buffer for this request. If we do, make - * sure that we can allocate a buffer. Do not waste space by allocating - * a bounce buffer if we are straddling the 16Mb line - */ - if (contiguous && SCpnt->request.bh && - virt_to_phys(SCpnt->request.bh->b_data) - + (SCpnt->request.nr_sectors << 9) - 1 > ISA_DMA_THRESHOLD - && SCpnt->host->unchecked_isa_dma) { - if(virt_to_phys(SCpnt->request.bh->b_data) > ISA_DMA_THRESHOLD) - bounce_buffer = (char *) scsi_malloc(bounce_size); - if(!bounce_buffer) contiguous = 0; - } - - if(contiguous && SCpnt->request.bh && SCpnt->request.bh->b_reqnext) - for(bh = SCpnt->request.bh, bhp = bh->b_reqnext; bhp; bh = bhp, - bhp = bhp->b_reqnext) { - if(!CONTIGUOUS_BUFFERS(bh,bhp)) { - if(bounce_buffer) scsi_free(bounce_buffer, bounce_size); - contiguous = 0; + if (rscsi_disks[dev].sector_size == 1024) + if ((block & 1) || (SCpnt->request.nr_sectors & 1)) { + printk("sd.c:Bad block number/count requested"); + SCpnt = end_scsi_request(SCpnt, 0, SCpnt->request.nr_sectors); + goto repeat; + } + if (rscsi_disks[dev].sector_size == 2048) + if ((block & 3) || (SCpnt->request.nr_sectors & 3)) { + printk("sd.c:Bad block number/count requested"); + SCpnt = end_scsi_request(SCpnt, 0, SCpnt->request.nr_sectors); + goto repeat; + } + if (rscsi_disks[dev].sector_size == 4096) + if ((block & 7) || (SCpnt->request.nr_sectors & 7)) { + printk("sd.cBad block number/count requested"); + SCpnt = end_scsi_request(SCpnt, 0, SCpnt->request.nr_sectors); + goto repeat; + } + switch (SCpnt->request.cmd) { + case WRITE: + if (!rscsi_disks[dev].device->writeable) { + SCpnt = end_scsi_request(SCpnt, 0, SCpnt->request.nr_sectors); + goto repeat; + } + cmd[0] = WRITE_6; break; - } + case READ: + cmd[0] = READ_6; + break; + default: + panic("Unknown sd command %d\n", SCpnt->request.cmd); } - if (!SCpnt->request.bh || contiguous) { - - /* case of page request (i.e. raw device), or unlinked buffer */ - this_count = SCpnt->request.nr_sectors; - buff = SCpnt->request.buffer; - SCpnt->use_sg = 0; - - } else if (SCpnt->host->sg_tablesize == 0 || - (scsi_need_isa_buffer && scsi_dma_free_sectors <= 10)) { - - /* Case of host adapter that cannot scatter-gather. We also - * come here if we are running low on DMA buffer memory. We set - * a threshold higher than that we would need for this request so - * we leave room for other requests. Even though we would not need - * it all, we need to be conservative, because if we run low enough - * we have no choice but to panic. + + SCpnt->this_count = 0; + + /* If the host adapter can deal with very large scatter-gather + * requests, it is a waste of time to cluster + */ + contiguous = (!CLUSTERABLE_DEVICE(SCpnt) ? 0 : 1); + bounce_buffer = NULL; + bounce_size = (SCpnt->request.nr_sectors << 9); + + /* First see if we need a bounce buffer for this request. If we do, make + * sure that we can allocate a buffer. Do not waste space by allocating + * a bounce buffer if we are straddling the 16Mb line */ - if (SCpnt->host->sg_tablesize != 0 && - scsi_need_isa_buffer && - scsi_dma_free_sectors <= 10) - printk("Warning: SCSI DMA buffer space running low. Using non scatter-gather I/O.\n"); + if (contiguous && SCpnt->request.bh && + virt_to_phys(SCpnt->request.bh->b_data) + + (SCpnt->request.nr_sectors << 9) - 1 > ISA_DMA_THRESHOLD + && SCpnt->host->unchecked_isa_dma) { + if (virt_to_phys(SCpnt->request.bh->b_data) > ISA_DMA_THRESHOLD) + bounce_buffer = (char *) scsi_malloc(bounce_size); + if (!bounce_buffer) + contiguous = 0; + } + if (contiguous && SCpnt->request.bh && SCpnt->request.bh->b_reqnext) + for (bh = SCpnt->request.bh, bhp = bh->b_reqnext; bhp; bh = bhp, + bhp = bhp->b_reqnext) { + if (!CONTIGUOUS_BUFFERS(bh, bhp)) { + if (bounce_buffer) + scsi_free(bounce_buffer, bounce_size); + contiguous = 0; + break; + } + } + if (!SCpnt->request.bh || contiguous) { + + /* case of page request (i.e. raw device), or unlinked buffer */ + this_count = SCpnt->request.nr_sectors; + buff = SCpnt->request.buffer; + SCpnt->use_sg = 0; + + } else if (SCpnt->host->sg_tablesize == 0 || + (scsi_need_isa_buffer && scsi_dma_free_sectors <= 10)) { + + /* Case of host adapter that cannot scatter-gather. We also + * come here if we are running low on DMA buffer memory. We set + * a threshold higher than that we would need for this request so + * we leave room for other requests. Even though we would not need + * it all, we need to be conservative, because if we run low enough + * we have no choice but to panic. + */ + if (SCpnt->host->sg_tablesize != 0 && + scsi_need_isa_buffer && + scsi_dma_free_sectors <= 10) + printk("Warning: SCSI DMA buffer space running low. Using non scatter-gather I/O.\n"); - this_count = SCpnt->request.current_nr_sectors; - buff = SCpnt->request.buffer; - SCpnt->use_sg = 0; + this_count = SCpnt->request.current_nr_sectors; + buff = SCpnt->request.buffer; + SCpnt->use_sg = 0; - } else { + } else { - /* Scatter-gather capable host adapter */ - struct scatterlist * sgpnt; - int count, this_count_max; - int counted; + /* Scatter-gather capable host adapter */ + struct scatterlist *sgpnt; + int count, this_count_max; + int counted; - bh = SCpnt->request.bh; - this_count = 0; - this_count_max = (rscsi_disks[dev].ten ? 0xffff : 0xff); - count = 0; - bhp = NULL; - while(bh) { - if ((this_count + (bh->b_size >> 9)) > this_count_max) break; - if(!bhp || !CONTIGUOUS_BUFFERS(bhp,bh) || - !CLUSTERABLE_DEVICE(SCpnt) || - (SCpnt->host->unchecked_isa_dma && - virt_to_phys(bh->b_data-1) == ISA_DMA_THRESHOLD)) { - if (count < SCpnt->host->sg_tablesize) count++; - else break; - } - this_count += (bh->b_size >> 9); - bhp = bh; - bh = bh->b_reqnext; - } + bh = SCpnt->request.bh; + this_count = 0; + this_count_max = (rscsi_disks[dev].ten ? 0xffff : 0xff); + count = 0; + bhp = NULL; + while (bh) { + if ((this_count + (bh->b_size >> 9)) > this_count_max) + break; + if (!bhp || !CONTIGUOUS_BUFFERS(bhp, bh) || + !CLUSTERABLE_DEVICE(SCpnt) || + (SCpnt->host->unchecked_isa_dma && + virt_to_phys(bh->b_data - 1) == ISA_DMA_THRESHOLD)) { + if (count < SCpnt->host->sg_tablesize) + count++; + else + break; + } + this_count += (bh->b_size >> 9); + bhp = bh; + bh = bh->b_reqnext; + } #if 0 - if(SCpnt->host->unchecked_isa_dma && - virt_to_phys(SCpnt->request.bh->b_data-1) == ISA_DMA_THRESHOLD) count--; + if (SCpnt->host->unchecked_isa_dma && + virt_to_phys(SCpnt->request.bh->b_data - 1) == ISA_DMA_THRESHOLD) + count--; #endif - SCpnt->use_sg = count; /* Number of chains */ - /* scsi_malloc can only allocate in chunks of 512 bytes */ - count = (SCpnt->use_sg * sizeof(struct scatterlist) + 511) & ~511; - - SCpnt->sglist_len = count; - max_sg = count / sizeof(struct scatterlist); - if(SCpnt->host->sg_tablesize < max_sg) - max_sg = SCpnt->host->sg_tablesize; - sgpnt = (struct scatterlist * ) scsi_malloc(count); - if (!sgpnt) { - printk("Warning - running *really* short on DMA buffers\n"); - SCpnt->use_sg = 0; /* No memory left - bail out */ - this_count = SCpnt->request.current_nr_sectors; - buff = SCpnt->request.buffer; - } else { - memset(sgpnt, 0, count); /* Zero so it is easy to fill, but only - * if memory is available - */ - buff = (char *) sgpnt; - counted = 0; - for(count = 0, bh = SCpnt->request.bh, bhp = bh->b_reqnext; - count < SCpnt->use_sg && bh; - count++, bh = bhp) { - - bhp = bh->b_reqnext; - - if(!sgpnt[count].address) sgpnt[count].address = bh->b_data; - sgpnt[count].length += bh->b_size; - counted += bh->b_size >> 9; - - if (virt_to_phys(sgpnt[count].address) + sgpnt[count].length - 1 > - ISA_DMA_THRESHOLD && (SCpnt->host->unchecked_isa_dma) && - !sgpnt[count].alt_address) { - sgpnt[count].alt_address = sgpnt[count].address; - /* We try to avoid exhausting the DMA pool, since it is - * easier to control usage here. In other places we might - * have a more pressing need, and we would be screwed if - * we ran out */ - if(scsi_dma_free_sectors < (sgpnt[count].length >> 9) + 10) { - sgpnt[count].address = NULL; - } else { - sgpnt[count].address = - (char *) scsi_malloc(sgpnt[count].length); - } - /* If we start running low on DMA buffers, we abort the - * scatter-gather operation, and free all of the memory - * we have allocated. We want to ensure that all scsi - * operations are able to do at least a non-scatter/gather - * operation */ - if(sgpnt[count].address == NULL){ /* Out of dma memory */ -#if 0 - printk("Warning: Running low on SCSI DMA buffers"); - /* Try switching back to a non s-g operation. */ - while(--count >= 0){ - if(sgpnt[count].alt_address) - scsi_free(sgpnt[count].address, - sgpnt[count].length); - } + SCpnt->use_sg = count; /* Number of chains */ + /* scsi_malloc can only allocate in chunks of 512 bytes */ + count = (SCpnt->use_sg * sizeof(struct scatterlist) + 511) & ~511; + + SCpnt->sglist_len = count; + max_sg = count / sizeof(struct scatterlist); + if (SCpnt->host->sg_tablesize < max_sg) + max_sg = SCpnt->host->sg_tablesize; + sgpnt = (struct scatterlist *) scsi_malloc(count); + if (!sgpnt) { + printk("Warning - running *really* short on DMA buffers\n"); + SCpnt->use_sg = 0; /* No memory left - bail out */ this_count = SCpnt->request.current_nr_sectors; buff = SCpnt->request.buffer; - SCpnt->use_sg = 0; - scsi_free(sgpnt, SCpnt->sglist_len); + } else { + memset(sgpnt, 0, count); /* Zero so it is easy to fill, but only + * if memory is available + */ + buff = (char *) sgpnt; + counted = 0; + for (count = 0, bh = SCpnt->request.bh, bhp = bh->b_reqnext; + count < SCpnt->use_sg && bh; + count++, bh = bhp) { + + bhp = bh->b_reqnext; + + if (!sgpnt[count].address) + sgpnt[count].address = bh->b_data; + sgpnt[count].length += bh->b_size; + counted += bh->b_size >> 9; + + if (virt_to_phys(sgpnt[count].address) + sgpnt[count].length - 1 > + ISA_DMA_THRESHOLD && (SCpnt->host->unchecked_isa_dma) && + !sgpnt[count].alt_address) { + sgpnt[count].alt_address = sgpnt[count].address; + /* We try to avoid exhausting the DMA pool, since it is + * easier to control usage here. In other places we might + * have a more pressing need, and we would be screwed if + * we ran out */ + if (scsi_dma_free_sectors < (sgpnt[count].length >> 9) + 10) { + sgpnt[count].address = NULL; + } else { + sgpnt[count].address = + (char *) scsi_malloc(sgpnt[count].length); + } + /* If we start running low on DMA buffers, we abort the + * scatter-gather operation, and free all of the memory + * we have allocated. We want to ensure that all scsi + * operations are able to do at least a non-scatter/gather + * operation */ + if (sgpnt[count].address == NULL) { /* Out of dma memory */ +#if 0 + printk("Warning: Running low on SCSI DMA buffers"); + /* Try switching back to a non s-g operation. */ + while (--count >= 0) { + if (sgpnt[count].alt_address) + scsi_free(sgpnt[count].address, + sgpnt[count].length); + } + this_count = SCpnt->request.current_nr_sectors; + buff = SCpnt->request.buffer; + SCpnt->use_sg = 0; + scsi_free(sgpnt, SCpnt->sglist_len); #endif - SCpnt->use_sg = count; - this_count = counted -= bh->b_size >> 9; - break; - } + SCpnt->use_sg = count; + this_count = counted -= bh->b_size >> 9; + break; + } + } + /* Only cluster buffers if we know that we can supply DMA + * buffers large enough to satisfy the request. Do not cluster + * a new request if this would mean that we suddenly need to + * start using DMA bounce buffers */ + if (bhp && CONTIGUOUS_BUFFERS(bh, bhp) + && CLUSTERABLE_DEVICE(SCpnt)) { + char *tmp; + + if (virt_to_phys(sgpnt[count].address) + sgpnt[count].length + + bhp->b_size - 1 > ISA_DMA_THRESHOLD && + (SCpnt->host->unchecked_isa_dma) && + !sgpnt[count].alt_address) + continue; + + if (!sgpnt[count].alt_address) { + count--; + continue; + } + if (scsi_dma_free_sectors > 10) + tmp = (char *) scsi_malloc(sgpnt[count].length + + bhp->b_size); + else { + tmp = NULL; + max_sg = SCpnt->use_sg; + } + if (tmp) { + scsi_free(sgpnt[count].address, sgpnt[count].length); + sgpnt[count].address = tmp; + count--; + continue; + } + /* If we are allowed another sg chain, then increment + * counter so we can insert it. Otherwise we will end + up truncating */ + + if (SCpnt->use_sg < max_sg) + SCpnt->use_sg++; + } /* contiguous buffers */ + } /* for loop */ + + /* This is actually how many we are going to transfer */ + this_count = counted; + + if (count < SCpnt->use_sg || SCpnt->use_sg + > SCpnt->host->sg_tablesize) { + bh = SCpnt->request.bh; + printk("Use sg, count %d %x %d\n", + SCpnt->use_sg, count, scsi_dma_free_sectors); + printk("maxsg = %x, counted = %d this_count = %d\n", + max_sg, counted, this_count); + while (bh) { + printk("[%p %x] ", bh->b_data, bh->b_size); + bh = bh->b_reqnext; + } + if (SCpnt->use_sg < 16) + for (count = 0; count < SCpnt->use_sg; count++) + printk("{%d:%p %p %d} ", count, + sgpnt[count].address, + sgpnt[count].alt_address, + sgpnt[count].length); + panic("Ooops"); + } + if (SCpnt->request.cmd == WRITE) + for (count = 0; count < SCpnt->use_sg; count++) + if (sgpnt[count].alt_address) + memcpy(sgpnt[count].address, sgpnt[count].alt_address, + sgpnt[count].length); + } /* Able to malloc sgpnt */ + } /* Host adapter capable of scatter-gather */ + + /* Now handle the possibility of DMA to addresses > 16Mb */ + + if (SCpnt->use_sg == 0) { + if (virt_to_phys(buff) + (this_count << 9) - 1 > ISA_DMA_THRESHOLD && + (SCpnt->host->unchecked_isa_dma)) { + if (bounce_buffer) + buff = bounce_buffer; + else + buff = (char *) scsi_malloc(this_count << 9); + if (buff == NULL) { /* Try backing off a bit if we are low on mem */ + this_count = SCpnt->request.current_nr_sectors; + buff = (char *) scsi_malloc(this_count << 9); + if (!buff) + panic("Ran out of DMA buffers."); + } + if (SCpnt->request.cmd == WRITE) + memcpy(buff, (char *) SCpnt->request.buffer, this_count << 9); } + } + SCSI_LOG_HLQUEUE(2, printk("%s : %s %d/%ld 512 byte blocks.\n", + nbuff, + (SCpnt->request.cmd == WRITE) ? "writing" : "reading", + this_count, SCpnt->request.nr_sectors)); + + cmd[1] = (SCpnt->lun << 5) & 0xe0; + + if (rscsi_disks[dev].sector_size == 4096) { + if (block & 7) + panic("sd.c:Bad block number requested"); + if (this_count & 7) + panic("sd.c:Bad block number requested"); + block = block >> 3; + this_count = block >> 3; + } + if (rscsi_disks[dev].sector_size == 2048) { + if (block & 3) + panic("sd.c:Bad block number requested"); + if (this_count & 3) + panic("sd.c:Bad block number requested"); + block = block >> 2; + this_count = this_count >> 2; + } + if (rscsi_disks[dev].sector_size == 1024) { + if (block & 1) + panic("sd.c:Bad block number requested"); + if (this_count & 1) + panic("sd.c:Bad block number requested"); + block = block >> 1; + this_count = this_count >> 1; + } + if (rscsi_disks[dev].sector_size == 256) { + block = block << 1; + this_count = this_count << 1; + } + if (((this_count > 0xff) || (block > 0x1fffff)) && rscsi_disks[dev].ten) { + if (this_count > 0xffff) + this_count = 0xffff; + + cmd[0] += READ_10 - READ_6; + cmd[2] = (unsigned char) (block >> 24) & 0xff; + cmd[3] = (unsigned char) (block >> 16) & 0xff; + cmd[4] = (unsigned char) (block >> 8) & 0xff; + cmd[5] = (unsigned char) block & 0xff; + cmd[6] = cmd[9] = 0; + cmd[7] = (unsigned char) (this_count >> 8) & 0xff; + cmd[8] = (unsigned char) this_count & 0xff; + } else { + if (this_count > 0xff) + this_count = 0xff; + + cmd[1] |= (unsigned char) ((block >> 16) & 0x1f); + cmd[2] = (unsigned char) ((block >> 8) & 0xff); + cmd[3] = (unsigned char) block & 0xff; + cmd[4] = (unsigned char) this_count; + cmd[5] = 0; + } - /* Only cluster buffers if we know that we can supply DMA - * buffers large enough to satisfy the request. Do not cluster - * a new request if this would mean that we suddenly need to - * start using DMA bounce buffers */ - if(bhp && CONTIGUOUS_BUFFERS(bh,bhp) - && CLUSTERABLE_DEVICE(SCpnt)) { - char * tmp; - - if (virt_to_phys(sgpnt[count].address) + sgpnt[count].length + - bhp->b_size - 1 > ISA_DMA_THRESHOLD && - (SCpnt->host->unchecked_isa_dma) && - !sgpnt[count].alt_address) continue; - - if(!sgpnt[count].alt_address) {count--; continue; } - if(scsi_dma_free_sectors > 10) - tmp = (char *) scsi_malloc(sgpnt[count].length - + bhp->b_size); - else { - tmp = NULL; - max_sg = SCpnt->use_sg; - } - if(tmp){ - scsi_free(sgpnt[count].address, sgpnt[count].length); - sgpnt[count].address = tmp; - count--; - continue; - } + /* + * We shouldn't disconnect in the middle of a sector, so with a dumb + * host adapter, it's safe to assume that we can at least transfer + * this many bytes between each connect / disconnect. + */ - /* If we are allowed another sg chain, then increment - * counter so we can insert it. Otherwise we will end - up truncating */ + SCpnt->transfersize = rscsi_disks[dev].sector_size; + SCpnt->underflow = this_count << 9; + SCpnt->cmd_len = 0; + scsi_do_cmd(SCpnt, (void *) cmd, buff, + this_count * rscsi_disks[dev].sector_size, + rw_intr, + (SCpnt->device->type == TYPE_DISK ? + SD_TIMEOUT : SD_MOD_TIMEOUT), + MAX_RETRIES); +} - if (SCpnt->use_sg < max_sg) SCpnt->use_sg++; - } /* contiguous buffers */ - } /* for loop */ +static int check_scsidisk_media_change(kdev_t full_dev) +{ + int retval; + int target; + struct inode inode; + int flag = 0; - /* This is actually how many we are going to transfer */ - this_count = counted; + target = DEVICE_NR(full_dev); - if(count < SCpnt->use_sg || SCpnt->use_sg - > SCpnt->host->sg_tablesize){ - bh = SCpnt->request.bh; - printk("Use sg, count %d %x %d\n", - SCpnt->use_sg, count, scsi_dma_free_sectors); - printk("maxsg = %x, counted = %d this_count = %d\n", - max_sg, counted, this_count); - while(bh){ - printk("[%p %x] ", bh->b_data, bh->b_size); - bh = bh->b_reqnext; - } - if(SCpnt->use_sg < 16) - for(count=0; count<SCpnt->use_sg; count++) - printk("{%d:%p %p %d} ", count, - sgpnt[count].address, - sgpnt[count].alt_address, - sgpnt[count].length); - panic("Ooops"); - } - - if (SCpnt->request.cmd == WRITE) - for(count=0; count<SCpnt->use_sg; count++) - if(sgpnt[count].alt_address) - memcpy(sgpnt[count].address, sgpnt[count].alt_address, - sgpnt[count].length); - } /* Able to malloc sgpnt */ - } /* Host adapter capable of scatter-gather */ - - /* Now handle the possibility of DMA to addresses > 16Mb */ - - if(SCpnt->use_sg == 0){ - if (virt_to_phys(buff) + (this_count << 9) - 1 > ISA_DMA_THRESHOLD && - (SCpnt->host->unchecked_isa_dma)) { - if(bounce_buffer) - buff = bounce_buffer; - else - buff = (char *) scsi_malloc(this_count << 9); - if(buff == NULL) { /* Try backing off a bit if we are low on mem*/ - this_count = SCpnt->request.current_nr_sectors; - buff = (char *) scsi_malloc(this_count << 9); - if(!buff) panic("Ran out of DMA buffers."); - } - if (SCpnt->request.cmd == WRITE) - memcpy(buff, (char *)SCpnt->request.buffer, this_count << 9); + if (target >= sd_template.dev_max || + !rscsi_disks[target].device) { + printk("SCSI disk request error: invalid device.\n"); + return 0; } - } - SCSI_LOG_HLQUEUE(2,printk("%s : %s %d/%ld 512 byte blocks.\n", - nbuff, - (SCpnt->request.cmd == WRITE) ? "writing" : "reading", - this_count, SCpnt->request.nr_sectors)); - - cmd[1] = (SCpnt->lun << 5) & 0xe0; - - if (rscsi_disks[dev].sector_size == 4096){ - if(block & 7) panic("sd.c:Bad block number requested"); - if(this_count & 7) panic("sd.c:Bad block number requested"); - block = block >> 3; - this_count = block >> 3; - } - - if (rscsi_disks[dev].sector_size == 2048){ - if(block & 3) panic("sd.c:Bad block number requested"); - if(this_count & 3) panic("sd.c:Bad block number requested"); - block = block >> 2; - this_count = this_count >> 2; - } - - if (rscsi_disks[dev].sector_size == 1024){ - if(block & 1) panic("sd.c:Bad block number requested"); - if(this_count & 1) panic("sd.c:Bad block number requested"); - block = block >> 1; - this_count = this_count >> 1; - } - - if (rscsi_disks[dev].sector_size == 256){ - block = block << 1; - this_count = this_count << 1; - } - - if (((this_count > 0xff) || (block > 0x1fffff)) && rscsi_disks[dev].ten) - { - if (this_count > 0xffff) - this_count = 0xffff; - - cmd[0] += READ_10 - READ_6 ; - cmd[2] = (unsigned char) (block >> 24) & 0xff; - cmd[3] = (unsigned char) (block >> 16) & 0xff; - cmd[4] = (unsigned char) (block >> 8) & 0xff; - cmd[5] = (unsigned char) block & 0xff; - cmd[6] = cmd[9] = 0; - cmd[7] = (unsigned char) (this_count >> 8) & 0xff; - cmd[8] = (unsigned char) this_count & 0xff; - } - else - { - if (this_count > 0xff) - this_count = 0xff; - - cmd[1] |= (unsigned char) ((block >> 16) & 0x1f); - cmd[2] = (unsigned char) ((block >> 8) & 0xff); - cmd[3] = (unsigned char) block & 0xff; - cmd[4] = (unsigned char) this_count; - cmd[5] = 0; - } - - /* - * We shouldn't disconnect in the middle of a sector, so with a dumb - * host adapter, it's safe to assume that we can at least transfer - * this many bytes between each connect / disconnect. - */ - - SCpnt->transfersize = rscsi_disks[dev].sector_size; - SCpnt->underflow = this_count << 9; - SCpnt->cmd_len = 0; - scsi_do_cmd (SCpnt, (void *) cmd, buff, - this_count * rscsi_disks[dev].sector_size, - rw_intr, - (SCpnt->device->type == TYPE_DISK ? - SD_TIMEOUT : SD_MOD_TIMEOUT), - MAX_RETRIES); -} + if (!rscsi_disks[target].device->removable) + return 0; -static int check_scsidisk_media_change(kdev_t full_dev){ - int retval; - int target; - struct inode inode; - int flag = 0; + /* + * If the device is offline, don't send any commands - just pretend as if + * the command failed. If the device ever comes back online, we can deal with + * it then. It is only because of unrecoverable errors that we would ever + * take a device offline in the first place. + */ + if (rscsi_disks[target].device->online == FALSE) { + rscsi_disks[target].ready = 0; + rscsi_disks[target].device->changed = 1; + return 1; /* This will force a flush, if called from + * check_disk_change */ + } + inode.i_rdev = full_dev; /* This is all we really need here */ - target = DEVICE_NR(full_dev); + /* Using Start/Stop enables differentiation between drive with + * no cartridge loaded - NOT READY, drive with changed cartridge - + * UNIT ATTENTION, or with same cartridge - GOOD STATUS. + * This also handles drives that auto spin down. eg iomega jaz 1GB + * as this will spin up the drive. + */ + retval = sd_ioctl(&inode, NULL, SCSI_IOCTL_START_UNIT, 0); - if (target >= sd_template.dev_max || - !rscsi_disks[target].device) { - printk("SCSI disk request error: invalid device.\n"); - return 0; - } - - if(!rscsi_disks[target].device->removable) return 0; - - /* - * If the device is offline, don't send any commands - just pretend as if - * the command failed. If the device ever comes back online, we can deal with - * it then. It is only because of unrecoverable errors that we would ever - * take a device offline in the first place. - */ - if( rscsi_disks[target].device->online == FALSE ) - { - rscsi_disks[target].ready = 0; - rscsi_disks[target].device->changed = 1; - return 1; /* This will force a flush, if called from - * check_disk_change */ - } - - inode.i_rdev = full_dev; /* This is all we really need here */ - - /* Using Start/Stop enables differentiation between drive with - * no cartridge loaded - NOT READY, drive with changed cartridge - - * UNIT ATTENTION, or with same cartridge - GOOD STATUS. - * This also handles drives that auto spin down. eg iomega jaz 1GB - * as this will spin up the drive. - */ - retval = sd_ioctl(&inode, NULL, SCSI_IOCTL_START_UNIT, 0); - - if(retval){ /* Unable to test, unit probably not ready. This usually - * means there is no disc in the drive. Mark as changed, - * and we will figure it out later once the drive is - * available again. */ - - rscsi_disks[target].ready = 0; - rscsi_disks[target].device->changed = 1; - return 1; /* This will force a flush, if called from - * check_disk_change */ - } - - /* - * for removable scsi disk ( FLOPTICAL ) we have to recognise the - * presence of disk in the drive. This is kept in the Scsi_Disk - * struct and tested at open ! Daniel Roche ( dan@lectra.fr ) - */ - - rscsi_disks[target].ready = 1; /* FLOPTICAL */ - - retval = rscsi_disks[target].device->changed; - if(!flag) rscsi_disks[target].device->changed = 0; - return retval; + if (retval) { /* Unable to test, unit probably not ready. This usually + * means there is no disc in the drive. Mark as changed, + * and we will figure it out later once the drive is + * available again. */ + + rscsi_disks[target].ready = 0; + rscsi_disks[target].device->changed = 1; + return 1; /* This will force a flush, if called from + * check_disk_change */ + } + /* + * for removable scsi disk ( FLOPTICAL ) we have to recognise the + * presence of disk in the drive. This is kept in the Scsi_Disk + * struct and tested at open ! Daniel Roche ( dan@lectra.fr ) + */ + + rscsi_disks[target].ready = 1; /* FLOPTICAL */ + + retval = rscsi_disks[target].device->changed; + if (!flag) + rscsi_disks[target].device->changed = 0; + return retval; +} + +static void sd_wait_cmd (Scsi_Cmnd * SCpnt, const void *cmnd , + void *buffer, unsigned bufflen, void (*done)(Scsi_Cmnd *), + int timeout, int retries) +{ + DECLARE_MUTEX_LOCKED(sem); + + SCpnt->request.sem = &sem; + SCpnt->request.rq_status = RQ_SCSI_BUSY; + scsi_do_cmd (SCpnt, (void *) cmnd, + buffer, bufflen, done, timeout, retries); + spin_unlock_irq(&io_request_lock); + down (&sem); + spin_lock_irq(&io_request_lock); + SCpnt->request.sem = NULL; } -static void sd_init_done (Scsi_Cmnd * SCpnt) +static void sd_init_done(Scsi_Cmnd * SCpnt) { - struct request * req; + struct request *req; - req = &SCpnt->request; - req->rq_status = RQ_SCSI_DONE; /* Busy, but indicate request done */ + req = &SCpnt->request; + req->rq_status = RQ_SCSI_DONE; /* Busy, but indicate request done */ - if (req->sem != NULL) { - up(req->sem); - } + if (req->sem != NULL) { + up(req->sem); + } } - static int sd_init_onedisk(int i) { - unsigned char cmd[10]; - char nbuff[6]; - unsigned char *buffer; - unsigned long spintime; - int the_result, retries; - Scsi_Cmnd * SCpnt; - - /* - * Get the name of the disk, in case we need to log it somewhere. - */ - sd_devname(i, nbuff); - - /* - * If the device is offline, don't try and read capacity or any of the other - * nicities. - */ - if( rscsi_disks[i].device->online == FALSE ) - { - return i; - } - - spin_lock_irq(&io_request_lock); - - /* We need to retry the READ_CAPACITY because a UNIT_ATTENTION is - * considered a fatal error, and many devices report such an error - * just after a scsi bus reset. - */ - - SCpnt = scsi_allocate_device(NULL, rscsi_disks[i].device, 1); - buffer = (unsigned char *) scsi_malloc(512); - - spintime = 0; - - /* Spin up drives, as required. Only do this at boot time */ - /* Spinup needs to be done for module loads too. */ - do{ - retries = 0; - while(retries < 3) - { - cmd[0] = TEST_UNIT_READY; - cmd[1] = (rscsi_disks[i].device->lun << 5) & 0xe0; - memset ((void *) &cmd[2], 0, 8); - SCpnt->cmd_len = 0; - SCpnt->sense_buffer[0] = 0; - SCpnt->sense_buffer[2] = 0; + unsigned char cmd[10]; + char nbuff[6]; + unsigned char *buffer; + unsigned long spintime_value = 0; + int the_result, retries, spintime; + Scsi_Cmnd *SCpnt; - { - DECLARE_MUTEX_LOCKED(sem); - /* Mark as really busy again */ - SCpnt->request.rq_status = RQ_SCSI_BUSY; - SCpnt->request.sem = &sem; - scsi_do_cmd (SCpnt, - (void *) cmd, (void *) buffer, - 512, sd_init_done, SD_TIMEOUT, - MAX_RETRIES); - spin_unlock_irq(&io_request_lock); - down(&sem); - spin_lock_irq(&io_request_lock); - SCpnt->request.sem = NULL; + /* + * Get the name of the disk, in case we need to log it somewhere. + */ + sd_devname(i, nbuff); + + /* + * If the device is offline, don't try and read capacity or any of the other + * nicities. + */ + if (rscsi_disks[i].device->online == FALSE) { + return i; + } + spin_lock_irq(&io_request_lock); + + /* We need to retry the READ_CAPACITY because a UNIT_ATTENTION is + * considered a fatal error, and many devices report such an error + * just after a scsi bus reset. + */ + + SCpnt = scsi_allocate_device(NULL, rscsi_disks[i].device, 1); + buffer = (unsigned char *) scsi_malloc(512); + + spintime = 0; + + /* Spin up drives, as required. Only do this at boot time */ + /* Spinup needs to be done for module loads too. */ + do { + retries = 0; + + while (retries < 3) { + cmd[0] = TEST_UNIT_READY; + cmd[1] = (rscsi_disks[i].device->lun << 5) & 0xe0; + memset((void *) &cmd[2], 0, 8); + SCpnt->cmd_len = 0; + SCpnt->sense_buffer[0] = 0; + SCpnt->sense_buffer[2] = 0; + + sd_wait_cmd (SCpnt, (void *) cmd, (void *) buffer, + 512, sd_init_done, SD_TIMEOUT, MAX_RETRIES); + + the_result = SCpnt->result; + retries++; + if (the_result == 0 + || SCpnt->sense_buffer[2] != UNIT_ATTENTION) + break; } - the_result = SCpnt->result; - retries++; - if( the_result == 0 - || SCpnt->sense_buffer[2] != UNIT_ATTENTION) - break; - } - - /* Look for non-removable devices that return NOT_READY. - * Issue command to spin up drive for these cases. */ - if(the_result && !rscsi_disks[i].device->removable && - SCpnt->sense_buffer[2] == NOT_READY) { - unsigned long time1; - if(!spintime){ - printk( "%s: Spinning up disk...", nbuff ); - cmd[0] = START_STOP; - cmd[1] = (rscsi_disks[i].device->lun << 5) & 0xe0; - cmd[1] |= 1; /* Return immediately */ - memset ((void *) &cmd[2], 0, 8); - cmd[4] = 1; /* Start spin cycle */ - SCpnt->cmd_len = 0; - SCpnt->sense_buffer[0] = 0; - SCpnt->sense_buffer[2] = 0; - - { - DECLARE_MUTEX_LOCKED(sem); - /* Mark as really busy again */ - SCpnt->request.rq_status = RQ_SCSI_BUSY; - SCpnt->request.sem = &sem; - scsi_do_cmd (SCpnt, - (void *) cmd, (void *) buffer, - 512, sd_init_done, SD_TIMEOUT, - MAX_RETRIES); + /* Look for non-removable devices that return NOT_READY. + * Issue command to spin up drive for these cases. */ + if (the_result && !rscsi_disks[i].device->removable && + SCpnt->sense_buffer[2] == NOT_READY) + { + unsigned long time1; + if (!spintime) + { + printk("%s: Spinning up disk...", nbuff); + cmd[0] = START_STOP; + cmd[1] = (rscsi_disks[i].device->lun << 5) & 0xe0; + cmd[1] |= 1; /* Return immediately */ + memset((void *) &cmd[2], 0, 8); + cmd[4] = 1; /* Start spin cycle */ + SCpnt->cmd_len = 0; + SCpnt->sense_buffer[0] = 0; + SCpnt->sense_buffer[2] = 0; + + sd_wait_cmd(SCpnt, (void *) cmd, (void *) buffer, + 512, sd_init_done, SD_TIMEOUT, MAX_RETRIES); + } + + spintime = 1; + spintime_value = jiffies; + time1 = jiffies + HZ; spin_unlock_irq(&io_request_lock); - down(&sem); + while(time_before(jiffies, time1)); /* Wait 1 second for next try */ + printk("."); spin_lock_irq(&io_request_lock); - SCpnt->request.sem = NULL; - } - - spintime = jiffies; } + } while(the_result && spintime && time_after(spintime_value+100*HZ, jiffies)); - time1 = jiffies + HZ; - spin_unlock_irq(&io_request_lock); - while(jiffies < time1); /* Wait 1 second for next try */ - printk( "." ); - spin_lock_irq(&io_request_lock); - } - } while(the_result && spintime && spintime+100*HZ > jiffies); if (spintime) { - if (the_result) - printk( "not responding...\n" ); - else - printk( "ready\n" ); + if (the_result) + printk("not responding...\n"); + else + printk("ready\n"); } + retries = 3; + do { + cmd[0] = READ_CAPACITY; + cmd[1] = (rscsi_disks[i].device->lun << 5) & 0xe0; + memset((void *) &cmd[2], 0, 8); + memset((void *) buffer, 0, 8); + SCpnt->cmd_len = 0; + SCpnt->sense_buffer[0] = 0; + SCpnt->sense_buffer[2] = 0; - retries = 3; - do { - cmd[0] = READ_CAPACITY; - cmd[1] = (rscsi_disks[i].device->lun << 5) & 0xe0; - memset ((void *) &cmd[2], 0, 8); - memset ((void *) buffer, 0, 8); - SCpnt->cmd_len = 0; - SCpnt->sense_buffer[0] = 0; - SCpnt->sense_buffer[2] = 0; - - { - DECLARE_MUTEX_LOCKED(sem); - /* Mark as really busy again */ - SCpnt->request.rq_status = RQ_SCSI_BUSY; - SCpnt->request.sem = &sem; - scsi_do_cmd (SCpnt, - (void *) cmd, (void *) buffer, - 8, sd_init_done, SD_TIMEOUT, - MAX_RETRIES); - spin_unlock_irq(&io_request_lock); - down(&sem); /* sleep until it is ready */ - spin_lock_irq(&io_request_lock); - SCpnt->request.sem = NULL; - } + sd_wait_cmd(SCpnt, (void *) cmd, (void *) buffer, + 8, sd_init_done, SD_TIMEOUT, MAX_RETRIES); + + the_result = SCpnt->result; + retries--; + + } while (the_result && retries); - the_result = SCpnt->result; - retries--; - - } while(the_result && retries); - - /* - * The SCSI standard says: - * "READ CAPACITY is necessary for self configuring software" - * While not mandatory, support of READ CAPACITY is strongly encouraged. - * We used to die if we couldn't successfully do a READ CAPACITY. - * But, now we go on about our way. The side effects of this are - * - * 1. We can't know block size with certainty. I have said "512 bytes - * is it" as this is most common. - * - * 2. Recovery from when some one attempts to read past the end of the - * raw device will be slower. - */ - - if (the_result) - { - printk ("%s : READ CAPACITY failed.\n" - "%s : status = %x, message = %02x, host = %d, driver = %02x \n", - nbuff, nbuff, - status_byte(the_result), - msg_byte(the_result), - host_byte(the_result), - driver_byte(the_result) - ); - if (driver_byte(the_result) & DRIVER_SENSE) - printk("%s : extended sense code = %1x \n", - nbuff, SCpnt->sense_buffer[2] & 0xf); - else - printk("%s : sense not available. \n", nbuff); - - printk("%s : block size assumed to be 512 bytes, disk size 1GB. \n", - nbuff); - rscsi_disks[i].capacity = 0x1fffff; - rscsi_disks[i].sector_size = 512; - - /* Set dirty bit for removable devices if not ready - sometimes drives - * will not report this properly. */ - if(rscsi_disks[i].device->removable && - SCpnt->sense_buffer[2] == NOT_READY) - rscsi_disks[i].device->changed = 1; - - } - else - { /* - * FLOPTICAL , if read_capa is ok , drive is assumed to be ready + * The SCSI standard says: + * "READ CAPACITY is necessary for self configuring software" + * While not mandatory, support of READ CAPACITY is strongly encouraged. + * We used to die if we couldn't successfully do a READ CAPACITY. + * But, now we go on about our way. The side effects of this are + * + * 1. We can't know block size with certainty. I have said "512 bytes + * is it" as this is most common. + * + * 2. Recovery from when some one attempts to read past the end of the + * raw device will be slower. */ - rscsi_disks[i].ready = 1; - rscsi_disks[i].capacity = 1 + ((buffer[0] << 24) | - (buffer[1] << 16) | - (buffer[2] << 8) | - buffer[3]); + if (the_result) { + printk("%s : READ CAPACITY failed.\n" + "%s : status = %x, message = %02x, host = %d, driver = %02x \n", + nbuff, nbuff, + status_byte(the_result), + msg_byte(the_result), + host_byte(the_result), + driver_byte(the_result) + ); + if (driver_byte(the_result) & DRIVER_SENSE) + printk("%s : extended sense code = %1x \n", + nbuff, SCpnt->sense_buffer[2] & 0xf); + else + printk("%s : sense not available. \n", nbuff); - rscsi_disks[i].sector_size = (buffer[4] << 24) | - (buffer[5] << 16) | (buffer[6] << 8) | buffer[7]; + printk("%s : block size assumed to be 512 bytes, disk size 1GB. \n", + nbuff); + rscsi_disks[i].capacity = 0x1fffff; + rscsi_disks[i].sector_size = 512; - if (rscsi_disks[i].sector_size == 0) { - rscsi_disks[i].sector_size = 512; - printk("%s : sector size 0 reported, assuming 512.\n", nbuff); - } + /* Set dirty bit for removable devices if not ready - sometimes drives + * will not report this properly. */ + if (rscsi_disks[i].device->removable && + SCpnt->sense_buffer[2] == NOT_READY) + rscsi_disks[i].device->changed = 1; + } else { + /* + * FLOPTICAL , if read_capa is ok , drive is assumed to be ready + */ + rscsi_disks[i].ready = 1; - if (rscsi_disks[i].sector_size != 512 && - rscsi_disks[i].sector_size != 1024 && - rscsi_disks[i].sector_size != 2048 && - rscsi_disks[i].sector_size != 4096 && - rscsi_disks[i].sector_size != 256) - { - printk ("%s : unsupported sector size %d.\n", - nbuff, rscsi_disks[i].sector_size); - if(rscsi_disks[i].device->removable){ - rscsi_disks[i].capacity = 0; - } else { - printk ("scsi : deleting disk entry.\n"); - rscsi_disks[i].device = NULL; - sd_template.nr_dev--; - SD_GENDISK(i).nr_real--; - - /* Wake up a process waiting for device */ - wake_up(&SCpnt->device->device_wait); - scsi_release_command(SCpnt); - SCpnt = NULL; - - return i; - } - } + rscsi_disks[i].capacity = 1 + ((buffer[0] << 24) | + (buffer[1] << 16) | + (buffer[2] << 8) | + buffer[3]); - if( rscsi_disks[i].sector_size == 2048 ) - { - int m; - - /* - * We must fix the sd_blocksizes and sd_hardsizes - * to allow us to read the partition tables. - * The disk reading code does not allow for reading - * of partial sectors. - */ - for (m=i<<4; m<((i+1)<<4); m++) - { - sd_blocksizes[m] = 2048; - } - } - { - /* - * The msdos fs needs to know the hardware sector size - * So I have created this table. See ll_rw_blk.c - * Jacques Gelinas (Jacques@solucorp.qc.ca) - */ - int m, mb; - int sz_quot, sz_rem; - int hard_sector = rscsi_disks[i].sector_size; - /* There are 16 minors allocated for each major device */ - for (m=i<<4; m<((i+1)<<4); m++){ - sd_hardsizes[m] = hard_sector; + rscsi_disks[i].sector_size = (buffer[4] << 24) | + (buffer[5] << 16) | (buffer[6] << 8) | buffer[7]; + + if (rscsi_disks[i].sector_size == 0) { + rscsi_disks[i].sector_size = 512; + printk("%s : sector size 0 reported, assuming 512.\n", nbuff); + } + if (rscsi_disks[i].sector_size != 512 && + rscsi_disks[i].sector_size != 1024 && + rscsi_disks[i].sector_size != 2048 && + rscsi_disks[i].sector_size != 4096 && + rscsi_disks[i].sector_size != 256) { + printk("%s : unsupported sector size %d.\n", + nbuff, rscsi_disks[i].sector_size); + if (rscsi_disks[i].device->removable) { + rscsi_disks[i].capacity = 0; + } else { + printk("scsi : deleting disk entry.\n"); + sd_detach(rscsi_disks[i].device); + rscsi_disks[i].device = NULL; + + /* Wake up a process waiting for device */ + wake_up(&SCpnt->device->device_wait); + scsi_release_command(SCpnt); + SCpnt = NULL; + scsi_free(buffer, 512); + spin_unlock_irq(&io_request_lock); + + return i; + } + } + if (rscsi_disks[i].sector_size == 2048) { + int m; + + /* + * We must fix the sd_blocksizes and sd_hardsizes + * to allow us to read the partition tables. + * The disk reading code does not allow for reading + * of partial sectors. + */ + for (m = i << 4; m < ((i + 1) << 4); m++) { + sd_blocksizes[m] = 2048; + } + } { + /* + * The msdos fs needs to know the hardware sector size + * So I have created this table. See ll_rw_blk.c + * Jacques Gelinas (Jacques@solucorp.qc.ca) + */ + int m, mb; + int sz_quot, sz_rem; + int hard_sector = rscsi_disks[i].sector_size; + /* There are 16 minors allocated for each major device */ + for (m = i << 4; m < ((i + 1) << 4); m++) { + sd_hardsizes[m] = hard_sector; + } + mb = rscsi_disks[i].capacity / 1024 * hard_sector / 1024; + /* sz = div(m/100, 10); this seems to not be in the libr */ + m = (mb + 50) / 100; + sz_quot = m / 10; + sz_rem = m - (10 * sz_quot); + printk("SCSI device %s: hdwr sector= %d bytes." + " Sectors= %d [%d MB] [%d.%1d GB]\n", + nbuff, hard_sector, rscsi_disks[i].capacity, + mb, sz_quot, sz_rem); + } + if (rscsi_disks[i].sector_size == 4096) + rscsi_disks[i].capacity <<= 3; + if (rscsi_disks[i].sector_size == 2048) + rscsi_disks[i].capacity <<= 2; /* Change into 512 byte sectors */ + if (rscsi_disks[i].sector_size == 1024) + rscsi_disks[i].capacity <<= 1; /* Change into 512 byte sectors */ + if (rscsi_disks[i].sector_size == 256) + rscsi_disks[i].capacity >>= 1; /* Change into 512 byte sectors */ } - mb = rscsi_disks[i].capacity / 1024 * hard_sector / 1024; - /* sz = div(m/100, 10); this seems to not be in the libr */ - m = (mb + 50) / 100; - sz_quot = m / 10; - sz_rem = m - (10 * sz_quot); - printk ("SCSI device %s: hdwr sector= %d bytes." - " Sectors= %d [%d MB] [%d.%1d GB]\n", - nbuff, hard_sector, rscsi_disks[i].capacity, - mb, sz_quot, sz_rem); - } - if(rscsi_disks[i].sector_size == 4096) - rscsi_disks[i].capacity <<= 3; - if(rscsi_disks[i].sector_size == 2048) - rscsi_disks[i].capacity <<= 2; /* Change into 512 byte sectors */ - if(rscsi_disks[i].sector_size == 1024) - rscsi_disks[i].capacity <<= 1; /* Change into 512 byte sectors */ - if(rscsi_disks[i].sector_size == 256) - rscsi_disks[i].capacity >>= 1; /* Change into 512 byte sectors */ - } - - - /* - * Unless otherwise specified, this is not write protected. - */ - rscsi_disks[i].write_prot = 0; - if ( rscsi_disks[i].device->removable && rscsi_disks[i].ready ) { - /* FLOPTICAL */ + /* - * for removable scsi disk ( FLOPTICAL ) we have to recognise - * the Write Protect Flag. This flag is kept in the Scsi_Disk struct - * and tested at open ! - * Daniel Roche ( dan@lectra.fr ) + * Unless otherwise specified, this is not write protected. */ + rscsi_disks[i].write_prot = 0; + if (rscsi_disks[i].device->removable && rscsi_disks[i].ready) { + /* FLOPTICAL */ - memset ((void *) &cmd[0], 0, 8); - cmd[0] = MODE_SENSE; - cmd[1] = (rscsi_disks[i].device->lun << 5) & 0xe0; - cmd[2] = 1; /* page code 1 ?? */ - cmd[4] = 12; - SCpnt->cmd_len = 0; - SCpnt->sense_buffer[0] = 0; - SCpnt->sense_buffer[2] = 0; - - /* same code as READCAPA !! */ - { - DECLARE_MUTEX_LOCKED(sem); - SCpnt->request.rq_status = RQ_SCSI_BUSY; /* Mark as really busy again */ - SCpnt->request.sem = &sem; - scsi_do_cmd (SCpnt, - (void *) cmd, (void *) buffer, - 512, sd_init_done, SD_TIMEOUT, - MAX_RETRIES); - spin_unlock_irq(&io_request_lock); - down(&sem); - spin_lock_irq(&io_request_lock); - SCpnt->request.sem = NULL; - } + /* + * for removable scsi disk ( FLOPTICAL ) we have to recognise + * the Write Protect Flag. This flag is kept in the Scsi_Disk struct + * and tested at open ! + * Daniel Roche ( dan@lectra.fr ) + */ - the_result = SCpnt->result; + memset((void *) &cmd[0], 0, 8); + cmd[0] = MODE_SENSE; + cmd[1] = (rscsi_disks[i].device->lun << 5) & 0xe0; + cmd[2] = 1; /* page code 1 ?? */ + cmd[4] = 12; + SCpnt->cmd_len = 0; + SCpnt->sense_buffer[0] = 0; + SCpnt->sense_buffer[2] = 0; - if ( the_result ) { - printk ("%s: test WP failed, assume Write Protected\n",nbuff); - rscsi_disks[i].write_prot = 1; - } else { - rscsi_disks[i].write_prot = ((buffer[2] & 0x80) != 0); - printk ("%s: Write Protect is %s\n",nbuff, - rscsi_disks[i].write_prot ? "on" : "off"); - } + /* same code as READCAPA !! */ + sd_wait_cmd(SCpnt, (void *) cmd, (void *) buffer, + 512, sd_init_done, SD_TIMEOUT, MAX_RETRIES); - } /* check for write protect */ + the_result = SCpnt->result; - /* Wake up a process waiting for device */ - wake_up(&SCpnt->device->device_wait); - scsi_release_command(SCpnt); - SCpnt = NULL; + if (the_result) { + printk("%s: test WP failed, assume Write Protected\n", nbuff); + rscsi_disks[i].write_prot = 1; + } else { + rscsi_disks[i].write_prot = ((buffer[2] & 0x80) != 0); + printk("%s: Write Protect is %s\n", nbuff, + rscsi_disks[i].write_prot ? "on" : "off"); + } - rscsi_disks[i].ten = 1; - rscsi_disks[i].remap = 1; - scsi_free(buffer, 512); - spin_unlock_irq(&io_request_lock); - return i; + } /* check for write protect */ + /* Wake up a process waiting for device */ + wake_up(&SCpnt->device->device_wait); + scsi_release_command(SCpnt); + SCpnt = NULL; + + rscsi_disks[i].ten = 1; + rscsi_disks[i].remap = 1; + scsi_free(buffer, 512); + spin_unlock_irq(&io_request_lock); + return i; } /* @@ -1492,171 +1424,170 @@ static int sd_registered = 0; static int sd_init() { - int i; + int i; - if (sd_template.dev_noticed == 0) return 0; + if (sd_template.dev_noticed == 0) + return 0; - if (!rscsi_disks) - sd_template.dev_max = sd_template.dev_noticed + SD_EXTRA_DEVS; + if (!rscsi_disks) + sd_template.dev_max = sd_template.dev_noticed + SD_EXTRA_DEVS; - if(sd_template.dev_max > N_SD_MAJORS * SCSI_DISKS_PER_MAJOR ) - sd_template.dev_max = N_SD_MAJORS * SCSI_DISKS_PER_MAJOR; + if (sd_template.dev_max > N_SD_MAJORS * SCSI_DISKS_PER_MAJOR) + sd_template.dev_max = N_SD_MAJORS * SCSI_DISKS_PER_MAJOR; - if(!sd_registered) { - for (i=0; i <= (sd_template.dev_max - 1) / SCSI_DISKS_PER_MAJOR; i++) { - if (register_blkdev(SD_MAJOR(i),"sd",&sd_fops)) { - printk("Unable to get major %d for SCSI disk\n", SD_MAJOR(i)); - return 1; - } + if (!sd_registered) { + for (i = 0; i <= (sd_template.dev_max - 1) / SCSI_DISKS_PER_MAJOR; i++) { + if (register_blkdev(SD_MAJOR(i), "sd", &sd_fops)) { + printk("Unable to get major %d for SCSI disk\n", SD_MAJOR(i)); + return 1; + } + } + sd_registered++; } - sd_registered++; - } - - /* We do not support attaching loadable devices yet. */ - if(rscsi_disks) return 0; - - rscsi_disks = (Scsi_Disk *) - scsi_init_malloc(sd_template.dev_max * sizeof(Scsi_Disk), GFP_ATOMIC); - memset(rscsi_disks, 0, sd_template.dev_max * sizeof(Scsi_Disk)); - - /* for every (necessary) major: */ - sd_sizes = (int *) scsi_init_malloc((sd_template.dev_max << 4) * sizeof(int), GFP_ATOMIC); - memset(sd_sizes, 0, (sd_template.dev_max << 4) * sizeof(int)); - - sd_blocksizes = (int *) scsi_init_malloc((sd_template.dev_max << 4) * sizeof(int), GFP_ATOMIC); - sd_hardsizes = (int *) scsi_init_malloc((sd_template.dev_max << 4) * sizeof(int), GFP_ATOMIC); - - for(i=0; i < sd_template.dev_max << 4; i++) { - sd_blocksizes[i] = 1024; - sd_hardsizes[i] = 512; - } - - for (i=0; i < N_USED_SD_MAJORS; i++) { - blksize_size[SD_MAJOR(i)] = sd_blocksizes + i * (SCSI_DISKS_PER_MAJOR << 4); - hardsect_size[SD_MAJOR(i)] = sd_hardsizes + i * (SCSI_DISKS_PER_MAJOR << 4); - } - sd = (struct hd_struct *) scsi_init_malloc((sd_template.dev_max << 4) * - sizeof(struct hd_struct), - GFP_ATOMIC); - - if (N_USED_SD_MAJORS > 1) - sd_gendisks = (struct gendisk *) - kmalloc(N_USED_SD_MAJORS * sizeof(struct gendisk), GFP_ATOMIC); - for (i=0; i < N_USED_SD_MAJORS; i++) { - sd_gendisks[i].major = SD_MAJOR(i); - sd_gendisks[i].major_name = "sd"; - sd_gendisks[i].minor_shift = 4; - sd_gendisks[i].max_p = 1 << 4; - sd_gendisks[i].max_nr = SCSI_DISKS_PER_MAJOR; - sd_gendisks[i].init = sd_geninit; - sd_gendisks[i].part = sd + (i * SCSI_DISKS_PER_MAJOR << 4); - sd_gendisks[i].sizes = sd_sizes + (i * SCSI_DISKS_PER_MAJOR << 4); - sd_gendisks[i].nr_real = 0; - sd_gendisks[i].next = sd_gendisks + i + 1; - sd_gendisks[i].real_devices = - (void *) (rscsi_disks + i * SCSI_DISKS_PER_MAJOR); - } - - LAST_SD_GENDISK.max_nr = - (sd_template.dev_max -1 ) % SCSI_DISKS_PER_MAJOR + 1; - LAST_SD_GENDISK.next = NULL; - return 0; + /* We do not support attaching loadable devices yet. */ + if (rscsi_disks) + return 0; + + rscsi_disks = (Scsi_Disk *) + scsi_init_malloc(sd_template.dev_max * sizeof(Scsi_Disk), GFP_ATOMIC); + memset(rscsi_disks, 0, sd_template.dev_max * sizeof(Scsi_Disk)); + + /* for every (necessary) major: */ + sd_sizes = (int *) scsi_init_malloc((sd_template.dev_max << 4) * sizeof(int), GFP_ATOMIC); + memset(sd_sizes, 0, (sd_template.dev_max << 4) * sizeof(int)); + + sd_blocksizes = (int *) scsi_init_malloc((sd_template.dev_max << 4) * sizeof(int), GFP_ATOMIC); + sd_hardsizes = (int *) scsi_init_malloc((sd_template.dev_max << 4) * sizeof(int), GFP_ATOMIC); + + for (i = 0; i < sd_template.dev_max << 4; i++) { + sd_blocksizes[i] = 1024; + sd_hardsizes[i] = 512; + } + + for (i = 0; i < N_USED_SD_MAJORS; i++) { + blksize_size[SD_MAJOR(i)] = sd_blocksizes + i * (SCSI_DISKS_PER_MAJOR << 4); + hardsect_size[SD_MAJOR(i)] = sd_hardsizes + i * (SCSI_DISKS_PER_MAJOR << 4); + } + sd = (struct hd_struct *) scsi_init_malloc((sd_template.dev_max << 4) * + sizeof(struct hd_struct), + GFP_ATOMIC); + + if (N_USED_SD_MAJORS > 1) + sd_gendisks = (struct gendisk *) + kmalloc(N_USED_SD_MAJORS * sizeof(struct gendisk), GFP_ATOMIC); + for (i = 0; i < N_USED_SD_MAJORS; i++) { + sd_gendisks[i].major = SD_MAJOR(i); + sd_gendisks[i].major_name = "sd"; + sd_gendisks[i].minor_shift = 4; + sd_gendisks[i].max_p = 1 << 4; + sd_gendisks[i].max_nr = SCSI_DISKS_PER_MAJOR; + sd_gendisks[i].init = sd_geninit; + sd_gendisks[i].part = sd + (i * SCSI_DISKS_PER_MAJOR << 4); + sd_gendisks[i].sizes = sd_sizes + (i * SCSI_DISKS_PER_MAJOR << 4); + sd_gendisks[i].nr_real = 0; + sd_gendisks[i].next = sd_gendisks + i + 1; + sd_gendisks[i].real_devices = + (void *) (rscsi_disks + i * SCSI_DISKS_PER_MAJOR); + } + + LAST_SD_GENDISK.max_nr = + (sd_template.dev_max - 1) % SCSI_DISKS_PER_MAJOR + 1; + LAST_SD_GENDISK.next = NULL; + return 0; } /* * sd_get_queue() returns the queue which corresponds to a given device. */ -static struct request **sd_get_queue (kdev_t dev) +static struct request **sd_get_queue(kdev_t dev) { return &blk_dev[MAJOR_NR].current_request; } - static void sd_finish() { - struct gendisk *gendisk; - int i; - - for (i=0; i <= (sd_template.dev_max - 1) / SCSI_DISKS_PER_MAJOR; i++) { - /* FIXME: After 2.2 we should implement multiple sd queues */ - blk_dev[SD_MAJOR(i)].request_fn = DEVICE_REQUEST; - if (i) blk_dev[SD_MAJOR(i)].queue = sd_get_queue; - } - - for (gendisk = gendisk_head; gendisk != NULL; gendisk = gendisk->next) - if (gendisk == sd_gendisks) - break; - if (gendisk == NULL) - { - LAST_SD_GENDISK.next = gendisk_head; - gendisk_head = sd_gendisks; - } - - for (i = 0; i < sd_template.dev_max; ++i) - if (!rscsi_disks[i].capacity && - rscsi_disks[i].device) - { - if (MODULE_FLAG - && !rscsi_disks[i].has_part_table) { - sd_sizes[i << 4] = rscsi_disks[i].capacity; - /* revalidate does sd_init_onedisk via MAYBE_REINIT*/ - revalidate_scsidisk(MKDEV_SD(i), 0); - } - else - i=sd_init_onedisk(i); - rscsi_disks[i].has_part_table = 1; + struct gendisk *gendisk; + int i; + + for (i = 0; i <= (sd_template.dev_max - 1) / SCSI_DISKS_PER_MAJOR; i++) { + /* FIXME: After 2.2 we should implement multiple sd queues */ + blk_dev[SD_MAJOR(i)].request_fn = DEVICE_REQUEST; + if (i) + blk_dev[SD_MAJOR(i)].queue = sd_get_queue; + } + for (gendisk = gendisk_head; gendisk != NULL; gendisk = gendisk->next) + if (gendisk == sd_gendisks) + break; + if (gendisk == NULL) { + LAST_SD_GENDISK.next = gendisk_head; + gendisk_head = sd_gendisks; + } + for (i = 0; i < sd_template.dev_max; ++i) + if (!rscsi_disks[i].capacity && + rscsi_disks[i].device) { + if (MODULE_FLAG + && !rscsi_disks[i].has_part_table) { + sd_sizes[i << 4] = rscsi_disks[i].capacity; + /* revalidate does sd_init_onedisk via MAYBE_REINIT */ + revalidate_scsidisk(MKDEV_SD(i), 0); + } else + i = sd_init_onedisk(i); + rscsi_disks[i].has_part_table = 1; + } + /* If our host adapter is capable of scatter-gather, then we increase + * the read-ahead to 60 blocks (120 sectors). If not, we use + * a two block (4 sector) read ahead. We can only respect this with the + * granularity of every 16 disks (one device major). + */ + for (i = 0; i < N_USED_SD_MAJORS; i++) { + read_ahead[SD_MAJOR(i)] = + (rscsi_disks[i * SCSI_DISKS_PER_MAJOR].device + && rscsi_disks[i * SCSI_DISKS_PER_MAJOR].device->host->sg_tablesize) + ? 120 /* 120 sector read-ahead */ + : 4; /* 4 sector read-ahead */ } - /* If our host adapter is capable of scatter-gather, then we increase - * the read-ahead to 60 blocks (120 sectors). If not, we use - * a two block (4 sector) read ahead. We can only respect this with the - * granularity of every 16 disks (one device major). - */ - for (i=0; i < N_USED_SD_MAJORS; i++) { - read_ahead[SD_MAJOR(i)] = - (rscsi_disks[i * SCSI_DISKS_PER_MAJOR].device - && rscsi_disks[i * SCSI_DISKS_PER_MAJOR].device->host->sg_tablesize) - ? 120 /* 120 sector read-ahead */ - : 4; /* 4 sector read-ahead */ - } - - return; + return; } -static int sd_detect(Scsi_Device * SDp){ - char nbuff[6]; - if(SDp->type != TYPE_DISK && SDp->type != TYPE_MOD) return 0; +static int sd_detect(Scsi_Device * SDp) +{ + char nbuff[6]; + if (SDp->type != TYPE_DISK && SDp->type != TYPE_MOD) + return 0; - sd_devname(sd_template.dev_noticed++, nbuff); - printk("Detected scsi %sdisk %s at scsi%d, channel %d, id %d, lun %d\n", - SDp->removable ? "removable " : "", - nbuff, - SDp->host->host_no, SDp->channel, SDp->id, SDp->lun); + sd_devname(sd_template.dev_noticed++, nbuff); + printk("Detected scsi %sdisk %s at scsi%d, channel %d, id %d, lun %d\n", + SDp->removable ? "removable " : "", + nbuff, + SDp->host->host_no, SDp->channel, SDp->id, SDp->lun); - return 1; + return 1; } +static int sd_attach(Scsi_Device * SDp) +{ + Scsi_Disk *dpnt; + int i; -static int sd_attach(Scsi_Device * SDp){ - Scsi_Disk * dpnt; - int i; - - if(SDp->type != TYPE_DISK && SDp->type != TYPE_MOD) return 0; + if (SDp->type != TYPE_DISK && SDp->type != TYPE_MOD) + return 0; - if(sd_template.nr_dev >= sd_template.dev_max) { - SDp->attached--; - return 1; - } - - for(dpnt = rscsi_disks, i=0; i<sd_template.dev_max; i++, dpnt++) - if(!dpnt->device) break; + if (sd_template.nr_dev >= sd_template.dev_max) { + SDp->attached--; + return 1; + } + for (dpnt = rscsi_disks, i = 0; i < sd_template.dev_max; i++, dpnt++) + if (!dpnt->device) + break; - if(i >= sd_template.dev_max) panic ("scsi_devices corrupt (sd)"); + if (i >= sd_template.dev_max) + panic("scsi_devices corrupt (sd)"); - SDp->scsi_request_fn = do_sd_request; - rscsi_disks[i].device = SDp; - rscsi_disks[i].has_part_table = 0; - sd_template.nr_dev++; - SD_GENDISK(i).nr_real++; - return 0; + SDp->scsi_request_fn = do_sd_request; + rscsi_disks[i].device = SDp; + rscsi_disks[i].has_part_table = 0; + sd_template.nr_dev++; + SD_GENDISK(i).nr_real++; + return 0; } #define DEVICE_BUSY rscsi_disks[target].device->busy @@ -1671,160 +1602,162 @@ static int sd_attach(Scsi_Device * SDp){ * usage == 1 (we need an open channel to use an ioctl :-), so this * is our limit. */ -int revalidate_scsidisk(kdev_t dev, int maxusage) { - int target; - int max_p; - int start; - int i; - - target = DEVICE_NR(dev); - - if (DEVICE_BUSY || USAGE > maxusage) { - printk("Device busy for revalidation (usage=%d)\n", USAGE); - return -EBUSY; - } - DEVICE_BUSY = 1; - - max_p = sd_gendisks->max_p; - start = target << sd_gendisks->minor_shift; - - for (i=max_p - 1; i >=0 ; i--) { - int index = start+i; - kdev_t devi = MKDEV_SD_PARTITION(index); - struct super_block *sb = get_super(devi); - sync_dev(devi); - if (sb) invalidate_inodes(sb); - invalidate_buffers(devi); - sd_gendisks->part[index].start_sect = 0; - sd_gendisks->part[index].nr_sects = 0; - /* - * Reset the blocksize for everything so that we can read - * the partition table. Technically we will determine the - * correct block size when we revalidate, but we do this just - * to make sure that everything remains consistent. - */ - sd_blocksizes[index] = 1024; - if( rscsi_disks[target].sector_size == 2048 ) - sd_blocksizes[index] = 2048; - else - sd_blocksizes[index] = 1024; - } - -#ifdef MAYBE_REINIT - MAYBE_REINIT; -#endif - - sd_gendisks->part[start].nr_sects = CAPACITY; - resetup_one_dev(&SD_GENDISK(target), - target % SCSI_DISKS_PER_MAJOR); - - DEVICE_BUSY = 0; - return 0; -} - -static int fop_revalidate_scsidisk(kdev_t dev){ - return revalidate_scsidisk(dev, 0); -} - - -static void sd_detach(Scsi_Device * SDp) +int revalidate_scsidisk(kdev_t dev, int maxusage) { - Scsi_Disk * dpnt; - int i, j; - int max_p; - int start; + int target; + int max_p; + int start; + int i; + + target = DEVICE_NR(dev); - for(dpnt = rscsi_disks, i=0; i<sd_template.dev_max; i++, dpnt++) - if(dpnt->device == SDp) { + if (DEVICE_BUSY || USAGE > maxusage) { + printk("Device busy for revalidation (usage=%d)\n", USAGE); + return -EBUSY; + } + DEVICE_BUSY = 1; - /* If we are disconnecting a disk driver, sync and invalidate - * everything */ - max_p = sd_gendisk.max_p; - start = i << sd_gendisk.minor_shift; + max_p = sd_gendisks->max_p; + start = target << sd_gendisks->minor_shift; - for (j=max_p - 1; j >=0 ; j--) { - int index = start+j; + for (i = max_p - 1; i >= 0; i--) { + int index = start + i; kdev_t devi = MKDEV_SD_PARTITION(index); - struct super_block *sb = get_super(devi); + struct super_block *sb = get_super(devi); sync_dev(devi); - if (sb) invalidate_inodes(sb); + if (sb) + invalidate_inodes(sb); invalidate_buffers(devi); sd_gendisks->part[index].start_sect = 0; sd_gendisks->part[index].nr_sects = 0; - sd_sizes[index] = 0; - } - - dpnt->has_part_table = 0; - dpnt->device = NULL; - dpnt->capacity = 0; - SDp->attached--; - sd_template.dev_noticed--; - sd_template.nr_dev--; - SD_GENDISK(i).nr_real--; - return; + /* + * Reset the blocksize for everything so that we can read + * the partition table. Technically we will determine the + * correct block size when we revalidate, but we do this just + * to make sure that everything remains consistent. + */ + sd_blocksizes[index] = 1024; + if (rscsi_disks[target].sector_size == 2048) + sd_blocksizes[index] = 2048; + else + sd_blocksizes[index] = 1024; } - return; + +#ifdef MAYBE_REINIT + MAYBE_REINIT; +#endif + + sd_gendisks->part[start].nr_sects = CAPACITY; + if (!rscsi_disks[target].device) + return -EBUSY; + resetup_one_dev(&SD_GENDISK(target), + target % SCSI_DISKS_PER_MAJOR); + + DEVICE_BUSY = 0; + return 0; +} + +static int fop_revalidate_scsidisk(kdev_t dev) +{ + return revalidate_scsidisk(dev, 0); +} +static void sd_detach(Scsi_Device * SDp) +{ + Scsi_Disk *dpnt; + int i, j; + int max_p; + int start; + + for (dpnt = rscsi_disks, i = 0; i < sd_template.dev_max; i++, dpnt++) + if (dpnt->device == SDp) { + + /* If we are disconnecting a disk driver, sync and invalidate + * everything */ + max_p = sd_gendisk.max_p; + start = i << sd_gendisk.minor_shift; + + for (j = max_p - 1; j >= 0; j--) { + int index = start + j; + kdev_t devi = MKDEV_SD_PARTITION(index); + struct super_block *sb = get_super(devi); + sync_dev(devi); + if (sb) + invalidate_inodes(sb); + invalidate_buffers(devi); + sd_gendisks->part[index].start_sect = 0; + sd_gendisks->part[index].nr_sects = 0; + sd_sizes[index] = 0; + } + dpnt->has_part_table = 0; + dpnt->device = NULL; + dpnt->capacity = 0; + SDp->attached--; + sd_template.dev_noticed--; + sd_template.nr_dev--; + SD_GENDISK(i).nr_real--; + return; + } + return; } #ifdef MODULE -int init_module(void) { - sd_template.module = &__this_module; - return scsi_register_module(MODULE_SCSI_DEV, &sd_template); +int init_module(void) +{ + sd_template.module = &__this_module; + return scsi_register_module(MODULE_SCSI_DEV, &sd_template); } - -void cleanup_module( void) +void cleanup_module(void) { - struct gendisk ** prev_sdgd_link; - struct gendisk * sdgd; - int i; - int removed = 0; - - scsi_unregister_module(MODULE_SCSI_DEV, &sd_template); - - for (i=0; i <= (sd_template.dev_max - 1) / SCSI_DISKS_PER_MAJOR; i++) - unregister_blkdev(SD_MAJOR(i),"sd"); - - sd_registered--; - if( rscsi_disks != NULL ) - { - scsi_init_free((char *) rscsi_disks, - sd_template.dev_max * sizeof(Scsi_Disk)); - scsi_init_free((char *) sd_sizes, sd_template.dev_max * sizeof(int)); - scsi_init_free((char *) sd_blocksizes, sd_template.dev_max * sizeof(int)); - scsi_init_free((char *) sd_hardsizes, sd_template.dev_max * sizeof(int)); - scsi_init_free((char *) sd, - (sd_template.dev_max << 4) * sizeof(struct hd_struct)); + struct gendisk **prev_sdgd_link; + struct gendisk *sdgd; + int i; + int removed = 0; - /* - * Now remove sd_gendisks from the linked list - */ - prev_sdgd_link = &gendisk_head; - while ((sdgd = *prev_sdgd_link) != NULL) { - if (sdgd >= sd_gendisks && sdgd <= &LAST_SD_GENDISK) { - removed++; - *prev_sdgd_link = sdgd->next; - continue; - } - prev_sdgd_link = &sdgd->next; - } + scsi_unregister_module(MODULE_SCSI_DEV, &sd_template); - if (removed != N_USED_SD_MAJORS) - printk("%s %d sd_gendisks in disk chain", - removed > N_USED_SD_MAJORS ? "total" : "just", removed); - - } - - for (i=0; i <= (sd_template.dev_max - 1) / SCSI_DISKS_PER_MAJOR; i++) { - blk_dev[SD_MAJOR(i)].request_fn = NULL; - blk_size[SD_MAJOR(i)] = NULL; - hardsect_size[SD_MAJOR(i)] = NULL; - read_ahead[SD_MAJOR(i)] = 0; - } - sd_template.dev_max = 0; - if (sd_gendisks != &sd_gendisk) kfree(sd_gendisks); + for (i = 0; i <= (sd_template.dev_max - 1) / SCSI_DISKS_PER_MAJOR; i++) + unregister_blkdev(SD_MAJOR(i), "sd"); + + sd_registered--; + if (rscsi_disks != NULL) { + scsi_init_free((char *) rscsi_disks, + sd_template.dev_max * sizeof(Scsi_Disk)); + scsi_init_free((char *) sd_sizes, sd_template.dev_max * sizeof(int)); + scsi_init_free((char *) sd_blocksizes, sd_template.dev_max * sizeof(int)); + scsi_init_free((char *) sd_hardsizes, sd_template.dev_max * sizeof(int)); + scsi_init_free((char *) sd, + (sd_template.dev_max << 4) * sizeof(struct hd_struct)); + + /* + * Now remove sd_gendisks from the linked list + */ + prev_sdgd_link = &gendisk_head; + while ((sdgd = *prev_sdgd_link) != NULL) { + if (sdgd >= sd_gendisks && sdgd <= &LAST_SD_GENDISK) { + removed++; + *prev_sdgd_link = sdgd->next; + continue; + } + prev_sdgd_link = &sdgd->next; + } + + if (removed != N_USED_SD_MAJORS) + printk("%s %d sd_gendisks in disk chain", + removed > N_USED_SD_MAJORS ? "total" : "just", removed); + + } + for (i = 0; i <= (sd_template.dev_max - 1) / SCSI_DISKS_PER_MAJOR; i++) { + blk_dev[SD_MAJOR(i)].request_fn = NULL; + blk_size[SD_MAJOR(i)] = NULL; + hardsect_size[SD_MAJOR(i)] = NULL; + read_ahead[SD_MAJOR(i)] = 0; + } + sd_template.dev_max = 0; + if (sd_gendisks != &sd_gendisk) + kfree(sd_gendisks); } -#endif /* MODULE */ +#endif /* MODULE */ /* * Overrides for Emacs so that we almost follow Linus's tabbing style. |