/** * 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(struct scsi_cmnd * SCpnt) { unsigned int this_count, timeout; struct gendisk *disk; sector_t block; struct scsi_device *sdp = SCpnt->device; timeout = sdp->timeout; /* * these are already setup, just copy cdb basically */ if (SCpnt->request->flags & REQ_BLOCK_PC) { struct request *rq = SCpnt->request; if (sizeof(rq->cmd) > sizeof(SCpnt->cmnd)) return 0; memcpy(SCpnt->cmnd, rq->cmd, sizeof(SCpnt->cmnd)); if (rq_data_dir(rq) == WRITE) SCpnt->sc_data_direction = DMA_TO_DEVICE; else if (rq->data_len) SCpnt->sc_data_direction = DMA_FROM_DEVICE; else SCpnt->sc_data_direction = DMA_NONE; this_count = rq->data_len; if (rq->timeout) timeout = rq->timeout; SCpnt->transfersize = rq->data_len; goto queue; } /* * we only do REQ_CMD and REQ_BLOCK_PC */ if (!(SCpnt->request->flags & REQ_CMD)) return 0; disk = SCpnt->request->rq_disk; block = SCpnt->request->sector; this_count = SCpnt->request_bufflen >> 9; SCSI_LOG_HLQUEUE(1, printk("sd_init_command: disk=%s, block=%llu, " "count=%d\n", disk->disk_name, (unsigned long long)block, this_count)); if (!sdp || !scsi_device_online(sdp) || block + SCpnt->request->nr_sectors > get_capacity(disk)) { 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, printk("%s : block=%llu\n", disk->disk_name, (unsigned long long)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 = DMA_TO_DEVICE; } else if (rq_data_dir(SCpnt->request) == READ) { SCpnt->cmnd[0] = READ_6; SCpnt->sc_data_direction = DMA_FROM_DEVICE; } 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", disk->disk_name, (rq_data_dir(SCpnt->request) == WRITE) ? "writing" : "reading", this_count, SCpnt->request->nr_sectors)); SCpnt->cmnd[1] = 0; if (block > 0xffffffff) { SCpnt->cmnd[0] += READ_16 - READ_6; SCpnt->cmnd[2] = sizeof(block) > 4 ? (unsigned char) (block >> 56) & 0xff : 0; SCpnt->cmnd[3] = sizeof(block) > 4 ? (unsigned char) (block >> 48) & 0xff : 0; SCpnt->cmnd[4] = sizeof(block) > 4 ? (unsigned char) (block >> 40) & 0xff : 0; SCpnt->cmnd[5] = sizeof(block) > 4 ? (unsigned char) (block >> 32) & 0xff : 0; SCpnt->cmnd[6] = (unsigned char) (block >> 24) & 0xff; SCpnt->cmnd[7] = (unsigned char) (block >> 16) & 0xff; SCpnt->cmnd[8] = (unsigned char) (block >> 8) & 0xff; SCpnt->cmnd[9] = (unsigned char) block & 0xff; SCpnt->cmnd[10] = (unsigned char) (this_count >> 24) & 0xff; SCpnt->cmnd[11] = (unsigned char) (this_count >> 16) & 0xff; SCpnt->cmnd[12] = (unsigned char) (this_count >> 8) & 0xff; SCpnt->cmnd[13] = (unsigned char) this_count & 0xff; SCpnt->cmnd[14] = SCpnt->cmnd[15] = 0; } else if ((this_count > 0xff) || (block > 0x1fffff) ||
static int sd_init_command(Scsi_Cmnd * SCpnt) { int dev, block, this_count; struct hd_struct *ppnt; Scsi_Disk *dpnt; #if CONFIG_SCSI_LOGGING char nbuff[6]; #endif ppnt = &sd_gendisks[SD_MAJOR_IDX(SCpnt->request.rq_dev)].part[MINOR(SCpnt->request.rq_dev)]; dev = DEVICE_NR(SCpnt->request.rq_dev); block = SCpnt->request.sector; this_count = SCpnt->request_bufflen >> 9; SCSI_LOG_HLQUEUE(1, printk("Doing sd request, dev = 0x%x, block = %d\n", SCpnt->request.rq_dev, block)); dpnt = &rscsi_disks[dev]; if (dev >= sd_template.dev_max || !dpnt->device || !dpnt->device->online || block + SCpnt->request.nr_sectors > ppnt->nr_sects) { 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; } block += ppnt->start_sect; if (dpnt->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"); */ return 0; } SCSI_LOG_HLQUEUE(2, sd_devname(dev, 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 (dpnt->device->sector_size == 1024) { if ((block & 1) || (SCpnt->request.nr_sectors & 1)) { printk("sd.c:Bad block number requested"); return 0; } else { block = block >> 1; this_count = this_count >> 1; } } if (dpnt->device->sector_size == 2048) { if ((block & 3) || (SCpnt->request.nr_sectors & 3)) { printk("sd.c:Bad block number requested"); return 0; } else { block = block >> 2; this_count = this_count >> 2; } } if (dpnt->device->sector_size == 4096) { if ((block & 7) || (SCpnt->request.nr_sectors & 7)) { printk("sd.c:Bad block number requested"); return 0; } else { block = block >> 3; this_count = this_count >> 3; } } switch (SCpnt->request.cmd) { case WRITE: if (!dpnt->device->writeable) { return 0; } SCpnt->cmnd[0] = WRITE_6; SCpnt->sc_data_direction = SCSI_DATA_WRITE; break; case READ: SCpnt->cmnd[0] = READ_6; SCpnt->sc_data_direction = SCSI_DATA_READ; break; default: panic("Unknown sd command %d\n", SCpnt->request.cmd); } 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)); 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)