提交 98339cbd 编写于 作者: L Linus Torvalds

Merge git://git.kernel.org/pub/scm/linux/kernel/git/bart/ide-2.6

* git://git.kernel.org/pub/scm/linux/kernel/git/bart/ide-2.6: (80 commits)
  ide-floppy: fix unfortunate function naming
  ide-tape: unify idetape_create_read/write_cmd
  ide: add ide_pc_intr() helper
  ide-{floppy,scsi}: read Status Register before stopping DMA engine
  ide-scsi: add more debugging to idescsi_pc_intr()
  ide-scsi: use pc->callback
  ide-floppy: add more debugging to idefloppy_pc_intr()
  ide-tape: always log debug info in idetape_pc_intr() if debugging is enabled
  ide-tape: add ide_tape_io_buffers() helper
  ide-tape: factor out DSC handling from idetape_pc_intr()
  ide-{floppy,tape}: move checking of ->failed_pc to ->callback
  ide: add ide_issue_pc() helper
  ide: add PC_FLAG_DRQ_INTERRUPT pc flag
  ide-scsi: move idescsi_map_sg() call out from idescsi_issue_pc()
  ide: add ide_transfer_pc() helper
  ide-scsi: set drive->scsi flag for devices handled by the driver
  ide-{cd,floppy,tape}: remove checking for drive->scsi
  ide: add PC_FLAG_ZIP_DRIVE pc flag
  ide-tape: factor out waiting for good ireason from idetape_transfer_pc()
  ide-tape: set PC_FLAG_DMA_IN_PROGRESS flag in idetape_transfer_pc()
  ...
