/* * sd.c Copyright (C) 1992 Drew Eckhardt * Copyright (C) 1993, 1994, 1995, 1999 Eric Youngdale * * Linux scsi disk driver * Initial versions: Drew Eckhardt * Subsequent revisions: Eric Youngdale * Modification history: * - Drew Eckhardt <drew@colorado.edu> original * - Eric Youngdale <eric@andante.org> add scatter-gather, multiple * outstanding request, and other enhancements. * Support loadable low-level scsi drivers. * - Jirka Hanika <geo@ff.cuni.cz> support more scsi disks using * eight major numbers. * - Richard Gooch <rgooch@atnf.csiro.au> support devfs. * - Torben Mathiasen <tmm@image.dk> Resource allocation fixes in * sd_init and cleanups. * - Alex Davis <letmein@erols.com> Fix problem where partition info * not being read in sd_open. Fix problem where removable media * could be ejected after sd_open. * - Douglas Gilbert <dgilbert@interlog.com> cleanup for lk 2.5 series * * Logging policy (needs CONFIG_SCSI_LOGGING defined): * - setting up transfer: SCSI_LOG_HLQUEUE levels 1 and 2 * - end of transfer (bh + scsi_lib): SCSI_LOG_HLCOMPLETE level 1 * - entering sd_ioctl: SCSI_LOG_IOCTL level 1 * - entering other commands: SCSI_LOG_HLQUEUE level 3 * Note: when the logging level is set by the user, it must be greater * than the level indicated above to trigger output. */ #include <linux/config.h> #include <linux/module.h> #include <linux/fs.h> #include <linux/kernel.h> #include <linux/sched.h> #include <linux/mm.h> #include <linux/bio.h> #include <linux/string.h> #include <linux/hdreg.h> #include <linux/errno.h> #include <linux/interrupt.h> #include <linux/init.h> #include <linux/vmalloc.h> #include <linux/smp.h> #include <asm/uaccess.h> #include <asm/system.h> #include <asm/io.h> #define MAJOR_NR SCSI_DISK0_MAJOR #define LOCAL_END_REQUEST #define DEVICE_NR(device) (((major(device) & SD_MAJOR_MASK) << (8 - 4)) + (minor(device) >> 4)) #include <linux/blk.h> #include <linux/blkpg.h> #include "scsi.h" #include "hosts.h" #include "sd.h" #include <scsi/scsi_ioctl.h> #include <scsi/scsicam.h> /* must follow "hosts.h" */ #include <linux/genhd.h> /* static char sd_version_str[] = "Version: 2.0.3 (20020417)"; */ #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) #define MKDEV_SD_PARTITION(i) mk_kdev(SD_MAJOR_NUMBER(i), (i) & 255) #define MKDEV_SD(index) MKDEV_SD_PARTITION((index) << 4) #define N_USED_SD_MAJORS (1 + ((sd_template.dev_max - 1) >> 4)) #define MAX_RETRIES 5 /* * Time out in seconds for disks and Magneto-opticals (which are slower). */ #define SD_TIMEOUT (30 * HZ) #define SD_MOD_TIMEOUT (75 * HZ) #define SD_DSK_ARR_LUMP 6 /* amount to over allocate sd_dsk_arr by */ struct hd_struct *sd; static Scsi_Disk ** sd_dsk_arr; static rwlock_t sd_dsk_arr_lock = RW_LOCK_UNLOCKED; static int check_scsidisk_media_change(kdev_t); static int sd_revalidate(kdev_t); static void sd_init_onedisk(Scsi_Disk * sdkp, int dsk_nr); static int sd_init(void); static void sd_finish(void); static int sd_attach(Scsi_Device *); static int sd_detect(Scsi_Device *); static void sd_detach(Scsi_Device *); static int sd_init_command(Scsi_Cmnd *); static struct Scsi_Device_Template sd_template = { module:THIS_MODULE, name:"disk", tag:"sd", scsi_type:TYPE_DISK, major:SCSI_DISK0_MAJOR, /* * Secondary range of majors that this driver handles. */ min_major:SCSI_DISK1_MAJOR, max_major:SCSI_DISK7_MAJOR, blk:1, detect:sd_detect, init:sd_init, finish:sd_finish, attach:sd_attach, detach:sd_detach, init_command:sd_init_command, }; static void sd_rw_intr(Scsi_Cmnd * SCpnt); static Scsi_Disk * sd_get_sdisk(int index); #if defined(CONFIG_PPC32) /** * sd_find_target - find kdev_t of first scsi disk that matches * given host and scsi_id. * @host: Scsi_Host object pointer that owns scsi device of interest * @scsi_id: scsi (target) id number of device of interest * * Returns kdev_t of first scsi device that matches arguments or * NODEV of no match. * * Notes: Looks like a hack, should scan for <host,channel,id,lin> * tuple. * [Architectural dependency: ppc only.] Moved here from * arch/ppc/pmac_setup.c. **/ kdev_t __init sd_find_target(void *hp, int scsi_id) { Scsi_Disk *sdkp; Scsi_Device *sdp; struct Scsi_Host *shp = hp; int dsk_nr; kdev_t retval = NODEV; unsigned long iflags; SCSI_LOG_HLQUEUE(3, printk("sd_find_target: host_nr=%d, " "scsi_id=%d\n", shp->host_no, scsi_id)); read_lock_irqsave(&sd_dsk_arr_lock, iflags); for (dsk_nr = 0; dsk_nr < sd_template.dev_max; ++dsk_nr) { sdkp = sd_dsk_arr[dsk_nr]; if (sdkp == NULL) continue; sdp = sdkp->device; if (sdp && (sdp->host == shp) && (sdp->id == scsi_id)) { retval = MKDEV_SD(dsk_nr); break; } } read_unlock_irqrestore(&sd_dsk_arr_lock, iflags); return retval; } #endif /** * sd_ioctl - process an ioctl * @inode: only i_rdev member may be used * @filp: only f_mode and f_flags may be used * @cmd: ioctl command number * @arg: this is third argument given to ioctl(2) system call. * Often contains a pointer. * * Returns 0 if successful (some ioctls return postive numbers on * success as well). Returns a negated errno value in case of error. * * Note: most ioctls are forward onto the block subsystem or further * down in the scsi subsytem. **/ static int sd_ioctl(struct inode * inode, struct file * filp, unsigned int cmd, unsigned long arg) { kdev_t dev = inode->i_rdev; Scsi_Disk * sdkp; struct Scsi_Host * host; Scsi_Device * sdp; int diskinfo[4]; int dsk_nr = DEVICE_NR(dev); SCSI_LOG_IOCTL(1, printk("sd_ioctl: dsk_nr=%d, cmd=0x%x\n", dsk_nr, cmd)); sdkp = sd_get_sdisk(dsk_nr); if ((NULL == sdkp) || (NULL == (sdp = sdkp->device))) return -ENODEV; /* * If we are in the middle of error recovery, don't let anyone * else try and use this device. Also, if error recovery fails, it * may try and take the device offline, in which case all further * access to the device is prohibited. */ if( !scsi_block_when_processing_errors(sdp) ) return -ENODEV; switch (cmd) { case HDIO_GETGEO: /* Return BIOS disk parameters */ { struct hd_geometry *loc = (struct hd_geometry *) arg; if(!loc) return -EINVAL; host = sdp->host; /* default to most commonly used values */ diskinfo[0] = 0x40; /* 1 << 6 */ diskinfo[1] = 0x20; /* 1 << 5 */ diskinfo[2] = sdkp->capacity >> 11; /* override with calculated, extended default, or driver values */ if(host->hostt->bios_param != NULL) host->hostt->bios_param(sdkp, inode->i_bdev, &diskinfo[0]); else scsicam_bios_param(sdkp, inode->i_bdev, &diskinfo[0]); if (put_user(diskinfo[0], &loc->heads) || put_user(diskinfo[1], &loc->sectors) || put_user(diskinfo[2], &loc->cylinders) || put_user((unsigned) get_start_sect(inode->i_bdev), (unsigned long *) &loc->start)) return -EFAULT; return 0; } default: return scsi_ioctl(sdp, cmd, (void *) arg); } } static void sd_dskname(unsigned int dsk_nr, char *buffer) { if (dsk_nr < 26) sprintf(buffer, "sd%c", 'a' + dsk_nr); else { unsigned int min1; unsigned int min2; /* * For larger numbers of disks, we need to go to a new * naming scheme. */ min1 = dsk_nr / 26; min2 = dsk_nr % 26; sprintf(buffer, "sd%c%c", 'a' + min1 - 1, 'a' + min2); } } /** * sd_find_queue - yields queue associated with device * @dev: kernel device descriptor (kdev_t) * * Returns NULL if no match, otherwise returns pointer to associated * request queue. * * Note: this function is invoked (often) from the block subsystem * and should not wait on anything (sd_get_sdisk() does have a read * spinlock). **/ static request_queue_t *sd_find_queue(kdev_t dev) { Scsi_Disk *sdkp; int dsk_nr = DEVICE_NR(dev); sdkp = sd_get_sdisk(dsk_nr); if (sdkp && sdkp->device) return &sdkp->device->request_queue; else return NULL; /* No such device */ } static struct gendisk **sd_disks; /** * sd_init_command - build a scsi (read or write) command from * information in the request structure. * @SCpnt: pointer to mid-level's per scsi command structure that * contains request and into which the scsi command is written * * Returns 1 if successful and 0 if error (or cannot be done now). **/ static int sd_init_command(Scsi_Cmnd * SCpnt) { int dsk_nr, part_nr, block, this_count; Scsi_Device *sdp; #if CONFIG_SCSI_LOGGING char nbuff[6]; #endif /* * don't support specials for nwo */ if (!(SCpnt->request->flags & REQ_CMD)) return 0; part_nr = SD_PARTITION(SCpnt->request->rq_dev); dsk_nr = DEVICE_NR(SCpnt->request->rq_dev); block = SCpnt->request->sector; this_count = SCpnt->request_bufflen >> 9; SCSI_LOG_HLQUEUE(1, printk("sd_command_init: dsk_nr=%d, block=%d, " "count=%d\n", dsk_nr, block, this_count)); sdp = SCpnt->device; /* >>>>> the "(part_nr & 0xf)" excludes 15th partition, why?? */ /* >>>>> this change is not in the lk 2.5 series */ if (part_nr >= (sd_template.dev_max << 4) || (part_nr & 0xf) || !sdp || !sdp->online || block + SCpnt->request->nr_sectors > get_capacity(sd_disks[dsk_nr])) { SCSI_LOG_HLQUEUE(2, printk("Finishing %ld sectors\n", SCpnt->request->nr_sectors)); SCSI_LOG_HLQUEUE(2, printk("Retry with 0x%p\n", SCpnt)); return 0; } if (sdp->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"); */ return 0; } SCSI_LOG_HLQUEUE(2, sd_dskname(dsk_nr, nbuff)); SCSI_LOG_HLQUEUE(2, printk("%s : [part_nr=%d], block=%d\n", nbuff, part_nr, 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 (sdp->sector_size == 1024) { if ((block & 1) || (SCpnt->request->nr_sectors & 1)) { printk(KERN_ERR "sd: Bad block number requested"); return 0; } else { block = block >> 1; this_count = this_count >> 1; } } if (sdp->sector_size == 2048) { if ((block & 3) || (SCpnt->request->nr_sectors & 3)) { printk(KERN_ERR "sd: Bad block number requested"); return 0; } else { block = block >> 2; this_count = this_count >> 2; } } if (sdp->sector_size == 4096) { if ((block & 7) || (SCpnt->request->nr_sectors & 7)) { printk(KERN_ERR "sd: Bad block number requested"); return 0; } else { block = block >> 3; this_count = this_count >> 3; } } if (rq_data_dir(SCpnt->request) == WRITE) { if (!sdp->writeable) { return 0; } SCpnt->cmnd[0] = WRITE_6; SCpnt->sc_data_direction = SCSI_DATA_WRITE; } else if (rq_data_dir(SCpnt->request) == READ) { SCpnt->cmnd[0] = READ_6; SCpnt->sc_data_direction = SCSI_DATA_READ; } else { printk(KERN_ERR "sd: Unknown command %lx\n", SCpnt->request->flags); /* overkill panic("Unknown sd command %lx\n", SCpnt->request->flags); */ return 0; } SCSI_LOG_HLQUEUE(2, printk("%s : %s %d/%ld 512 byte blocks.\n", nbuff, (rq_data_dir(SCpnt->request) == WRITE) ? "writing" : "reading", this_count, SCpnt->request->nr_sectors)); SCpnt->cmnd[1] = (SCpnt->device->scsi_level <= SCSI_2) ? ((SCpnt->lun << 5) & 0xe0) : 0; if (((this_count > 0xff) || (block > 0x1fffff)) || SCpnt->device->ten) { if (this_count > 0xffff) this_count = 0xffff; SCpnt->cmnd[0] += READ_10 - READ_6; SCpnt->cmnd[2] = (unsigned char) (block >> 24) & 0xff; SCpnt->cmnd[3] = (unsigned char) (block >> 16) & 0xff; SCpnt->cmnd[4] = (unsigned char) (block >> 8) & 0xff; SCpnt->cmnd[5] = (unsigned char) block & 0xff; SCpnt->cmnd[6] = SCpnt->cmnd[9] = 0; SCpnt->cmnd[7] = (unsigned char) (this_count >> 8) & 0xff; SCpnt->cmnd[8] = (unsigned char) this_count & 0xff; } else { if (this_count > 0xff) this_count = 0xff; SCpnt->cmnd[1] |= (unsigned char) ((block >> 16) & 0x1f); SCpnt->cmnd[2] = (unsigned char) ((block >> 8) & 0xff); SCpnt->cmnd[3] = (unsigned char) block & 0xff; SCpnt->cmnd[4] = (unsigned char) this_count; SCpnt->cmnd[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 = sdp->sector_size; SCpnt->underflow = this_count << 9; SCpnt->allowed = MAX_RETRIES; SCpnt->timeout_per_command = (SCpnt->device->type == TYPE_DISK ? SD_TIMEOUT : SD_MOD_TIMEOUT); /* * This is the completion routine we use. This is matched in terms * of capability to this function. */ SCpnt->done = sd_rw_intr; /* * This indicates that the command is ready from our end to be * queued. */ return 1; } /** * sd_open - open a scsi disk device * @inode: only i_rdev member may be used * @filp: only f_mode and f_flags may be used * * Returns 0 if successful. Returns a negated errno value in case * of error. * * Note: This can be called from a user context (e.g. fsck(1) ) * or from within the kernel (e.g. as a result of a mount(1) ). * In the latter case @inode and @filp carry an abridged amount * of information as noted above. **/ static int sd_open(struct inode *inode, struct file *filp) { int retval = -ENXIO; Scsi_Device * sdp; Scsi_Disk * sdkp; int dsk_nr = DEVICE_NR(inode->i_rdev); SCSI_LOG_HLQUEUE(3, printk("sd_open: dsk_nr=%d, part_nr=%d\n", dsk_nr, SD_PARTITION(inode->i_rdev))); sdkp = sd_get_sdisk(dsk_nr); if ((NULL == sdkp) || (NULL == (sdp = sdkp->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(sdp)) return -ENXIO; /* * The following code can sleep. * Module unloading must be prevented */ if (sdp->host->hostt->module) __MOD_INC_USE_COUNT(sdp->host->hostt->module); if (sd_template.module) __MOD_INC_USE_COUNT(sd_template.module); sdp->access_count++; if (sdp->removable) { check_disk_change(inode->i_bdev); /* * If the drive is empty, just let the open fail. */ if ((!sdkp->media_present) && !(filp->f_flags & O_NDELAY)) { retval = -ENOMEDIUM; goto error_out; } /* * 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 ((sdkp->write_prot) && (filp->f_mode & FMODE_WRITE)) { retval = -EROFS; goto error_out; } } /* * 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 (!sdp->online) { goto error_out; } if (sdp->removable) if (sdp->access_count==1) if (scsi_block_when_processing_errors(sdp)) scsi_ioctl(sdp, SCSI_IOCTL_DOORLOCK, NULL); return 0; error_out: sdp->access_count--; if (sdp->host->hostt->module) __MOD_DEC_USE_COUNT(sdp->host->hostt->module); if (sd_template.module) __MOD_DEC_USE_COUNT(sd_template.module); return retval; } /** * sd_release - invoked when the (last) close(2) is called on this * scsi disk. * @inode: only i_rdev member may be used * @filp: only f_mode and f_flags may be used * * Returns 0. * * Note: may block (uninterruptible) if error recovery is underway * on this disk. **/ static int sd_release(struct inode *inode, struct file *filp) { Scsi_Disk * sdkp; int dsk_nr = DEVICE_NR(inode->i_rdev); Scsi_Device * sdp; SCSI_LOG_HLQUEUE(3, printk("sd_release: dsk_nr=%d, part_nr=%d\n", dsk_nr, SD_PARTITION(inode->i_rdev))); sdkp = sd_get_sdisk(dsk_nr); if ((NULL == sdkp) || (NULL == (sdp = sdkp->device))) return -ENODEV; /* open uses ENXIO ?? */ /* ... and what if there are packets in flight and this close() * is followed by a "rmmod sd_mod" */ sdp->access_count--; if (sdp->removable) { if (!sdp->access_count) if (scsi_block_when_processing_errors(sdp)) scsi_ioctl(sdp, SCSI_IOCTL_DOORUNLOCK, NULL); } if (sdp->host->hostt->module) __MOD_DEC_USE_COUNT(sdp->host->hostt->module); if (sd_template.module) __MOD_DEC_USE_COUNT(sd_template.module); return 0; } static struct block_device_operations sd_fops = { owner: THIS_MODULE, open: sd_open, release: sd_release, ioctl: sd_ioctl, check_media_change: check_scsidisk_media_change, revalidate: sd_revalidate }; /** * sd_rw_intr - bottom half handler: called when the lower level * driver has completed (successfully or otherwise) a scsi command. * @SCpnt: mid-level's per command structure. * * Note: potentially run from within an ISR. Must not block. **/ static void sd_rw_intr(Scsi_Cmnd * SCpnt) { int result = SCpnt->result; int this_count = SCpnt->bufflen >> 9; int good_sectors = (result == 0 ? this_count : 0); int block_sectors = 1; long error_sector; #if CONFIG_SCSI_LOGGING char nbuff[6]; SCSI_LOG_HLCOMPLETE(1, sd_dskname(DEVICE_NR(SCpnt->request->rq_dev), nbuff)); SCSI_LOG_HLCOMPLETE(1, printk("sd_rw_intr: %s: res=0x%x\n", nbuff, result)); if (0 != result) { SCSI_LOG_HLCOMPLETE(1, printk("sd_rw_intr: sb[0,2,asc,ascq]" "=%x,%x,%x,%x\n", SCpnt->sense_buffer[0], SCpnt->sense_buffer[2], SCpnt->sense_buffer[12], SCpnt->sense_buffer[13])); } #endif /* 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. */ /* An error occurred */ if (driver_byte(result) != 0 && /* An error occured */ SCpnt->sense_buffer[0] != 0xF0) { /* Sense data is valid */ switch (SCpnt->sense_buffer[2]) { case MEDIUM_ERROR: error_sector = (SCpnt->sense_buffer[3] << 24) | (SCpnt->sense_buffer[4] << 16) | (SCpnt->sense_buffer[5] << 8) | SCpnt->sense_buffer[6]; if (SCpnt->request->bio != NULL) block_sectors = bio_sectors(SCpnt->request->bio); switch (SCpnt->device->sector_size) { case 1024: error_sector <<= 1; if (block_sectors < 2) block_sectors = 2; break; case 2048: error_sector <<= 2; if (block_sectors < 4) block_sectors = 4; break; case 4096: error_sector <<=3; if (block_sectors < 8) block_sectors = 8; break; case 256: error_sector >>= 1; break; default: break; } error_sector &= ~(block_sectors - 1); good_sectors = error_sector - SCpnt->request->sector; if (good_sectors < 0 || good_sectors >= this_count) good_sectors = 0; break; case RECOVERED_ERROR: /* * An error occured, but it recovered. Inform the * user, but make sure that it's not treated as a * hard error. */ print_sense("sd", SCpnt); result = 0; SCpnt->sense_buffer[0] = 0x0; good_sectors = this_count; break; case ILLEGAL_REQUEST: if (SCpnt->device->ten == 1) { if (SCpnt->cmnd[0] == READ_10 || SCpnt->cmnd[0] == WRITE_10) SCpnt->device->ten = 0; } break; default: break; } } /* * This calls the generic completion function, now that we know * how many actual sectors finished, and how many sectors we need * to say have failed. */ scsi_io_completion(SCpnt, good_sectors, block_sectors); } static void sd_set_media_not_present(Scsi_Disk *sdkp) { sdkp->media_present = 0; sdkp->capacity = 0; sdkp->device->changed = 1; } /** * check_scsidisk_media_change - self descriptive * @full_dev: kernel device descriptor (kdev_t) * * Returns 0 if not applicable or no change; 1 if change * * Note: this function is invoked from the block subsystem. **/ static int check_scsidisk_media_change(kdev_t full_dev) { int retval; int flag = 0; /* <<<< what is this for?? */ Scsi_Disk * sdkp; Scsi_Device * sdp; int dsk_nr = DEVICE_NR(full_dev); sdkp = sd_get_sdisk(dsk_nr); SCSI_LOG_HLQUEUE(3, printk("check_scsidisk_media_change: " "dsk_nr=%d\n", dsk_nr)); if ((NULL == sdkp) || (NULL == (sdp = sdkp->device))) { printk(KERN_ERR "check_scsidisk_media_change: dsk_nr=%d, " "invalid device\n", dsk_nr); return 0; } if (!sdp->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 (sdp->online == FALSE) { sd_set_media_not_present(sdkp); return 1; /* This will force a flush, if called from * check_disk_change */ } /* 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 = -ENODEV; if (scsi_block_when_processing_errors(sdp)) retval = scsi_ioctl(sdp, SCSI_IOCTL_START_UNIT, NULL); 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. */ sd_set_media_not_present(sdkp); return 1; /* This will force a flush, if called from * check_disk_change */ } /* * For removable scsi disk we have to recognise the presence * of a disk in the drive. This is kept in the Scsi_Disk * struct and tested at open ! Daniel Roche ( dan@lectra.fr ) */ sdkp->media_present = 1; retval = sdp->changed; if (!flag) sdp->changed = 0; return retval; } static int sd_media_not_present(Scsi_Disk *sdkp, Scsi_Request *SRpnt) { int the_result = SRpnt->sr_result; if (the_result != 0 && (driver_byte(the_result) & DRIVER_SENSE) != 0 && (SRpnt->sr_sense_buffer[2] == NOT_READY || SRpnt->sr_sense_buffer[2] == UNIT_ATTENTION) && SRpnt->sr_sense_buffer[12] == 0x3A /* medium not present */) { sd_set_media_not_present(sdkp); return 1; } return 0; } /* * spinup disk - called only in sd_init_onedisk() */ static void sd_spinup_disk(Scsi_Disk *sdkp, char *diskname, Scsi_Request *SRpnt, unsigned char *buffer) { unsigned char cmd[10]; Scsi_Device *sdp = sdkp->device; unsigned long spintime_value = 0; int the_result, retries, spintime; 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] = (sdp->scsi_level <= SCSI_2) ? ((sdp->lun << 5) & 0xe0) : 0; memset((void *) &cmd[2], 0, 8); SRpnt->sr_cmd_len = 0; SRpnt->sr_sense_buffer[0] = 0; SRpnt->sr_sense_buffer[2] = 0; SRpnt->sr_data_direction = SCSI_DATA_NONE; scsi_wait_req (SRpnt, (void *) cmd, (void *) buffer, 0/*512*/, SD_TIMEOUT, MAX_RETRIES); the_result = SRpnt->sr_result; retries++; if (the_result == 0 || SRpnt->sr_sense_buffer[2] != UNIT_ATTENTION) break; } /* * If the drive has indicated to us that it doesn't have * any media in it, don't bother with any of the rest of * this crap. */ if (sd_media_not_present(sdkp, SRpnt)) return; /* Look for non-removable devices that return NOT_READY. * Issue command to spin up drive for these cases. */ if (the_result && !sdp->removable && SRpnt->sr_sense_buffer[2] == NOT_READY) { unsigned long time1; if (!spintime) { printk(KERN_NOTICE "%s: Spinning up disk...", diskname); cmd[0] = START_STOP; cmd[1] = (sdp->scsi_level <= SCSI_2) ? ((sdp->lun << 5) & 0xe0) : 0; cmd[1] |= 1; /* Return immediately */ memset((void *) &cmd[2], 0, 8); cmd[4] = 1; /* Start spin cycle */ SRpnt->sr_cmd_len = 0; SRpnt->sr_sense_buffer[0] = 0; SRpnt->sr_sense_buffer[2] = 0; SRpnt->sr_data_direction = SCSI_DATA_READ; scsi_wait_req(SRpnt, (void *)cmd, (void *) buffer, 0/*512*/, SD_TIMEOUT, MAX_RETRIES); spintime_value = jiffies; } spintime = 1; time1 = HZ; /* Wait 1 second for next try */ do { current->state = TASK_UNINTERRUPTIBLE; time1 = schedule_timeout(time1); } while(time1); printk("."); } } while (the_result && spintime && time_after(spintime_value + 100 * HZ, jiffies)); if (spintime) { if (the_result) printk("not responding...\n"); else printk("ready\n"); } } /* * read disk capacity - called only in sd_init_onedisk() */ static void sd_read_capacity(Scsi_Disk *sdkp, char *diskname, Scsi_Request *SRpnt, unsigned char *buffer) { unsigned char cmd[10]; Scsi_Device *sdp = sdkp->device; int the_result, retries; int sector_size; retries = 3; do { cmd[0] = READ_CAPACITY; cmd[1] = (sdp->scsi_level <= SCSI_2) ? ((sdp->lun << 5) & 0xe0) : 0; memset((void *) &cmd[2], 0, 8); memset((void *) buffer, 0, 8); SRpnt->sr_cmd_len = 0; SRpnt->sr_sense_buffer[0] = 0; SRpnt->sr_sense_buffer[2] = 0; SRpnt->sr_data_direction = SCSI_DATA_READ; scsi_wait_req(SRpnt, (void *) cmd, (void *) buffer, 8, SD_TIMEOUT, MAX_RETRIES); if (sd_media_not_present(sdkp, SRpnt)) return; the_result = SRpnt->sr_result; retries--; } while (the_result && retries); if (the_result) { printk(KERN_NOTICE "%s : READ CAPACITY failed.\n" "%s : status=%x, message=%02x, host=%d, driver=%02x \n", diskname, diskname, status_byte(the_result), msg_byte(the_result), host_byte(the_result), driver_byte(the_result)); if (driver_byte(the_result) & DRIVER_SENSE) print_req_sense("sd", SRpnt); else printk("%s : sense not available. \n", diskname); /* Set dirty bit for removable devices if not ready - * sometimes drives will not report this properly. */ if (sdp->removable && SRpnt->sr_sense_buffer[2] == NOT_READY) sdp->changed = 1; /* Either no media are present but the drive didnt tell us, or they are present but the read capacity command fails */ /* sdkp->media_present = 0; -- not always correct */ sdkp->capacity = 0x200000; /* 1 GB - random */ return; } sdkp->capacity = 1 + ((buffer[0] << 24) | (buffer[1] << 16) | (buffer[2] << 8) | buffer[3]); sector_size = (buffer[4] << 24) | (buffer[5] << 16) | (buffer[6] << 8) | buffer[7]; if (sector_size == 0) { sector_size = 512; printk(KERN_NOTICE "%s : sector size 0 reported, " "assuming 512.\n", diskname); } if (sector_size != 512 && sector_size != 1024 && sector_size != 2048 && sector_size != 4096 && sector_size != 256) { printk(KERN_NOTICE "%s : unsupported sector size " "%d.\n", diskname, sector_size); /* * The user might want to re-format the drive with * a supported sectorsize. Once this happens, it * would be relatively trivial to set the thing up. * For this reason, we leave the thing in the table. */ sdkp->capacity = 0; } { /* * 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 hard_sector = sector_size; int sz = sdkp->capacity * (hard_sector/256); request_queue_t *queue = &sdp->request_queue; blk_queue_hardsect_size(queue, hard_sector); printk(KERN_NOTICE "SCSI device %s: " "%d %d-byte hdwr sectors (%d MB)\n", diskname, sdkp->capacity, hard_sector, (sz/2 - sz/1250 + 974)/1950); } /* Rescale capacity to 512-byte units */ if (sector_size == 4096) sdkp->capacity <<= 3; if (sector_size == 2048) sdkp->capacity <<= 2; if (sector_size == 1024) sdkp->capacity <<= 1; if (sector_size == 256) sdkp->capacity >>= 1; sdkp->device->sector_size = sector_size; } /* * read write protect setting, if possible - called only in sd_init_onedisk() */ static void sd_read_write_protect_flag(Scsi_Disk *sdkp, char *diskname, Scsi_Request *SRpnt, unsigned char *buffer) { Scsi_Device *sdp = sdkp->device; unsigned char cmd[8]; int the_result; /* * For removable scsi disks 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 ) * * Changed to get all pages (0x3f) rather than page 1 to * get around devices which do not have a page 1. Since * we're only interested in the header anyway, this should * be fine. * -- Matthew Dharm (mdharm-scsi@one-eyed-alien.net) * * As it turns out, some devices return an error for * every MODE_SENSE request except one for page 0. * So, we should also try that. --aeb */ memset((void *) &cmd[0], 0, 8); cmd[0] = MODE_SENSE; cmd[1] = (sdp->scsi_level <= SCSI_2) ? ((sdp->lun << 5) & 0xe0) : 0; cmd[2] = 0x3f; /* Get all pages */ cmd[4] = 255; /* Ask for 255 bytes, even tho we want just the first 8 */ SRpnt->sr_cmd_len = 0; SRpnt->sr_sense_buffer[0] = 0; SRpnt->sr_sense_buffer[2] = 0; SRpnt->sr_data_direction = SCSI_DATA_READ; scsi_wait_req(SRpnt, (void *) cmd, (void *) buffer, 255, SD_TIMEOUT, MAX_RETRIES); the_result = SRpnt->sr_result; if (the_result) { printk("%s: test WP failed, assume Write Enabled\n", diskname); /* alternatively, try page 0 */ } else { sdkp->write_prot = ((buffer[2] & 0x80) != 0); printk(KERN_NOTICE "%s: Write Protect is %s\n", diskname, sdkp->write_prot ? "on" : "off"); } } /** * sd_init_onedisk - called the first time a new disk is seen, * performs disk spin up, read_capacity, etc. * @sdkp: pointer to associated Scsi_Disk object * @dsk_nr: disk number within this driver (e.g. 0->/dev/sda, * 1->/dev/sdb, etc) * * Note: this function is local to this driver. **/ static void sd_init_onedisk(Scsi_Disk * sdkp, int dsk_nr) { char diskname[40]; unsigned char *buffer; Scsi_Device *sdp; Scsi_Request *SRpnt; SCSI_LOG_HLQUEUE(3, printk("sd_init_onedisk: dsk_nr=%d\n", dsk_nr)); /* * Get the name of the disk, in case we need to log it somewhere. */ sd_dskname(dsk_nr, diskname); /* * If the device is offline, don't try and read capacity or any * of the other niceties. */ sdp = sdkp->device; if (sdp->online == FALSE) return; SRpnt = scsi_allocate_request(sdp); if (!SRpnt) { printk(KERN_WARNING "(sd_init_onedisk:) Request allocation " "failure.\n"); return; } buffer = kmalloc(512, GFP_DMA); if (!buffer) { printk(KERN_WARNING "(sd_init_onedisk:) Memory allocation " "failure.\n"); goto leave; } /* defaults, until the device tells us otherwise */ sdkp->capacity = 0; sdkp->device->sector_size = 512; sdkp->media_present = 1; sdkp->write_prot = 0; sd_spinup_disk(sdkp, diskname, SRpnt, buffer); if (sdkp->media_present) sd_read_capacity(sdkp, diskname, SRpnt, buffer); if (sdp->removable && sdkp->media_present) sd_read_write_protect_flag(sdkp, diskname, SRpnt, buffer); SRpnt->sr_device->ten = 1; SRpnt->sr_device->remap = 1; leave: scsi_release_request(SRpnt); kfree(buffer); } /* * The sd_init() function looks at all SCSI drives present, determines * their size, and reads partition table entries for them. */ static int sd_registered; /** * sd_init- called during driver initialization (after * sd_detect() is called for each scsi device present). * * Returns 0 is successful (or already called); 1 if error * * Note: this function is invoked from the scsi mid-level. **/ static int sd_init() { int k, maxparts; Scsi_Disk * sdkp; SCSI_LOG_HLQUEUE(3, printk("sd_init: dev_noticed=%d\n", sd_template.dev_noticed)); if (sd_template.dev_noticed == 0) return 0; if (NULL == sd_dsk_arr) 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; /* At most 16 partitions on each scsi disk. */ maxparts = (sd_template.dev_max << 4); if (maxparts == 0) return 0; if (!sd_registered) { for (k = 0; k < N_USED_SD_MAJORS; k++) { if (register_blkdev(SD_MAJOR(k), "sd", &sd_fops)) { printk(KERN_NOTICE "Unable to get major %d " "for SCSI disk\n", SD_MAJOR(k)); return 1; } } sd_registered++; } /* We do not support attaching loadable devices yet. */ if (sd_dsk_arr) return 0; /* allocate memory */ #define init_mem_lth(x,n) x = vmalloc((n) * sizeof(*x)) #define zero_mem_lth(x,n) memset(x, 0, (n) * sizeof(*x)) init_mem_lth(sd_dsk_arr, sd_template.dev_max); if (sd_dsk_arr) { zero_mem_lth(sd_dsk_arr, sd_template.dev_max); for (k = 0; k < sd_template.dev_max; ++k) { sdkp = vmalloc(sizeof(Scsi_Disk)); if (NULL == sdkp) goto cleanup_mem; memset(sdkp, 0, sizeof(Scsi_Disk)); sd_dsk_arr[k] = sdkp; } } init_mem_lth(sd_disks, sd_template.dev_max); if (sd_disks) zero_mem_lth(sd_disks, sd_template.dev_max); init_mem_lth(sd, maxparts); if (!sd_dsk_arr || !sd || !sd_disks) goto cleanup_mem; zero_mem_lth(sd, maxparts); return 0; #undef init_mem_lth #undef zero_mem_lth cleanup_mem: vfree(sd_disks); sd_disks = NULL; vfree(sd); sd = NULL; if (sd_dsk_arr) { for (k = 0; k < sd_template.dev_max; ++k) vfree(sd_dsk_arr[k]); vfree(sd_dsk_arr); sd_dsk_arr = NULL; } for (k = 0; k < N_USED_SD_MAJORS; k++) { unregister_blkdev(SD_MAJOR(k), "sd"); } sd_registered--; return 1; } /** * sd_finish - called during driver initialization, after all * the sd_attach() calls are finished. * * Note: this function is invoked from the scsi mid-level. * This function is not called after driver initialization has completed. * Specifically later device attachments invoke sd_attach() but not * this function. **/ static void sd_finish() { int k; Scsi_Disk * sdkp; SCSI_LOG_HLQUEUE(3, printk("sd_finish: \n")); for (k = 0; k < N_USED_SD_MAJORS; k++) blk_dev[SD_MAJOR(k)].queue = sd_find_queue; for (k = 0; k < sd_template.dev_max; ++k) { sdkp = sd_get_sdisk(k); if (sdkp && (0 == sdkp->capacity) && sdkp->device) { sd_init_onedisk(sdkp, k); if (!sdkp->has_been_registered) { add_gendisk(sd_disks[k]); register_disk(sd_disks[k], MKDEV_SD(k), 1<<4, &sd_fops, sdkp->capacity); sdkp->has_been_registered = 1; } } } return; } /** * sd_detect - called at the start of driver initialization, once * for each scsi device (not just disks) present. * * Returns 0 if not interested in this scsi device (e.g. scanner); * 1 if this device is of interest (e.g. a disk). * * Note: this function is invoked from the scsi mid-level. * This function is called before sd_init() so very little is available. **/ static int sd_detect(Scsi_Device * sdp) { SCSI_LOG_HLQUEUE(3, printk("sd_detect: type=%d\n", sdp->type)); if (sdp->type != TYPE_DISK && sdp->type != TYPE_MOD) return 0; sd_template.dev_noticed++; return 1; } /** * sd_attach - called during driver initialization and whenever a * new scsi device is attached to the system. It is called once * for each scsi device (not just disks) present. * @sdp: pointer to mid level scsi device object * * Returns 0 if successful (or not interested in this scsi device * (e.g. scanner)); 1 when there is an error. * * Note: this function is invoked from the scsi mid-level. * This function sets up the mapping between a given * <host,channel,id,lun> (found in sdp) and new device name * (e.g. /dev/sda). More precisely it is the block device major * and minor number that is chosen here. **/ static int sd_attach(Scsi_Device * sdp) { Scsi_Disk *sdkp; int dsk_nr; char diskname[6]; unsigned long iflags; struct { struct gendisk disk; char name[5]; } *p; struct gendisk *gd; if ((NULL == sdp) || ((sdp->type != TYPE_DISK) && (sdp->type != TYPE_MOD))) return 0; p = kmalloc(sizeof(*p), GFP_KERNEL); if (!p) return 1; gd = &p->disk; SCSI_LOG_HLQUEUE(3, printk("sd_attach: scsi device: <%d,%d,%d,%d>\n", sdp->host->host_no, sdp->channel, sdp->id, sdp->lun)); if (sd_template.nr_dev >= sd_template.dev_max) { sdp->attached--; printk(KERN_ERR "sd_init: no more room for device\n"); kfree(p); return 1; } /* Assume sd_attach is not re-entrant (for time being) */ /* Also think about sd_attach() and sd_detach() running coincidentally. */ write_lock_irqsave(&sd_dsk_arr_lock, iflags); for (dsk_nr = 0; dsk_nr < sd_template.dev_max; dsk_nr++) { sdkp = sd_dsk_arr[dsk_nr]; if (!sdkp->device) { memset(sdkp, 0, sizeof(Scsi_Disk)); sdkp->device = sdp; break; } } write_unlock_irqrestore(&sd_dsk_arr_lock, iflags); if (dsk_nr >= sd_template.dev_max) { /* panic("scsi_devices corrupt (sd)"); overkill */ printk(KERN_ERR "sd_init: sd_dsk_arr corrupted\n"); kfree(p); return 1; } sd_template.nr_dev++; gd->de = sdp->de; gd->major = SD_MAJOR(dsk_nr>>4); gd->first_minor = (dsk_nr & 15)<<4; gd->minor_shift = 4; gd->part = sd + (dsk_nr << 4); gd->fops = &sd_fops; if (dsk_nr > 26) sprintf(p->name, "sd%c%c", 'a'+dsk_nr/26-1, 'a'+dsk_nr%26); else sprintf(p->name, "sd%c", 'a'+dsk_nr%26); gd->major_name = p->name; gd->flags = sdp->removable ? GENHD_FL_REMOVABLE : 0; gd->driverfs_dev = &sdp->sdev_driverfs_dev; gd->flags |= GENHD_FL_DRIVERFS | GENHD_FL_DEVFS; sd_disks[dsk_nr] = gd; sd_dskname(dsk_nr, diskname); printk(KERN_NOTICE "Attached scsi %sdisk %s at scsi%d, channel %d, " "id %d, lun %d\n", sdp->removable ? "removable " : "", diskname, sdp->host->host_no, sdp->channel, sdp->id, sdp->lun); return 0; } static int sd_revalidate(kdev_t dev) { int dsk_nr = DEVICE_NR(dev); Scsi_Disk * sdkp = sd_get_sdisk(dsk_nr); if (!sdkp || !sdkp->device) return -ENODEV; sd_init_onedisk(sdkp, dsk_nr); set_capacity(sd_disks[dsk_nr], sdkp->capacity); return 0; } /** * sd_detach - called whenever a scsi disk (previously recognized by * sd_attach) is detached from the system. It is called (potentially * multiple times) during sd module unload. * @sdp: pointer to mid level scsi device object * * Note: this function is invoked from the scsi mid-level. * This function potentially frees up a device name (e.g. /dev/sdc) * that could be re-used by a subsequent sd_attach(). * This function is not called when the built-in sd driver is "exit-ed". **/ static void sd_detach(Scsi_Device * sdp) { Scsi_Disk *sdkp = NULL; kdev_t dev; int dsk_nr; unsigned long iflags; SCSI_LOG_HLQUEUE(3, printk("sd_detach: <%d,%d,%d,%d>\n", sdp->host->host_no, sdp->channel, sdp->id, sdp->lun)); write_lock_irqsave(&sd_dsk_arr_lock, iflags); for (dsk_nr = 0; dsk_nr < sd_template.dev_max; dsk_nr++) { sdkp = sd_dsk_arr[dsk_nr]; if (sdkp->device == sdp) { sdkp->device = NULL; sdkp->capacity = 0; /* sdkp->detaching = 1; */ break; } } write_unlock_irqrestore(&sd_dsk_arr_lock, iflags); if (dsk_nr >= sd_template.dev_max) return; if (sdkp->has_been_registered) { sdkp->has_been_registered = 0; dev = MKDEV_SD(dsk_nr); del_gendisk(sd_disks[dsk_nr]); } sdp->attached--; sd_template.dev_noticed--; sd_template.nr_dev--; kfree(sd_disks[dsk_nr]); sd_disks[dsk_nr] = NULL; } /** * init_sd - entry point for this driver (both when built in or when * a module). * * Note: this function registers this driver with the scsi mid-level. **/ static int __init init_sd(void) { int rc; SCSI_LOG_HLQUEUE(3, printk("init_sd: sd driver entry point\n")); sd_template.module = THIS_MODULE; rc = scsi_register_device(&sd_template); if (!rc) { sd_template.scsi_driverfs_driver.name = (char *)sd_template.tag; sd_template.scsi_driverfs_driver.bus = &scsi_driverfs_bus_type; driver_register(&sd_template.scsi_driverfs_driver); } return rc; } /** * exit_sd - exit point for this driver (when it is a module). * * Note: this function unregisters this driver from the scsi mid-level. **/ static void __exit exit_sd(void) { int k; SCSI_LOG_HLQUEUE(3, printk("exit_sd: exiting sd driver\n")); scsi_unregister_device(&sd_template); for (k = 0; k < N_USED_SD_MAJORS; k++) unregister_blkdev(SD_MAJOR(k), "sd"); sd_registered--; if (sd_dsk_arr != NULL) { for (k = 0; k < sd_template.dev_max; ++k) vfree(sd_dsk_arr[k]); vfree(sd_dsk_arr); } vfree((char *) sd); for (k = 0; k < N_USED_SD_MAJORS; k++) { blk_dev[SD_MAJOR(k)].queue = NULL; blk_clear(SD_MAJOR(k)); } sd_template.dev_max = 0; remove_driver(&sd_template.scsi_driverfs_driver); } static Scsi_Disk * sd_get_sdisk(int index) { Scsi_Disk * sdkp = NULL; unsigned long iflags; read_lock_irqsave(&sd_dsk_arr_lock, iflags); if (sd_dsk_arr && (index >= 0) && (index < sd_template.dev_max)) sdkp = sd_dsk_arr[index]; read_unlock_irqrestore(&sd_dsk_arr_lock, iflags); return sdkp; } MODULE_LICENSE("GPL"); MODULE_AUTHOR("Eric Youngdale"); MODULE_DESCRIPTION("SCSI disk (sd) driver"); module_init(init_sd); module_exit(exit_sd);