summaryrefslogtreecommitdiff
path: root/drivers/scsi
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi')
-rw-r--r--drivers/scsi/a100u2w.c49
-rw-r--r--drivers/scsi/aic94xx/aic94xx_sds.c12
-rw-r--r--drivers/scsi/aic94xx/aic94xx_sds.h4
-rw-r--r--drivers/scsi/aic94xx/aic94xx_seq.c7
-rw-r--r--drivers/scsi/ide-scsi.c302
-rw-r--r--drivers/scsi/sd.c5
6 files changed, 125 insertions, 254 deletions
diff --git a/drivers/scsi/a100u2w.c b/drivers/scsi/a100u2w.c
index ced3eeb..84bb616 100644
--- a/drivers/scsi/a100u2w.c
+++ b/drivers/scsi/a100u2w.c
@@ -389,7 +389,7 @@ static u8 orc_load_firmware(struct orc_host * host)
outb(PRGMRST | DOWNLOAD, host->base + ORC_RISCCTL); /* Enable SRAM programming */
data32_ptr = (u8 *) & data32;
- data32 = 0; /* Initial FW address to 0 */
+ data32 = cpu_to_le32(0); /* Initial FW address to 0 */
outw(0x0010, host->base + ORC_EBIOSADR0);
*data32_ptr = inb(host->base + ORC_EBIOSDATA); /* Read from BIOS */
outw(0x0011, host->base + ORC_EBIOSADR0);
@@ -397,18 +397,19 @@ static u8 orc_load_firmware(struct orc_host * host)
outw(0x0012, host->base + ORC_EBIOSADR0);
*(data32_ptr + 2) = inb(host->base + ORC_EBIOSDATA); /* Read from BIOS */
outw(*(data32_ptr + 2), host->base + ORC_EBIOSADR2);
- outl(data32, host->base + ORC_FWBASEADR); /* Write FW address */
+ outl(le32_to_cpu(data32), host->base + ORC_FWBASEADR); /* Write FW address */
/* Copy the code from the BIOS to the SRAM */
- bios_addr = (u16) data32; /* FW code locate at BIOS address + ? */
+ udelay(500); /* Required on Sun Ultra 5 ... 350 -> failures */
+ bios_addr = (u16) le32_to_cpu(data32); /* FW code locate at BIOS address + ? */
for (i = 0, data32_ptr = (u8 *) & data32; /* Download the code */
i < 0x1000; /* Firmware code size = 4K */
i++, bios_addr++) {
outw(bios_addr, host->base + ORC_EBIOSADR0);
*data32_ptr++ = inb(host->base + ORC_EBIOSDATA); /* Read from BIOS */
if ((i % 4) == 3) {
- outl(data32, host->base + ORC_RISCRAM); /* Write every 4 bytes */
+ outl(le32_to_cpu(data32), host->base + ORC_RISCRAM); /* Write every 4 bytes */
data32_ptr = (u8 *) & data32;
}
}
@@ -423,7 +424,7 @@ static u8 orc_load_firmware(struct orc_host * host)
outw(bios_addr, host->base + ORC_EBIOSADR0);
*data32_ptr++ = inb(host->base + ORC_EBIOSDATA); /* Read from BIOS */
if ((i % 4) == 3) {
- if (inl(host->base + ORC_RISCRAM) != data32) {
+ if (inl(host->base + ORC_RISCRAM) != le32_to_cpu(data32)) {
outb(PRGMRST, host->base + ORC_RISCCTL); /* Reset program to 0 */
outb(data, host->base + ORC_GCFG); /*Disable EEPROM programming */
return 0;
@@ -459,8 +460,8 @@ static void setup_SCBs(struct orc_host * host)
for (i = 0; i < ORC_MAXQUEUE; i++) {
escb_phys = (host->escb_phys + (sizeof(struct orc_extended_scb) * i));
- scb->sg_addr = (u32) escb_phys;
- scb->sense_addr = (u32) escb_phys;
+ scb->sg_addr = cpu_to_le32((u32) escb_phys);
+ scb->sense_addr = cpu_to_le32((u32) escb_phys);
scb->escb = escb;
scb->scbidx = i;
scb++;
@@ -642,8 +643,8 @@ static int orc_device_reset(struct orc_host * host, struct scsi_cmnd *cmd, unsig
scb->link = 0xFF;
scb->reserved0 = 0;
scb->reserved1 = 0;
- scb->xferlen = 0;
- scb->sg_len = 0;
+ scb->xferlen = cpu_to_le32(0);
+ scb->sg_len = cpu_to_le32(0);
escb->srb = NULL;
escb->srb = cmd;
@@ -839,7 +840,7 @@ static irqreturn_t orc_interrupt(struct orc_host * host)
* Build a host adapter control block from the SCSI mid layer command
*/
-static void inia100_build_scb(struct orc_host * host, struct orc_scb * scb, struct scsi_cmnd * cmd)
+static int inia100_build_scb(struct orc_host * host, struct orc_scb * scb, struct scsi_cmnd * cmd)
{ /* Create corresponding SCB */
struct scatterlist *sg;
struct orc_sgent *sgent; /* Pointer to SG list */
@@ -858,28 +859,30 @@ static void inia100_build_scb(struct orc_host * host, struct orc_scb * scb, stru
scb->lun = cmd->device->lun;
scb->reserved0 = 0;
scb->reserved1 = 0;
- scb->sg_len = 0;
+ scb->sg_len = cpu_to_le32(0);
- scb->xferlen = (u32) scsi_bufflen(cmd);
+ scb->xferlen = cpu_to_le32((u32) scsi_bufflen(cmd));
sgent = (struct orc_sgent *) & escb->sglist[0];
count_sg = scsi_dma_map(cmd);
- BUG_ON(count_sg < 0);
+ if (count_sg < 0)
+ return count_sg;
+ BUG_ON(count_sg > TOTAL_SG_ENTRY);
/* Build the scatter gather lists */
if (count_sg) {
- scb->sg_len = (u32) (count_sg * 8);
+ scb->sg_len = cpu_to_le32((u32) (count_sg * 8));
scsi_for_each_sg(cmd, sg, count_sg, i) {
- sgent->base = (u32) sg_dma_address(sg);
- sgent->length = (u32) sg_dma_len(sg);
+ sgent->base = cpu_to_le32((u32) sg_dma_address(sg));
+ sgent->length = cpu_to_le32((u32) sg_dma_len(sg));
sgent++;
}
} else {
- scb->sg_len = 0;
- sgent->base = 0;
- sgent->length = 0;
+ scb->sg_len = cpu_to_le32(0);
+ sgent->base = cpu_to_le32(0);
+ sgent->length = cpu_to_le32(0);
}
- scb->sg_addr = (u32) scb->sense_addr;
+ scb->sg_addr = (u32) scb->sense_addr; /* sense_addr is already little endian */
scb->hastat = 0;
scb->tastat = 0;
scb->link = 0xFF;
@@ -896,6 +899,7 @@ static void inia100_build_scb(struct orc_host * host, struct orc_scb * scb, stru
scb->tag_msg = 0; /* No tag support */
}
memcpy(scb->cdb, cmd->cmnd, scb->cdb_len);
+ return 0;
}
/**
@@ -919,7 +923,10 @@ static int inia100_queue(struct scsi_cmnd * cmd, void (*done) (struct scsi_cmnd
if ((scb = orc_alloc_scb(host)) == NULL)
return SCSI_MLQUEUE_HOST_BUSY;
- inia100_build_scb(host, scb, cmd);
+ if (inia100_build_scb(host, scb, cmd)) {
+ orc_release_scb(host, scb);
+ return SCSI_MLQUEUE_HOST_BUSY;
+ }
orc_exec_scb(host, scb); /* Start execute SCB */
return 0;
}
diff --git a/drivers/scsi/aic94xx/aic94xx_sds.c b/drivers/scsi/aic94xx/aic94xx_sds.c
index 4446e3d..8630a75 100644
--- a/drivers/scsi/aic94xx/aic94xx_sds.c
+++ b/drivers/scsi/aic94xx/aic94xx_sds.c
@@ -1093,9 +1093,9 @@ out:
* @bytes_to_verify: total bytes to verify
*/
int asd_verify_flash_seg(struct asd_ha_struct *asd_ha,
- void *src, u32 dest_offset, u32 bytes_to_verify)
+ const void *src, u32 dest_offset, u32 bytes_to_verify)
{
- u8 *src_buf;
+ const u8 *src_buf;
u8 flash_char;
int err;
u32 nv_offset, reg, i;
@@ -1105,7 +1105,7 @@ int asd_verify_flash_seg(struct asd_ha_struct *asd_ha,
err = FLASH_OK;
nv_offset = dest_offset;
- src_buf = (u8 *)src;
+ src_buf = (const u8 *)src;
for (i = 0; i < bytes_to_verify; i++) {
flash_char = asd_read_reg_byte(asd_ha, reg + nv_offset + i);
if (flash_char != src_buf[i]) {
@@ -1124,9 +1124,9 @@ int asd_verify_flash_seg(struct asd_ha_struct *asd_ha,
* @bytes_to_write: total bytes to write
*/
int asd_write_flash_seg(struct asd_ha_struct *asd_ha,
- void *src, u32 dest_offset, u32 bytes_to_write)
+ const void *src, u32 dest_offset, u32 bytes_to_write)
{
- u8 *src_buf;
+ const u8 *src_buf;
u32 nv_offset, reg, i;
int err;
@@ -1153,7 +1153,7 @@ int asd_write_flash_seg(struct asd_ha_struct *asd_ha,
return err;
}
- src_buf = (u8 *)src;
+ src_buf = (const u8 *)src;
for (i = 0; i < bytes_to_write; i++) {
/* Setup program command sequence */
switch (asd_ha->hw_prof.flash.method) {
diff --git a/drivers/scsi/aic94xx/aic94xx_sds.h b/drivers/scsi/aic94xx/aic94xx_sds.h
index bb9795a..a06dc01 100644
--- a/drivers/scsi/aic94xx/aic94xx_sds.h
+++ b/drivers/scsi/aic94xx/aic94xx_sds.h
@@ -110,9 +110,9 @@ struct bios_file_header {
};
int asd_verify_flash_seg(struct asd_ha_struct *asd_ha,
- void *src, u32 dest_offset, u32 bytes_to_verify);
+ const void *src, u32 dest_offset, u32 bytes_to_verify);
int asd_write_flash_seg(struct asd_ha_struct *asd_ha,
- void *src, u32 dest_offset, u32 bytes_to_write);
+ const void *src, u32 dest_offset, u32 bytes_to_write);
int asd_chk_write_status(struct asd_ha_struct *asd_ha,
u32 sector_addr, u8 erase_flag);
int asd_check_flash_type(struct asd_ha_struct *asd_ha);
diff --git a/drivers/scsi/aic94xx/aic94xx_seq.c b/drivers/scsi/aic94xx/aic94xx_seq.c
index f4272ac..8f98e33 100644
--- a/drivers/scsi/aic94xx/aic94xx_seq.c
+++ b/drivers/scsi/aic94xx/aic94xx_seq.c
@@ -46,7 +46,7 @@
static const struct firmware *sequencer_fw;
static u16 cseq_vecs[CSEQ_NUM_VECS], lseq_vecs[LSEQ_NUM_VECS], mode2_task,
cseq_idle_loop, lseq_idle_loop;
-static u8 *cseq_code, *lseq_code;
+static const u8 *cseq_code, *lseq_code;
static u32 cseq_code_size, lseq_code_size;
static u16 first_scb_site_no = 0xFFFF;
@@ -1235,7 +1235,8 @@ int asd_release_firmware(void)
static int asd_request_firmware(struct asd_ha_struct *asd_ha)
{
int err, i;
- struct sequencer_file_header header, *hdr_ptr;
+ struct sequencer_file_header header;
+ const struct sequencer_file_header *hdr_ptr;
u32 csum = 0;
u16 *ptr_cseq_vecs, *ptr_lseq_vecs;
@@ -1249,7 +1250,7 @@ static int asd_request_firmware(struct asd_ha_struct *asd_ha)
if (err)
return err;
- hdr_ptr = (struct sequencer_file_header *)sequencer_fw->data;
+ hdr_ptr = (const struct sequencer_file_header *)sequencer_fw->data;
header.csum = le32_to_cpu(hdr_ptr->csum);
header.major = le32_to_cpu(hdr_ptr->major);
diff --git a/drivers/scsi/ide-scsi.c b/drivers/scsi/ide-scsi.c
index 44d8d51..683bce3 100644
--- a/drivers/scsi/ide-scsi.c
+++ b/drivers/scsi/ide-scsi.c
@@ -60,6 +60,13 @@
#define IDESCSI_DEBUG_LOG 0
+#if IDESCSI_DEBUG_LOG
+#define debug_log(fmt, args...) \
+ printk(KERN_INFO "ide-scsi: " fmt, ## args)
+#else
+#define debug_log(fmt, args...) do {} while (0)
+#endif
+
/*
* SCSI command transformation layer
*/
@@ -129,14 +136,15 @@ static inline idescsi_scsi_t *drive_to_idescsi(ide_drive_t *ide_drive)
#define IDESCSI_PC_RQ 90
/*
- * PIO data transfer routines using the scatter gather table.
+ * PIO data transfer routine using the scatter gather table.
*/
-static void idescsi_input_buffers(ide_drive_t *drive, struct ide_atapi_pc *pc,
- unsigned int bcount)
+static void ide_scsi_io_buffers(ide_drive_t *drive, struct ide_atapi_pc *pc,
+ unsigned int bcount, int write)
{
ide_hwif_t *hwif = drive->hwif;
- int count;
+ xfer_func_t *xf = write ? hwif->output_data : hwif->input_data;
char *buf;
+ int count;
while (bcount) {
count = min(pc->sg->length - pc->b_count, bcount);
@@ -145,13 +153,13 @@ static void idescsi_input_buffers(ide_drive_t *drive, struct ide_atapi_pc *pc,
local_irq_save(flags);
buf = kmap_atomic(sg_page(pc->sg), KM_IRQ0) +
- pc->sg->offset;
- hwif->input_data(drive, NULL, buf + pc->b_count, count);
+ pc->sg->offset;
+ xf(drive, NULL, buf + pc->b_count, count);
kunmap_atomic(buf - pc->sg->offset, KM_IRQ0);
local_irq_restore(flags);
} else {
buf = sg_virt(pc->sg);
- hwif->input_data(drive, NULL, buf + pc->b_count, count);
+ xf(drive, NULL, buf + pc->b_count, count);
}
bcount -= count; pc->b_count += count;
if (pc->b_count == pc->sg->length) {
@@ -163,51 +171,34 @@ static void idescsi_input_buffers(ide_drive_t *drive, struct ide_atapi_pc *pc,
}
if (bcount) {
- printk (KERN_ERR "ide-scsi: scatter gather table too small, discarding data\n");
- ide_pad_transfer(drive, 0, bcount);
+ printk(KERN_ERR "%s: scatter gather table too small, %s\n",
+ drive->name, write ? "padding with zeros"
+ : "discarding data");
+ ide_pad_transfer(drive, write, bcount);
}
}
-static void idescsi_output_buffers(ide_drive_t *drive, struct ide_atapi_pc *pc,
- unsigned int bcount)
+static void ide_scsi_hex_dump(u8 *data, int len)
{
- ide_hwif_t *hwif = drive->hwif;
- int count;
- char *buf;
+ print_hex_dump(KERN_CONT, "", DUMP_PREFIX_NONE, 16, 1, data, len, 0);
+}
- while (bcount) {
- count = min(pc->sg->length - pc->b_count, bcount);
- if (PageHighMem(sg_page(pc->sg))) {
- unsigned long flags;
+static int idescsi_end_request(ide_drive_t *, int, int);
- local_irq_save(flags);
- buf = kmap_atomic(sg_page(pc->sg), KM_IRQ0) +
- pc->sg->offset;
- hwif->output_data(drive, NULL, buf + pc->b_count, count);
- kunmap_atomic(buf - pc->sg->offset, KM_IRQ0);
- local_irq_restore(flags);
- } else {
- buf = sg_virt(pc->sg);
- hwif->output_data(drive, NULL, buf + pc->b_count, count);
- }
- bcount -= count; pc->b_count += count;
- if (pc->b_count == pc->sg->length) {
- if (!--pc->sg_cnt)
- break;
- pc->sg = sg_next(pc->sg);
- pc->b_count = 0;
- }
- }
+static void ide_scsi_callback(ide_drive_t *drive)
+{
+ idescsi_scsi_t *scsi = drive_to_idescsi(drive);
+ struct ide_atapi_pc *pc = scsi->pc;
- if (bcount) {
- printk (KERN_ERR "ide-scsi: scatter gather table too small, padding with zeros\n");
- ide_pad_transfer(drive, 1, bcount);
- }
-}
+ if (pc->flags & PC_FLAG_TIMEDOUT)
+ debug_log("%s: got timed out packet %lu at %lu\n", __func__,
+ pc->scsi_cmd->serial_number, jiffies);
+ /* end this request now - scsi should retry it*/
+ else if (test_bit(IDESCSI_LOG_CMD, &scsi->log))
+ printk(KERN_INFO "Packet command completed, %d bytes"
+ " transferred\n", pc->xferred);
-static void ide_scsi_hex_dump(u8 *data, int len)
-{
- print_hex_dump(KERN_CONT, "", DUMP_PREFIX_NONE, 16, 1, data, len, 0);
+ idescsi_end_request(drive, 1, 0);
}
static int idescsi_check_condition(ide_drive_t *drive,
@@ -228,14 +219,16 @@ static int idescsi_check_condition(ide_drive_t *drive,
kfree(pc);
return -ENOMEM;
}
- ide_init_drive_cmd(rq);
+ blk_rq_init(NULL, rq);
rq->special = (char *) pc;
pc->rq = rq;
pc->buf = buf;
pc->c[0] = REQUEST_SENSE;
pc->c[4] = pc->req_xfer = pc->buf_size = SCSI_SENSE_BUFFERSIZE;
rq->cmd_type = REQ_TYPE_SENSE;
+ rq->cmd_flags |= REQ_PREEMPT;
pc->timeout = jiffies + WAIT_READY;
+ pc->callback = ide_scsi_callback;
/* NOTE! Save the failed packet command in "rq->buffer" */
rq->buffer = (void *) failed_cmd->special;
pc->scsi_cmd = ((struct ide_atapi_pc *) failed_cmd->special)->scsi_cmd;
@@ -244,11 +237,10 @@ static int idescsi_check_condition(ide_drive_t *drive,
ide_scsi_hex_dump(pc->c, 6);
}
rq->rq_disk = scsi->disk;
- return ide_do_drive_cmd(drive, rq, ide_preempt);
+ ide_do_drive_cmd(drive, rq);
+ return 0;
}
-static int idescsi_end_request(ide_drive_t *, int, int);
-
static ide_startstop_t
idescsi_atapi_error(ide_drive_t *drive, struct request *rq, u8 stat, u8 err)
{
@@ -256,7 +248,7 @@ idescsi_atapi_error(ide_drive_t *drive, struct request *rq, u8 stat, u8 err)
if (ide_read_status(drive) & (BUSY_STAT | DRQ_STAT))
/* force an abort */
- hwif->OUTBSYNC(drive, WIN_IDLEIMMEDIATE,
+ hwif->OUTBSYNC(hwif, WIN_IDLEIMMEDIATE,
hwif->io_ports.command_addr);
rq->errors++;
@@ -269,10 +261,9 @@ idescsi_atapi_error(ide_drive_t *drive, struct request *rq, u8 stat, u8 err)
static ide_startstop_t
idescsi_atapi_abort(ide_drive_t *drive, struct request *rq)
{
-#if IDESCSI_DEBUG_LOG
- printk(KERN_WARNING "idescsi_atapi_abort called for %lu\n",
+ debug_log("%s called for %lu\n", __func__,
((struct ide_atapi_pc *) rq->special)->scsi_cmd->serial_number);
-#endif
+
rq->errors |= ERROR_MAX;
idescsi_end_request(drive, 0, 0);
@@ -351,9 +342,9 @@ static int idescsi_expiry(ide_drive_t *drive)
idescsi_scsi_t *scsi = drive_to_idescsi(drive);
struct ide_atapi_pc *pc = scsi->pc;
-#if IDESCSI_DEBUG_LOG
- printk(KERN_WARNING "idescsi_expiry called for %lu at %lu\n", pc->scsi_cmd->serial_number, jiffies);
-#endif
+ debug_log("%s called for %lu at %lu\n", __func__,
+ pc->scsi_cmd->serial_number, jiffies);
+
pc->flags |= PC_FLAG_TIMEDOUT;
return 0; /* we do not want the ide subsystem to retry */
@@ -365,141 +356,19 @@ static int idescsi_expiry(ide_drive_t *drive)
static ide_startstop_t idescsi_pc_intr (ide_drive_t *drive)
{
idescsi_scsi_t *scsi = drive_to_idescsi(drive);
- ide_hwif_t *hwif = drive->hwif;
struct ide_atapi_pc *pc = scsi->pc;
- struct request *rq = pc->rq;
- unsigned int temp;
- u16 bcount;
- u8 stat, ireason;
-
-#if IDESCSI_DEBUG_LOG
- printk (KERN_INFO "ide-scsi: Reached idescsi_pc_intr interrupt handler\n");
-#endif /* IDESCSI_DEBUG_LOG */
-
- if (pc->flags & PC_FLAG_TIMEDOUT) {
-#if IDESCSI_DEBUG_LOG
- printk(KERN_WARNING "idescsi_pc_intr: got timed out packet %lu at %lu\n",
- pc->scsi_cmd->serial_number, jiffies);
-#endif
- /* end this request now - scsi should retry it*/
- idescsi_end_request (drive, 1, 0);
- return ide_stopped;
- }
- if (pc->flags & PC_FLAG_DMA_IN_PROGRESS) {
- pc->flags &= ~PC_FLAG_DMA_IN_PROGRESS;
-#if IDESCSI_DEBUG_LOG
- printk ("ide-scsi: %s: DMA complete\n", drive->name);
-#endif /* IDESCSI_DEBUG_LOG */
- pc->xferred = pc->req_xfer;
- (void)hwif->dma_ops->dma_end(drive);
- }
-
- /* Clear the interrupt */
- stat = ide_read_status(drive);
-
- if ((stat & DRQ_STAT) == 0) {
- /* No more interrupts */
- if (test_bit(IDESCSI_LOG_CMD, &scsi->log))
- printk(KERN_INFO "Packet command completed, %d bytes"
- " transferred\n", pc->xferred);
- local_irq_enable_in_hardirq();
- if (stat & ERR_STAT)
- rq->errors++;
- idescsi_end_request (drive, 1, 0);
- return ide_stopped;
- }
- bcount = (hwif->INB(hwif->io_ports.lbah_addr) << 8) |
- hwif->INB(hwif->io_ports.lbam_addr);
- ireason = hwif->INB(hwif->io_ports.nsect_addr);
-
- if (ireason & CD) {
- printk(KERN_ERR "ide-scsi: CoD != 0 in idescsi_pc_intr\n");
- return ide_do_reset (drive);
- }
- if (ireason & IO) {
- temp = pc->xferred + bcount;
- if (temp > pc->req_xfer) {
- if (temp > pc->buf_size) {
- printk(KERN_ERR "ide-scsi: The scsi wants to "
- "send us more data than expected "
- "- discarding data\n");
- temp = pc->buf_size - pc->xferred;
- if (temp) {
- pc->flags &= ~PC_FLAG_WRITING;
- if (pc->sg)
- idescsi_input_buffers(drive, pc,
- temp);
- else
- hwif->input_data(drive, NULL,
- pc->cur_pos, temp);
- printk(KERN_ERR "ide-scsi: transferred"
- " %d of %d bytes\n",
- temp, bcount);
- }
- pc->xferred += temp;
- pc->cur_pos += temp;
- ide_pad_transfer(drive, 0, bcount - temp);
- ide_set_handler(drive, &idescsi_pc_intr, get_timeout(pc), idescsi_expiry);
- return ide_started;
- }
-#if IDESCSI_DEBUG_LOG
- printk (KERN_NOTICE "ide-scsi: The scsi wants to send us more data than expected - allowing transfer\n");
-#endif /* IDESCSI_DEBUG_LOG */
- }
- }
- if (ireason & IO) {
- pc->flags &= ~PC_FLAG_WRITING;
- if (pc->sg)
- idescsi_input_buffers(drive, pc, bcount);
- else
- hwif->input_data(drive, NULL, pc->cur_pos, bcount);
- } else {
- pc->flags |= PC_FLAG_WRITING;
- if (pc->sg)
- idescsi_output_buffers(drive, pc, bcount);
- else
- hwif->output_data(drive, NULL, pc->cur_pos, bcount);
- }
- /* Update the current position */
- pc->xferred += bcount;
- pc->cur_pos += bcount;
- /* And set the interrupt handler again */
- ide_set_handler(drive, &idescsi_pc_intr, get_timeout(pc), idescsi_expiry);
- return ide_started;
+ return ide_pc_intr(drive, pc, idescsi_pc_intr, get_timeout(pc),
+ idescsi_expiry, NULL, NULL, NULL,
+ ide_scsi_io_buffers);
}
static ide_startstop_t idescsi_transfer_pc(ide_drive_t *drive)
{
- ide_hwif_t *hwif = drive->hwif;
idescsi_scsi_t *scsi = drive_to_idescsi(drive);
- struct ide_atapi_pc *pc = scsi->pc;
- ide_startstop_t startstop;
- u8 ireason;
- if (ide_wait_stat(&startstop,drive,DRQ_STAT,BUSY_STAT,WAIT_READY)) {
- printk(KERN_ERR "ide-scsi: Strange, packet command "
- "initiated yet DRQ isn't asserted\n");
- return startstop;
- }
- ireason = hwif->INB(hwif->io_ports.nsect_addr);
- if ((ireason & CD) == 0 || (ireason & IO)) {
- printk(KERN_ERR "ide-scsi: (IO,CoD) != (0,1) while "
- "issuing a packet command\n");
- return ide_do_reset (drive);
- }
- BUG_ON(HWGROUP(drive)->handler != NULL);
- /* Set the interrupt routine */
- ide_set_handler(drive, &idescsi_pc_intr, get_timeout(pc), idescsi_expiry);
-
- /* Send the actual packet */
- hwif->output_data(drive, NULL, scsi->pc->c, 12);
-
- if (pc->flags & PC_FLAG_DMA_OK) {
- pc->flags |= PC_FLAG_DMA_IN_PROGRESS;
- hwif->dma_ops->dma_start(drive);
- }
- return ide_started;
+ return ide_transfer_pc(drive, scsi->pc, idescsi_pc_intr,
+ get_timeout(scsi->pc), idescsi_expiry);
}
static inline int idescsi_set_direction(struct ide_atapi_pc *pc)
@@ -545,38 +414,12 @@ static ide_startstop_t idescsi_issue_pc(ide_drive_t *drive,
struct ide_atapi_pc *pc)
{
idescsi_scsi_t *scsi = drive_to_idescsi(drive);
- ide_hwif_t *hwif = drive->hwif;
- u16 bcount;
- u8 dma = 0;
/* Set the current packet command */
scsi->pc = pc;
- /* We haven't transferred any data yet */
- pc->xferred = 0;
- pc->cur_pos = pc->buf;
- /* Request to transfer the entire buffer at once */
- bcount = min(pc->req_xfer, 63 * 1024);
-
- if (drive->using_dma && !idescsi_map_sg(drive, pc)) {
- hwif->sg_mapped = 1;
- dma = !hwif->dma_ops->dma_setup(drive);
- hwif->sg_mapped = 0;
- }
-
- ide_pktcmd_tf_load(drive, IDE_TFLAG_NO_SELECT_MASK, bcount, dma);
- if (dma)
- pc->flags |= PC_FLAG_DMA_OK;
-
- if (test_bit(IDESCSI_DRQ_INTERRUPT, &scsi->flags)) {
- ide_execute_command(drive, WIN_PACKETCMD, &idescsi_transfer_pc,
- get_timeout(pc), idescsi_expiry);
- return ide_started;
- } else {
- /* Issue the packet command */
- ide_execute_pkt_cmd(drive);
- return idescsi_transfer_pc(drive);
- }
+ return ide_issue_pc(drive, pc, idescsi_transfer_pc,
+ get_timeout(pc), idescsi_expiry);
}
/*
@@ -584,14 +427,22 @@ static ide_startstop_t idescsi_issue_pc(ide_drive_t *drive,
*/
static ide_startstop_t idescsi_do_request (ide_drive_t *drive, struct request *rq, sector_t block)
{
-#if IDESCSI_DEBUG_LOG
- printk (KERN_INFO "dev: %s, cmd: %x, errors: %d\n", rq->rq_disk->disk_name,rq->cmd[0],rq->errors);
- printk (KERN_INFO "sector: %ld, nr_sectors: %ld, current_nr_sectors: %d\n",rq->sector,rq->nr_sectors,rq->current_nr_sectors);
-#endif /* IDESCSI_DEBUG_LOG */
+ debug_log("dev: %s, cmd: %x, errors: %d\n", rq->rq_disk->disk_name,
+ rq->cmd[0], rq->errors);
+ debug_log("sector: %ld, nr_sectors: %ld, current_nr_sectors: %d\n",
+ rq->sector, rq->nr_sectors, rq->current_nr_sectors);
if (blk_sense_request(rq) || blk_special_request(rq)) {
- return idescsi_issue_pc(drive,
- (struct ide_atapi_pc *) rq->special);
+ struct ide_atapi_pc *pc = (struct ide_atapi_pc *)rq->special;
+ idescsi_scsi_t *scsi = drive_to_idescsi(drive);
+
+ if (test_bit(IDESCSI_DRQ_INTERRUPT, &scsi->flags))
+ pc->flags |= PC_FLAG_DRQ_INTERRUPT;
+
+ if (drive->using_dma && !idescsi_map_sg(drive, pc))
+ pc->flags |= PC_FLAG_DMA_OK;
+
+ return idescsi_issue_pc(drive, pc);
}
blk_dump_rq_flags(rq, "ide-scsi: unsup command");
idescsi_end_request (drive, 0, 0);
@@ -646,6 +497,8 @@ static void ide_scsi_remove(ide_drive_t *drive)
put_disk(g);
ide_scsi_put(scsi);
+
+ drive->scsi = 0;
}
static int ide_scsi_probe(ide_drive_t *);
@@ -765,6 +618,8 @@ static int idescsi_queue (struct scsi_cmnd *cmd,
memset (pc->c, 0, 12);
pc->flags = 0;
+ if (cmd->sc_data_direction == DMA_TO_DEVICE)
+ pc->flags |= PC_FLAG_WRITING;
pc->rq = rq;
memcpy (pc->c, cmd->cmnd, cmd->cmd_len);
pc->buf = NULL;
@@ -775,6 +630,7 @@ static int idescsi_queue (struct scsi_cmnd *cmd,
pc->scsi_cmd = cmd;
pc->done = done;
pc->timeout = jiffies + cmd->timeout_per_command;
+ pc->callback = ide_scsi_callback;
if (test_bit(IDESCSI_LOG_CMD, &scsi->log)) {
printk ("ide-scsi: %s: que %lu, cmd = ", drive->name, cmd->serial_number);
@@ -785,12 +641,11 @@ static int idescsi_queue (struct scsi_cmnd *cmd,
}
}
- ide_init_drive_cmd (rq);
+ blk_rq_init(NULL, rq);
rq->special = (char *) pc;
rq->cmd_type = REQ_TYPE_SPECIAL;
spin_unlock_irq(host->host_lock);
- rq->rq_disk = scsi->disk;
- (void) ide_do_drive_cmd (drive, rq, ide_end);
+ blk_execute_rq_nowait(drive->queue, scsi->disk, rq, 0, NULL);
spin_lock_irq(host->host_lock);
return 0;
abort:
@@ -985,6 +840,8 @@ static int ide_scsi_probe(ide_drive_t *drive)
!(host = scsi_host_alloc(&idescsi_template,sizeof(idescsi_scsi_t))))
return -ENODEV;
+ drive->scsi = 1;
+
g = alloc_disk(1 << PARTN_BITS);
if (!g)
goto out_host_put;
@@ -993,10 +850,10 @@ static int ide_scsi_probe(ide_drive_t *drive)
host->max_id = 1;
-#if IDESCSI_DEBUG_LOG
if (drive->id->last_lun)
- printk(KERN_NOTICE "%s: id->last_lun=%u\n", drive->name, drive->id->last_lun);
-#endif
+ debug_log("%s: id->last_lun=%u\n", drive->name,
+ drive->id->last_lun);
+
if ((drive->id->last_lun & 0x7) != 7)
host->max_lun = (drive->id->last_lun & 0x7) + 1;
else
@@ -1025,6 +882,7 @@ static int ide_scsi_probe(ide_drive_t *drive)
put_disk(g);
out_host_put:
+ drive->scsi = 0;
scsi_host_put(host);
return err;
}
diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c
index 01cefbb..d53312c 100644
--- a/drivers/scsi/sd.c
+++ b/drivers/scsi/sd.c
@@ -1124,6 +1124,8 @@ sd_spinup_disk(struct scsi_disk *sdkp)
cmd[1] = 1; /* Return immediately */
memset((void *) &cmd[2], 0, 8);
cmd[4] = 1; /* Start spin cycle */
+ if (sdkp->device->start_stop_pwr_cond)
+ cmd[4] |= 1 << 4;
scsi_execute_req(sdkp->device, cmd, DMA_NONE,
NULL, 0, &sshdr,
SD_TIMEOUT, SD_MAX_RETRIES);
@@ -1790,6 +1792,9 @@ static int sd_start_stop_device(struct scsi_disk *sdkp, int start)
if (start)
cmd[4] |= 1; /* START */
+ if (sdp->start_stop_pwr_cond)
+ cmd[4] |= start ? 1 << 4 : 3 << 4; /* Active or Standby */
+
if (!scsi_device_online(sdp))
return -ENODEV;