...@@ -758,9 +758,6 @@ and is between 256 and 4096 characters. It is defined in the file ...@@ -758,9 +758,6 @@ and is between 256 and 4096 characters. It is defined in the file
hd= [EIDE] (E)IDE hard drive subsystem geometry hd= [EIDE] (E)IDE hard drive subsystem geometry
Format: <cyl>,<head>,<sect> Format: <cyl>,<head>,<sect>
hd?= [HW] (E)IDE subsystem
hd?lun= See Documentation/ide/ide.txt.
highmem=nn[KMG] [KNL,BOOT] forces the highmem zone to have an exact highmem=nn[KMG] [KNL,BOOT] forces the highmem zone to have an exact
size of <nn>. This works even on boxes that have no size of <nn>. This works even on boxes that have no
highmem otherwise. This also works to reduce highmem highmem otherwise. This also works to reduce highmem
......
...@@ -1042,15 +1042,9 @@ void blk_put_request(struct request *req) ...@@ -1042,15 +1042,9 @@ void blk_put_request(struct request *req)
unsigned long flags; unsigned long flags;
struct request_queue *q = req->q; struct request_queue *q = req->q;
/* spin_lock_irqsave(q->queue_lock, flags);
* Gee, IDE calls in w/ NULL q. Fix IDE and remove the __blk_put_request(q, req);
* following if (q) test. spin_unlock_irqrestore(q->queue_lock, flags);
*/
if (q) {
spin_lock_irqsave(q->queue_lock, flags);
__blk_put_request(q, req);
spin_unlock_irqrestore(q->queue_lock, flags);
}
} }
EXPORT_SYMBOL(blk_put_request); EXPORT_SYMBOL(blk_put_request);
......
...@@ -18,7 +18,7 @@ ...@@ -18,7 +18,7 @@
* @rq: request to complete * @rq: request to complete
* @error: end io status of the request * @error: end io status of the request
*/ */
void blk_end_sync_rq(struct request *rq, int error) static void blk_end_sync_rq(struct request *rq, int error)
{ {
struct completion *waiting = rq->end_io_data; struct completion *waiting = rq->end_io_data;
...@@ -31,7 +31,6 @@ void blk_end_sync_rq(struct request *rq, int error) ...@@ -31,7 +31,6 @@ void blk_end_sync_rq(struct request *rq, int error)
*/ */
complete(waiting); complete(waiting);
} }
EXPORT_SYMBOL(blk_end_sync_rq);
/** /**
* blk_execute_rq_nowait - insert a request into queue for execution * blk_execute_rq_nowait - insert a request into queue for execution
...@@ -58,6 +57,9 @@ void blk_execute_rq_nowait(struct request_queue *q, struct gendisk *bd_disk, ...@@ -58,6 +57,9 @@ void blk_execute_rq_nowait(struct request_queue *q, struct gendisk *bd_disk,
spin_lock_irq(q->queue_lock); spin_lock_irq(q->queue_lock);
__elv_add_request(q, rq, where, 1); __elv_add_request(q, rq, where, 1);
__generic_unplug_device(q); __generic_unplug_device(q);
/* the queue is stopped so it won't be plugged+unplugged */
if (blk_pm_resume_request(rq))
q->request_fn(q);
spin_unlock_irq(q->queue_lock); spin_unlock_irq(q->queue_lock);
} }
EXPORT_SYMBOL_GPL(blk_execute_rq_nowait); EXPORT_SYMBOL_GPL(blk_execute_rq_nowait);
......
...@@ -712,19 +712,17 @@ static void do_pd_request(struct request_queue * q) ...@@ -712,19 +712,17 @@ static void do_pd_request(struct request_queue * q)
static int pd_special_command(struct pd_unit *disk, static int pd_special_command(struct pd_unit *disk,
enum action (*func)(struct pd_unit *disk)) enum action (*func)(struct pd_unit *disk))
{ {
DECLARE_COMPLETION_ONSTACK(wait); struct request *rq;
struct request rq;
int err = 0; int err = 0;
blk_rq_init(NULL, &rq); rq = blk_get_request(disk->gd->queue, READ, __GFP_WAIT);
rq.rq_disk = disk->gd;
rq.end_io_data = &wait; rq->cmd_type = REQ_TYPE_SPECIAL;
rq.end_io = blk_end_sync_rq; rq->special = func;
blk_insert_request(disk->gd->queue, &rq, 0, func);
wait_for_completion(&wait); err = blk_execute_rq(disk->gd->queue, disk->gd, rq, 0);
if (rq.errors)
err = -EIO; blk_put_request(rq);
blk_put_request(&rq);
return err; return err;
} }
......
...@@ -98,6 +98,9 @@ if BLK_DEV_IDE ...@@ -98,6 +98,9 @@ if BLK_DEV_IDE
comment "Please see Documentation/ide/ide.txt for help/info on IDE drives" comment "Please see Documentation/ide/ide.txt for help/info on IDE drives"
config IDE_ATAPI
bool
config BLK_DEV_IDE_SATA config BLK_DEV_IDE_SATA
bool "Support for SATA (deprecated; conflicts with libata SATA driver)" bool "Support for SATA (deprecated; conflicts with libata SATA driver)"
default n default n
...@@ -201,6 +204,7 @@ config BLK_DEV_IDECD_VERBOSE_ERRORS ...@@ -201,6 +204,7 @@ config BLK_DEV_IDECD_VERBOSE_ERRORS
config BLK_DEV_IDETAPE config BLK_DEV_IDETAPE
tristate "Include IDE/ATAPI TAPE support" tristate "Include IDE/ATAPI TAPE support"
select IDE_ATAPI
help help
If you have an IDE tape drive using the ATAPI protocol, say Y. If you have an IDE tape drive using the ATAPI protocol, say Y.
ATAPI is a newer protocol used by IDE tape and CD-ROM drives, ATAPI is a newer protocol used by IDE tape and CD-ROM drives,
...@@ -223,6 +227,7 @@ config BLK_DEV_IDETAPE ...@@ -223,6 +227,7 @@ config BLK_DEV_IDETAPE
config BLK_DEV_IDEFLOPPY config BLK_DEV_IDEFLOPPY
tristate "Include IDE/ATAPI FLOPPY support" tristate "Include IDE/ATAPI FLOPPY support"
select IDE_ATAPI
---help--- ---help---
If you have an IDE floppy drive which uses the ATAPI protocol, If you have an IDE floppy drive which uses the ATAPI protocol,
answer Y. ATAPI is a newer protocol used by IDE CD-ROM/tape/floppy answer Y. ATAPI is a newer protocol used by IDE CD-ROM/tape/floppy
...@@ -246,6 +251,7 @@ config BLK_DEV_IDEFLOPPY ...@@ -246,6 +251,7 @@ config BLK_DEV_IDEFLOPPY
config BLK_DEV_IDESCSI config BLK_DEV_IDESCSI
tristate "SCSI emulation support" tristate "SCSI emulation support"
depends on SCSI depends on SCSI
select IDE_ATAPI
---help--- ---help---
WARNING: ide-scsi is no longer needed for cd writing applications! WARNING: ide-scsi is no longer needed for cd writing applications!
The 2.6 kernel supports direct writing to ide-cd, which eliminates The 2.6 kernel supports direct writing to ide-cd, which eliminates
......
...@@ -14,6 +14,7 @@ EXTRA_CFLAGS += -Idrivers/ide ...@@ -14,6 +14,7 @@ EXTRA_CFLAGS += -Idrivers/ide
ide-core-y += ide.o ide-io.o ide-iops.o ide-lib.o ide-probe.o ide-taskfile.o ide-core-y += ide.o ide-io.o ide-iops.o ide-lib.o ide-probe.o ide-taskfile.o
# core IDE code # core IDE code
ide-core-$(CONFIG_IDE_ATAPI) += ide-atapi.o
ide-core-$(CONFIG_BLK_DEV_IDEPCI) += setup-pci.o ide-core-$(CONFIG_BLK_DEV_IDEPCI) += setup-pci.o
ide-core-$(CONFIG_BLK_DEV_IDEDMA) += ide-dma.o ide-core-$(CONFIG_BLK_DEV_IDEDMA) += ide-dma.o
ide-core-$(CONFIG_IDE_PROC_FS) += ide-proc.o ide-core-$(CONFIG_IDE_PROC_FS) += ide-proc.o
......
...@@ -83,7 +83,7 @@ static const struct palm_bk3710_udmatiming palm_bk3710_udmatimings[6] = { ...@@ -83,7 +83,7 @@ static const struct palm_bk3710_udmatiming palm_bk3710_udmatimings[6] = {
{125, 160}, /* UDMA Mode 1 */ {125, 160}, /* UDMA Mode 1 */
{100, 120}, /* UDMA Mode 2 */ {100, 120}, /* UDMA Mode 2 */
{100, 90}, /* UDMA Mode 3 */ {100, 90}, /* UDMA Mode 3 */
{85, 60}, /* UDMA Mode 4 */ {100, 60}, /* UDMA Mode 4 */
}; };
static void palm_bk3710_setudmamode(void __iomem *base, unsigned int dev, static void palm_bk3710_setudmamode(void __iomem *base, unsigned int dev,
...@@ -405,7 +405,6 @@ static int __devinit palm_bk3710_probe(struct platform_device *pdev) ...@@ -405,7 +405,6 @@ static int __devinit palm_bk3710_probe(struct platform_device *pdev)
ide_init_port_data(hwif, i); ide_init_port_data(hwif, i);
ide_init_port_hw(hwif, &hw); ide_init_port_hw(hwif, &hw);
hwif->mmio = 1;
default_hwif_mmiops(hwif); default_hwif_mmiops(hwif);
idx[0] = i; idx[0] = i;
......
...@@ -52,8 +52,6 @@ static void h8300_tf_load(ide_drive_t *drive, ide_task_t *task) ...@@ -52,8 +52,6 @@ static void h8300_tf_load(ide_drive_t *drive, ide_task_t *task)
if (task->tf_flags & IDE_TFLAG_FLAGGED) if (task->tf_flags & IDE_TFLAG_FLAGGED)
HIHI = 0xFF; HIHI = 0xFF;
ide_set_irq(drive, 1);
if (task->tf_flags & IDE_TFLAG_OUT_DATA) if (task->tf_flags & IDE_TFLAG_OUT_DATA)
mm_outw((tf->hob_data << 8) | tf->data, io_ports->data_addr); mm_outw((tf->hob_data << 8) | tf->data, io_ports->data_addr);
...@@ -98,7 +96,7 @@ static void h8300_tf_read(ide_drive_t *drive, ide_task_t *task) ...@@ -98,7 +96,7 @@ static void h8300_tf_read(ide_drive_t *drive, ide_task_t *task)
} }
/* be sure we're looking at the low order bits */ /* be sure we're looking at the low order bits */
outb(drive->ctl & ~0x80, io_ports->ctl_addr); outb(ATA_DEVCTL_OBS & ~0x80, io_ports->ctl_addr);
if (task->tf_flags & IDE_TFLAG_IN_NSECT) if (task->tf_flags & IDE_TFLAG_IN_NSECT)
tf->nsect = inb(io_ports->nsect_addr); tf->nsect = inb(io_ports->nsect_addr);
...@@ -112,7 +110,7 @@ static void h8300_tf_read(ide_drive_t *drive, ide_task_t *task) ...@@ -112,7 +110,7 @@ static void h8300_tf_read(ide_drive_t *drive, ide_task_t *task)
tf->device = inb(io_ports->device_addr); tf->device = inb(io_ports->device_addr);
if (task->tf_flags & IDE_TFLAG_LBA48) { if (task->tf_flags & IDE_TFLAG_LBA48) {
outb(drive->ctl | 0x80, io_ports->ctl_addr); outb(ATA_DEVCTL_OBS | 0x80, io_ports->ctl_addr);
if (task->tf_flags & IDE_TFLAG_IN_HOB_FEATURE) if (task->tf_flags & IDE_TFLAG_IN_HOB_FEATURE)
tf->hob_feature = inb(io_ports->feature_addr); tf->hob_feature = inb(io_ports->feature_addr);
......
...@@ -60,15 +60,15 @@ struct ide_acpi_hwif_link { ...@@ -60,15 +60,15 @@ struct ide_acpi_hwif_link {
#define DEBPRINT(fmt, args...) do {} while (0) #define DEBPRINT(fmt, args...) do {} while (0)
#endif /* DEBUGGING */ #endif /* DEBUGGING */
int ide_noacpi; static int ide_noacpi;
module_param_named(noacpi, ide_noacpi, bool, 0); module_param_named(noacpi, ide_noacpi, bool, 0);
MODULE_PARM_DESC(noacpi, "disable IDE ACPI support"); MODULE_PARM_DESC(noacpi, "disable IDE ACPI support");
int ide_acpigtf; static int ide_acpigtf;
module_param_named(acpigtf, ide_acpigtf, bool, 0); module_param_named(acpigtf, ide_acpigtf, bool, 0);
MODULE_PARM_DESC(acpigtf, "enable IDE ACPI _GTF support"); MODULE_PARM_DESC(acpigtf, "enable IDE ACPI _GTF support");
int ide_acpionboot; static int ide_acpionboot;
module_param_named(acpionboot, ide_acpionboot, bool, 0); module_param_named(acpionboot, ide_acpionboot, bool, 0);
MODULE_PARM_DESC(acpionboot, "call IDE ACPI methods on boot"); MODULE_PARM_DESC(acpionboot, "call IDE ACPI methods on boot");
......
/*
* ATAPI support.
*/
#include <linux/kernel.h>
#include <linux/delay.h>
#include <linux/ide.h>
#include <scsi/scsi.h>
#ifdef DEBUG
#define debug_log(fmt, args...) \
printk(KERN_INFO "ide: " fmt, ## args)
#else
#define debug_log(fmt, args...) do {} while (0)
#endif
/* TODO: unify the code thus making some arguments go away */
ide_startstop_t ide_pc_intr(ide_drive_t *drive, struct ide_atapi_pc *pc,
ide_handler_t *handler, unsigned int timeout, ide_expiry_t *expiry,
void (*update_buffers)(ide_drive_t *, struct ide_atapi_pc *),
void (*retry_pc)(ide_drive_t *), void (*dsc_handle)(ide_drive_t *),
void (*io_buffers)(ide_drive_t *, struct ide_atapi_pc *, unsigned, int))
{
ide_hwif_t *hwif = drive->hwif;
xfer_func_t *xferfunc;
unsigned int temp;
u16 bcount;
u8 stat, ireason, scsi = drive->scsi;
debug_log("Enter %s - interrupt handler\n", __func__);
if (pc->flags & PC_FLAG_TIMEDOUT) {
pc->callback(drive);
return ide_stopped;
}
/* Clear the interrupt */
stat = ide_read_status(drive);
if (pc->flags & PC_FLAG_DMA_IN_PROGRESS) {
if (hwif->dma_ops->dma_end(drive) ||
(drive->media == ide_tape && !scsi && (stat & ERR_STAT))) {
if (drive->media == ide_floppy && !scsi)
printk(KERN_ERR "%s: DMA %s error\n",
drive->name, rq_data_dir(pc->rq)
? "write" : "read");
pc->flags |= PC_FLAG_DMA_ERROR;
} else {
pc->xferred = pc->req_xfer;
if (update_buffers)
update_buffers(drive, pc);
}
debug_log("%s: DMA finished\n", drive->name);
}
/* No more interrupts */
if ((stat & DRQ_STAT) == 0) {
debug_log("Packet command completed, %d bytes transferred\n",
pc->xferred);
pc->flags &= ~PC_FLAG_DMA_IN_PROGRESS;
local_irq_enable_in_hardirq();
if (drive->media == ide_tape && !scsi &&
(stat & ERR_STAT) && pc->c[0] == REQUEST_SENSE)
stat &= ~ERR_STAT;
if ((stat & ERR_STAT) || (pc->flags & PC_FLAG_DMA_ERROR)) {
/* Error detected */
debug_log("%s: I/O error\n", drive->name);
if (drive->media != ide_tape || scsi) {
pc->rq->errors++;
if (scsi)
goto cmd_finished;
}
if (pc->c[0] == REQUEST_SENSE) {
printk(KERN_ERR "%s: I/O error in request sense"
" command\n", drive->name);
return ide_do_reset(drive);
}
debug_log("[cmd %x]: check condition\n", pc->c[0]);
/* Retry operation */
retry_pc(drive);
/* queued, but not started */
return ide_stopped;
}
cmd_finished:
pc->error = 0;
if ((pc->flags & PC_FLAG_WAIT_FOR_DSC) &&
(stat & SEEK_STAT) == 0) {
dsc_handle(drive);
return ide_stopped;
}
/* Command finished - Call the callback function */
pc->callback(drive);
return ide_stopped;
}
if (pc->flags & PC_FLAG_DMA_IN_PROGRESS) {
pc->flags &= ~PC_FLAG_DMA_IN_PROGRESS;
printk(KERN_ERR "%s: The device wants to issue more interrupts "
"in DMA mode\n", drive->name);
ide_dma_off(drive);
return ide_do_reset(drive);
}
/* Get the number of bytes to transfer on this interrupt. */
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 "%s: CoD != 0 in %s\n", drive->name, __func__);
return ide_do_reset(drive);
}
if (((ireason & IO) == IO) == !!(pc->flags & PC_FLAG_WRITING)) {
/* Hopefully, we will never get here */
printk(KERN_ERR "%s: We wanted to %s, but the device wants us "
"to %s!\n", drive->name,
(ireason & IO) ? "Write" : "Read",
(ireason & IO) ? "Read" : "Write");
return ide_do_reset(drive);
}
if (!(pc->flags & PC_FLAG_WRITING)) {
/* Reading - Check that we have enough space */
temp = pc->xferred + bcount;
if (temp > pc->req_xfer) {
if (temp > pc->buf_size) {
printk(KERN_ERR "%s: The device wants to send "
"us more data than expected - "
"discarding data\n",
drive->name);
if (scsi)
temp = pc->buf_size - pc->xferred;
else
temp = 0;
if (temp) {
if (pc->sg)
io_buffers(drive, pc, temp, 0);
else
hwif->input_data(drive, NULL,
pc->cur_pos, temp);
printk(KERN_ERR "%s: transferred %d of "
"%d bytes\n",
drive->name,
temp, bcount);
}
pc->xferred += temp;
pc->cur_pos += temp;
ide_pad_transfer(drive, 0, bcount - temp);
ide_set_handler(drive, handler, timeout,
expiry);
return ide_started;
}
debug_log("The device wants to send us more data than "
"expected - allowing transfer\n");
}
xferfunc = hwif->input_data;
} else
xferfunc = hwif->output_data;
if ((drive->media == ide_floppy && !scsi && !pc->buf) ||
(drive->media == ide_tape && !scsi && pc->bh) ||
(scsi && pc->sg))
io_buffers(drive, pc, bcount, !!(pc->flags & PC_FLAG_WRITING));
else
xferfunc(drive, NULL, pc->cur_pos, bcount);
/* Update the current position */
pc->xferred += bcount;
pc->cur_pos += bcount;
debug_log("[cmd %x] transferred %d bytes on that intr.\n",
pc->c[0], bcount);
/* And set the interrupt handler again */
ide_set_handler(drive, handler, timeout, expiry);
return ide_started;
}
EXPORT_SYMBOL_GPL(ide_pc_intr);
static u8 ide_wait_ireason(ide_drive_t *drive, u8 ireason)
{
ide_hwif_t *hwif = drive->hwif;
int retries = 100;
while (retries-- && ((ireason & CD) == 0 || (ireason & IO))) {
printk(KERN_ERR "%s: (IO,CoD != (0,1) while issuing "
"a packet command, retrying\n", drive->name);
udelay(100);
ireason = hwif->INB(hwif->io_ports.nsect_addr);
if (retries == 0) {
printk(KERN_ERR "%s: (IO,CoD != (0,1) while issuing "
"a packet command, ignoring\n",
drive->name);
ireason |= CD;
ireason &= ~IO;
}
}
return ireason;
}
ide_startstop_t ide_transfer_pc(ide_drive_t *drive, struct ide_atapi_pc *pc,
ide_handler_t *handler, unsigned int timeout,
ide_expiry_t *expiry)
{
ide_hwif_t *hwif = drive->hwif;
ide_startstop_t startstop;
u8 ireason;
if (ide_wait_stat(&startstop, drive, DRQ_STAT, BUSY_STAT, WAIT_READY)) {
printk(KERN_ERR "%s: Strange, packet command initiated yet "
"DRQ isn't asserted\n", drive->name);
return startstop;
}
ireason = hwif->INB(hwif->io_ports.nsect_addr);
if (drive->media == ide_tape && !drive->scsi)
ireason = ide_wait_ireason(drive, ireason);
if ((ireason & CD) == 0 || (ireason & IO)) {
printk(KERN_ERR "%s: (IO,CoD) != (0,1) while issuing "
"a packet command\n", drive->name);
return ide_do_reset(drive);
}
/* Set the interrupt routine */
ide_set_handler(drive, handler, timeout, expiry);
/* Begin DMA, if necessary */
if (pc->flags & PC_FLAG_DMA_OK) {
pc->flags |= PC_FLAG_DMA_IN_PROGRESS;
hwif->dma_ops->dma_start(drive);
}
/* Send the actual packet */
if ((pc->flags & PC_FLAG_ZIP_DRIVE) == 0)
hwif->output_data(drive, NULL, pc->c, 12);
return ide_started;
}
EXPORT_SYMBOL_GPL(ide_transfer_pc);
ide_startstop_t ide_issue_pc(ide_drive_t *drive, struct ide_atapi_pc *pc,
ide_handler_t *handler, unsigned int timeout,
ide_expiry_t *expiry)
{
ide_hwif_t *hwif = drive->hwif;
u16 bcount;
u8 dma = 0;
/* We haven't transferred any data yet */
pc->xferred = 0;
pc->cur_pos = pc->buf;
/* Request to transfer the entire buffer at once */
if (drive->media == ide_tape && !drive->scsi)
bcount = pc->req_xfer;
else
bcount = min(pc->req_xfer, 63 * 1024);
if (pc->flags & PC_FLAG_DMA_ERROR) {
pc->flags &= ~PC_FLAG_DMA_ERROR;
ide_dma_off(drive);
}
if ((pc->flags & PC_FLAG_DMA_OK) && drive->using_dma) {
if (drive->scsi)
hwif->sg_mapped = 1;
dma = !hwif->dma_ops->dma_setup(drive);
if (drive->scsi)
hwif->sg_mapped = 0;
}
if (!dma)
pc->flags &= ~PC_FLAG_DMA_OK;
ide_pktcmd_tf_load(drive, drive->scsi ? 0 : IDE_TFLAG_OUT_DEVICE,
bcount, dma);
/* Issue the packet command */
if (pc->flags & PC_FLAG_DRQ_INTERRUPT) {
ide_execute_command(drive, WIN_PACKETCMD, handler,
timeout, NULL);
return ide_started;
} else {
ide_execute_pkt_cmd(drive);
return (*handler)(drive);
}
}
EXPORT_SYMBOL_GPL(ide_issue_pc);
...@@ -188,16 +188,6 @@ static void cdrom_analyze_sense_data(ide_drive_t *drive, ...@@ -188,16 +188,6 @@ static void cdrom_analyze_sense_data(ide_drive_t *drive,
ide_cd_log_error(drive->name, failed_command, sense); ide_cd_log_error(drive->name, failed_command, sense);
} }
/* Initialize a ide-cd packet command request */
void ide_cd_init_rq(ide_drive_t *drive, struct request *rq)
{
struct cdrom_info *cd = drive->driver_data;
ide_init_drive_cmd(rq);
rq->cmd_type = REQ_TYPE_ATA_PC;
rq->rq_disk = cd->disk;
}
static void cdrom_queue_request_sense(ide_drive_t *drive, void *sense, static void cdrom_queue_request_sense(ide_drive_t *drive, void *sense,
struct request *failed_command) struct request *failed_command)
{ {
...@@ -208,7 +198,9 @@ static void cdrom_queue_request_sense(ide_drive_t *drive, void *sense, ...@@ -208,7 +198,9 @@ static void cdrom_queue_request_sense(ide_drive_t *drive, void *sense,
sense = &info->sense_data; sense = &info->sense_data;
/* stuff the sense request in front of our current request */ /* stuff the sense request in front of our current request */
ide_cd_init_rq(drive, rq); blk_rq_init(NULL, rq);
rq->cmd_type = REQ_TYPE_ATA_PC;
rq->rq_disk = info->disk;
rq->data = sense; rq->data = sense;
rq->cmd[0] = GPCMD_REQUEST_SENSE; rq->cmd[0] = GPCMD_REQUEST_SENSE;
...@@ -216,11 +208,12 @@ static void cdrom_queue_request_sense(ide_drive_t *drive, void *sense, ...@@ -216,11 +208,12 @@ static void cdrom_queue_request_sense(ide_drive_t *drive, void *sense,
rq->data_len = 18; rq->data_len = 18;
rq->cmd_type = REQ_TYPE_SENSE; rq->cmd_type = REQ_TYPE_SENSE;
rq->cmd_flags |= REQ_PREEMPT;
/* NOTE! Save the failed command in "rq->buffer" */ /* NOTE! Save the failed command in "rq->buffer" */
rq->buffer = (void *) failed_command; rq->buffer = (void *) failed_command;
(void) ide_do_drive_cmd(drive, rq, ide_preempt); ide_do_drive_cmd(drive, rq);
} }
static void cdrom_end_request(ide_drive_t *drive, int uptodate) static void cdrom_end_request(ide_drive_t *drive, int uptodate)
...@@ -537,8 +530,8 @@ static ide_startstop_t cdrom_start_packet_command(ide_drive_t *drive, ...@@ -537,8 +530,8 @@ static ide_startstop_t cdrom_start_packet_command(ide_drive_t *drive,
info->dma = !hwif->dma_ops->dma_setup(drive); info->dma = !hwif->dma_ops->dma_setup(drive);
/* set up the controller registers */ /* set up the controller registers */
ide_pktcmd_tf_load(drive, IDE_TFLAG_OUT_NSECT | IDE_TFLAG_OUT_LBAL | ide_pktcmd_tf_load(drive, IDE_TFLAG_OUT_NSECT | IDE_TFLAG_OUT_LBAL,
IDE_TFLAG_NO_SELECT_MASK, xferlen, info->dma); xferlen, info->dma);
if (info->cd_flags & IDE_CD_FLAG_DRQ_INTERRUPT) { if (info->cd_flags & IDE_CD_FLAG_DRQ_INTERRUPT) {
/* waiting for CDB interrupt, not DMA yet. */ /* waiting for CDB interrupt, not DMA yet. */
...@@ -838,34 +831,54 @@ static void ide_cd_request_sense_fixup(struct request *rq) ...@@ -838,34 +831,54 @@ static void ide_cd_request_sense_fixup(struct request *rq)
} }
} }
int ide_cd_queue_pc(ide_drive_t *drive, struct request *rq) int ide_cd_queue_pc(ide_drive_t *drive, const unsigned char *cmd,
int write, void *buffer, unsigned *bufflen,
struct request_sense *sense, int timeout,
unsigned int cmd_flags)
{ {
struct request_sense sense; struct cdrom_info *info = drive->driver_data;
struct request_sense local_sense;
int retries = 10; int retries = 10;
unsigned int flags = rq->cmd_flags; unsigned int flags = 0;
if (rq->sense == NULL) if (!sense)
rq->sense = &sense; sense = &local_sense;
/* start of retry loop */ /* start of retry loop */
do { do {
struct request *rq;
int error; int error;
unsigned long time = jiffies;
rq->cmd_flags = flags;
error = ide_do_drive_cmd(drive, rq, ide_wait); rq = blk_get_request(drive->queue, write, __GFP_WAIT);
time = jiffies - time;
memcpy(rq->cmd, cmd, BLK_MAX_CDB);
rq->cmd_type = REQ_TYPE_ATA_PC;
rq->sense = sense;
rq->cmd_flags |= cmd_flags;
rq->timeout = timeout;
if (buffer) {
rq->data = buffer;
rq->data_len = *bufflen;
}
error = blk_execute_rq(drive->queue, info->disk, rq, 0);
if (buffer)
*bufflen = rq->data_len;
flags = rq->cmd_flags;
blk_put_request(rq);
/* /*
* FIXME: we should probably abort/retry or something in case of * FIXME: we should probably abort/retry or something in case of
* failure. * failure.
*/ */
if (rq->cmd_flags & REQ_FAILED) { if (flags & REQ_FAILED) {
/* /*
* The request failed. Retry if it was due to a unit * The request failed. Retry if it was due to a unit
* attention status (usually means media was changed). * attention status (usually means media was changed).
*/ */
struct request_sense *reqbuf = rq->sense; struct request_sense *reqbuf = sense;
if (reqbuf->sense_key == UNIT_ATTENTION) if (reqbuf->sense_key == UNIT_ATTENTION)
cdrom_saw_media_change(drive); cdrom_saw_media_change(drive);
...@@ -885,10 +898,10 @@ int ide_cd_queue_pc(ide_drive_t *drive, struct request *rq) ...@@ -885,10 +898,10 @@ int ide_cd_queue_pc(ide_drive_t *drive, struct request *rq)
} }
/* end of retry loop */ /* end of retry loop */
} while ((rq->cmd_flags & REQ_FAILED) && retries >= 0); } while ((flags & REQ_FAILED) && retries >= 0);
/* return an error if the command failed */ /* return an error if the command failed */
return (rq->cmd_flags & REQ_FAILED) ? -EIO : 0; return (flags & REQ_FAILED) ? -EIO : 0;
} }
/* /*
...@@ -1268,23 +1281,20 @@ static void msf_from_bcd(struct atapi_msf *msf) ...@@ -1268,23 +1281,20 @@ static void msf_from_bcd(struct atapi_msf *msf)
int cdrom_check_status(ide_drive_t *drive, struct request_sense *sense) int cdrom_check_status(ide_drive_t *drive, struct request_sense *sense)
{ {
struct request req;
struct cdrom_info *info = drive->driver_data; struct cdrom_info *info = drive->driver_data;
struct cdrom_device_info *cdi = &info->devinfo; struct cdrom_device_info *cdi = &info->devinfo;
unsigned char cmd[BLK_MAX_CDB];
ide_cd_init_rq(drive, &req); memset(cmd, 0, BLK_MAX_CDB);
cmd[0] = GPCMD_TEST_UNIT_READY;
req.sense = sense;
req.cmd[0] = GPCMD_TEST_UNIT_READY;
req.cmd_flags |= REQ_QUIET;
/* /*
* Sanyo 3 CD changer uses byte 7 of TEST_UNIT_READY to switch CDs * Sanyo 3 CD changer uses byte 7 of TEST_UNIT_READY to switch CDs
* instead of supporting the LOAD_UNLOAD opcode. * instead of supporting the LOAD_UNLOAD opcode.
*/ */
req.cmd[7] = cdi->sanyo_slot % 3; cmd[7] = cdi->sanyo_slot % 3;
return ide_cd_queue_pc(drive, &req); return ide_cd_queue_pc(drive, cmd, 0, NULL, 0, sense, 0, REQ_QUIET);
} }
static int cdrom_read_capacity(ide_drive_t *drive, unsigned long *capacity, static int cdrom_read_capacity(ide_drive_t *drive, unsigned long *capacity,
...@@ -1297,17 +1307,14 @@ static int cdrom_read_capacity(ide_drive_t *drive, unsigned long *capacity, ...@@ -1297,17 +1307,14 @@ static int cdrom_read_capacity(ide_drive_t *drive, unsigned long *capacity,
} capbuf; } capbuf;
int stat; int stat;
struct request req; unsigned char cmd[BLK_MAX_CDB];
unsigned len = sizeof(capbuf);
ide_cd_init_rq(drive, &req);
req.sense = sense; memset(cmd, 0, BLK_MAX_CDB);
req.cmd[0] = GPCMD_READ_CDVD_CAPACITY; cmd[0] = GPCMD_READ_CDVD_CAPACITY;
req.data = (char *)&capbuf;
req.data_len = sizeof(capbuf);
req.cmd_flags |= REQ_QUIET;
stat = ide_cd_queue_pc(drive, &req); stat = ide_cd_queue_pc(drive, cmd, 0, &capbuf, &len, sense, 0,
REQ_QUIET);
if (stat == 0) { if (stat == 0) {
*capacity = 1 + be32_to_cpu(capbuf.lba); *capacity = 1 + be32_to_cpu(capbuf.lba);
*sectors_per_frame = *sectors_per_frame =
...@@ -1321,24 +1328,20 @@ static int cdrom_read_tocentry(ide_drive_t *drive, int trackno, int msf_flag, ...@@ -1321,24 +1328,20 @@ static int cdrom_read_tocentry(ide_drive_t *drive, int trackno, int msf_flag,
int format, char *buf, int buflen, int format, char *buf, int buflen,
struct request_sense *sense) struct request_sense *sense)
{ {
struct request req; unsigned char cmd[BLK_MAX_CDB];
ide_cd_init_rq(drive, &req); memset(cmd, 0, BLK_MAX_CDB);
req.sense = sense; cmd[0] = GPCMD_READ_TOC_PMA_ATIP;
req.data = buf; cmd[6] = trackno;
req.data_len = buflen; cmd[7] = (buflen >> 8);
req.cmd_flags |= REQ_QUIET; cmd[8] = (buflen & 0xff);
req.cmd[0] = GPCMD_READ_TOC_PMA_ATIP; cmd[9] = (format << 6);
req.cmd[6] = trackno;
req.cmd[7] = (buflen >> 8);
req.cmd[8] = (buflen & 0xff);
req.cmd[9] = (format << 6);
if (msf_flag) if (msf_flag)
req.cmd[1] = 2; cmd[1] = 2;
return ide_cd_queue_pc(drive, &req); return ide_cd_queue_pc(drive, cmd, 0, buf, &buflen, sense, 0, REQ_QUIET);
} }
/* Try to read the entire TOC for the disk into our internal buffer. */ /* Try to read the entire TOC for the disk into our internal buffer. */
...@@ -2103,11 +2106,6 @@ static int ide_cd_probe(ide_drive_t *drive) ...@@ -2103,11 +2106,6 @@ static int ide_cd_probe(ide_drive_t *drive)
goto failed; goto failed;
} }
} }
if (drive->scsi) {
printk(KERN_INFO "ide-cd: passing drive %s to ide-scsi "
"emulation.\n", drive->name);
goto failed;
}
info = kzalloc(sizeof(struct cdrom_info), GFP_KERNEL); info = kzalloc(sizeof(struct cdrom_info), GFP_KERNEL);
if (info == NULL) { if (info == NULL) {
printk(KERN_ERR "%s: Can't allocate a cdrom structure\n", printk(KERN_ERR "%s: Can't allocate a cdrom structure\n",
......
...@@ -143,8 +143,8 @@ struct cdrom_info { ...@@ -143,8 +143,8 @@ struct cdrom_info {
void ide_cd_log_error(const char *, struct request *, struct request_sense *); void ide_cd_log_error(const char *, struct request *, struct request_sense *);
/* ide-cd.c functions used by ide-cd_ioctl.c */ /* ide-cd.c functions used by ide-cd_ioctl.c */
void ide_cd_init_rq(ide_drive_t *, struct request *); int ide_cd_queue_pc(ide_drive_t *, const unsigned char *, int, void *,
int ide_cd_queue_pc(ide_drive_t *, struct request *); unsigned *, struct request_sense *, int, unsigned int);
int ide_cd_read_toc(ide_drive_t *, struct request_sense *); int ide_cd_read_toc(ide_drive_t *, struct request_sense *);
int ide_cdrom_get_capabilities(ide_drive_t *, u8 *); int ide_cdrom_get_capabilities(ide_drive_t *, u8 *);
void ide_cdrom_update_speed(ide_drive_t *, u8 *); void ide_cdrom_update_speed(ide_drive_t *, u8 *);
......
...@@ -104,8 +104,8 @@ int cdrom_eject(ide_drive_t *drive, int ejectflag, ...@@ -104,8 +104,8 @@ int cdrom_eject(ide_drive_t *drive, int ejectflag,
{ {
struct cdrom_info *cd = drive->driver_data; struct cdrom_info *cd = drive->driver_data;
struct cdrom_device_info *cdi = &cd->devinfo; struct cdrom_device_info *cdi = &cd->devinfo;
struct request req;
char loej = 0x02; char loej = 0x02;
unsigned char cmd[BLK_MAX_CDB];
if ((cd->cd_flags & IDE_CD_FLAG_NO_EJECT) && !ejectflag) if ((cd->cd_flags & IDE_CD_FLAG_NO_EJECT) && !ejectflag)
return -EDRIVE_CANT_DO_THIS; return -EDRIVE_CANT_DO_THIS;
...@@ -114,17 +114,16 @@ int cdrom_eject(ide_drive_t *drive, int ejectflag, ...@@ -114,17 +114,16 @@ int cdrom_eject(ide_drive_t *drive, int ejectflag,
if ((cd->cd_flags & IDE_CD_FLAG_DOOR_LOCKED) && ejectflag) if ((cd->cd_flags & IDE_CD_FLAG_DOOR_LOCKED) && ejectflag)
return 0; return 0;
ide_cd_init_rq(drive, &req);
/* only tell drive to close tray if open, if it can do that */ /* only tell drive to close tray if open, if it can do that */
if (ejectflag && (cdi->mask & CDC_CLOSE_TRAY)) if (ejectflag && (cdi->mask & CDC_CLOSE_TRAY))
loej = 0; loej = 0;
req.sense = sense; memset(cmd, 0, BLK_MAX_CDB);
req.cmd[0] = GPCMD_START_STOP_UNIT;
req.cmd[4] = loej | (ejectflag != 0); cmd[0] = GPCMD_START_STOP_UNIT;
cmd[4] = loej | (ejectflag != 0);
return ide_cd_queue_pc(drive, &req); return ide_cd_queue_pc(drive, cmd, 0, NULL, 0, sense, 0, 0);
} }
/* Lock the door if LOCKFLAG is nonzero; unlock it otherwise. */ /* Lock the door if LOCKFLAG is nonzero; unlock it otherwise. */
...@@ -134,7 +133,6 @@ int ide_cd_lockdoor(ide_drive_t *drive, int lockflag, ...@@ -134,7 +133,6 @@ int ide_cd_lockdoor(ide_drive_t *drive, int lockflag,
{ {
struct cdrom_info *cd = drive->driver_data; struct cdrom_info *cd = drive->driver_data;
struct request_sense my_sense; struct request_sense my_sense;
struct request req;
int stat; int stat;
if (sense == NULL) if (sense == NULL)
...@@ -144,11 +142,15 @@ int ide_cd_lockdoor(ide_drive_t *drive, int lockflag, ...@@ -144,11 +142,15 @@ int ide_cd_lockdoor(ide_drive_t *drive, int lockflag,
if (cd->cd_flags & IDE_CD_FLAG_NO_DOORLOCK) { if (cd->cd_flags & IDE_CD_FLAG_NO_DOORLOCK) {
stat = 0; stat = 0;
} else { } else {
ide_cd_init_rq(drive, &req); unsigned char cmd[BLK_MAX_CDB];
req.sense = sense;
req.cmd[0] = GPCMD_PREVENT_ALLOW_MEDIUM_REMOVAL; memset(cmd, 0, BLK_MAX_CDB);
req.cmd[4] = lockflag ? 1 : 0;
stat = ide_cd_queue_pc(drive, &req); cmd[0] = GPCMD_PREVENT_ALLOW_MEDIUM_REMOVAL;
cmd[4] = lockflag ? 1 : 0;
stat = ide_cd_queue_pc(drive, cmd, 0, NULL, 0,
sense, 0, 0);
} }
/* If we got an illegal field error, the drive /* If we got an illegal field error, the drive
...@@ -206,32 +208,30 @@ int ide_cdrom_select_speed(struct cdrom_device_info *cdi, int speed) ...@@ -206,32 +208,30 @@ int ide_cdrom_select_speed(struct cdrom_device_info *cdi, int speed)
{ {
ide_drive_t *drive = cdi->handle; ide_drive_t *drive = cdi->handle;
struct cdrom_info *cd = drive->driver_data; struct cdrom_info *cd = drive->driver_data;
struct request rq;
struct request_sense sense; struct request_sense sense;
u8 buf[ATAPI_CAPABILITIES_PAGE_SIZE]; u8 buf[ATAPI_CAPABILITIES_PAGE_SIZE];
int stat; int stat;
unsigned char cmd[BLK_MAX_CDB];
ide_cd_init_rq(drive, &rq);
rq.sense = &sense;
if (speed == 0) if (speed == 0)
speed = 0xffff; /* set to max */ speed = 0xffff; /* set to max */
else else
speed *= 177; /* Nx to kbytes/s */ speed *= 177; /* Nx to kbytes/s */
rq.cmd[0] = GPCMD_SET_SPEED; memset(cmd, 0, BLK_MAX_CDB);
cmd[0] = GPCMD_SET_SPEED;
/* Read Drive speed in kbytes/second MSB/LSB */ /* Read Drive speed in kbytes/second MSB/LSB */
rq.cmd[2] = (speed >> 8) & 0xff; cmd[2] = (speed >> 8) & 0xff;
rq.cmd[3] = speed & 0xff; cmd[3] = speed & 0xff;
if ((cdi->mask & (CDC_CD_R | CDC_CD_RW | CDC_DVD_R)) != if ((cdi->mask & (CDC_CD_R | CDC_CD_RW | CDC_DVD_R)) !=
(CDC_CD_R | CDC_CD_RW | CDC_DVD_R)) { (CDC_CD_R | CDC_CD_RW | CDC_DVD_R)) {
/* Write Drive speed in kbytes/second MSB/LSB */ /* Write Drive speed in kbytes/second MSB/LSB */
rq.cmd[4] = (speed >> 8) & 0xff; cmd[4] = (speed >> 8) & 0xff;
rq.cmd[5] = speed & 0xff; cmd[5] = speed & 0xff;
} }
stat = ide_cd_queue_pc(drive, &rq); stat = ide_cd_queue_pc(drive, cmd, 0, NULL, 0, &sense, 0, 0);
if (!ide_cdrom_get_capabilities(drive, buf)) { if (!ide_cdrom_get_capabilities(drive, buf)) {
ide_cdrom_update_speed(drive, buf); ide_cdrom_update_speed(drive, buf);
...@@ -268,21 +268,19 @@ int ide_cdrom_get_mcn(struct cdrom_device_info *cdi, ...@@ -268,21 +268,19 @@ int ide_cdrom_get_mcn(struct cdrom_device_info *cdi,
{ {
ide_drive_t *drive = cdi->handle; ide_drive_t *drive = cdi->handle;
int stat, mcnlen; int stat, mcnlen;
struct request rq;
char buf[24]; char buf[24];
unsigned char cmd[BLK_MAX_CDB];
unsigned len = sizeof(buf);
ide_cd_init_rq(drive, &rq); memset(cmd, 0, BLK_MAX_CDB);
rq.data = buf; cmd[0] = GPCMD_READ_SUBCHANNEL;
rq.data_len = sizeof(buf); cmd[1] = 2; /* MSF addressing */
cmd[2] = 0x40; /* request subQ data */
cmd[3] = 2; /* format */
cmd[8] = len;
rq.cmd[0] = GPCMD_READ_SUBCHANNEL; stat = ide_cd_queue_pc(drive, cmd, 0, buf, &len, NULL, 0, 0);
rq.cmd[1] = 2; /* MSF addressing */
rq.cmd[2] = 0x40; /* request subQ data */
rq.cmd[3] = 2; /* format */
rq.cmd[8] = sizeof(buf);
stat = ide_cd_queue_pc(drive, &rq);
if (stat) if (stat)
return stat; return stat;
...@@ -298,14 +296,14 @@ int ide_cdrom_reset(struct cdrom_device_info *cdi) ...@@ -298,14 +296,14 @@ int ide_cdrom_reset(struct cdrom_device_info *cdi)
ide_drive_t *drive = cdi->handle; ide_drive_t *drive = cdi->handle;
struct cdrom_info *cd = drive->driver_data; struct cdrom_info *cd = drive->driver_data;
struct request_sense sense; struct request_sense sense;
struct request req; struct request *rq;
int ret; int ret;
ide_cd_init_rq(drive, &req); rq = blk_get_request(drive->queue, READ, __GFP_WAIT);
req.cmd_type = REQ_TYPE_SPECIAL; rq->cmd_type = REQ_TYPE_SPECIAL;
req.cmd_flags = REQ_QUIET; rq->cmd_flags = REQ_QUIET;
ret = ide_do_drive_cmd(drive, &req, ide_wait); ret = blk_execute_rq(drive->queue, cd->disk, rq, 0);
blk_put_request(rq);
/* /*
* A reset will unlock the door. If it was previously locked, * A reset will unlock the door. If it was previously locked,
* lock it again. * lock it again.
...@@ -351,8 +349,8 @@ static int ide_cd_fake_play_trkind(ide_drive_t *drive, void *arg) ...@@ -351,8 +349,8 @@ static int ide_cd_fake_play_trkind(ide_drive_t *drive, void *arg)
struct atapi_toc_entry *first_toc, *last_toc; struct atapi_toc_entry *first_toc, *last_toc;
unsigned long lba_start, lba_end; unsigned long lba_start, lba_end;
int stat; int stat;
struct request rq;
struct request_sense sense; struct request_sense sense;
unsigned char cmd[BLK_MAX_CDB];
stat = ide_cd_get_toc_entry(drive, ti->cdti_trk0, &first_toc); stat = ide_cd_get_toc_entry(drive, ti->cdti_trk0, &first_toc);
if (stat) if (stat)
...@@ -370,14 +368,13 @@ static int ide_cd_fake_play_trkind(ide_drive_t *drive, void *arg) ...@@ -370,14 +368,13 @@ static int ide_cd_fake_play_trkind(ide_drive_t *drive, void *arg)
if (lba_end <= lba_start) if (lba_end <= lba_start)
return -EINVAL; return -EINVAL;
ide_cd_init_rq(drive, &rq); memset(cmd, 0, BLK_MAX_CDB);
rq.sense = &sense; cmd[0] = GPCMD_PLAY_AUDIO_MSF;
rq.cmd[0] = GPCMD_PLAY_AUDIO_MSF; lba_to_msf(lba_start, &cmd[3], &cmd[4], &cmd[5]);
lba_to_msf(lba_start, &rq.cmd[3], &rq.cmd[4], &rq.cmd[5]); lba_to_msf(lba_end - 1, &cmd[6], &cmd[7], &cmd[8]);
lba_to_msf(lba_end - 1, &rq.cmd[6], &rq.cmd[7], &rq.cmd[8]);
return ide_cd_queue_pc(drive, &rq); return ide_cd_queue_pc(drive, cmd, 0, NULL, 0, &sense, 0, 0);
} }
static int ide_cd_read_tochdr(ide_drive_t *drive, void *arg) static int ide_cd_read_tochdr(ide_drive_t *drive, void *arg)
...@@ -447,8 +444,9 @@ int ide_cdrom_audio_ioctl(struct cdrom_device_info *cdi, ...@@ -447,8 +444,9 @@ int ide_cdrom_audio_ioctl(struct cdrom_device_info *cdi,
int ide_cdrom_packet(struct cdrom_device_info *cdi, int ide_cdrom_packet(struct cdrom_device_info *cdi,
struct packet_command *cgc) struct packet_command *cgc)
{ {
struct request req;
ide_drive_t *drive = cdi->handle; ide_drive_t *drive = cdi->handle;
unsigned int flags = 0;
unsigned len = cgc->buflen;
if (cgc->timeout <= 0) if (cgc->timeout <= 0)
cgc->timeout = ATAPI_WAIT_PC; cgc->timeout = ATAPI_WAIT_PC;
...@@ -456,24 +454,21 @@ int ide_cdrom_packet(struct cdrom_device_info *cdi, ...@@ -456,24 +454,21 @@ int ide_cdrom_packet(struct cdrom_device_info *cdi,
/* here we queue the commands from the uniform CD-ROM /* here we queue the commands from the uniform CD-ROM
layer. the packet must be complete, as we do not layer. the packet must be complete, as we do not
touch it at all. */ touch it at all. */
ide_cd_init_rq(drive, &req);
if (cgc->data_direction == CGC_DATA_WRITE) if (cgc->data_direction == CGC_DATA_WRITE)
req.cmd_flags |= REQ_RW; flags |= REQ_RW;
memcpy(req.cmd, cgc->cmd, CDROM_PACKET_SIZE);
if (cgc->sense) if (cgc->sense)
memset(cgc->sense, 0, sizeof(struct request_sense)); memset(cgc->sense, 0, sizeof(struct request_sense));
req.data = cgc->buffer;
req.data_len = cgc->buflen;
req.timeout = cgc->timeout;
if (cgc->quiet) if (cgc->quiet)
req.cmd_flags |= REQ_QUIET; flags |= REQ_QUIET;
req.sense = cgc->sense; cgc->stat = ide_cd_queue_pc(drive, cgc->cmd,
cgc->stat = ide_cd_queue_pc(drive, &req); cgc->data_direction == CGC_DATA_WRITE,
cgc->buffer, &len,
cgc->sense, cgc->timeout, flags);
if (!cgc->stat) if (!cgc->stat)
cgc->buflen -= req.data_len; cgc->buflen -= len;
return cgc->stat; return cgc->stat;
} }
...@@ -198,8 +198,7 @@ static ide_startstop_t __ide_do_rw_disk(ide_drive_t *drive, struct request *rq, ...@@ -198,8 +198,7 @@ static ide_startstop_t __ide_do_rw_disk(ide_drive_t *drive, struct request *rq,
} }
memset(&task, 0, sizeof(task)); memset(&task, 0, sizeof(task));
task.tf_flags = IDE_TFLAG_NO_SELECT_MASK; /* FIXME? */ task.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE;
task.tf_flags |= (IDE_TFLAG_TF | IDE_TFLAG_DEVICE);
if (drive->select.b.lba) { if (drive->select.b.lba) {
if (lba48) { if (lba48) {
...@@ -617,7 +616,8 @@ static void idedisk_prepare_flush(struct request_queue *q, struct request *rq) ...@@ -617,7 +616,8 @@ static void idedisk_prepare_flush(struct request_queue *q, struct request *rq)
*/ */
static int set_multcount(ide_drive_t *drive, int arg) static int set_multcount(ide_drive_t *drive, int arg)
{ {
struct request rq; struct request *rq;
int error;
if (arg < 0 || arg > drive->id->max_multsect) if (arg < 0 || arg > drive->id->max_multsect)
return -EINVAL; return -EINVAL;
...@@ -625,12 +625,13 @@ static int set_multcount(ide_drive_t *drive, int arg) ...@@ -625,12 +625,13 @@ static int set_multcount(ide_drive_t *drive, int arg)
if (drive->special.b.set_multmode) if (drive->special.b.set_multmode)
return -EBUSY; return -EBUSY;
ide_init_drive_cmd(&rq); rq = blk_get_request(drive->queue, READ, __GFP_WAIT);
rq.cmd_type = REQ_TYPE_ATA_TASKFILE; rq->cmd_type = REQ_TYPE_ATA_TASKFILE;
drive->mult_req = arg; drive->mult_req = arg;
drive->special.b.set_multmode = 1; drive->special.b.set_multmode = 1;
(void)ide_do_drive_cmd(drive, &rq, ide_wait); error = blk_execute_rq(drive->queue, NULL, rq, 0);
blk_put_request(rq);
return (drive->mult_count == arg) ? 0 : -EIO; return (drive->mult_count == arg) ? 0 : -EIO;
} }
......
...@@ -463,7 +463,7 @@ int ide_dma_setup(ide_drive_t *drive) ...@@ -463,7 +463,7 @@ int ide_dma_setup(ide_drive_t *drive)
} }
/* PRD table */ /* PRD table */
if (hwif->mmio) if (hwif->host_flags & IDE_HFLAG_MMIO)
writel(hwif->dmatable_dma, writel(hwif->dmatable_dma,
(void __iomem *)(hwif->dma_base + ATA_DMA_TABLE_OFS)); (void __iomem *)(hwif->dma_base + ATA_DMA_TABLE_OFS));
else else
...@@ -692,7 +692,7 @@ static int ide_tune_dma(ide_drive_t *drive) ...@@ -692,7 +692,7 @@ static int ide_tune_dma(ide_drive_t *drive)
ide_hwif_t *hwif = drive->hwif; ide_hwif_t *hwif = drive->hwif;
u8 speed; u8 speed;
if (noautodma || drive->nodma || (drive->id->capability & 1) == 0) if (drive->nodma || (drive->id->capability & 1) == 0)
return 0; return 0;
/* consult the list of known "bad" drives */ /* consult the list of known "bad" drives */
......
...@@ -286,11 +286,12 @@ static void idefloppy_queue_pc_head(ide_drive_t *drive, struct ide_atapi_pc *pc, ...@@ -286,11 +286,12 @@ static void idefloppy_queue_pc_head(ide_drive_t *drive, struct ide_atapi_pc *pc,
{ {
struct ide_floppy_obj *floppy = drive->driver_data; struct ide_floppy_obj *floppy = drive->driver_data;
ide_init_drive_cmd(rq); blk_rq_init(NULL, rq);
rq->buffer = (char *) pc; rq->buffer = (char *) pc;
rq->cmd_type = REQ_TYPE_SPECIAL; rq->cmd_type = REQ_TYPE_SPECIAL;
rq->cmd_flags |= REQ_PREEMPT;
rq->rq_disk = floppy->disk; 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) static struct ide_atapi_pc *idefloppy_next_pc_storage(ide_drive_t *drive)
...@@ -311,50 +312,41 @@ static struct request *idefloppy_next_rq_storage(ide_drive_t *drive) ...@@ -311,50 +312,41 @@ static struct request *idefloppy_next_rq_storage(ide_drive_t *drive)
return (&floppy->rq_stack[floppy->rq_stack_index++]); return (&floppy->rq_stack[floppy->rq_stack_index++]);
} }
static void idefloppy_request_sense_callback(ide_drive_t *drive) static void ide_floppy_callback(ide_drive_t *drive)
{ {
idefloppy_floppy_t *floppy = drive->driver_data; idefloppy_floppy_t *floppy = drive->driver_data;
u8 *buf = floppy->pc->buf; struct ide_atapi_pc *pc = floppy->pc;
int uptodate = pc->error ? 0 : 1;
debug_log("Reached %s\n", __func__); debug_log("Reached %s\n", __func__);
if (!floppy->pc->error) { if (floppy->failed_pc == pc)
floppy->sense_key = buf[2] & 0x0F; floppy->failed_pc = NULL;
floppy->asc = buf[12];
floppy->ascq = buf[13];
floppy->progress_indication = buf[15] & 0x80 ?
(u16)get_unaligned((u16 *)&buf[16]) : 0x10000;
if (floppy->failed_pc) if (pc->c[0] == GPCMD_READ_10 || pc->c[0] == GPCMD_WRITE_10 ||
debug_log("pc = %x, sense key = %x, asc = %x," (pc->rq && blk_pc_request(pc->rq)))
" ascq = %x\n", uptodate = 1; /* FIXME */
floppy->failed_pc->c[0], else if (pc->c[0] == GPCMD_REQUEST_SENSE) {
floppy->sense_key, u8 *buf = floppy->pc->buf;
floppy->asc,
floppy->ascq);
else
debug_log("sense key = %x, asc = %x, ascq = %x\n",
floppy->sense_key,
floppy->asc,
floppy->ascq);
if (!pc->error) {
floppy->sense_key = buf[2] & 0x0F;
floppy->asc = buf[12];
floppy->ascq = buf[13];
floppy->progress_indication = buf[15] & 0x80 ?
(u16)get_unaligned((u16 *)&buf[16]) : 0x10000;
idefloppy_end_request(drive, 1, 0); if (floppy->failed_pc)
} else { debug_log("pc = %x, ", floppy->failed_pc->c[0]);
printk(KERN_ERR "Error in REQUEST SENSE itself - Aborting"
" request!\n");
idefloppy_end_request(drive, 0, 0);
}
}
/* General packet command callback function. */ debug_log("sense key = %x, asc = %x, ascq = %x\n",
static void idefloppy_pc_callback(ide_drive_t *drive) floppy->sense_key, floppy->asc, floppy->ascq);
{ } else
idefloppy_floppy_t *floppy = drive->driver_data; printk(KERN_ERR "Error in REQUEST SENSE itself - "
"Aborting request!\n");
debug_log("Reached %s\n", __func__); }
idefloppy_end_request(drive, floppy->pc->error ? 0 : 1, 0); idefloppy_end_request(drive, uptodate, 0);
} }
static void idefloppy_init_pc(struct ide_atapi_pc *pc) static void idefloppy_init_pc(struct ide_atapi_pc *pc)
...@@ -365,7 +357,7 @@ static void idefloppy_init_pc(struct ide_atapi_pc *pc) ...@@ -365,7 +357,7 @@ static void idefloppy_init_pc(struct ide_atapi_pc *pc)
pc->req_xfer = 0; pc->req_xfer = 0;
pc->buf = pc->pc_buf; pc->buf = pc->pc_buf;
pc->buf_size = IDEFLOPPY_PC_BUFFER_SIZE; pc->buf_size = IDEFLOPPY_PC_BUFFER_SIZE;
pc->idefloppy_callback = &idefloppy_pc_callback; pc->callback = ide_floppy_callback;
} }
static void idefloppy_create_request_sense_cmd(struct ide_atapi_pc *pc) static void idefloppy_create_request_sense_cmd(struct ide_atapi_pc *pc)
...@@ -374,7 +366,6 @@ static void idefloppy_create_request_sense_cmd(struct ide_atapi_pc *pc) ...@@ -374,7 +366,6 @@ static void idefloppy_create_request_sense_cmd(struct ide_atapi_pc *pc)
pc->c[0] = GPCMD_REQUEST_SENSE; pc->c[0] = GPCMD_REQUEST_SENSE;
pc->c[4] = 255; pc->c[4] = 255;
pc->req_xfer = 18; pc->req_xfer = 18;
pc->idefloppy_callback = &idefloppy_request_sense_callback;
} }
/* /*
...@@ -397,174 +388,19 @@ static void idefloppy_retry_pc(ide_drive_t *drive) ...@@ -397,174 +388,19 @@ static void idefloppy_retry_pc(ide_drive_t *drive)
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; idefloppy_floppy_t *floppy = drive->driver_data;
ide_hwif_t *hwif = drive->hwif;
struct ide_atapi_pc *pc = floppy->pc;
struct request *rq = pc->rq;
xfer_func_t *xferfunc;
unsigned int temp;
int dma_error = 0;
u16 bcount;
u8 stat, ireason;
debug_log("Reached %s interrupt handler\n", __func__);
if (pc->flags & PC_FLAG_DMA_IN_PROGRESS) {
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");
pc->flags |= PC_FLAG_DMA_ERROR;
} else {
pc->xferred = pc->req_xfer;
idefloppy_update_buffers(drive, pc);
}
debug_log("DMA finished\n");
}
/* Clear the interrupt */
stat = ide_read_status(drive);
/* No more interrupts */
if ((stat & DRQ_STAT) == 0) {
debug_log("Packet command completed, %d bytes transferred\n",
pc->xferred);
pc->flags &= ~PC_FLAG_DMA_IN_PROGRESS;
local_irq_enable_in_hardirq();
if ((stat & ERR_STAT) || (pc->flags & PC_FLAG_DMA_ERROR)) {
/* Error detected */
debug_log("%s: I/O error\n", drive->name);
rq->errors++;
if (pc->c[0] == GPCMD_REQUEST_SENSE) {
printk(KERN_ERR "ide-floppy: I/O error in "
"request sense command\n");
return ide_do_reset(drive);
}
/* Retry operation */
idefloppy_retry_pc(drive);
/* queued, but not started */
return ide_stopped;
}
pc->error = 0;
if (floppy->failed_pc == pc)
floppy->failed_pc = NULL;
/* Command finished - Call the callback function */
pc->idefloppy_callback(drive);
return ide_stopped;
}
if (pc->flags & PC_FLAG_DMA_IN_PROGRESS) {
pc->flags &= ~PC_FLAG_DMA_IN_PROGRESS;
printk(KERN_ERR "ide-floppy: The floppy wants to issue "
"more interrupts in DMA mode\n");
ide_dma_off(drive);
return ide_do_reset(drive);
}
/* Get the number of bytes to transfer */
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.nsect_addr);
if (ireason & CD) {
printk(KERN_ERR "ide-floppy: CoD != 0 in %s\n", __func__);
return ide_do_reset(drive);
}
if (((ireason & IO) == IO) == !!(pc->flags & PC_FLAG_WRITING)) {
/* Hopefully, we will never get here */
printk(KERN_ERR "ide-floppy: We wanted to %s, ",
(ireason & IO) ? "Write" : "Read");
printk(KERN_ERR "but the floppy wants us to %s !\n",
(ireason & IO) ? "Read" : "Write");
return ide_do_reset(drive);
}
if (!(pc->flags & PC_FLAG_WRITING)) {
/* Reading - Check that we have enough space */
temp = pc->xferred + bcount;
if (temp > pc->req_xfer) {
if (temp > pc->buf_size) {
printk(KERN_ERR "ide-floppy: The floppy wants "
"to send us more data than expected "
"- discarding data\n");
ide_pad_transfer(drive, 0, bcount);
ide_set_handler(drive,
&idefloppy_pc_intr,
IDEFLOPPY_WAIT_CMD,
NULL);
return ide_started;
}
debug_log("The floppy wants to send us more data than"
" expected - allowing transfer\n");
}
}
if (pc->flags & PC_FLAG_WRITING)
xferfunc = hwif->output_data;
else
xferfunc = hwif->input_data;
if (pc->buf)
xferfunc(drive, NULL, pc->cur_pos, bcount);
else
ide_floppy_io_buffers(drive, pc, bcount,
!!(pc->flags & PC_FLAG_WRITING));
/* Update the current position */
pc->xferred += bcount;
pc->cur_pos += bcount;
/* And set the interrupt handler again */
ide_set_handler(drive, &idefloppy_pc_intr, IDEFLOPPY_WAIT_CMD, NULL);
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.nsect_addr);
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 */ return ide_pc_intr(drive, floppy->pc, idefloppy_pc_intr,
ide_set_handler(drive, &idefloppy_pc_intr, IDEFLOPPY_WAIT_CMD, NULL); IDEFLOPPY_WAIT_CMD, NULL, idefloppy_update_buffers,
idefloppy_retry_pc, NULL, ide_floppy_io_buffers);
/* Send the actual packet */
hwif->output_data(drive, NULL, floppy->pc->c, 12);
return ide_started;
} }
/* /*
* What we have here is a classic case of a top half / bottom half interrupt * 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 * service routine. In interrupt mode, the device sends an interrupt to signal
* that it is ready to receive a packet. However, we need to delay about 2-3 * that it is ready to receive a packet. However, we need to delay about 2-3
* ticks before issuing the packet or we gets in trouble. * ticks before issuing the packet or we gets in trouble.
*
* So, follow carefully. transfer_pc1 is called as an interrupt (or directly).
* In either case, when the device says it's ready for a packet, we schedule
* the packet transfer to occur about 2-3 ticks later in transfer_pc2.
*/ */
static int idefloppy_transfer_pc2(ide_drive_t *drive) static int idefloppy_transfer_pc(ide_drive_t *drive)
{ {
idefloppy_floppy_t *floppy = drive->driver_data; idefloppy_floppy_t *floppy = drive->driver_data;
...@@ -575,24 +411,19 @@ static int idefloppy_transfer_pc2(ide_drive_t *drive) ...@@ -575,24 +411,19 @@ static int idefloppy_transfer_pc2(ide_drive_t *drive)
return IDEFLOPPY_WAIT_CMD; return IDEFLOPPY_WAIT_CMD;
} }
static ide_startstop_t idefloppy_transfer_pc1(ide_drive_t *drive)
/*
* Called as an interrupt (or directly). When the device says it's ready for a
* packet, we schedule the packet transfer to occur about 2-3 ticks later in
* transfer_pc.
*/
static ide_startstop_t idefloppy_start_pc_transfer(ide_drive_t *drive)
{ {
ide_hwif_t *hwif = drive->hwif;
idefloppy_floppy_t *floppy = drive->driver_data; idefloppy_floppy_t *floppy = drive->driver_data;
ide_startstop_t startstop; struct ide_atapi_pc *pc = floppy->pc;
u8 ireason; ide_expiry_t *expiry;
unsigned int timeout;
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.nsect_addr);
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);
}
/* /*
* The following delay solves a problem with ATAPI Zip 100 drives * The following delay solves a problem with ATAPI Zip 100 drives
* where the Busy flag was apparently being deasserted before the * where the Busy flag was apparently being deasserted before the
...@@ -601,10 +432,15 @@ static ide_startstop_t idefloppy_transfer_pc1(ide_drive_t *drive) ...@@ -601,10 +432,15 @@ static ide_startstop_t idefloppy_transfer_pc1(ide_drive_t *drive)
* 40 and 50msec work well. idefloppy_pc_intr will not be actually * 40 and 50msec work well. idefloppy_pc_intr will not be actually
* used until after the packet is moved in about 50 msec. * used until after the packet is moved in about 50 msec.
*/ */
if (pc->flags & PC_FLAG_ZIP_DRIVE) {
timeout = floppy->ticks;
expiry = &idefloppy_transfer_pc;
} else {
timeout = IDEFLOPPY_WAIT_CMD;
expiry = NULL;
}
ide_set_handler(drive, &idefloppy_pc_intr, floppy->ticks, return ide_transfer_pc(drive, pc, idefloppy_pc_intr, timeout, expiry);
&idefloppy_transfer_pc2);
return ide_started;
} }
static void ide_floppy_report_error(idefloppy_floppy_t *floppy, static void ide_floppy_report_error(idefloppy_floppy_t *floppy,
...@@ -627,10 +463,6 @@ static ide_startstop_t idefloppy_issue_pc(ide_drive_t *drive, ...@@ -627,10 +463,6 @@ static ide_startstop_t idefloppy_issue_pc(ide_drive_t *drive,
struct ide_atapi_pc *pc) struct ide_atapi_pc *pc)
{ {
idefloppy_floppy_t *floppy = drive->driver_data; idefloppy_floppy_t *floppy = drive->driver_data;
ide_hwif_t *hwif = drive->hwif;
ide_handler_t *pkt_xfer_routine;
u16 bcount;
u8 dma;
if (floppy->failed_pc == NULL && if (floppy->failed_pc == NULL &&
pc->c[0] != GPCMD_REQUEST_SENSE) pc->c[0] != GPCMD_REQUEST_SENSE)
...@@ -645,65 +477,16 @@ static ide_startstop_t idefloppy_issue_pc(ide_drive_t *drive, ...@@ -645,65 +477,16 @@ static ide_startstop_t idefloppy_issue_pc(ide_drive_t *drive,
pc->error = IDEFLOPPY_ERROR_GENERAL; pc->error = IDEFLOPPY_ERROR_GENERAL;
floppy->failed_pc = NULL; floppy->failed_pc = NULL;
pc->idefloppy_callback(drive); pc->callback(drive);
return ide_stopped; return ide_stopped;
} }
debug_log("Retry number - %d\n", pc->retries); debug_log("Retry number - %d\n", pc->retries);
pc->retries++; pc->retries++;
/* We haven't transferred any data yet */
pc->xferred = 0;
pc->cur_pos = pc->buf;
bcount = min(pc->req_xfer, 63 * 1024);
if (pc->flags & PC_FLAG_DMA_ERROR) {
pc->flags &= ~PC_FLAG_DMA_ERROR;
ide_dma_off(drive);
}
dma = 0;
if ((pc->flags & PC_FLAG_DMA_RECOMMENDED) && drive->using_dma)
dma = !hwif->dma_ops->dma_setup(drive);
ide_pktcmd_tf_load(drive, IDE_TFLAG_NO_SELECT_MASK | return ide_issue_pc(drive, pc, idefloppy_start_pc_transfer,
IDE_TFLAG_OUT_DEVICE, bcount, dma); IDEFLOPPY_WAIT_CMD, NULL);
if (dma) {
/* Begin DMA, if necessary */
pc->flags |= PC_FLAG_DMA_IN_PROGRESS;
hwif->dma_ops->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;
}
if (floppy->flags & IDEFLOPPY_FLAG_DRQ_INTERRUPT) {
/* Issue the packet command */
ide_execute_command(drive, WIN_PACKETCMD,
pkt_xfer_routine,
IDEFLOPPY_WAIT_CMD,
NULL);
return ide_started;
} else {
/* Issue the packet command */
ide_execute_pkt_cmd(drive);
return (*pkt_xfer_routine) (drive);
}
}
static void idefloppy_rw_callback(ide_drive_t *drive)
{
debug_log("Reached %s\n", __func__);
idefloppy_end_request(drive, 1, 0);
return;
} }
static void idefloppy_create_prevent_cmd(struct ide_atapi_pc *pc, int prevent) static void idefloppy_create_prevent_cmd(struct ide_atapi_pc *pc, int prevent)
...@@ -800,21 +583,19 @@ static void idefloppy_create_rw_cmd(idefloppy_floppy_t *floppy, ...@@ -800,21 +583,19 @@ static void idefloppy_create_rw_cmd(idefloppy_floppy_t *floppy,
put_unaligned(cpu_to_be16(blocks), (unsigned short *)&pc->c[7]); put_unaligned(cpu_to_be16(blocks), (unsigned short *)&pc->c[7]);
put_unaligned(cpu_to_be32(block), (unsigned int *) &pc->c[2]); put_unaligned(cpu_to_be32(block), (unsigned int *) &pc->c[2]);
pc->idefloppy_callback = &idefloppy_rw_callback;
pc->rq = rq; pc->rq = rq;
pc->b_count = cmd == READ ? 0 : rq->bio->bi_size; pc->b_count = cmd == READ ? 0 : rq->bio->bi_size;
if (rq->cmd_flags & REQ_RW) if (rq->cmd_flags & REQ_RW)
pc->flags |= PC_FLAG_WRITING; pc->flags |= PC_FLAG_WRITING;
pc->buf = NULL; pc->buf = NULL;
pc->req_xfer = pc->buf_size = blocks * floppy->block_size; pc->req_xfer = pc->buf_size = blocks * floppy->block_size;
pc->flags |= PC_FLAG_DMA_RECOMMENDED; pc->flags |= PC_FLAG_DMA_OK;
} }
static void idefloppy_blockpc_cmd(idefloppy_floppy_t *floppy, static void idefloppy_blockpc_cmd(idefloppy_floppy_t *floppy,
struct ide_atapi_pc *pc, struct request *rq) struct ide_atapi_pc *pc, struct request *rq)
{ {
idefloppy_init_pc(pc); idefloppy_init_pc(pc);
pc->idefloppy_callback = &idefloppy_rw_callback;
memcpy(pc->c, rq->cmd, sizeof(pc->c)); memcpy(pc->c, rq->cmd, sizeof(pc->c));
pc->rq = rq; pc->rq = rq;
pc->b_count = rq->data_len; pc->b_count = rq->data_len;
...@@ -822,7 +603,7 @@ static void idefloppy_blockpc_cmd(idefloppy_floppy_t *floppy, ...@@ -822,7 +603,7 @@ static void idefloppy_blockpc_cmd(idefloppy_floppy_t *floppy,
pc->flags |= PC_FLAG_WRITING; pc->flags |= PC_FLAG_WRITING;
pc->buf = rq->data; pc->buf = rq->data;
if (rq->bio) if (rq->bio)
pc->flags |= PC_FLAG_DMA_RECOMMENDED; pc->flags |= PC_FLAG_DMA_OK;
/* /*
* possibly problematic, doesn't look like ide-floppy correctly * possibly problematic, doesn't look like ide-floppy correctly
* handled scattered requests if dma fails... * handled scattered requests if dma fails...
...@@ -875,7 +656,14 @@ static ide_startstop_t idefloppy_do_request(ide_drive_t *drive, ...@@ -875,7 +656,14 @@ static ide_startstop_t idefloppy_do_request(ide_drive_t *drive,
return ide_stopped; return ide_stopped;
} }
if (floppy->flags & IDEFLOPPY_FLAG_DRQ_INTERRUPT)
pc->flags |= PC_FLAG_DRQ_INTERRUPT;
if (floppy->flags & IDEFLOPPY_FLAG_ZIP_DRIVE)
pc->flags |= PC_FLAG_ZIP_DRIVE;
pc->rq = rq; pc->rq = rq;
return idefloppy_issue_pc(drive, pc); return idefloppy_issue_pc(drive, pc);
} }
...@@ -886,14 +674,16 @@ static ide_startstop_t idefloppy_do_request(ide_drive_t *drive, ...@@ -886,14 +674,16 @@ static ide_startstop_t idefloppy_do_request(ide_drive_t *drive,
static int idefloppy_queue_pc_tail(ide_drive_t *drive, struct ide_atapi_pc *pc) static int idefloppy_queue_pc_tail(ide_drive_t *drive, struct ide_atapi_pc *pc)
{ {
struct ide_floppy_obj *floppy = drive->driver_data; struct ide_floppy_obj *floppy = drive->driver_data;
struct request rq; struct request *rq;
int error;
ide_init_drive_cmd(&rq); rq = blk_get_request(drive->queue, READ, __GFP_WAIT);
rq.buffer = (char *) pc; rq->buffer = (char *) pc;
rq.cmd_type = REQ_TYPE_SPECIAL; rq->cmd_type = REQ_TYPE_SPECIAL;
rq.rq_disk = floppy->disk; 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;
} }
/* /*
...@@ -1622,11 +1412,6 @@ static int ide_floppy_probe(ide_drive_t *drive) ...@@ -1622,11 +1412,6 @@ static int ide_floppy_probe(ide_drive_t *drive)
" of ide-floppy\n", drive->name); " of ide-floppy\n", drive->name);
goto failed; goto failed;
} }
if (drive->scsi) {
printk(KERN_INFO "ide-floppy: passing drive %s to ide-scsi"
" emulation.\n", drive->name);
goto failed;
}
floppy = kzalloc(sizeof(idefloppy_floppy_t), GFP_KERNEL); floppy = kzalloc(sizeof(idefloppy_floppy_t), GFP_KERNEL);
if (!floppy) { if (!floppy) {
printk(KERN_ERR "ide-floppy: %s: Can't allocate a floppy" printk(KERN_ERR "ide-floppy: %s: Can't allocate a floppy"
......
...@@ -358,31 +358,6 @@ void ide_end_drive_cmd (ide_drive_t *drive, u8 stat, u8 err) ...@@ -358,31 +358,6 @@ void ide_end_drive_cmd (ide_drive_t *drive, u8 stat, u8 err)
EXPORT_SYMBOL(ide_end_drive_cmd); EXPORT_SYMBOL(ide_end_drive_cmd);
/**
* try_to_flush_leftover_data - flush junk
* @drive: drive to flush
*
* try_to_flush_leftover_data() is invoked in response to a drive
* unexpectedly having its DRQ_STAT bit set. As an alternative to
* resetting the drive, this routine tries to clear the condition
* by read a sector's worth of data from the drive. Of course,
* this may not help if the drive is *waiting* for data from *us*.
*/
static void try_to_flush_leftover_data (ide_drive_t *drive)
{
int i = (drive->mult_count ? drive->mult_count : 1) * SECTOR_WORDS;
if (drive->media != ide_disk)
return;
while (i > 0) {
u32 buffer[16];
u32 wcount = (i > 16) ? 16 : i;
i -= wcount;
drive->hwif->input_data(drive, NULL, buffer, wcount * 4);
}
}
static void ide_kill_rq(ide_drive_t *drive, struct request *rq) static void ide_kill_rq(ide_drive_t *drive, struct request *rq)
{ {
if (rq->rq_disk) { if (rq->rq_disk) {
...@@ -422,8 +397,11 @@ static ide_startstop_t ide_ata_error(ide_drive_t *drive, struct request *rq, u8 ...@@ -422,8 +397,11 @@ static ide_startstop_t ide_ata_error(ide_drive_t *drive, struct request *rq, u8
} }
if ((stat & DRQ_STAT) && rq_data_dir(rq) == READ && if ((stat & DRQ_STAT) && rq_data_dir(rq) == READ &&
(hwif->host_flags & IDE_HFLAG_ERROR_STOPS_FIFO) == 0) (hwif->host_flags & IDE_HFLAG_ERROR_STOPS_FIFO) == 0) {
try_to_flush_leftover_data(drive); int nsect = drive->mult_count ? drive->mult_count : 1;
ide_pad_transfer(drive, READ, nsect * SECTOR_SIZE);
}
if (rq->errors >= ERROR_MAX || blk_noretry_request(rq)) { if (rq->errors >= ERROR_MAX || blk_noretry_request(rq)) {
ide_kill_rq(drive, rq); ide_kill_rq(drive, rq);
...@@ -459,7 +437,7 @@ static ide_startstop_t ide_atapi_error(ide_drive_t *drive, struct request *rq, u ...@@ -459,7 +437,7 @@ static ide_startstop_t ide_atapi_error(ide_drive_t *drive, struct request *rq, u
if (ide_read_status(drive) & (BUSY_STAT | DRQ_STAT)) if (ide_read_status(drive) & (BUSY_STAT | DRQ_STAT))
/* force an abort */ /* force an abort */
hwif->OUTBSYNC(drive, WIN_IDLEIMMEDIATE, hwif->OUTBSYNC(hwif, WIN_IDLEIMMEDIATE,
hwif->io_ports.command_addr); hwif->io_ports.command_addr);
if (rq->errors >= ERROR_MAX) { if (rq->errors >= ERROR_MAX) {
...@@ -1538,89 +1516,31 @@ irqreturn_t ide_intr (int irq, void *dev_id) ...@@ -1538,89 +1516,31 @@ irqreturn_t ide_intr (int irq, void *dev_id)
return IRQ_HANDLED; return IRQ_HANDLED;
} }
/**
* ide_init_drive_cmd - initialize a drive command request
* @rq: request object
*
* Initialize a request before we fill it in and send it down to
* ide_do_drive_cmd. Commands must be set up by this function. Right
* now it doesn't do a lot, but if that changes abusers will have a
* nasty surprise.
*/
void ide_init_drive_cmd (struct request *rq)
{
blk_rq_init(NULL, rq);
}
EXPORT_SYMBOL(ide_init_drive_cmd);
/** /**
* ide_do_drive_cmd - issue IDE special command * ide_do_drive_cmd - issue IDE special command
* @drive: device to issue command * @drive: device to issue command
* @rq: request to issue * @rq: request to issue
* @action: action for processing
* *
* This function issues a special IDE device request * This function issues a special IDE device request
* onto the request queue. * onto the request queue.
* *
* If action is ide_wait, then the rq is queued at the end of the * the rq is queued at the head of the request queue, displacing
* request queue, and the function sleeps until it has been processed. * the currently-being-processed request and this function
* This is for use when invoked from an ioctl handler. * returns immediately without waiting for the new rq to be
* * completed. This is VERY DANGEROUS, and is intended for
* If action is ide_preempt, then the rq is queued at the head of * careful use by the ATAPI tape/cdrom driver code.
* the request queue, displacing the currently-being-processed
* request and this function returns immediately without waiting
* for the new rq to be completed. This is VERY DANGEROUS, and is
* intended for careful use by the ATAPI tape/cdrom driver code.
*
* If action is ide_end, then the rq is queued at the end of the
* request queue, and the function returns immediately without waiting
* for the new rq to be completed. This is again intended for careful
* use by the ATAPI tape/cdrom driver code.
*/ */
int ide_do_drive_cmd (ide_drive_t *drive, struct request *rq, ide_action_t action) void ide_do_drive_cmd(ide_drive_t *drive, struct request *rq)
{ {
unsigned long flags; unsigned long flags;
ide_hwgroup_t *hwgroup = HWGROUP(drive); ide_hwgroup_t *hwgroup = HWGROUP(drive);
DECLARE_COMPLETION_ONSTACK(wait);
int where = ELEVATOR_INSERT_BACK, err;
int must_wait = (action == ide_wait || action == ide_head_wait);
rq->errors = 0;
/*
* we need to hold an extra reference to request for safe inspection
* after completion
*/
if (must_wait) {
rq->ref_count++;
rq->end_io_data = &wait;
rq->end_io = blk_end_sync_rq;
}
spin_lock_irqsave(&ide_lock, flags); spin_lock_irqsave(&ide_lock, flags);
if (action == ide_preempt) hwgroup->rq = NULL;
hwgroup->rq = NULL; __elv_add_request(drive->queue, rq, ELEVATOR_INSERT_FRONT, 1);
if (action == ide_preempt || action == ide_head_wait) { __generic_unplug_device(drive->queue);
where = ELEVATOR_INSERT_FRONT;
rq->cmd_flags |= REQ_PREEMPT;
}
__elv_add_request(drive->queue, rq, where, 0);
ide_do_request(hwgroup, IDE_NO_IRQ);
spin_unlock_irqrestore(&ide_lock, flags); spin_unlock_irqrestore(&ide_lock, flags);
err = 0;
if (must_wait) {
wait_for_completion(&wait);
if (rq->errors)
err = -EIO;
blk_put_request(rq);
}
return err;
} }
EXPORT_SYMBOL(ide_do_drive_cmd); EXPORT_SYMBOL(ide_do_drive_cmd);
...@@ -1637,6 +1557,8 @@ void ide_pktcmd_tf_load(ide_drive_t *drive, u32 tf_flags, u16 bcount, u8 dma) ...@@ -1637,6 +1557,8 @@ void ide_pktcmd_tf_load(ide_drive_t *drive, u32 tf_flags, u16 bcount, u8 dma)
task.tf.lbah = (bcount >> 8) & 0xff; task.tf.lbah = (bcount >> 8) & 0xff;
ide_tf_dump(drive->name, &task.tf); ide_tf_dump(drive->name, &task.tf);
ide_set_irq(drive, 1);
SELECT_MASK(drive, 0);
drive->hwif->tf_load(drive, &task); drive->hwif->tf_load(drive, &task);
} }
......
...@@ -42,7 +42,7 @@ static void ide_outb (u8 val, unsigned long port) ...@@ -42,7 +42,7 @@ static void ide_outb (u8 val, unsigned long port)
outb(val, port); outb(val, port);
} }
static void ide_outbsync (ide_drive_t *drive, u8 addr, unsigned long port) static void ide_outbsync(ide_hwif_t *hwif, u8 addr, unsigned long port)
{ {
outb(addr, port); outb(addr, port);
} }
...@@ -68,7 +68,7 @@ static void ide_mm_outb (u8 value, unsigned long port) ...@@ -68,7 +68,7 @@ static void ide_mm_outb (u8 value, unsigned long port)
writeb(value, (void __iomem *) port); writeb(value, (void __iomem *) port);
} }
static void ide_mm_outbsync (ide_drive_t *drive, u8 value, unsigned long port) static void ide_mm_outbsync(ide_hwif_t *hwif, u8 value, unsigned long port)
{ {
writeb(value, (void __iomem *) port); writeb(value, (void __iomem *) port);
} }
...@@ -95,7 +95,7 @@ void SELECT_DRIVE (ide_drive_t *drive) ...@@ -95,7 +95,7 @@ void SELECT_DRIVE (ide_drive_t *drive)
hwif->OUTB(drive->select.all, hwif->io_ports.device_addr); hwif->OUTB(drive->select.all, hwif->io_ports.device_addr);
} }
static void SELECT_MASK(ide_drive_t *drive, int mask) void SELECT_MASK(ide_drive_t *drive, int mask)
{ {
const struct ide_port_ops *port_ops = drive->hwif->port_ops; const struct ide_port_ops *port_ops = drive->hwif->port_ops;
...@@ -120,11 +120,6 @@ static void ide_tf_load(ide_drive_t *drive, ide_task_t *task) ...@@ -120,11 +120,6 @@ static void ide_tf_load(ide_drive_t *drive, ide_task_t *task)
if (task->tf_flags & IDE_TFLAG_FLAGGED) if (task->tf_flags & IDE_TFLAG_FLAGGED)
HIHI = 0xFF; HIHI = 0xFF;
ide_set_irq(drive, 1);
if ((task->tf_flags & IDE_TFLAG_NO_SELECT_MASK) == 0)
SELECT_MASK(drive, 0);
if (task->tf_flags & IDE_TFLAG_OUT_DATA) { if (task->tf_flags & IDE_TFLAG_OUT_DATA) {
u16 data = (tf->hob_data << 8) | tf->data; u16 data = (tf->hob_data << 8) | tf->data;
...@@ -191,7 +186,7 @@ static void ide_tf_read(ide_drive_t *drive, ide_task_t *task) ...@@ -191,7 +186,7 @@ static void ide_tf_read(ide_drive_t *drive, ide_task_t *task)
} }
/* be sure we're looking at the low order bits */ /* be sure we're looking at the low order bits */
tf_outb(drive->ctl & ~0x80, io_ports->ctl_addr); tf_outb(ATA_DEVCTL_OBS & ~0x80, io_ports->ctl_addr);
if (task->tf_flags & IDE_TFLAG_IN_NSECT) if (task->tf_flags & IDE_TFLAG_IN_NSECT)
tf->nsect = tf_inb(io_ports->nsect_addr); tf->nsect = tf_inb(io_ports->nsect_addr);
...@@ -205,7 +200,7 @@ static void ide_tf_read(ide_drive_t *drive, ide_task_t *task) ...@@ -205,7 +200,7 @@ static void ide_tf_read(ide_drive_t *drive, ide_task_t *task)
tf->device = tf_inb(io_ports->device_addr); tf->device = tf_inb(io_ports->device_addr);
if (task->tf_flags & IDE_TFLAG_LBA48) { if (task->tf_flags & IDE_TFLAG_LBA48) {
tf_outb(drive->ctl | 0x80, io_ports->ctl_addr); tf_outb(ATA_DEVCTL_OBS | 0x80, io_ports->ctl_addr);
if (task->tf_flags & IDE_TFLAG_IN_HOB_FEATURE) if (task->tf_flags & IDE_TFLAG_IN_HOB_FEATURE)
tf->hob_feature = tf_inb(io_ports->feature_addr); tf->hob_feature = tf_inb(io_ports->feature_addr);
...@@ -689,9 +684,9 @@ int ide_driveid_update(ide_drive_t *drive) ...@@ -689,9 +684,9 @@ int ide_driveid_update(ide_drive_t *drive)
*/ */
SELECT_MASK(drive, 1); SELECT_MASK(drive, 1);
ide_set_irq(drive, 1); ide_set_irq(drive, 0);
msleep(50); msleep(50);
hwif->OUTBSYNC(drive, WIN_IDENTIFY, hwif->io_ports.command_addr); hwif->OUTBSYNC(hwif, WIN_IDENTIFY, hwif->io_ports.command_addr);
timeout = jiffies + WAIT_WORSTCASE; timeout = jiffies + WAIT_WORSTCASE;
do { do {
if (time_after(jiffies, timeout)) { if (time_after(jiffies, timeout)) {
...@@ -744,9 +739,6 @@ int ide_config_drive_speed(ide_drive_t *drive, u8 speed) ...@@ -744,9 +739,6 @@ int ide_config_drive_speed(ide_drive_t *drive, u8 speed)
int error = 0; int error = 0;
u8 stat; u8 stat;
// while (HWGROUP(drive)->busy)
// msleep(50);
#ifdef CONFIG_BLK_DEV_IDEDMA #ifdef CONFIG_BLK_DEV_IDEDMA
if (hwif->dma_ops) /* check if host supports DMA */ if (hwif->dma_ops) /* check if host supports DMA */
hwif->dma_ops->dma_host_set(drive, 0); hwif->dma_ops->dma_host_set(drive, 0);
...@@ -781,7 +773,7 @@ int ide_config_drive_speed(ide_drive_t *drive, u8 speed) ...@@ -781,7 +773,7 @@ int ide_config_drive_speed(ide_drive_t *drive, u8 speed)
ide_set_irq(drive, 0); ide_set_irq(drive, 0);
hwif->OUTB(speed, io_ports->nsect_addr); hwif->OUTB(speed, io_ports->nsect_addr);
hwif->OUTB(SETFEATURES_XFER, io_ports->feature_addr); hwif->OUTB(SETFEATURES_XFER, io_ports->feature_addr);
hwif->OUTBSYNC(drive, WIN_SETFEATURES, io_ports->command_addr); hwif->OUTBSYNC(hwif, WIN_SETFEATURES, io_ports->command_addr);
if (drive->quirk_list == 2) if (drive->quirk_list == 2)
ide_set_irq(drive, 1); ide_set_irq(drive, 1);
...@@ -889,7 +881,7 @@ void ide_execute_command(ide_drive_t *drive, u8 cmd, ide_handler_t *handler, ...@@ -889,7 +881,7 @@ void ide_execute_command(ide_drive_t *drive, u8 cmd, ide_handler_t *handler,
spin_lock_irqsave(&ide_lock, flags); spin_lock_irqsave(&ide_lock, flags);
__ide_set_handler(drive, handler, timeout, expiry); __ide_set_handler(drive, handler, timeout, expiry);
hwif->OUTBSYNC(drive, cmd, hwif->io_ports.command_addr); hwif->OUTBSYNC(hwif, cmd, hwif->io_ports.command_addr);
/* /*
* Drive takes 400nS to respond, we must avoid the IRQ being * Drive takes 400nS to respond, we must avoid the IRQ being
* serviced before that. * serviced before that.
...@@ -907,7 +899,7 @@ void ide_execute_pkt_cmd(ide_drive_t *drive) ...@@ -907,7 +899,7 @@ void ide_execute_pkt_cmd(ide_drive_t *drive)
unsigned long flags; unsigned long flags;
spin_lock_irqsave(&ide_lock, flags); spin_lock_irqsave(&ide_lock, flags);
hwif->OUTBSYNC(drive, WIN_PACKETCMD, hwif->io_ports.command_addr); hwif->OUTBSYNC(hwif, WIN_PACKETCMD, hwif->io_ports.command_addr);
ndelay(400); ndelay(400);
spin_unlock_irqrestore(&ide_lock, flags); spin_unlock_irqrestore(&ide_lock, flags);
} }
...@@ -1102,7 +1094,7 @@ static ide_startstop_t do_reset1 (ide_drive_t *drive, int do_not_try_atapi) ...@@ -1102,7 +1094,7 @@ static ide_startstop_t do_reset1 (ide_drive_t *drive, int do_not_try_atapi)
pre_reset(drive); pre_reset(drive);
SELECT_DRIVE(drive); SELECT_DRIVE(drive);
udelay (20); udelay (20);
hwif->OUTBSYNC(drive, WIN_SRST, io_ports->command_addr); hwif->OUTBSYNC(hwif, WIN_SRST, io_ports->command_addr);
ndelay(400); ndelay(400);
hwgroup->poll_timeout = jiffies + WAIT_WORSTCASE; hwgroup->poll_timeout = jiffies + WAIT_WORSTCASE;
hwgroup->polling = 1; hwgroup->polling = 1;
...@@ -1133,14 +1125,14 @@ static ide_startstop_t do_reset1 (ide_drive_t *drive, int do_not_try_atapi) ...@@ -1133,14 +1125,14 @@ static ide_startstop_t do_reset1 (ide_drive_t *drive, int do_not_try_atapi)
* recover from reset very quickly, saving us the first 50ms wait time. * recover from reset very quickly, saving us the first 50ms wait time.
*/ */
/* set SRST and nIEN */ /* set SRST and nIEN */
hwif->OUTBSYNC(drive, drive->ctl|6, io_ports->ctl_addr); hwif->OUTBSYNC(hwif, ATA_DEVCTL_OBS | 6, io_ports->ctl_addr);
/* more than enough time */ /* more than enough time */
udelay(10); udelay(10);
if (drive->quirk_list == 2) if (drive->quirk_list == 2)
ctl = drive->ctl; /* clear SRST and nIEN */ ctl = ATA_DEVCTL_OBS; /* clear SRST and nIEN */
else else
ctl = drive->ctl | 2; /* clear SRST, leave nIEN */ ctl = ATA_DEVCTL_OBS | 2; /* clear SRST, leave nIEN */
hwif->OUTBSYNC(drive, ctl, io_ports->ctl_addr); hwif->OUTBSYNC(hwif, ctl, io_ports->ctl_addr);
/* more than enough time */ /* more than enough time */
udelay(10); udelay(10);
hwgroup->poll_timeout = jiffies + WAIT_WORSTCASE; hwgroup->poll_timeout = jiffies + WAIT_WORSTCASE;
......
...@@ -293,7 +293,7 @@ static int actual_try_to_identify (ide_drive_t *drive, u8 cmd) ...@@ -293,7 +293,7 @@ static int actual_try_to_identify (ide_drive_t *drive, u8 cmd)
hwif->OUTB(0, io_ports->feature_addr); hwif->OUTB(0, io_ports->feature_addr);
/* ask drive for ID */ /* ask drive for ID */
hwif->OUTBSYNC(drive, cmd, io_ports->command_addr); hwif->OUTBSYNC(hwif, cmd, hwif->io_ports.command_addr);
timeout = ((cmd == WIN_IDENTIFY) ? WAIT_WORSTCASE : WAIT_PIDENTIFY) / 2; timeout = ((cmd == WIN_IDENTIFY) ? WAIT_WORSTCASE : WAIT_PIDENTIFY) / 2;
timeout += jiffies; timeout += jiffies;
...@@ -478,9 +478,9 @@ static int do_probe (ide_drive_t *drive, u8 cmd) ...@@ -478,9 +478,9 @@ static int do_probe (ide_drive_t *drive, u8 cmd)
printk(KERN_ERR "%s: no response (status = 0x%02x), " printk(KERN_ERR "%s: no response (status = 0x%02x), "
"resetting drive\n", drive->name, stat); "resetting drive\n", drive->name, stat);
msleep(50); msleep(50);
hwif->OUTB(drive->select.all, io_ports->device_addr); SELECT_DRIVE(drive);
msleep(50); msleep(50);
hwif->OUTBSYNC(drive, WIN_SRST, io_ports->command_addr); hwif->OUTBSYNC(hwif, WIN_SRST, io_ports->command_addr);
(void)ide_busy_sleep(hwif); (void)ide_busy_sleep(hwif);
rc = try_to_identify(drive, cmd); rc = try_to_identify(drive, cmd);
} }
...@@ -516,7 +516,7 @@ static void enable_nest (ide_drive_t *drive) ...@@ -516,7 +516,7 @@ static void enable_nest (ide_drive_t *drive)
printk("%s: enabling %s -- ", hwif->name, drive->id->model); printk("%s: enabling %s -- ", hwif->name, drive->id->model);
SELECT_DRIVE(drive); SELECT_DRIVE(drive);
msleep(50); msleep(50);
hwif->OUTBSYNC(drive, EXABYTE_ENABLE_NEST, hwif->io_ports.command_addr); hwif->OUTBSYNC(hwif, EXABYTE_ENABLE_NEST, hwif->io_ports.command_addr);
if (ide_busy_sleep(hwif)) { if (ide_busy_sleep(hwif)) {
printk(KERN_CONT "failed (timeout)\n"); printk(KERN_CONT "failed (timeout)\n");
...@@ -1065,7 +1065,7 @@ static int init_irq (ide_hwif_t *hwif) ...@@ -1065,7 +1065,7 @@ static int init_irq (ide_hwif_t *hwif)
if (io_ports->ctl_addr) if (io_ports->ctl_addr)
/* clear nIEN */ /* clear nIEN */
hwif->OUTB(0x08, io_ports->ctl_addr); hwif->OUTBSYNC(hwif, ATA_DEVCTL_OBS, io_ports->ctl_addr);
if (request_irq(hwif->irq,&ide_intr,sa,hwif->name,hwgroup)) if (request_irq(hwif->irq,&ide_intr,sa,hwif->name,hwgroup))
goto out_unlink; goto out_unlink;
......
此差异已折叠。
...@@ -109,13 +109,15 @@ ide_startstop_t do_rw_taskfile (ide_drive_t *drive, ide_task_t *task) ...@@ -109,13 +109,15 @@ ide_startstop_t do_rw_taskfile (ide_drive_t *drive, ide_task_t *task)
if ((task->tf_flags & IDE_TFLAG_DMA_PIO_FALLBACK) == 0) { if ((task->tf_flags & IDE_TFLAG_DMA_PIO_FALLBACK) == 0) {
ide_tf_dump(drive->name, tf); ide_tf_dump(drive->name, tf);
ide_set_irq(drive, 1);
SELECT_MASK(drive, 0);
hwif->tf_load(drive, task); hwif->tf_load(drive, task);
} }
switch (task->data_phase) { switch (task->data_phase) {
case TASKFILE_MULTI_OUT: case TASKFILE_MULTI_OUT:
case TASKFILE_OUT: case TASKFILE_OUT:
hwif->OUTBSYNC(drive, tf->command, hwif->io_ports.command_addr); hwif->OUTBSYNC(hwif, tf->command, hwif->io_ports.command_addr);
ndelay(400); /* FIXME */ ndelay(400); /* FIXME */
return pre_task_out_intr(drive, task->rq); return pre_task_out_intr(drive, task->rq);
case TASKFILE_MULTI_IN: case TASKFILE_MULTI_IN:
...@@ -492,11 +494,12 @@ static ide_startstop_t pre_task_out_intr(ide_drive_t *drive, struct request *rq) ...@@ -492,11 +494,12 @@ static ide_startstop_t pre_task_out_intr(ide_drive_t *drive, struct request *rq)
int ide_raw_taskfile(ide_drive_t *drive, ide_task_t *task, u8 *buf, u16 nsect) int ide_raw_taskfile(ide_drive_t *drive, ide_task_t *task, u8 *buf, u16 nsect)
{ {
struct request rq; struct request *rq;
int error;
blk_rq_init(NULL, &rq); rq = blk_get_request(drive->queue, READ, __GFP_WAIT);
rq.cmd_type = REQ_TYPE_ATA_TASKFILE; rq->cmd_type = REQ_TYPE_ATA_TASKFILE;
rq.buffer = buf; rq->buffer = buf;
/* /*
* (ks) We transfer currently only whole sectors. * (ks) We transfer currently only whole sectors.
...@@ -504,16 +507,19 @@ int ide_raw_taskfile(ide_drive_t *drive, ide_task_t *task, u8 *buf, u16 nsect) ...@@ -504,16 +507,19 @@ int ide_raw_taskfile(ide_drive_t *drive, ide_task_t *task, u8 *buf, u16 nsect)
* if we would find a solution to transfer any size. * if we would find a solution to transfer any size.
* To support special commands like READ LONG. * To support special commands like READ LONG.
*/ */
rq.hard_nr_sectors = rq.nr_sectors = nsect; rq->hard_nr_sectors = rq->nr_sectors = nsect;
rq.hard_cur_sectors = rq.current_nr_sectors = nsect; rq->hard_cur_sectors = rq->current_nr_sectors = nsect;
if (task->tf_flags & IDE_TFLAG_WRITE) if (task->tf_flags & IDE_TFLAG_WRITE)
rq.cmd_flags |= REQ_RW; rq->cmd_flags |= REQ_RW;
rq.special = task; rq->special = task;
task->rq = &rq; task->rq = rq;
return ide_do_drive_cmd(drive, &rq, ide_wait); error = blk_execute_rq(drive->queue, NULL, rq, 0);
blk_put_request(rq);
return error;
} }
EXPORT_SYMBOL(ide_raw_taskfile); EXPORT_SYMBOL(ide_raw_taskfile);
...@@ -739,12 +745,14 @@ int ide_cmd_ioctl (ide_drive_t *drive, unsigned int cmd, unsigned long arg) ...@@ -739,12 +745,14 @@ int ide_cmd_ioctl (ide_drive_t *drive, unsigned int cmd, unsigned long arg)
struct hd_driveid *id = drive->id; struct hd_driveid *id = drive->id;
if (NULL == (void *) arg) { if (NULL == (void *) arg) {
struct request rq; struct request *rq;
ide_init_drive_cmd(&rq); rq = blk_get_request(drive->queue, READ, __GFP_WAIT);
rq.cmd_type = REQ_TYPE_ATA_TASKFILE; rq->cmd_type = REQ_TYPE_ATA_TASKFILE;
err = blk_execute_rq(drive->queue, NULL, rq, 0);
blk_put_request(rq);
return ide_do_drive_cmd(drive, &rq, ide_wait); return err;
} }
if (copy_from_user(args, (void __user *)arg, 4)) if (copy_from_user(args, (void __user *)arg, 4))
......
...@@ -95,7 +95,6 @@ static struct ide_timing ide_timing[] = { ...@@ -95,7 +95,6 @@ static struct ide_timing ide_timing[] = {
#define IDE_TIMING_UDMA 0x80 #define IDE_TIMING_UDMA 0x80
#define IDE_TIMING_ALL 0xff #define IDE_TIMING_ALL 0xff
#define FIT(v,vmin,vmax) max_t(short,min_t(short,v,vmax),vmin)
#define ENOUGH(v,unit) (((v)-1)/(unit)+1) #define ENOUGH(v,unit) (((v)-1)/(unit)+1)
#define EZ(v,unit) ((v)?ENOUGH(v,unit):0) #define EZ(v,unit) ((v)?ENOUGH(v,unit):0)
......
...@@ -86,13 +86,10 @@ static const u8 ide_hwif_to_major[] = { IDE0_MAJOR, IDE1_MAJOR, ...@@ -86,13 +86,10 @@ static const u8 ide_hwif_to_major[] = { IDE0_MAJOR, IDE1_MAJOR,
IDE6_MAJOR, IDE7_MAJOR, IDE6_MAJOR, IDE7_MAJOR,
IDE8_MAJOR, IDE9_MAJOR }; IDE8_MAJOR, IDE9_MAJOR };
static int idebus_parameter; /* holds the "idebus=" parameter */
static int system_bus_speed; /* holds what we think is VESA/PCI bus speed */
DEFINE_MUTEX(ide_cfg_mtx); DEFINE_MUTEX(ide_cfg_mtx);
__cacheline_aligned_in_smp DEFINE_SPINLOCK(ide_lock);
int noautodma = 0; __cacheline_aligned_in_smp DEFINE_SPINLOCK(ide_lock);
EXPORT_SYMBOL(ide_lock);
ide_hwif_t ide_hwifs[MAX_HWIFS]; /* master data repository */ ide_hwif_t ide_hwifs[MAX_HWIFS]; /* master data repository */
...@@ -139,7 +136,6 @@ static void ide_port_init_devices_data(ide_hwif_t *hwif) ...@@ -139,7 +136,6 @@ static void ide_port_init_devices_data(ide_hwif_t *hwif)
drive->media = ide_disk; drive->media = ide_disk;
drive->select.all = (unit<<4)|0xa0; drive->select.all = (unit<<4)|0xa0;
drive->hwif = hwif; drive->hwif = hwif;
drive->ctl = 0x08;
drive->ready_stat = READY_STAT; drive->ready_stat = READY_STAT;
drive->bad_wstat = BAD_W_STAT; drive->bad_wstat = BAD_W_STAT;
drive->special.b.recalibrate = 1; drive->special.b.recalibrate = 1;
...@@ -154,32 +150,9 @@ static void ide_port_init_devices_data(ide_hwif_t *hwif) ...@@ -154,32 +150,9 @@ static void ide_port_init_devices_data(ide_hwif_t *hwif)
} }
} }
/*
* init_ide_data() sets reasonable default values into all fields
* of all instances of the hwifs and drives, but only on the first call.
* Subsequent calls have no effect (they don't wipe out anything).
*
* This routine is normally called at driver initialization time,
* but may also be called MUCH earlier during kernel "command-line"
* parameter processing. As such, we cannot depend on any other parts
* of the kernel (such as memory allocation) to be functioning yet.
*
* This is too bad, as otherwise we could dynamically allocate the
* ide_drive_t structs as needed, rather than always consuming memory
* for the max possible number (MAX_HWIFS * MAX_DRIVES) of them.
*
* FIXME: We should stuff the setup data into __init and copy the
* relevant hwifs/allocate them properly during boot.
*/
#define MAGIC_COOKIE 0x12345678
static void __init init_ide_data (void) static void __init init_ide_data (void)
{ {
unsigned int index; unsigned int index;
static unsigned long magic_cookie = MAGIC_COOKIE;
if (magic_cookie != MAGIC_COOKIE)
return; /* already initialized */
magic_cookie = 0;
/* Initialise all interface structures */ /* Initialise all interface structures */
for (index = 0; index < MAX_HWIFS; ++index) { for (index = 0; index < MAX_HWIFS; ++index) {
...@@ -189,38 +162,6 @@ static void __init init_ide_data (void) ...@@ -189,38 +162,6 @@ static void __init init_ide_data (void)
} }
} }
/**
* ide_system_bus_speed - guess bus speed
*
* ide_system_bus_speed() returns what we think is the system VESA/PCI
* bus speed (in MHz). This is used for calculating interface PIO timings.
* The default is 40 for known PCI systems, 50 otherwise.
* The "idebus=xx" parameter can be used to override this value.
* The actual value to be used is computed/displayed the first time
* through. Drivers should only use this as a last resort.
*
* Returns a guessed speed in MHz.
*/
static int ide_system_bus_speed(void)
{
#ifdef CONFIG_PCI
static struct pci_device_id pci_default[] = {
{ PCI_DEVICE(PCI_ANY_ID, PCI_ANY_ID) },
{ }
};
#else
#define pci_default 0
#endif /* CONFIG_PCI */
/* user supplied value */
if (idebus_parameter)
return idebus_parameter;
/* safe default value for PCI or VESA and PCI*/
return pci_dev_present(pci_default) ? 33 : 50;
}
void ide_remove_port_from_hwgroup(ide_hwif_t *hwif) void ide_remove_port_from_hwgroup(ide_hwif_t *hwif)
{ {
ide_hwgroup_t *hwgroup = hwif->hwgroup; ide_hwgroup_t *hwgroup = hwif->hwgroup;
...@@ -498,7 +439,7 @@ int set_using_dma(ide_drive_t *drive, int arg) ...@@ -498,7 +439,7 @@ int set_using_dma(ide_drive_t *drive, int arg)
int set_pio_mode(ide_drive_t *drive, int arg) int set_pio_mode(ide_drive_t *drive, int arg)
{ {
struct request rq; struct request *rq;
ide_hwif_t *hwif = drive->hwif; ide_hwif_t *hwif = drive->hwif;
const struct ide_port_ops *port_ops = hwif->port_ops; const struct ide_port_ops *port_ops = hwif->port_ops;
...@@ -512,12 +453,15 @@ int set_pio_mode(ide_drive_t *drive, int arg) ...@@ -512,12 +453,15 @@ int set_pio_mode(ide_drive_t *drive, int arg)
if (drive->special.b.set_tune) if (drive->special.b.set_tune)
return -EBUSY; return -EBUSY;
ide_init_drive_cmd(&rq); rq = blk_get_request(drive->queue, READ, __GFP_WAIT);
rq.cmd_type = REQ_TYPE_ATA_TASKFILE; rq->cmd_type = REQ_TYPE_ATA_TASKFILE;
drive->tune_req = (u8) arg; drive->tune_req = (u8) arg;
drive->special.b.set_tune = 1; drive->special.b.set_tune = 1;
(void) ide_do_drive_cmd(drive, &rq, ide_wait);
blk_execute_rq(drive->queue, NULL, rq, 0);
blk_put_request(rq);
return 0; return 0;
} }
...@@ -537,25 +481,11 @@ static int set_unmaskirq(ide_drive_t *drive, int arg) ...@@ -537,25 +481,11 @@ static int set_unmaskirq(ide_drive_t *drive, int arg)
return 0; return 0;
} }
/**
* system_bus_clock - clock guess
*
* External version of the bus clock guess used by very old IDE drivers
* for things like VLB timings. Should not be used.
*/
int system_bus_clock (void)
{
return system_bus_speed;
}
EXPORT_SYMBOL(system_bus_clock);
static int generic_ide_suspend(struct device *dev, pm_message_t mesg) static int generic_ide_suspend(struct device *dev, pm_message_t mesg)
{ {
ide_drive_t *drive = dev->driver_data; ide_drive_t *drive = dev->driver_data;
ide_hwif_t *hwif = HWIF(drive); ide_hwif_t *hwif = HWIF(drive);
struct request rq; struct request *rq;
struct request_pm_state rqpm; struct request_pm_state rqpm;
ide_task_t args; ide_task_t args;
int ret; int ret;
...@@ -564,18 +494,19 @@ static int generic_ide_suspend(struct device *dev, pm_message_t mesg) ...@@ -564,18 +494,19 @@ static int generic_ide_suspend(struct device *dev, pm_message_t mesg)
if (!(drive->dn % 2)) if (!(drive->dn % 2))
ide_acpi_get_timing(hwif); ide_acpi_get_timing(hwif);
blk_rq_init(NULL, &rq);
memset(&rqpm, 0, sizeof(rqpm)); memset(&rqpm, 0, sizeof(rqpm));
memset(&args, 0, sizeof(args)); memset(&args, 0, sizeof(args));
rq.cmd_type = REQ_TYPE_PM_SUSPEND; rq = blk_get_request(drive->queue, READ, __GFP_WAIT);
rq.special = &args; rq->cmd_type = REQ_TYPE_PM_SUSPEND;
rq.data = &rqpm; rq->special = &args;
rq->data = &rqpm;
rqpm.pm_step = ide_pm_state_start_suspend; rqpm.pm_step = ide_pm_state_start_suspend;
if (mesg.event == PM_EVENT_PRETHAW) if (mesg.event == PM_EVENT_PRETHAW)
mesg.event = PM_EVENT_FREEZE; mesg.event = PM_EVENT_FREEZE;
rqpm.pm_state = mesg.event; rqpm.pm_state = mesg.event;
ret = ide_do_drive_cmd(drive, &rq, ide_wait); ret = blk_execute_rq(drive->queue, NULL, rq, 0);
blk_put_request(rq);
/* only call ACPI _PS3 after both drivers are suspended */ /* only call ACPI _PS3 after both drivers are suspended */
if (!ret && (((drive->dn % 2) && hwif->drives[0].present if (!ret && (((drive->dn % 2) && hwif->drives[0].present
&& hwif->drives[1].present) && hwif->drives[1].present)
...@@ -589,7 +520,7 @@ static int generic_ide_resume(struct device *dev) ...@@ -589,7 +520,7 @@ static int generic_ide_resume(struct device *dev)
{ {
ide_drive_t *drive = dev->driver_data; ide_drive_t *drive = dev->driver_data;
ide_hwif_t *hwif = HWIF(drive); ide_hwif_t *hwif = HWIF(drive);
struct request rq; struct request *rq;
struct request_pm_state rqpm; struct request_pm_state rqpm;
ide_task_t args; ide_task_t args;
int err; int err;
...@@ -602,16 +533,18 @@ static int generic_ide_resume(struct device *dev) ...@@ -602,16 +533,18 @@ static int generic_ide_resume(struct device *dev)
ide_acpi_exec_tfs(drive); ide_acpi_exec_tfs(drive);
blk_rq_init(NULL, &rq);
memset(&rqpm, 0, sizeof(rqpm)); memset(&rqpm, 0, sizeof(rqpm));
memset(&args, 0, sizeof(args)); memset(&args, 0, sizeof(args));
rq.cmd_type = REQ_TYPE_PM_RESUME; rq = blk_get_request(drive->queue, READ, __GFP_WAIT);
rq.special = &args; rq->cmd_type = REQ_TYPE_PM_RESUME;
rq.data = &rqpm; rq->cmd_flags |= REQ_PREEMPT;
rq->special = &args;
rq->data = &rqpm;
rqpm.pm_step = ide_pm_state_start_resume; rqpm.pm_step = ide_pm_state_start_resume;
rqpm.pm_state = PM_EVENT_ON; rqpm.pm_state = PM_EVENT_ON;
err = ide_do_drive_cmd(drive, &rq, ide_head_wait); err = blk_execute_rq(drive->queue, NULL, rq, 1);
blk_put_request(rq);
if (err == 0 && dev->driver) { if (err == 0 && dev->driver) {
ide_driver_t *drv = to_ide_driver(dev->driver); ide_driver_t *drv = to_ide_driver(dev->driver);
...@@ -764,212 +697,6 @@ int generic_ide_ioctl(ide_drive_t *drive, struct file *file, struct block_device ...@@ -764,212 +697,6 @@ int generic_ide_ioctl(ide_drive_t *drive, struct file *file, struct block_device
EXPORT_SYMBOL(generic_ide_ioctl); EXPORT_SYMBOL(generic_ide_ioctl);
/*
* stridx() returns the offset of c within s,
* or -1 if c is '\0' or not found within s.
*/
static int __init stridx (const char *s, char c)
{
char *i = strchr(s, c);
return (i && c) ? i - s : -1;
}
/*
* match_parm() does parsing for ide_setup():
*
* 1. the first char of s must be '='.
* 2. if the remainder matches one of the supplied keywords,
* the index (1 based) of the keyword is negated and returned.
* 3. if the remainder is a series of no more than max_vals numbers
* separated by commas, the numbers are saved in vals[] and a
* count of how many were saved is returned. Base10 is assumed,
* and base16 is allowed when prefixed with "0x".
* 4. otherwise, zero is returned.
*/
static int __init match_parm (char *s, const char *keywords[], int vals[], int max_vals)
{
static const char *decimal = "0123456789";
static const char *hex = "0123456789abcdef";
int i, n;
if (*s++ == '=') {
/*
* Try matching against the supplied keywords,
* and return -(index+1) if we match one
*/
if (keywords != NULL) {
for (i = 0; *keywords != NULL; ++i) {
if (!strcmp(s, *keywords++))
return -(i+1);
}
}
/*
* Look for a series of no more than "max_vals"
* numeric values separated by commas, in base10,
* or base16 when prefixed with "0x".
* Return a count of how many were found.
*/
for (n = 0; (i = stridx(decimal, *s)) >= 0;) {
vals[n] = i;
while ((i = stridx(decimal, *++s)) >= 0)
vals[n] = (vals[n] * 10) + i;
if (*s == 'x' && !vals[n]) {
while ((i = stridx(hex, *++s)) >= 0)
vals[n] = (vals[n] * 0x10) + i;
}
if (++n == max_vals)
break;
if (*s == ',' || *s == ';')
++s;
}
if (!*s)
return n;
}
return 0; /* zero = nothing matched */
}
/*
* ide_setup() gets called VERY EARLY during initialization,
* to handle kernel "command line" strings beginning with "hdx=" or "ide".
*
* Remember to update Documentation/ide/ide.txt if you change something here.
*/
static int __init ide_setup(char *s)
{
ide_hwif_t *hwif;
ide_drive_t *drive;
unsigned int hw, unit;
int vals[3];
const char max_drive = 'a' + ((MAX_HWIFS * MAX_DRIVES) - 1);
if (strncmp(s,"hd",2) == 0 && s[2] == '=') /* hd= is for hd.c */
return 0; /* driver and not us */
if (strncmp(s,"ide",3) && strncmp(s,"idebus",6) && strncmp(s,"hd",2))
return 0;
printk(KERN_INFO "ide_setup: %s", s);
init_ide_data ();
#ifdef CONFIG_BLK_DEV_IDEDOUBLER
if (!strcmp(s, "ide=doubler")) {
extern int ide_doubler;
printk(" : Enabled support for IDE doublers\n");
ide_doubler = 1;
goto obsolete_option;
}
#endif /* CONFIG_BLK_DEV_IDEDOUBLER */
if (!strcmp(s, "ide=nodma")) {
printk(" : Prevented DMA\n");
noautodma = 1;
goto obsolete_option;
}
#ifdef CONFIG_BLK_DEV_IDEACPI
if (!strcmp(s, "ide=noacpi")) {
//printk(" : Disable IDE ACPI support.\n");
ide_noacpi = 1;
goto obsolete_option;
}
if (!strcmp(s, "ide=acpigtf")) {
//printk(" : Enable IDE ACPI _GTF support.\n");
ide_acpigtf = 1;
goto obsolete_option;
}
if (!strcmp(s, "ide=acpionboot")) {
//printk(" : Call IDE ACPI methods on boot.\n");
ide_acpionboot = 1;
goto obsolete_option;
}
#endif /* CONFIG_BLK_DEV_IDEACPI */
/*
* Look for drive options: "hdx="
*/
if (s[0] == 'h' && s[1] == 'd' && s[2] >= 'a' && s[2] <= max_drive) {
const char *hd_words[] = {
"none", "noprobe", "nowerr", "cdrom", "nodma",
"-6", "-7", "-8", "-9", "-10",
"noflush", "remap", "remap63", "scsi", NULL };
unit = s[2] - 'a';
hw = unit / MAX_DRIVES;
unit = unit % MAX_DRIVES;
hwif = &ide_hwifs[hw];
drive = &hwif->drives[unit];
if (strncmp(s + 4, "ide-", 4) == 0) {
strlcpy(drive->driver_req, s + 4, sizeof(drive->driver_req));
goto obsolete_option;
}
switch (match_parm(&s[3], hd_words, vals, 3)) {
case -1: /* "none" */
case -2: /* "noprobe" */
drive->noprobe = 1;
goto obsolete_option;
case -3: /* "nowerr" */
drive->bad_wstat = BAD_R_STAT;
goto obsolete_option;
case -4: /* "cdrom" */
drive->present = 1;
drive->media = ide_cdrom;
/* an ATAPI device ignores DRDY */
drive->ready_stat = 0;
goto obsolete_option;
case -5: /* nodma */
drive->nodma = 1;
goto obsolete_option;
case -11: /* noflush */
drive->noflush = 1;
goto obsolete_option;
case -12: /* "remap" */
drive->remap_0_to_1 = 1;
goto obsolete_option;
case -13: /* "remap63" */
drive->sect0 = 63;
goto obsolete_option;
case -14: /* "scsi" */
drive->scsi = 1;
goto obsolete_option;
case 3: /* cyl,head,sect */
drive->media = ide_disk;
drive->ready_stat = READY_STAT;
drive->cyl = drive->bios_cyl = vals[0];
drive->head = drive->bios_head = vals[1];
drive->sect = drive->bios_sect = vals[2];
drive->present = 1;
drive->forced_geom = 1;
goto obsolete_option;
default:
goto bad_option;
}
}
if (s[0] != 'i' || s[1] != 'd' || s[2] != 'e')
goto bad_option;
/*
* Look for bus speed option: "idebus="
*/
if (s[3] == 'b' && s[4] == 'u' && s[5] == 's') {
if (match_parm(&s[6], NULL, vals, 1) != 1)
goto bad_option;
if (vals[0] >= 20 && vals[0] <= 66) {
idebus_parameter = vals[0];
} else
printk(" -- BAD BUS SPEED! Expected value from 20 to 66");
goto obsolete_option;
}
bad_option:
printk(" -- BAD OPTION\n");
return 1;
obsolete_option:
printk(" -- OBSOLETE OPTION, WILL BE REMOVED SOON!\n");
return 1;
}
EXPORT_SYMBOL(ide_lock);
static int ide_bus_match(struct device *dev, struct device_driver *drv) static int ide_bus_match(struct device *dev, struct device_driver *drv)
{ {
return 1; return 1;
...@@ -1281,11 +1008,6 @@ static int __init ide_init(void) ...@@ -1281,11 +1008,6 @@ static int __init ide_init(void)
int ret; int ret;
printk(KERN_INFO "Uniform Multi-Platform E-IDE driver\n"); printk(KERN_INFO "Uniform Multi-Platform E-IDE driver\n");
system_bus_speed = ide_system_bus_speed();
printk(KERN_INFO "ide: Assuming %dMHz system bus speed "
"for PIO modes%s\n", system_bus_speed,
idebus_parameter ? "" : "; override with idebus=xx");
ret = bus_register(&ide_bus_type); ret = bus_register(&ide_bus_type);
if (ret < 0) { if (ret < 0) {
...@@ -1311,32 +1033,7 @@ static int __init ide_init(void) ...@@ -1311,32 +1033,7 @@ static int __init ide_init(void)
return ret; return ret;
} }
#ifdef MODULE static void __exit ide_exit(void)
static char *options = NULL;
module_param(options, charp, 0);
MODULE_LICENSE("GPL");
static void __init parse_options (char *line)
{
char *next = line;
if (line == NULL || !*line)
return;
while ((line = next) != NULL) {
if ((next = strchr(line,' ')) != NULL)
*next++ = 0;
if (!ide_setup(line))
printk (KERN_INFO "Unknown option '%s'\n", line);
}
}
int __init init_module (void)
{
parse_options(options);
return ide_init();
}
void __exit cleanup_module (void)
{ {
proc_ide_destroy(); proc_ide_destroy();
...@@ -1345,10 +1042,7 @@ void __exit cleanup_module (void) ...@@ -1345,10 +1042,7 @@ void __exit cleanup_module (void)
bus_unregister(&ide_bus_type); bus_unregister(&ide_bus_type);
} }
#else /* !MODULE */
__setup("", ide_setup);
module_init(ide_init); module_init(ide_init);
module_exit(ide_exit);
#endif /* MODULE */ MODULE_LICENSE("GPL");
...@@ -116,7 +116,7 @@ static void ali14xx_set_pio_mode(ide_drive_t *drive, const u8 pio) ...@@ -116,7 +116,7 @@ static void ali14xx_set_pio_mode(ide_drive_t *drive, const u8 pio)
int time1, time2; int time1, time2;
u8 param1, param2, param3, param4; u8 param1, param2, param3, param4;
unsigned long flags; unsigned long flags;
int bus_speed = ide_vlb_clk ? ide_vlb_clk : system_bus_clock(); int bus_speed = ide_vlb_clk ? ide_vlb_clk : 50;
/* calculate timing, according to PIO mode */ /* calculate timing, according to PIO mode */
time1 = ide_pio_cycle_time(drive, pio); time1 = ide_pio_cycle_time(drive, pio);
......
...@@ -64,9 +64,7 @@ ...@@ -64,9 +64,7 @@
#define GAYLE_HAS_CONTROL_REG (!ide_doubler) #define GAYLE_HAS_CONTROL_REG (!ide_doubler)
#define GAYLE_IDEREG_SIZE (ide_doubler ? 0x1000 : 0x2000) #define GAYLE_IDEREG_SIZE (ide_doubler ? 0x1000 : 0x2000)
int ide_doubler = 0; /* support IDE doublers? */ static int ide_doubler;
EXPORT_SYMBOL_GPL(ide_doubler);
module_param_named(doubler, ide_doubler, bool, 0); module_param_named(doubler, ide_doubler, bool, 0);
MODULE_PARM_DESC(doubler, "enable support for IDE doublers"); MODULE_PARM_DESC(doubler, "enable support for IDE doublers");
#endif /* CONFIG_BLK_DEV_IDEDOUBLER */ #endif /* CONFIG_BLK_DEV_IDEDOUBLER */
......
...@@ -212,7 +212,7 @@ static u8 ht_pio2timings(ide_drive_t *drive, const u8 pio) ...@@ -212,7 +212,7 @@ static u8 ht_pio2timings(ide_drive_t *drive, const u8 pio)
{ {
int active_time, recovery_time; int active_time, recovery_time;
int active_cycles, recovery_cycles; int active_cycles, recovery_cycles;
int bus_speed = ide_vlb_clk ? ide_vlb_clk : system_bus_clock(); int bus_speed = ide_vlb_clk ? ide_vlb_clk : 50;
if (pio) { if (pio) {
unsigned int cycle_time; unsigned int cycle_time;
......
...@@ -110,7 +110,7 @@ static void qd65xx_select(ide_drive_t *drive) ...@@ -110,7 +110,7 @@ static void qd65xx_select(ide_drive_t *drive)
static u8 qd6500_compute_timing (ide_hwif_t *hwif, int active_time, int recovery_time) static u8 qd6500_compute_timing (ide_hwif_t *hwif, int active_time, int recovery_time)
{ {
int clk = ide_vlb_clk ? ide_vlb_clk : system_bus_clock(); int clk = ide_vlb_clk ? ide_vlb_clk : 50;
u8 act_cyc, rec_cyc; u8 act_cyc, rec_cyc;
if (clk <= 33) { if (clk <= 33) {
...@@ -132,7 +132,7 @@ static u8 qd6500_compute_timing (ide_hwif_t *hwif, int active_time, int recovery ...@@ -132,7 +132,7 @@ static u8 qd6500_compute_timing (ide_hwif_t *hwif, int active_time, int recovery
static u8 qd6580_compute_timing (int active_time, int recovery_time) static u8 qd6580_compute_timing (int active_time, int recovery_time)
{ {
int clk = ide_vlb_clk ? ide_vlb_clk : system_bus_clock(); int clk = ide_vlb_clk ? ide_vlb_clk : 50;
u8 act_cyc, rec_cyc; u8 act_cyc, rec_cyc;
act_cyc = 17 - IDE_IN(active_time * clk / 1000 + 1, 2, 17); act_cyc = 17 - IDE_IN(active_time * clk / 1000 + 1, 2, 17);
......
...@@ -140,7 +140,7 @@ static void aec_set_pio_mode(ide_drive_t *drive, const u8 pio) ...@@ -140,7 +140,7 @@ static void aec_set_pio_mode(ide_drive_t *drive, const u8 pio)
static unsigned int __devinit init_chipset_aec62xx(struct pci_dev *dev, const char *name) static unsigned int __devinit init_chipset_aec62xx(struct pci_dev *dev, const char *name)
{ {
int bus_speed = ide_pci_clk ? ide_pci_clk : system_bus_clock(); int bus_speed = ide_pci_clk ? ide_pci_clk : 33;
if (bus_speed <= 33) if (bus_speed <= 33)
pci_set_drvdata(dev, (void *) aec6xxx_33_base); pci_set_drvdata(dev, (void *) aec6xxx_33_base);
......
...@@ -72,7 +72,7 @@ static void ali_set_pio_mode(ide_drive_t *drive, const u8 pio) ...@@ -72,7 +72,7 @@ static void ali_set_pio_mode(ide_drive_t *drive, const u8 pio)
int s_time, a_time, c_time; int s_time, a_time, c_time;
u8 s_clc, a_clc, r_clc; u8 s_clc, a_clc, r_clc;
unsigned long flags; unsigned long flags;
int bus_speed = ide_pci_clk ? ide_pci_clk : system_bus_clock(); int bus_speed = ide_pci_clk ? ide_pci_clk : 33;
int port = hwif->channel ? 0x5c : 0x58; int port = hwif->channel ? 0x5c : 0x58;
int portFIFO = hwif->channel ? 0x55 : 0x54; int portFIFO = hwif->channel ? 0x55 : 0x54;
u8 cd_dma_fifo = 0; u8 cd_dma_fifo = 0;
......
...@@ -53,20 +53,20 @@ static void amd_set_speed(struct pci_dev *dev, u8 dn, u8 udma_mask, ...@@ -53,20 +53,20 @@ static void amd_set_speed(struct pci_dev *dev, u8 dn, u8 udma_mask,
u8 t = 0, offset = amd_offset(dev); u8 t = 0, offset = amd_offset(dev);
pci_read_config_byte(dev, AMD_ADDRESS_SETUP + offset, &t); pci_read_config_byte(dev, AMD_ADDRESS_SETUP + offset, &t);
t = (t & ~(3 << ((3 - dn) << 1))) | ((FIT(timing->setup, 1, 4) - 1) << ((3 - dn) << 1)); t = (t & ~(3 << ((3 - dn) << 1))) | ((clamp_val(timing->setup, 1, 4) - 1) << ((3 - dn) << 1));
pci_write_config_byte(dev, AMD_ADDRESS_SETUP + offset, t); pci_write_config_byte(dev, AMD_ADDRESS_SETUP + offset, t);
pci_write_config_byte(dev, AMD_8BIT_TIMING + offset + (1 - (dn >> 1)), pci_write_config_byte(dev, AMD_8BIT_TIMING + offset + (1 - (dn >> 1)),
((FIT(timing->act8b, 1, 16) - 1) << 4) | (FIT(timing->rec8b, 1, 16) - 1)); ((clamp_val(timing->act8b, 1, 16) - 1) << 4) | (clamp_val(timing->rec8b, 1, 16) - 1));
pci_write_config_byte(dev, AMD_DRIVE_TIMING + offset + (3 - dn), pci_write_config_byte(dev, AMD_DRIVE_TIMING + offset + (3 - dn),
((FIT(timing->active, 1, 16) - 1) << 4) | (FIT(timing->recover, 1, 16) - 1)); ((clamp_val(timing->active, 1, 16) - 1) << 4) | (clamp_val(timing->recover, 1, 16) - 1));
switch (udma_mask) { switch (udma_mask) {
case ATA_UDMA2: t = timing->udma ? (0xc0 | (FIT(timing->udma, 2, 5) - 2)) : 0x03; break; case ATA_UDMA2: t = timing->udma ? (0xc0 | (clamp_val(timing->udma, 2, 5) - 2)) : 0x03; break;
case ATA_UDMA4: t = timing->udma ? (0xc0 | amd_cyc2udma[FIT(timing->udma, 2, 10)]) : 0x03; break; case ATA_UDMA4: t = timing->udma ? (0xc0 | amd_cyc2udma[clamp_val(timing->udma, 2, 10)]) : 0x03; break;
case ATA_UDMA5: t = timing->udma ? (0xc0 | amd_cyc2udma[FIT(timing->udma, 1, 10)]) : 0x03; break; case ATA_UDMA5: t = timing->udma ? (0xc0 | amd_cyc2udma[clamp_val(timing->udma, 1, 10)]) : 0x03; break;
case ATA_UDMA6: t = timing->udma ? (0xc0 | amd_cyc2udma[FIT(timing->udma, 1, 15)]) : 0x03; break; case ATA_UDMA6: t = timing->udma ? (0xc0 | amd_cyc2udma[clamp_val(timing->udma, 1, 15)]) : 0x03; break;
default: return; default: return;
} }
...@@ -179,7 +179,7 @@ static unsigned int __devinit init_chipset_amd74xx(struct pci_dev *dev, ...@@ -179,7 +179,7 @@ static unsigned int __devinit init_chipset_amd74xx(struct pci_dev *dev,
* Determine the system bus clock. * Determine the system bus clock.
*/ */
amd_clock = (ide_pci_clk ? ide_pci_clk : system_bus_clock()) * 1000; amd_clock = (ide_pci_clk ? ide_pci_clk : 33) * 1000;
switch (amd_clock) { switch (amd_clock) {
case 33000: amd_clock = 33333; break; case 33000: amd_clock = 33333; break;
......
...@@ -525,12 +525,10 @@ static void cmd640_set_mode(ide_drive_t *drive, unsigned int index, ...@@ -525,12 +525,10 @@ static void cmd640_set_mode(ide_drive_t *drive, unsigned int index,
u8 setup_count, active_count, recovery_count, recovery_count2, cycle_count; u8 setup_count, active_count, recovery_count, recovery_count2, cycle_count;
int bus_speed; int bus_speed;
if (cmd640_vlb && ide_vlb_clk) if (cmd640_vlb)
bus_speed = ide_vlb_clk; bus_speed = ide_vlb_clk ? ide_vlb_clk : 50;
else if (!cmd640_vlb && ide_pci_clk)
bus_speed = ide_pci_clk;
else else
bus_speed = system_bus_clock(); bus_speed = ide_pci_clk ? ide_pci_clk : 33;
if (pio_mode > 5) if (pio_mode > 5)
pio_mode = 5; pio_mode = 5;
......
...@@ -69,7 +69,7 @@ static u8 quantize_timing(int timing, int quant) ...@@ -69,7 +69,7 @@ static u8 quantize_timing(int timing, int quant)
static void program_cycle_times (ide_drive_t *drive, int cycle_time, int active_time) static void program_cycle_times (ide_drive_t *drive, int cycle_time, int active_time)
{ {
struct pci_dev *dev = to_pci_dev(drive->hwif->dev); struct pci_dev *dev = to_pci_dev(drive->hwif->dev);
int clock_time = 1000 / (ide_pci_clk ? ide_pci_clk : system_bus_clock()); int clock_time = 1000 / (ide_pci_clk ? ide_pci_clk : 33);
u8 cycle_count, active_count, recovery_count, drwtim; u8 cycle_count, active_count, recovery_count, drwtim;
static const u8 recovery_values[] = static const u8 recovery_values[] =
{15, 15, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 0}; {15, 15, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 0};
...@@ -128,7 +128,7 @@ static void cmd64x_tune_pio(ide_drive_t *drive, const u8 pio) ...@@ -128,7 +128,7 @@ static void cmd64x_tune_pio(ide_drive_t *drive, const u8 pio)
ide_pio_timings[pio].active_time); ide_pio_timings[pio].active_time);
setup_count = quantize_timing(ide_pio_timings[pio].setup_time, setup_count = quantize_timing(ide_pio_timings[pio].setup_time,
1000 / (ide_pci_clk ? ide_pci_clk : system_bus_clock())); 1000 / (ide_pci_clk ? ide_pci_clk : 33));
/* /*
* The primary channel has individual address setup timing registers * The primary channel has individual address setup timing registers
......
...@@ -134,7 +134,7 @@ static int calc_clk(int time, int bus_speed) ...@@ -134,7 +134,7 @@ static int calc_clk(int time, int bus_speed)
static void compute_clocks(u8 pio, pio_clocks_t *p_pclk) static void compute_clocks(u8 pio, pio_clocks_t *p_pclk)
{ {
int clk1, clk2; int clk1, clk2;
int bus_speed = ide_pci_clk ? ide_pci_clk : system_bus_clock(); int bus_speed = ide_pci_clk ? ide_pci_clk : 33;
/* we don't check against CY82C693's min and max speed, /* we don't check against CY82C693's min and max speed,
* so you can play with the idebus=xx parameter * so you can play with the idebus=xx parameter
......
...@@ -759,8 +759,7 @@ static void hpt3xx_maskproc(ide_drive_t *drive, int mask) ...@@ -759,8 +759,7 @@ static void hpt3xx_maskproc(ide_drive_t *drive, int mask)
enable_irq (hwif->irq); enable_irq (hwif->irq);
} }
} else } else
outb(mask ? (drive->ctl | 2) : (drive->ctl & ~2), outb(ATA_DEVCTL_OBS | (mask ? 2 : 0), hwif->io_ports.ctl_addr);
hwif->io_ports.ctl_addr);
} }
/* /*
......
...@@ -76,7 +76,7 @@ static void superio_tf_read(ide_drive_t *drive, ide_task_t *task) ...@@ -76,7 +76,7 @@ static void superio_tf_read(ide_drive_t *drive, ide_task_t *task)
} }
/* be sure we're looking at the low order bits */ /* be sure we're looking at the low order bits */
outb(drive->ctl & ~0x80, io_ports->ctl_addr); outb(ATA_DEVCTL_OBS & ~0x80, io_ports->ctl_addr);
if (task->tf_flags & IDE_TFLAG_IN_NSECT) if (task->tf_flags & IDE_TFLAG_IN_NSECT)
tf->nsect = inb(io_ports->nsect_addr); tf->nsect = inb(io_ports->nsect_addr);
...@@ -90,7 +90,7 @@ static void superio_tf_read(ide_drive_t *drive, ide_task_t *task) ...@@ -90,7 +90,7 @@ static void superio_tf_read(ide_drive_t *drive, ide_task_t *task)
tf->device = superio_ide_inb(io_ports->device_addr); tf->device = superio_ide_inb(io_ports->device_addr);
if (task->tf_flags & IDE_TFLAG_LBA48) { if (task->tf_flags & IDE_TFLAG_LBA48) {
outb(drive->ctl | 0x80, io_ports->ctl_addr); outb(ATA_DEVCTL_OBS | 0x80, io_ports->ctl_addr);
if (task->tf_flags & IDE_TFLAG_IN_HOB_FEATURE) if (task->tf_flags & IDE_TFLAG_IN_HOB_FEATURE)
tf->hob_feature = inb(io_ports->feature_addr); tf->hob_feature = inb(io_ports->feature_addr);
......
...@@ -148,11 +148,8 @@ static void scc_ide_outb(u8 addr, unsigned long port) ...@@ -148,11 +148,8 @@ static void scc_ide_outb(u8 addr, unsigned long port)
out_be32((void*)port, addr); out_be32((void*)port, addr);
} }
static void static void scc_ide_outbsync(ide_hwif_t *hwif, u8 addr, unsigned long port)
scc_ide_outbsync(ide_drive_t * drive, u8 addr, unsigned long port)
{ {
ide_hwif_t *hwif = HWIF(drive);
out_be32((void*)port, addr); out_be32((void*)port, addr);
eieio(); eieio();
in_be32((void*)(hwif->dma_base + 0x01c)); in_be32((void*)(hwif->dma_base + 0x01c));
...@@ -662,8 +659,6 @@ static void scc_tf_load(ide_drive_t *drive, ide_task_t *task) ...@@ -662,8 +659,6 @@ static void scc_tf_load(ide_drive_t *drive, ide_task_t *task)
if (task->tf_flags & IDE_TFLAG_FLAGGED) if (task->tf_flags & IDE_TFLAG_FLAGGED)
HIHI = 0xFF; HIHI = 0xFF;
ide_set_irq(drive, 1);
if (task->tf_flags & IDE_TFLAG_OUT_DATA) if (task->tf_flags & IDE_TFLAG_OUT_DATA)
out_be32((void *)io_ports->data_addr, out_be32((void *)io_ports->data_addr,
(tf->hob_data << 8) | tf->data); (tf->hob_data << 8) | tf->data);
...@@ -708,7 +703,7 @@ static void scc_tf_read(ide_drive_t *drive, ide_task_t *task) ...@@ -708,7 +703,7 @@ static void scc_tf_read(ide_drive_t *drive, ide_task_t *task)
} }
/* be sure we're looking at the low order bits */ /* be sure we're looking at the low order bits */
scc_ide_outb(drive->ctl & ~0x80, io_ports->ctl_addr); scc_ide_outb(ATA_DEVCTL_OBS & ~0x80, io_ports->ctl_addr);
if (task->tf_flags & IDE_TFLAG_IN_NSECT) if (task->tf_flags & IDE_TFLAG_IN_NSECT)
tf->nsect = scc_ide_inb(io_ports->nsect_addr); tf->nsect = scc_ide_inb(io_ports->nsect_addr);
...@@ -722,7 +717,7 @@ static void scc_tf_read(ide_drive_t *drive, ide_task_t *task) ...@@ -722,7 +717,7 @@ static void scc_tf_read(ide_drive_t *drive, ide_task_t *task)
tf->device = scc_ide_inb(io_ports->device_addr); tf->device = scc_ide_inb(io_ports->device_addr);
if (task->tf_flags & IDE_TFLAG_LBA48) { if (task->tf_flags & IDE_TFLAG_LBA48) {
scc_ide_outb(drive->ctl | 0x80, io_ports->ctl_addr); scc_ide_outb(ATA_DEVCTL_OBS | 0x80, io_ports->ctl_addr);
if (task->tf_flags & IDE_TFLAG_IN_HOB_FEATURE) if (task->tf_flags & IDE_TFLAG_IN_HOB_FEATURE)
tf->hob_feature = scc_ide_inb(io_ports->feature_addr); tf->hob_feature = scc_ide_inb(io_ports->feature_addr);
...@@ -795,7 +790,6 @@ static void __devinit init_mmio_iops_scc(ide_hwif_t *hwif) ...@@ -795,7 +790,6 @@ static void __devinit init_mmio_iops_scc(ide_hwif_t *hwif)
hwif->dma_base = dma_base; hwif->dma_base = dma_base;
hwif->config_data = ports->ctl; hwif->config_data = ports->ctl;
hwif->mmio = 1;
} }
/** /**
......
...@@ -111,7 +111,7 @@ sgiioc4_init_hwif_ports(hw_regs_t * hw, unsigned long data_port, ...@@ -111,7 +111,7 @@ sgiioc4_init_hwif_ports(hw_regs_t * hw, unsigned long data_port,
static void static void
sgiioc4_maskproc(ide_drive_t * drive, int mask) sgiioc4_maskproc(ide_drive_t * drive, int mask)
{ {
writeb(mask ? (drive->ctl | 2) : (drive->ctl & ~2), writeb(ATA_DEVCTL_OBS | (mask ? 2 : 0),
(void __iomem *)drive->hwif->io_ports.ctl_addr); (void __iomem *)drive->hwif->io_ports.ctl_addr);
} }
...@@ -369,8 +369,7 @@ ide_dma_sgiioc4(ide_hwif_t *hwif, const struct ide_port_info *d) ...@@ -369,8 +369,7 @@ ide_dma_sgiioc4(ide_hwif_t *hwif, const struct ide_port_info *d)
hwif->sg_max_nents = IOC4_PRD_ENTRIES; hwif->sg_max_nents = IOC4_PRD_ENTRIES;
pad = pci_alloc_consistent(dev, IOC4_IDE_CACHELINE_SIZE, pad = pci_alloc_consistent(dev, IOC4_IDE_CACHELINE_SIZE,
(dma_addr_t *) &(hwif->dma_status)); (dma_addr_t *)&hwif->extra_base);
if (pad) { if (pad) {
ide_set_hwifdata(hwif, pad); ide_set_hwifdata(hwif, pad);
return 0; return 0;
...@@ -439,7 +438,7 @@ sgiioc4_configure_for_dma(int dma_direction, ide_drive_t * drive) ...@@ -439,7 +438,7 @@ sgiioc4_configure_for_dma(int dma_direction, ide_drive_t * drive)
/* Address of the Ending DMA */ /* Address of the Ending DMA */
memset(ide_get_hwifdata(hwif), 0, IOC4_IDE_CACHELINE_SIZE); memset(ide_get_hwifdata(hwif), 0, IOC4_IDE_CACHELINE_SIZE);
ending_dma_addr = cpu_to_le32(hwif->dma_status); ending_dma_addr = cpu_to_le32(hwif->extra_base);
writel(ending_dma_addr, (void __iomem *)(dma_base + IOC4_DMA_END_ADDR * 4)); writel(ending_dma_addr, (void __iomem *)(dma_base + IOC4_DMA_END_ADDR * 4));
writel(dma_direction, (void __iomem *)ioc4_dma_addr); writel(dma_direction, (void __iomem *)ioc4_dma_addr);
......
...@@ -94,7 +94,7 @@ static unsigned long siimage_selreg(ide_hwif_t *hwif, int r) ...@@ -94,7 +94,7 @@ static unsigned long siimage_selreg(ide_hwif_t *hwif, int r)
unsigned long base = (unsigned long)hwif->hwif_data; unsigned long base = (unsigned long)hwif->hwif_data;
base += 0xA0 + r; base += 0xA0 + r;
if (hwif->mmio) if (hwif->host_flags & IDE_HFLAG_MMIO)
base += hwif->channel << 6; base += hwif->channel << 6;
else else
base += hwif->channel << 4; base += hwif->channel << 4;
...@@ -117,7 +117,7 @@ static inline unsigned long siimage_seldev(ide_drive_t *drive, int r) ...@@ -117,7 +117,7 @@ static inline unsigned long siimage_seldev(ide_drive_t *drive, int r)
unsigned long base = (unsigned long)hwif->hwif_data; unsigned long base = (unsigned long)hwif->hwif_data;
base += 0xA0 + r; base += 0xA0 + r;
if (hwif->mmio) if (hwif->host_flags & IDE_HFLAG_MMIO)
base += hwif->channel << 6; base += hwif->channel << 6;
else else
base += hwif->channel << 4; base += hwif->channel << 4;
...@@ -190,7 +190,9 @@ static u8 sil_pata_udma_filter(ide_drive_t *drive) ...@@ -190,7 +190,9 @@ static u8 sil_pata_udma_filter(ide_drive_t *drive)
unsigned long base = (unsigned long)hwif->hwif_data; unsigned long base = (unsigned long)hwif->hwif_data;
u8 scsc, mask = 0; u8 scsc, mask = 0;
scsc = sil_ioread8(dev, base + (hwif->mmio ? 0x4A : 0x8A)); base += (hwif->host_flags & IDE_HFLAG_MMIO) ? 0x4A : 0x8A;
scsc = sil_ioread8(dev, base);
switch (scsc & 0x30) { switch (scsc & 0x30) {
case 0x10: /* 133 */ case 0x10: /* 133 */
...@@ -238,8 +240,9 @@ static void sil_set_pio_mode(ide_drive_t *drive, u8 pio) ...@@ -238,8 +240,9 @@ static void sil_set_pio_mode(ide_drive_t *drive, u8 pio)
unsigned long tfaddr = siimage_selreg(hwif, 0x02); unsigned long tfaddr = siimage_selreg(hwif, 0x02);
unsigned long base = (unsigned long)hwif->hwif_data; unsigned long base = (unsigned long)hwif->hwif_data;
u8 tf_pio = pio; u8 tf_pio = pio;
u8 addr_mask = hwif->channel ? (hwif->mmio ? 0xF4 : 0x84) u8 mmio = (hwif->host_flags & IDE_HFLAG_MMIO) ? 1 : 0;
: (hwif->mmio ? 0xB4 : 0x80); u8 addr_mask = hwif->channel ? (mmio ? 0xF4 : 0x84)
: (mmio ? 0xB4 : 0x80);
u8 mode = 0; u8 mode = 0;
u8 unit = drive->select.b.unit; u8 unit = drive->select.b.unit;
...@@ -290,13 +293,13 @@ static void sil_set_dma_mode(ide_drive_t *drive, const u8 speed) ...@@ -290,13 +293,13 @@ static void sil_set_dma_mode(ide_drive_t *drive, const u8 speed)
u16 ultra = 0, multi = 0; u16 ultra = 0, multi = 0;
u8 mode = 0, unit = drive->select.b.unit; u8 mode = 0, unit = drive->select.b.unit;
unsigned long base = (unsigned long)hwif->hwif_data; unsigned long base = (unsigned long)hwif->hwif_data;
u8 scsc = 0, addr_mask = hwif->channel ? u8 mmio = (hwif->host_flags & IDE_HFLAG_MMIO) ? 1 : 0;
(hwif->mmio ? 0xF4 : 0x84) : u8 scsc = 0, addr_mask = hwif->channel ? (mmio ? 0xF4 : 0x84)
(hwif->mmio ? 0xB4 : 0x80); : (mmio ? 0xB4 : 0x80);
unsigned long ma = siimage_seldev(drive, 0x08); unsigned long ma = siimage_seldev(drive, 0x08);
unsigned long ua = siimage_seldev(drive, 0x0C); unsigned long ua = siimage_seldev(drive, 0x0C);
scsc = sil_ioread8 (dev, base + (hwif->mmio ? 0x4A : 0x8A)); scsc = sil_ioread8 (dev, base + (mmio ? 0x4A : 0x8A));
mode = sil_ioread8 (dev, base + addr_mask); mode = sil_ioread8 (dev, base + addr_mask);
multi = sil_ioread16(dev, ma); multi = sil_ioread16(dev, ma);
ultra = sil_ioread16(dev, ua); ultra = sil_ioread16(dev, ua);
...@@ -391,7 +394,7 @@ static int siimage_mmio_dma_test_irq(ide_drive_t *drive) ...@@ -391,7 +394,7 @@ static int siimage_mmio_dma_test_irq(ide_drive_t *drive)
static int siimage_dma_test_irq(ide_drive_t *drive) static int siimage_dma_test_irq(ide_drive_t *drive)
{ {
if (drive->hwif->mmio) if (drive->hwif->host_flags & IDE_HFLAG_MMIO)
return siimage_mmio_dma_test_irq(drive); return siimage_mmio_dma_test_irq(drive);
else else
return siimage_io_dma_test_irq(drive); return siimage_io_dma_test_irq(drive);
...@@ -640,8 +643,6 @@ static void __devinit init_mmio_iops_siimage(ide_hwif_t *hwif) ...@@ -640,8 +643,6 @@ static void __devinit init_mmio_iops_siimage(ide_hwif_t *hwif)
hwif->irq = dev->irq; hwif->irq = dev->irq;
hwif->dma_base = (unsigned long)addr + (ch ? 0x08 : 0x00); hwif->dma_base = (unsigned long)addr + (ch ? 0x08 : 0x00);
hwif->mmio = 1;
} }
static int is_dev_seagate_sata(ide_drive_t *drive) static int is_dev_seagate_sata(ide_drive_t *drive)
......
...@@ -120,21 +120,21 @@ static void via_set_speed(ide_hwif_t *hwif, u8 dn, struct ide_timing *timing) ...@@ -120,21 +120,21 @@ static void via_set_speed(ide_hwif_t *hwif, u8 dn, struct ide_timing *timing)
if (~vdev->via_config->flags & VIA_BAD_AST) { if (~vdev->via_config->flags & VIA_BAD_AST) {
pci_read_config_byte(dev, VIA_ADDRESS_SETUP, &t); pci_read_config_byte(dev, VIA_ADDRESS_SETUP, &t);
t = (t & ~(3 << ((3 - dn) << 1))) | ((FIT(timing->setup, 1, 4) - 1) << ((3 - dn) << 1)); t = (t & ~(3 << ((3 - dn) << 1))) | ((clamp_val(timing->setup, 1, 4) - 1) << ((3 - dn) << 1));
pci_write_config_byte(dev, VIA_ADDRESS_SETUP, t); pci_write_config_byte(dev, VIA_ADDRESS_SETUP, t);
} }
pci_write_config_byte(dev, VIA_8BIT_TIMING + (1 - (dn >> 1)), pci_write_config_byte(dev, VIA_8BIT_TIMING + (1 - (dn >> 1)),
((FIT(timing->act8b, 1, 16) - 1) << 4) | (FIT(timing->rec8b, 1, 16) - 1)); ((clamp_val(timing->act8b, 1, 16) - 1) << 4) | (clamp_val(timing->rec8b, 1, 16) - 1));
pci_write_config_byte(dev, VIA_DRIVE_TIMING + (3 - dn), pci_write_config_byte(dev, VIA_DRIVE_TIMING + (3 - dn),
((FIT(timing->active, 1, 16) - 1) << 4) | (FIT(timing->recover, 1, 16) - 1)); ((clamp_val(timing->active, 1, 16) - 1) << 4) | (clamp_val(timing->recover, 1, 16) - 1));
switch (vdev->via_config->udma_mask) { switch (vdev->via_config->udma_mask) {
case ATA_UDMA2: t = timing->udma ? (0xe0 | (FIT(timing->udma, 2, 5) - 2)) : 0x03; break; case ATA_UDMA2: t = timing->udma ? (0xe0 | (clamp_val(timing->udma, 2, 5) - 2)) : 0x03; break;
case ATA_UDMA4: t = timing->udma ? (0xe8 | (FIT(timing->udma, 2, 9) - 2)) : 0x0f; break; case ATA_UDMA4: t = timing->udma ? (0xe8 | (clamp_val(timing->udma, 2, 9) - 2)) : 0x0f; break;
case ATA_UDMA5: t = timing->udma ? (0xe0 | (FIT(timing->udma, 2, 9) - 2)) : 0x07; break; case ATA_UDMA5: t = timing->udma ? (0xe0 | (clamp_val(timing->udma, 2, 9) - 2)) : 0x07; break;
case ATA_UDMA6: t = timing->udma ? (0xe0 | (FIT(timing->udma, 2, 9) - 2)) : 0x07; break; case ATA_UDMA6: t = timing->udma ? (0xe0 | (clamp_val(timing->udma, 2, 9) - 2)) : 0x07; break;
default: return; default: return;
} }
...@@ -340,7 +340,7 @@ static unsigned int __devinit init_chipset_via82cxxx(struct pci_dev *dev, const ...@@ -340,7 +340,7 @@ static unsigned int __devinit init_chipset_via82cxxx(struct pci_dev *dev, const
* Determine system bus clock. * Determine system bus clock.
*/ */
via_clock = (ide_pci_clk ? ide_pci_clk : system_bus_clock()) * 1000; via_clock = (ide_pci_clk ? ide_pci_clk : 33) * 1000;
switch (via_clock) { switch (via_clock) {
case 33000: via_clock = 33333; break; case 33000: via_clock = 33333; break;
......
...@@ -480,13 +480,13 @@ pmac_ide_do_update_timings(ide_drive_t *drive) ...@@ -480,13 +480,13 @@ pmac_ide_do_update_timings(ide_drive_t *drive)
pmac_ide_selectproc(drive); pmac_ide_selectproc(drive);
} }
static void static void pmac_outbsync(ide_hwif_t *hwif, u8 value, unsigned long port)
pmac_outbsync(ide_drive_t *drive, u8 value, unsigned long port)
{ {
u32 tmp; u32 tmp;
writeb(value, (void __iomem *) port); writeb(value, (void __iomem *) port);
tmp = readl(PMAC_IDE_REG(IDE_TIMING_CONFIG)); tmp = readl((void __iomem *)(hwif->io_ports.data_addr
+ IDE_TIMING_CONFIG));
} }
/* /*
......
...@@ -87,7 +87,7 @@ unsigned long ide_pci_dma_base(ide_hwif_t *hwif, const struct ide_port_info *d) ...@@ -87,7 +87,7 @@ unsigned long ide_pci_dma_base(ide_hwif_t *hwif, const struct ide_port_info *d)
unsigned long dma_base = 0; unsigned long dma_base = 0;
u8 dma_stat = 0; u8 dma_stat = 0;
if (hwif->mmio) if (hwif->host_flags & IDE_HFLAG_MMIO)
return hwif->dma_base; return hwif->dma_base;
if (hwif->mate && hwif->mate->dma_base) { if (hwif->mate && hwif->mate->dma_base) {
...@@ -374,7 +374,7 @@ int ide_hwif_setup_dma(ide_hwif_t *hwif, const struct ide_port_info *d) ...@@ -374,7 +374,7 @@ int ide_hwif_setup_dma(ide_hwif_t *hwif, const struct ide_port_info *d)
if (base == 0 || ide_pci_set_master(dev, d->name) < 0) if (base == 0 || ide_pci_set_master(dev, d->name) < 0)
return -1; return -1;
if (hwif->mmio) if (hwif->host_flags & IDE_HFLAG_MMIO)
printk(KERN_INFO " %s: MMIO-DMA\n", hwif->name); printk(KERN_INFO " %s: MMIO-DMA\n", hwif->name);
else else
printk(KERN_INFO " %s: BM-DMA at 0x%04lx-0x%04lx\n", printk(KERN_INFO " %s: BM-DMA at 0x%04lx-0x%04lx\n",
......
...@@ -60,6 +60,13 @@ ...@@ -60,6 +60,13 @@
#define IDESCSI_DEBUG_LOG 0 #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 * SCSI command transformation layer
*/ */
...@@ -129,14 +136,15 @@ static inline idescsi_scsi_t *drive_to_idescsi(ide_drive_t *ide_drive) ...@@ -129,14 +136,15 @@ static inline idescsi_scsi_t *drive_to_idescsi(ide_drive_t *ide_drive)
#define IDESCSI_PC_RQ 90 #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, static void ide_scsi_io_buffers(ide_drive_t *drive, struct ide_atapi_pc *pc,
unsigned int bcount) unsigned int bcount, int write)
{ {
ide_hwif_t *hwif = drive->hwif; ide_hwif_t *hwif = drive->hwif;
int count; xfer_func_t *xf = write ? hwif->output_data : hwif->input_data;
char *buf; char *buf;
int count;
while (bcount) { while (bcount) {
count = min(pc->sg->length - pc->b_count, 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, ...@@ -145,13 +153,13 @@ static void idescsi_input_buffers(ide_drive_t *drive, struct ide_atapi_pc *pc,
local_irq_save(flags); local_irq_save(flags);
buf = kmap_atomic(sg_page(pc->sg), KM_IRQ0) + buf = kmap_atomic(sg_page(pc->sg), KM_IRQ0) +
pc->sg->offset; pc->sg->offset;
hwif->input_data(drive, NULL, buf + pc->b_count, count); xf(drive, NULL, buf + pc->b_count, count);
kunmap_atomic(buf - pc->sg->offset, KM_IRQ0); kunmap_atomic(buf - pc->sg->offset, KM_IRQ0);
local_irq_restore(flags); local_irq_restore(flags);
} else { } else {
buf = sg_virt(pc->sg); 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; bcount -= count; pc->b_count += count;
if (pc->b_count == pc->sg->length) { 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, ...@@ -163,51 +171,34 @@ static void idescsi_input_buffers(ide_drive_t *drive, struct ide_atapi_pc *pc,
} }
if (bcount) { if (bcount) {
printk (KERN_ERR "ide-scsi: scatter gather table too small, discarding data\n"); printk(KERN_ERR "%s: scatter gather table too small, %s\n",
ide_pad_transfer(drive, 0, bcount); 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, static void ide_scsi_hex_dump(u8 *data, int len)
unsigned int bcount)
{ {
ide_hwif_t *hwif = drive->hwif; print_hex_dump(KERN_CONT, "", DUMP_PREFIX_NONE, 16, 1, data, len, 0);
int count; }
char *buf;
while (bcount) { static int idescsi_end_request(ide_drive_t *, int, int);
count = min(pc->sg->length - pc->b_count, bcount);
if (PageHighMem(sg_page(pc->sg))) {
unsigned long flags;
local_irq_save(flags); static void ide_scsi_callback(ide_drive_t *drive)
buf = kmap_atomic(sg_page(pc->sg), KM_IRQ0) + {
pc->sg->offset; idescsi_scsi_t *scsi = drive_to_idescsi(drive);
hwif->output_data(drive, NULL, buf + pc->b_count, count); struct ide_atapi_pc *pc = scsi->pc;
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;
}
}
if (bcount) { if (pc->flags & PC_FLAG_TIMEDOUT)
printk (KERN_ERR "ide-scsi: scatter gather table too small, padding with zeros\n"); debug_log("%s: got timed out packet %lu at %lu\n", __func__,
ide_pad_transfer(drive, 1, bcount); 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) idescsi_end_request(drive, 1, 0);
{
print_hex_dump(KERN_CONT, "", DUMP_PREFIX_NONE, 16, 1, data, len, 0);
} }
static int idescsi_check_condition(ide_drive_t *drive, static int idescsi_check_condition(ide_drive_t *drive,
...@@ -228,14 +219,16 @@ static int idescsi_check_condition(ide_drive_t *drive, ...@@ -228,14 +219,16 @@ static int idescsi_check_condition(ide_drive_t *drive,
kfree(pc); kfree(pc);
return -ENOMEM; return -ENOMEM;
} }
ide_init_drive_cmd(rq); blk_rq_init(NULL, rq);
rq->special = (char *) pc; rq->special = (char *) pc;
pc->rq = rq; pc->rq = rq;
pc->buf = buf; pc->buf = buf;
pc->c[0] = REQUEST_SENSE; pc->c[0] = REQUEST_SENSE;
pc->c[4] = pc->req_xfer = pc->buf_size = SCSI_SENSE_BUFFERSIZE; pc->c[4] = pc->req_xfer = pc->buf_size = SCSI_SENSE_BUFFERSIZE;
rq->cmd_type = REQ_TYPE_SENSE; rq->cmd_type = REQ_TYPE_SENSE;
rq->cmd_flags |= REQ_PREEMPT;
pc->timeout = jiffies + WAIT_READY; pc->timeout = jiffies + WAIT_READY;
pc->callback = ide_scsi_callback;
/* NOTE! Save the failed packet command in "rq->buffer" */ /* NOTE! Save the failed packet command in "rq->buffer" */
rq->buffer = (void *) failed_cmd->special; rq->buffer = (void *) failed_cmd->special;
pc->scsi_cmd = ((struct ide_atapi_pc *) failed_cmd->special)->scsi_cmd; 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, ...@@ -244,11 +237,10 @@ static int idescsi_check_condition(ide_drive_t *drive,
ide_scsi_hex_dump(pc->c, 6); ide_scsi_hex_dump(pc->c, 6);
} }
rq->rq_disk = scsi->disk; 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 static ide_startstop_t
idescsi_atapi_error(ide_drive_t *drive, struct request *rq, u8 stat, u8 err) 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) ...@@ -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)) if (ide_read_status(drive) & (BUSY_STAT | DRQ_STAT))
/* force an abort */ /* force an abort */
hwif->OUTBSYNC(drive, WIN_IDLEIMMEDIATE, hwif->OUTBSYNC(hwif, WIN_IDLEIMMEDIATE,
hwif->io_ports.command_addr); hwif->io_ports.command_addr);
rq->errors++; rq->errors++;
...@@ -269,10 +261,9 @@ idescsi_atapi_error(ide_drive_t *drive, struct request *rq, u8 stat, u8 err) ...@@ -269,10 +261,9 @@ idescsi_atapi_error(ide_drive_t *drive, struct request *rq, u8 stat, u8 err)
static ide_startstop_t static ide_startstop_t
idescsi_atapi_abort(ide_drive_t *drive, struct request *rq) idescsi_atapi_abort(ide_drive_t *drive, struct request *rq)
{ {
#if IDESCSI_DEBUG_LOG debug_log("%s called for %lu\n", __func__,
printk(KERN_WARNING "idescsi_atapi_abort called for %lu\n",
((struct ide_atapi_pc *) rq->special)->scsi_cmd->serial_number); ((struct ide_atapi_pc *) rq->special)->scsi_cmd->serial_number);
#endif
rq->errors |= ERROR_MAX; rq->errors |= ERROR_MAX;
idescsi_end_request(drive, 0, 0); idescsi_end_request(drive, 0, 0);
...@@ -351,9 +342,9 @@ static int idescsi_expiry(ide_drive_t *drive) ...@@ -351,9 +342,9 @@ static int idescsi_expiry(ide_drive_t *drive)
idescsi_scsi_t *scsi = drive_to_idescsi(drive); idescsi_scsi_t *scsi = drive_to_idescsi(drive);
struct ide_atapi_pc *pc = scsi->pc; struct ide_atapi_pc *pc = scsi->pc;
#if IDESCSI_DEBUG_LOG debug_log("%s called for %lu at %lu\n", __func__,
printk(KERN_WARNING "idescsi_expiry called for %lu at %lu\n", pc->scsi_cmd->serial_number, jiffies); pc->scsi_cmd->serial_number, jiffies);
#endif
pc->flags |= PC_FLAG_TIMEDOUT; pc->flags |= PC_FLAG_TIMEDOUT;
return 0; /* we do not want the ide subsystem to retry */ return 0; /* we do not want the ide subsystem to retry */
...@@ -365,141 +356,19 @@ static int idescsi_expiry(ide_drive_t *drive) ...@@ -365,141 +356,19 @@ static int idescsi_expiry(ide_drive_t *drive)
static ide_startstop_t idescsi_pc_intr (ide_drive_t *drive) static ide_startstop_t idescsi_pc_intr (ide_drive_t *drive)
{ {
idescsi_scsi_t *scsi = drive_to_idescsi(drive); idescsi_scsi_t *scsi = drive_to_idescsi(drive);
ide_hwif_t *hwif = drive->hwif;
struct ide_atapi_pc *pc = scsi->pc; 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 */ return ide_pc_intr(drive, pc, idescsi_pc_intr, get_timeout(pc),
ide_set_handler(drive, &idescsi_pc_intr, get_timeout(pc), idescsi_expiry); idescsi_expiry, NULL, NULL, NULL,
return ide_started; ide_scsi_io_buffers);
} }
static ide_startstop_t idescsi_transfer_pc(ide_drive_t *drive) 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); 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)) { return ide_transfer_pc(drive, scsi->pc, idescsi_pc_intr,
printk(KERN_ERR "ide-scsi: Strange, packet command " get_timeout(scsi->pc), idescsi_expiry);
"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;
} }
static inline int idescsi_set_direction(struct ide_atapi_pc *pc) 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, ...@@ -545,38 +414,12 @@ static ide_startstop_t idescsi_issue_pc(ide_drive_t *drive,
struct ide_atapi_pc *pc) struct ide_atapi_pc *pc)
{ {
idescsi_scsi_t *scsi = drive_to_idescsi(drive); idescsi_scsi_t *scsi = drive_to_idescsi(drive);
ide_hwif_t *hwif = drive->hwif;
u16 bcount;
u8 dma = 0;
/* Set the current packet command */ /* Set the current packet command */
scsi->pc = pc; 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) return ide_issue_pc(drive, pc, idescsi_transfer_pc,
pc->flags |= PC_FLAG_DMA_OK; get_timeout(pc), idescsi_expiry);
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);
}
} }
/* /*
...@@ -584,14 +427,22 @@ static ide_startstop_t idescsi_issue_pc(ide_drive_t *drive, ...@@ -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) static ide_startstop_t idescsi_do_request (ide_drive_t *drive, struct request *rq, sector_t block)
{ {
#if IDESCSI_DEBUG_LOG debug_log("dev: %s, cmd: %x, errors: %d\n", rq->rq_disk->disk_name,
printk (KERN_INFO "dev: %s, cmd: %x, errors: %d\n", rq->rq_disk->disk_name,rq->cmd[0],rq->errors); 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); debug_log("sector: %ld, nr_sectors: %ld, current_nr_sectors: %d\n",
#endif /* IDESCSI_DEBUG_LOG */ rq->sector, rq->nr_sectors, rq->current_nr_sectors);
if (blk_sense_request(rq) || blk_special_request(rq)) { if (blk_sense_request(rq) || blk_special_request(rq)) {
return idescsi_issue_pc(drive, struct ide_atapi_pc *pc = (struct ide_atapi_pc *)rq->special;
(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"); blk_dump_rq_flags(rq, "ide-scsi: unsup command");
idescsi_end_request (drive, 0, 0); idescsi_end_request (drive, 0, 0);
...@@ -646,6 +497,8 @@ static void ide_scsi_remove(ide_drive_t *drive) ...@@ -646,6 +497,8 @@ static void ide_scsi_remove(ide_drive_t *drive)
put_disk(g); put_disk(g);
ide_scsi_put(scsi); ide_scsi_put(scsi);
drive->scsi = 0;
} }
static int ide_scsi_probe(ide_drive_t *); static int ide_scsi_probe(ide_drive_t *);
...@@ -765,6 +618,8 @@ static int idescsi_queue (struct scsi_cmnd *cmd, ...@@ -765,6 +618,8 @@ static int idescsi_queue (struct scsi_cmnd *cmd,
memset (pc->c, 0, 12); memset (pc->c, 0, 12);
pc->flags = 0; pc->flags = 0;
if (cmd->sc_data_direction == DMA_TO_DEVICE)
pc->flags |= PC_FLAG_WRITING;
pc->rq = rq; pc->rq = rq;
memcpy (pc->c, cmd->cmnd, cmd->cmd_len); memcpy (pc->c, cmd->cmnd, cmd->cmd_len);
pc->buf = NULL; pc->buf = NULL;
...@@ -775,6 +630,7 @@ static int idescsi_queue (struct scsi_cmnd *cmd, ...@@ -775,6 +630,7 @@ static int idescsi_queue (struct scsi_cmnd *cmd,
pc->scsi_cmd = cmd; pc->scsi_cmd = cmd;
pc->done = done; pc->done = done;
pc->timeout = jiffies + cmd->timeout_per_command; pc->timeout = jiffies + cmd->timeout_per_command;
pc->callback = ide_scsi_callback;
if (test_bit(IDESCSI_LOG_CMD, &scsi->log)) { if (test_bit(IDESCSI_LOG_CMD, &scsi->log)) {
printk ("ide-scsi: %s: que %lu, cmd = ", drive->name, cmd->serial_number); printk ("ide-scsi: %s: que %lu, cmd = ", drive->name, cmd->serial_number);
...@@ -785,12 +641,11 @@ static int idescsi_queue (struct scsi_cmnd *cmd, ...@@ -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->special = (char *) pc;
rq->cmd_type = REQ_TYPE_SPECIAL; rq->cmd_type = REQ_TYPE_SPECIAL;
spin_unlock_irq(host->host_lock); spin_unlock_irq(host->host_lock);
rq->rq_disk = scsi->disk; blk_execute_rq_nowait(drive->queue, scsi->disk, rq, 0, NULL);
(void) ide_do_drive_cmd (drive, rq, ide_end);
spin_lock_irq(host->host_lock); spin_lock_irq(host->host_lock);
return 0; return 0;
abort: abort:
...@@ -985,6 +840,8 @@ static int ide_scsi_probe(ide_drive_t *drive) ...@@ -985,6 +840,8 @@ static int ide_scsi_probe(ide_drive_t *drive)
!(host = scsi_host_alloc(&idescsi_template,sizeof(idescsi_scsi_t)))) !(host = scsi_host_alloc(&idescsi_template,sizeof(idescsi_scsi_t))))
return -ENODEV; return -ENODEV;
drive->scsi = 1;
g = alloc_disk(1 << PARTN_BITS); g = alloc_disk(1 << PARTN_BITS);
if (!g) if (!g)
goto out_host_put; goto out_host_put;
...@@ -993,10 +850,10 @@ static int ide_scsi_probe(ide_drive_t *drive) ...@@ -993,10 +850,10 @@ static int ide_scsi_probe(ide_drive_t *drive)
host->max_id = 1; host->max_id = 1;
#if IDESCSI_DEBUG_LOG
if (drive->id->last_lun) if (drive->id->last_lun)
printk(KERN_NOTICE "%s: id->last_lun=%u\n", drive->name, drive->id->last_lun); debug_log("%s: id->last_lun=%u\n", drive->name,
#endif drive->id->last_lun);
if ((drive->id->last_lun & 0x7) != 7) if ((drive->id->last_lun & 0x7) != 7)
host->max_lun = (drive->id->last_lun & 0x7) + 1; host->max_lun = (drive->id->last_lun & 0x7) + 1;
else else
...@@ -1025,6 +882,7 @@ static int ide_scsi_probe(ide_drive_t *drive) ...@@ -1025,6 +882,7 @@ static int ide_scsi_probe(ide_drive_t *drive)
put_disk(g); put_disk(g);
out_host_put: out_host_put:
drive->scsi = 0;
scsi_host_put(host); scsi_host_put(host);
return err; return err;
} }
......
...@@ -651,7 +651,6 @@ extern void generic_make_request(struct bio *bio); ...@@ -651,7 +651,6 @@ extern void generic_make_request(struct bio *bio);
extern void blk_rq_init(struct request_queue *q, struct request *rq); extern void blk_rq_init(struct request_queue *q, struct request *rq);
extern void blk_put_request(struct request *); extern void blk_put_request(struct request *);
extern void __blk_put_request(struct request_queue *, struct request *); extern void __blk_put_request(struct request_queue *, struct request *);
extern void blk_end_sync_rq(struct request *rq, int error);
extern struct request *blk_get_request(struct request_queue *, int, gfp_t); extern struct request *blk_get_request(struct request_queue *, int, gfp_t);
extern void blk_insert_request(struct request_queue *, struct request *, int, void *); extern void blk_insert_request(struct request_queue *, struct request *, int, void *);
extern void blk_requeue_request(struct request_queue *, struct request *); extern void blk_requeue_request(struct request_queue *, struct request *);
......
...@@ -364,7 +364,6 @@ typedef struct ide_drive_s { ...@@ -364,7 +364,6 @@ typedef struct ide_drive_s {
u8 wcache; /* status of write cache */ u8 wcache; /* status of write cache */
u8 acoustic; /* acoustic management */ u8 acoustic; /* acoustic management */
u8 media; /* disk, cdrom, tape, floppy, ... */ u8 media; /* disk, cdrom, tape, floppy, ... */
u8 ctl; /* "normal" value for Control register */
u8 ready_stat; /* min status value for drive ready */ u8 ready_stat; /* min status value for drive ready */
u8 mult_count; /* current multiple sector setting */ u8 mult_count; /* current multiple sector setting */
u8 mult_req; /* requested multiple sector setting */ u8 mult_req; /* requested multiple sector setting */
...@@ -493,7 +492,7 @@ typedef struct hwif_s { ...@@ -493,7 +492,7 @@ typedef struct hwif_s {
void (*ide_dma_clear_irq)(ide_drive_t *drive); void (*ide_dma_clear_irq)(ide_drive_t *drive);
void (*OUTB)(u8 addr, unsigned long port); void (*OUTB)(u8 addr, unsigned long port);
void (*OUTBSYNC)(ide_drive_t *drive, u8 addr, unsigned long port); void (*OUTBSYNC)(struct hwif_s *hwif, u8 addr, unsigned long port);
u8 (*INB)(unsigned long port); u8 (*INB)(unsigned long port);
...@@ -532,7 +531,6 @@ typedef struct hwif_s { ...@@ -532,7 +531,6 @@ typedef struct hwif_s {
unsigned serialized : 1; /* serialized all channel operation */ unsigned serialized : 1; /* serialized all channel operation */
unsigned sharing_irq: 1; /* 1 = sharing irq with another hwif */ unsigned sharing_irq: 1; /* 1 = sharing irq with another hwif */
unsigned sg_mapped : 1; /* sg_table and sg_nents are ready */ unsigned sg_mapped : 1; /* sg_table and sg_nents are ready */
unsigned mmio : 1; /* host uses MMIO */
struct device gendev; struct device gendev;
struct device *portdev; struct device *portdev;
...@@ -604,12 +602,13 @@ enum { ...@@ -604,12 +602,13 @@ enum {
PC_FLAG_SUPPRESS_ERROR = (1 << 1), PC_FLAG_SUPPRESS_ERROR = (1 << 1),
PC_FLAG_WAIT_FOR_DSC = (1 << 2), PC_FLAG_WAIT_FOR_DSC = (1 << 2),
PC_FLAG_DMA_OK = (1 << 3), PC_FLAG_DMA_OK = (1 << 3),
PC_FLAG_DMA_RECOMMENDED = (1 << 4), PC_FLAG_DMA_IN_PROGRESS = (1 << 4),
PC_FLAG_DMA_IN_PROGRESS = (1 << 5), PC_FLAG_DMA_ERROR = (1 << 5),
PC_FLAG_DMA_ERROR = (1 << 6), PC_FLAG_WRITING = (1 << 6),
PC_FLAG_WRITING = (1 << 7),
/* command timed out */ /* command timed out */
PC_FLAG_TIMEDOUT = (1 << 8), PC_FLAG_TIMEDOUT = (1 << 7),
PC_FLAG_ZIP_DRIVE = (1 << 8),
PC_FLAG_DRQ_INTERRUPT = (1 << 9),
}; };
struct ide_atapi_pc { struct ide_atapi_pc {
...@@ -642,8 +641,8 @@ struct ide_atapi_pc { ...@@ -642,8 +641,8 @@ struct ide_atapi_pc {
* to change/removal later. * to change/removal later.
*/ */
u8 pc_buf[256]; u8 pc_buf[256];
void (*idefloppy_callback) (ide_drive_t *);
ide_startstop_t (*idetape_callback) (ide_drive_t *); void (*callback)(ide_drive_t *);
/* idetape only */ /* idetape only */
struct idetape_bh *bh; struct idetape_bh *bh;
...@@ -813,10 +812,6 @@ int generic_ide_ioctl(ide_drive_t *, struct file *, struct block_device *, unsig ...@@ -813,10 +812,6 @@ int generic_ide_ioctl(ide_drive_t *, struct file *, struct block_device *, unsig
#ifndef _IDE_C #ifndef _IDE_C
extern ide_hwif_t ide_hwifs[]; /* master data repository */ extern ide_hwif_t ide_hwifs[]; /* master data repository */
#endif #endif
extern int ide_noacpi;
extern int ide_acpigtf;
extern int ide_acpionboot;
extern int noautodma;
extern int ide_vlb_clk; extern int ide_vlb_clk;
extern int ide_pci_clk; extern int ide_pci_clk;
...@@ -857,25 +852,12 @@ int ide_wait_stat(ide_startstop_t *, ide_drive_t *, u8, u8, unsigned long); ...@@ -857,25 +852,12 @@ int ide_wait_stat(ide_startstop_t *, ide_drive_t *, u8, u8, unsigned long);
extern ide_startstop_t ide_do_reset (ide_drive_t *); extern ide_startstop_t ide_do_reset (ide_drive_t *);
extern void ide_init_drive_cmd (struct request *rq); extern void ide_do_drive_cmd(ide_drive_t *, struct request *);
/*
* "action" parameter type for ide_do_drive_cmd() below.
*/
typedef enum {
ide_wait, /* insert rq at end of list, and wait for it */
ide_preempt, /* insert rq in front of current request */
ide_head_wait, /* insert rq in front of current request and wait for it */
ide_end /* insert rq at end of list, but don't wait for it */
} ide_action_t;
extern int ide_do_drive_cmd(ide_drive_t *, struct request *, ide_action_t);
extern void ide_end_drive_cmd(ide_drive_t *, u8, u8); extern void ide_end_drive_cmd(ide_drive_t *, u8, u8);
enum { enum {
IDE_TFLAG_LBA48 = (1 << 0), IDE_TFLAG_LBA48 = (1 << 0),
IDE_TFLAG_NO_SELECT_MASK = (1 << 1),
IDE_TFLAG_FLAGGED = (1 << 2), IDE_TFLAG_FLAGGED = (1 << 2),
IDE_TFLAG_OUT_DATA = (1 << 3), IDE_TFLAG_OUT_DATA = (1 << 3),
IDE_TFLAG_OUT_HOB_FEATURE = (1 << 4), IDE_TFLAG_OUT_HOB_FEATURE = (1 << 4),
...@@ -980,11 +962,23 @@ typedef struct ide_task_s { ...@@ -980,11 +962,23 @@ typedef struct ide_task_s {
void ide_tf_dump(const char *, struct ide_taskfile *); void ide_tf_dump(const char *, struct ide_taskfile *);
extern void SELECT_DRIVE(ide_drive_t *); extern void SELECT_DRIVE(ide_drive_t *);
void SELECT_MASK(ide_drive_t *, int);
extern int drive_is_ready(ide_drive_t *); extern int drive_is_ready(ide_drive_t *);
void ide_pktcmd_tf_load(ide_drive_t *, u32, u16, u8); void ide_pktcmd_tf_load(ide_drive_t *, u32, u16, u8);
ide_startstop_t ide_pc_intr(ide_drive_t *drive, struct ide_atapi_pc *pc,
ide_handler_t *handler, unsigned int timeout, ide_expiry_t *expiry,
void (*update_buffers)(ide_drive_t *, struct ide_atapi_pc *),
void (*retry_pc)(ide_drive_t *), void (*dsc_handle)(ide_drive_t *),
void (*io_buffers)(ide_drive_t *, struct ide_atapi_pc *, unsigned int,
int));
ide_startstop_t ide_transfer_pc(ide_drive_t *, struct ide_atapi_pc *,
ide_handler_t *, unsigned int, ide_expiry_t *);
ide_startstop_t ide_issue_pc(ide_drive_t *, struct ide_atapi_pc *,
ide_handler_t *, unsigned int, ide_expiry_t *);
ide_startstop_t do_rw_taskfile(ide_drive_t *, ide_task_t *); ide_startstop_t do_rw_taskfile(ide_drive_t *, ide_task_t *);
void task_end_request(ide_drive_t *, struct request *, u8); void task_end_request(ide_drive_t *, struct request *, u8);
...@@ -996,8 +990,6 @@ int ide_taskfile_ioctl(ide_drive_t *, unsigned int, unsigned long); ...@@ -996,8 +990,6 @@ int ide_taskfile_ioctl(ide_drive_t *, unsigned int, unsigned long);
int ide_cmd_ioctl(ide_drive_t *, unsigned int, unsigned long); int ide_cmd_ioctl(ide_drive_t *, unsigned int, unsigned long);
int ide_task_ioctl(ide_drive_t *, unsigned int, unsigned long); int ide_task_ioctl(ide_drive_t *, unsigned int, unsigned long);
extern int system_bus_clock(void);
extern int ide_driveid_update(ide_drive_t *); extern int ide_driveid_update(ide_drive_t *);
extern int ide_config_drive_speed(ide_drive_t *, u8); extern int ide_config_drive_speed(ide_drive_t *, u8);
extern u8 eighty_ninty_three (ide_drive_t *); extern u8 eighty_ninty_three (ide_drive_t *);
...@@ -1349,7 +1341,8 @@ static inline void ide_set_irq(ide_drive_t *drive, int on) ...@@ -1349,7 +1341,8 @@ static inline void ide_set_irq(ide_drive_t *drive, int on)
{ {
ide_hwif_t *hwif = drive->hwif; ide_hwif_t *hwif = drive->hwif;
hwif->OUTB(drive->ctl | (on ? 0 : 2), hwif->io_ports.ctl_addr); hwif->OUTBSYNC(hwif, ATA_DEVCTL_OBS | (on ? 0 : 2),
hwif->io_ports.ctl_addr);
} }
static inline u8 ide_read_status(ide_drive_t *drive) static inline u8 ide_read_status(ide_drive_t *drive)
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册