static void ide_floppy_io_buffers(ide_drive_t *drive, struct ide_atapi_pc *pc,
unsigned int bcount, int direction)
{
+ ide_hwif_t *hwif = drive->hwif;
struct request *rq = pc->rq;
struct req_iterator iter;
struct bio_vec *bvec;
data = bvec_kmap_irq(bvec, &flags);
if (direction)
- drive->hwif->atapi_output_bytes(drive, data, count);
+ hwif->output_data(drive, NULL, data, count);
else
- drive->hwif->atapi_input_bytes(drive, data, count);
+ hwif->input_data(drive, NULL, data, count);
bvec_kunmap_irq(data, &flags);
bcount -= count;
if (bcount) {
printk(KERN_ERR "%s: leftover data in %s, bcount == %d\n",
drive->name, __func__, bcount);
- if (direction)
- ide_atapi_write_zeros(drive, bcount);
- else
- ide_atapi_discard_data(drive, bcount);
+ ide_pad_transfer(drive, direction, bcount);
}
}
{
struct ide_floppy_obj *floppy = drive->driver_data;
- ide_init_drive_cmd(rq);
+ blk_rq_init(NULL, rq);
rq->buffer = (char *) pc;
rq->cmd_type = REQ_TYPE_SPECIAL;
+ rq->cmd_flags |= REQ_PREEMPT;
rq->rq_disk = floppy->disk;
- (void) ide_do_drive_cmd(drive, rq, ide_preempt);
+ ide_do_drive_cmd(drive, rq);
}
static struct ide_atapi_pc *idefloppy_next_pc_storage(ide_drive_t *drive)
}
/* The usual interrupt handler called during a packet command. */
-static ide_startstop_t idefloppy_pc_intr (ide_drive_t *drive)
+static ide_startstop_t idefloppy_pc_intr(ide_drive_t *drive)
{
idefloppy_floppy_t *floppy = drive->driver_data;
ide_hwif_t *hwif = drive->hwif;
debug_log("Reached %s interrupt handler\n", __func__);
if (pc->flags & PC_FLAG_DMA_IN_PROGRESS) {
- dma_error = hwif->ide_dma_end(drive);
+ dma_error = hwif->dma_ops->dma_end(drive);
if (dma_error) {
printk(KERN_ERR "%s: DMA %s error\n", drive->name,
rq_data_dir(rq) ? "write" : "read");
}
/* Get the number of bytes to transfer */
- bcount = (hwif->INB(hwif->io_ports[IDE_BCOUNTH_OFFSET]) << 8) |
- hwif->INB(hwif->io_ports[IDE_BCOUNTL_OFFSET]);
+ bcount = (hwif->INB(hwif->io_ports.lbah_addr) << 8) |
+ hwif->INB(hwif->io_ports.lbam_addr);
/* on this interrupt */
- ireason = hwif->INB(hwif->io_ports[IDE_IREASON_OFFSET]);
+ ireason = hwif->INB(hwif->io_ports.nsect_addr);
if (ireason & CD) {
printk(KERN_ERR "ide-floppy: CoD != 0 in %s\n", __func__);
printk(KERN_ERR "ide-floppy: The floppy wants "
"to send us more data than expected "
"- discarding data\n");
- ide_atapi_discard_data(drive, bcount);
+ ide_pad_transfer(drive, 0, bcount);
ide_set_handler(drive,
&idefloppy_pc_intr,
}
}
if (pc->flags & PC_FLAG_WRITING)
- xferfunc = hwif->atapi_output_bytes;
+ xferfunc = hwif->output_data;
else
- xferfunc = hwif->atapi_input_bytes;
+ xferfunc = hwif->input_data;
if (pc->buf)
- xferfunc(drive, pc->cur_pos, bcount);
+ xferfunc(drive, NULL, pc->cur_pos, bcount);
else
ide_floppy_io_buffers(drive, pc, bcount,
!!(pc->flags & PC_FLAG_WRITING));
return ide_started;
}
-/*
- * This is the original routine that did the packet transfer.
- * It fails at high speeds on the Iomega ZIP drive, so there's a slower version
- * for that drive below. The algorithm is chosen based on drive type
- */
-static ide_startstop_t idefloppy_transfer_pc(ide_drive_t *drive)
-{
- ide_hwif_t *hwif = drive->hwif;
- ide_startstop_t startstop;
- idefloppy_floppy_t *floppy = drive->driver_data;
- u8 ireason;
-
- if (ide_wait_stat(&startstop, drive, DRQ_STAT, BUSY_STAT, WAIT_READY)) {
- printk(KERN_ERR "ide-floppy: Strange, packet command "
- "initiated yet DRQ isn't asserted\n");
- return startstop;
- }
- ireason = hwif->INB(hwif->io_ports[IDE_IREASON_OFFSET]);
- if ((ireason & CD) == 0 || (ireason & IO)) {
- printk(KERN_ERR "ide-floppy: (IO,CoD) != (0,1) while "
- "issuing a packet command\n");
- return ide_do_reset(drive);
- }
-
- /* Set the interrupt routine */
- ide_set_handler(drive, &idefloppy_pc_intr, IDEFLOPPY_WAIT_CMD, NULL);
- /* Send the actual packet */
- HWIF(drive)->atapi_output_bytes(drive, floppy->pc->c, 12);
- return ide_started;
-}
-
-
/*
* What we have here is a classic case of a top half / bottom half interrupt
* service routine. In interrupt mode, the device sends an interrupt to signal
idefloppy_floppy_t *floppy = drive->driver_data;
/* Send the actual packet */
- HWIF(drive)->atapi_output_bytes(drive, floppy->pc->c, 12);
+ drive->hwif->output_data(drive, NULL, floppy->pc->c, 12);
+
/* Timeout for the packet command */
return IDEFLOPPY_WAIT_CMD;
}
{
ide_hwif_t *hwif = drive->hwif;
idefloppy_floppy_t *floppy = drive->driver_data;
+ ide_expiry_t *expiry;
+ unsigned int timeout;
ide_startstop_t startstop;
u8 ireason;
"initiated yet DRQ isn't asserted\n");
return startstop;
}
- ireason = hwif->INB(hwif->io_ports[IDE_IREASON_OFFSET]);
+ ireason = hwif->INB(hwif->io_ports.nsect_addr);
if ((ireason & CD) == 0 || (ireason & IO)) {
printk(KERN_ERR "ide-floppy: (IO,CoD) != (0,1) "
"while issuing a packet command\n");
* 40 and 50msec work well. idefloppy_pc_intr will not be actually
* used until after the packet is moved in about 50 msec.
*/
+ if (floppy->flags & IDEFLOPPY_FLAG_ZIP_DRIVE) {
+ timeout = floppy->ticks;
+ expiry = &idefloppy_transfer_pc2;
+ } else {
+ timeout = IDEFLOPPY_WAIT_CMD;
+ expiry = NULL;
+ }
+
+ ide_set_handler(drive, &idefloppy_pc_intr, timeout, expiry);
+
+ if ((floppy->flags & IDEFLOPPY_FLAG_ZIP_DRIVE) == 0)
+ /* Send the actual packet */
+ hwif->output_data(drive, NULL, floppy->pc->c, 12);
- ide_set_handler(drive, &idefloppy_pc_intr, floppy->ticks,
- &idefloppy_transfer_pc2);
return ide_started;
}
{
idefloppy_floppy_t *floppy = drive->driver_data;
ide_hwif_t *hwif = drive->hwif;
- ide_handler_t *pkt_xfer_routine;
u16 bcount;
u8 dma;
dma = 0;
if ((pc->flags & PC_FLAG_DMA_RECOMMENDED) && drive->using_dma)
- dma = !hwif->dma_setup(drive);
+ dma = !hwif->dma_ops->dma_setup(drive);
- ide_pktcmd_tf_load(drive, IDE_TFLAG_NO_SELECT_MASK |
- IDE_TFLAG_OUT_DEVICE, bcount, dma);
+ ide_pktcmd_tf_load(drive, IDE_TFLAG_OUT_DEVICE, bcount, dma);
if (dma) {
/* Begin DMA, if necessary */
pc->flags |= PC_FLAG_DMA_IN_PROGRESS;
- hwif->dma_start(drive);
- }
-
- /* Can we transfer the packet when we get the interrupt or wait? */
- if (floppy->flags & IDEFLOPPY_FLAG_ZIP_DRIVE) {
- /* wait */
- pkt_xfer_routine = &idefloppy_transfer_pc1;
- } else {
- /* immediate */
- pkt_xfer_routine = &idefloppy_transfer_pc;
+ hwif->dma_ops->dma_start(drive);
}
if (floppy->flags & IDEFLOPPY_FLAG_DRQ_INTERRUPT) {
/* Issue the packet command */
ide_execute_command(drive, WIN_PACKETCMD,
- pkt_xfer_routine,
+ &idefloppy_transfer_pc1,
IDEFLOPPY_WAIT_CMD,
NULL);
return ide_started;
} else {
/* Issue the packet command */
- hwif->OUTB(WIN_PACKETCMD, hwif->io_ports[IDE_COMMAND_OFFSET]);
- return (*pkt_xfer_routine) (drive);
+ ide_execute_pkt_cmd(drive);
+ return idefloppy_transfer_pc1(drive);
}
}
static int idefloppy_queue_pc_tail(ide_drive_t *drive, struct ide_atapi_pc *pc)
{
struct ide_floppy_obj *floppy = drive->driver_data;
- struct request rq;
+ struct request *rq;
+ int error;
- ide_init_drive_cmd(&rq);
- rq.buffer = (char *) pc;
- rq.cmd_type = REQ_TYPE_SPECIAL;
- rq.rq_disk = floppy->disk;
+ rq = blk_get_request(drive->queue, READ, __GFP_WAIT);
+ rq->buffer = (char *) pc;
+ rq->cmd_type = REQ_TYPE_SPECIAL;
+ error = blk_execute_rq(drive->queue, floppy->disk, rq, 0);
+ blk_put_request(rq);
- return ide_do_drive_cmd(drive, &rq, ide_wait);
+ return error;
}
/*
}
static struct block_device_operations idefloppy_ops = {
- .owner = THIS_MODULE,
- .open = idefloppy_open,
- .release = idefloppy_release,
- .ioctl = idefloppy_ioctl,
- .getgeo = idefloppy_getgeo,
- .media_changed = idefloppy_media_changed,
- .revalidate_disk= idefloppy_revalidate_disk
+ .owner = THIS_MODULE,
+ .open = idefloppy_open,
+ .release = idefloppy_release,
+ .ioctl = idefloppy_ioctl,
+ .getgeo = idefloppy_getgeo,
+ .media_changed = idefloppy_media_changed,
+ .revalidate_disk = idefloppy_revalidate_disk
};
static int ide_floppy_probe(ide_drive_t *drive)