diff options
45 files changed, 1573 insertions, 1958 deletions
diff --git a/drivers/ide/Kconfig b/drivers/ide/Kconfig index 5ea3bfad172..640c9920724 100644 --- a/drivers/ide/Kconfig +++ b/drivers/ide/Kconfig @@ -56,8 +56,12 @@ if IDE comment "Please see Documentation/ide/ide.txt for help/info on IDE drives" +config IDE_XFER_MODE + bool + config IDE_TIMINGS bool + select IDE_XFER_MODE config IDE_ATAPI bool @@ -698,6 +702,7 @@ config BLK_DEV_IDE_PMAC_ATA100FIRST config BLK_DEV_IDE_AU1XXX bool "IDE for AMD Alchemy Au1200" depends on SOC_AU1200 + select IDE_XFER_MODE choice prompt "IDE Mode for AMD Alchemy Au1200" default CONFIG_BLK_DEV_IDE_AU1XXX_PIO_DBDMA @@ -871,6 +876,7 @@ config BLK_DEV_ALI14XX config BLK_DEV_DTC2278 tristate "DTC-2278 support" + select IDE_XFER_MODE select IDE_LEGACY help This driver is enabled at runtime using the "dtc2278.probe" kernel @@ -902,6 +908,7 @@ config BLK_DEV_QD65XX config BLK_DEV_UMC8672 tristate "UMC-8672 support" + select IDE_XFER_MODE select IDE_LEGACY help This driver is enabled at runtime using the "umc8672.probe" kernel @@ -915,5 +922,6 @@ endif config BLK_DEV_IDEDMA def_bool BLK_DEV_IDEDMA_SFF || \ BLK_DEV_IDEDMA_ICS || BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA + select IDE_XFER_MODE endif # IDE diff --git a/drivers/ide/Makefile b/drivers/ide/Makefile index 1c326d94aa6..9b4bbe1cdc1 100644 --- a/drivers/ide/Makefile +++ b/drivers/ide/Makefile @@ -5,9 +5,11 @@ EXTRA_CFLAGS += -Idrivers/ide ide-core-y += ide.o ide-ioctls.o ide-io.o ide-iops.o ide-lib.o ide-probe.o \ - ide-taskfile.o ide-pm.o ide-park.o ide-pio-blacklist.o ide-sysfs.o + ide-taskfile.o ide-pm.o ide-park.o ide-sysfs.o ide-devsets.o \ + ide-io-std.o ide-eh.o # core IDE code +ide-core-$(CONFIG_IDE_XFER_MODE) += ide-pio-blacklist.o ide-xfer-mode.o ide-core-$(CONFIG_IDE_TIMINGS) += ide-timings.o ide-core-$(CONFIG_IDE_ATAPI) += ide-atapi.o ide-core-$(CONFIG_BLK_DEV_IDEPCI) += setup-pci.o diff --git a/drivers/ide/aec62xx.c b/drivers/ide/aec62xx.c index 4485b9c6f0e..878f8ec6dbe 100644 --- a/drivers/ide/aec62xx.c +++ b/drivers/ide/aec62xx.c @@ -139,7 +139,7 @@ static void aec_set_pio_mode(ide_drive_t *drive, const u8 pio) drive->hwif->port_ops->set_dma_mode(drive, pio + XFER_PIO_0); } -static unsigned int init_chipset_aec62xx(struct pci_dev *dev) +static int init_chipset_aec62xx(struct pci_dev *dev) { /* These are necessary to get AEC6280 Macintosh cards to work */ if ((dev->device == PCI_DEVICE_ID_ARTOP_ATP865) || @@ -156,7 +156,7 @@ static unsigned int init_chipset_aec62xx(struct pci_dev *dev) pci_write_config_byte(dev, 0x4a, reg4ah | 0x80); } - return dev->irq; + return 0; } static u8 atp86x_cable_detect(ide_hwif_t *hwif) diff --git a/drivers/ide/alim15x3.c b/drivers/ide/alim15x3.c index 66f43083408..d3513b6b853 100644 --- a/drivers/ide/alim15x3.c +++ b/drivers/ide/alim15x3.c @@ -212,7 +212,7 @@ static int ali15x3_dma_setup(ide_drive_t *drive) * appropriate also sets up the 1533 southbridge. */ -static unsigned int init_chipset_ali15x3(struct pci_dev *dev) +static int init_chipset_ali15x3(struct pci_dev *dev) { unsigned long flags; u8 tmpbyte; diff --git a/drivers/ide/amd74xx.c b/drivers/ide/amd74xx.c index 77267c85996..628cd2e5fed 100644 --- a/drivers/ide/amd74xx.c +++ b/drivers/ide/amd74xx.c @@ -140,7 +140,7 @@ static void amd7411_cable_detect(struct pci_dev *dev) * The initialization callback. Initialize drive independent registers. */ -static unsigned int init_chipset_amd74xx(struct pci_dev *dev) +static int init_chipset_amd74xx(struct pci_dev *dev) { u8 t = 0, offset = amd_offset(dev); @@ -172,7 +172,7 @@ static unsigned int init_chipset_amd74xx(struct pci_dev *dev) t |= 0xf0; pci_write_config_byte(dev, AMD_IDE_CONFIG + offset, t); - return dev->irq; + return 0; } static u8 amd_cable_detect(ide_hwif_t *hwif) @@ -183,14 +183,6 @@ static u8 amd_cable_detect(ide_hwif_t *hwif) return ATA_CBL_PATA40; } -static void __devinit init_hwif_amd74xx(ide_hwif_t *hwif) -{ - struct pci_dev *dev = to_pci_dev(hwif->dev); - - if (hwif->irq == 0) /* 0 is bogus but will do for now */ - hwif->irq = pci_get_legacy_ide_irq(dev, hwif->channel); -} - static const struct ide_port_ops amd_port_ops = { .set_pio_mode = amd_set_pio_mode, .set_dma_mode = amd_set_drive, @@ -207,7 +199,6 @@ static const struct ide_port_ops amd_port_ops = { { \ .name = DRV_NAME, \ .init_chipset = init_chipset_amd74xx, \ - .init_hwif = init_hwif_amd74xx, \ .enablebits = {{0x40,0x02,0x02}, {0x40,0x01,0x01}}, \ .port_ops = &amd_port_ops, \ .host_flags = IDE_HFLAGS_AMD, \ @@ -221,7 +212,6 @@ static const struct ide_port_ops amd_port_ops = { { \ .name = DRV_NAME, \ .init_chipset = init_chipset_amd74xx, \ - .init_hwif = init_hwif_amd74xx, \ .enablebits = {{0x50,0x02,0x02}, {0x50,0x01,0x01}}, \ .port_ops = &amd_port_ops, \ .host_flags = IDE_HFLAGS_AMD, \ diff --git a/drivers/ide/atiixp.c b/drivers/ide/atiixp.c index ecd1e62ca91..923cbfe259d 100644 --- a/drivers/ide/atiixp.c +++ b/drivers/ide/atiixp.c @@ -142,7 +142,6 @@ static const struct ide_port_info atiixp_pci_info[] __devinitdata = { .name = DRV_NAME, .enablebits = {{0x48,0x01,0x00}, {0x48,0x08,0x00}}, .port_ops = &atiixp_port_ops, - .host_flags = IDE_HFLAG_LEGACY_IRQS, .pio_mask = ATA_PIO4, .mwdma_mask = ATA_MWDMA2, .udma_mask = ATA_UDMA5, @@ -151,7 +150,7 @@ static const struct ide_port_info atiixp_pci_info[] __devinitdata = { .name = DRV_NAME, .enablebits = {{0x48,0x01,0x00}, {0x00,0x00,0x00}}, .port_ops = &atiixp_port_ops, - .host_flags = IDE_HFLAG_SINGLE | IDE_HFLAG_LEGACY_IRQS, + .host_flags = IDE_HFLAG_SINGLE, .pio_mask = ATA_PIO4, .mwdma_mask = ATA_MWDMA2, .udma_mask = ATA_UDMA5, diff --git a/drivers/ide/cmd64x.c b/drivers/ide/cmd64x.c index 2f9688d87ec..aeee036b150 100644 --- a/drivers/ide/cmd64x.c +++ b/drivers/ide/cmd64x.c @@ -333,7 +333,7 @@ static int cmd646_1_dma_end(ide_drive_t *drive) return (dma_stat & 7) != 4; } -static unsigned int init_chipset_cmd64x(struct pci_dev *dev) +static int init_chipset_cmd64x(struct pci_dev *dev) { u8 mrdmode = 0; diff --git a/drivers/ide/cs5520.c b/drivers/ide/cs5520.c index d003bec56ff..58fb90e5b76 100644 --- a/drivers/ide/cs5520.c +++ b/drivers/ide/cs5520.c @@ -133,7 +133,8 @@ static int __devinit cs5520_init_one(struct pci_dev *dev, const struct pci_devic * do all the device setup for us */ - ide_pci_setup_ports(dev, d, 14, &hw[0], &hws[0]); + ide_pci_setup_ports(dev, d, &hw[0], &hws[0]); + hw[0].irq = 14; return ide_host_add(d, hws, NULL); } diff --git a/drivers/ide/cs5530.c b/drivers/ide/cs5530.c index d8ede85fe17..8e8b35a8990 100644 --- a/drivers/ide/cs5530.c +++ b/drivers/ide/cs5530.c @@ -135,7 +135,7 @@ static void cs5530_set_dma_mode(ide_drive_t *drive, const u8 mode) * Initialize the cs5530 bridge for reliable IDE DMA operation. */ -static unsigned int init_chipset_cs5530(struct pci_dev *dev) +static int init_chipset_cs5530(struct pci_dev *dev) { struct pci_dev *master_0 = NULL, *cs5530_0 = NULL; diff --git a/drivers/ide/delkin_cb.c b/drivers/ide/delkin_cb.c index 8f1b2d9f051..bacb1194c9c 100644 --- a/drivers/ide/delkin_cb.c +++ b/drivers/ide/delkin_cb.c @@ -46,7 +46,7 @@ static const struct ide_port_ops delkin_cb_port_ops = { .quirkproc = ide_undecoded_slave, }; -static unsigned int delkin_cb_init_chipset(struct pci_dev *dev) +static int delkin_cb_init_chipset(struct pci_dev *dev) { unsigned long base = pci_resource_start(dev, 0); int i; diff --git a/drivers/ide/hpt366.c b/drivers/ide/hpt366.c index 3eb9b5c63a0..d3b3e824f44 100644 --- a/drivers/ide/hpt366.c +++ b/drivers/ide/hpt366.c @@ -995,7 +995,7 @@ static void hpt3xx_disable_fast_irq(struct pci_dev *dev, u8 mcr_addr) pci_write_config_byte(dev, mcr_addr + 1, new_mcr); } -static unsigned int init_chipset_hpt366(struct pci_dev *dev) +static int init_chipset_hpt366(struct pci_dev *dev) { unsigned long io_base = pci_resource_start(dev, 4); struct hpt_info *info = hpt3xx_get_info(&dev->dev); @@ -1237,7 +1237,7 @@ static unsigned int init_chipset_hpt366(struct pci_dev *dev) hpt3xx_disable_fast_irq(dev, 0x50); hpt3xx_disable_fast_irq(dev, 0x54); - return dev->irq; + return 0; } static u8 hpt3xx_cable_detect(ide_hwif_t *hwif) diff --git a/drivers/ide/ide-acpi.c b/drivers/ide/ide-acpi.c index ec7d07fa570..5b704f1ea90 100644 --- a/drivers/ide/ide-acpi.c +++ b/drivers/ide/ide-acpi.c @@ -20,9 +20,6 @@ #include <acpi/acpi_bus.h> #define REGS_PER_GTF 7 -struct taskfile_array { - u8 tfa[REGS_PER_GTF]; /* regs. 0x1f1 - 0x1f7 */ -}; struct GTM_buffer { u32 PIO_speed0; @@ -89,12 +86,8 @@ static const struct dmi_system_id ide_acpi_dmi_table[] = { { } /* terminate list */ }; -static int ide_acpi_blacklist(void) +int ide_acpi_init(void) { - static int done; - if (done) - return 0; - done = 1; dmi_check_system(ide_acpi_dmi_table); return 0; } @@ -202,40 +195,6 @@ static acpi_handle ide_acpi_hwif_get_handle(ide_hwif_t *hwif) } /** - * ide_acpi_drive_get_handle - Get ACPI object handle for a given drive - * @drive: device to locate - * - * Retrieves the object handle of a given drive. According to the ACPI - * spec the drive is a child of the hwif. - * - * Returns handle on success, 0 on error. - */ -static acpi_handle ide_acpi_drive_get_handle(ide_drive_t *drive) -{ - ide_hwif_t *hwif = drive->hwif; - int port; - acpi_handle drive_handle; - - if (!hwif->acpidata) - return NULL; - - if (!hwif->acpidata->obj_handle) - return NULL; - - port = hwif->channel ? drive->dn - 2: drive->dn; - - DEBPRINT("ENTER: %s at channel#: %d port#: %d\n", - drive->name, hwif->channel, port); - - - /* TBD: could also check ACPI object VALID bits */ - drive_handle = acpi_get_child(hwif->acpidata->obj_handle, port); - DEBPRINT("drive %s handle 0x%p\n", drive->name, drive_handle); - - return drive_handle; -} - -/** * do_drive_get_GTF - get the drive bootup default taskfile settings * @drive: the drive for which the taskfile settings should be retrieved * @gtf_length: number of bytes of _GTF data returned at @gtf_address @@ -257,47 +216,15 @@ static int do_drive_get_GTF(ide_drive_t *drive, acpi_status status; struct acpi_buffer output; union acpi_object *out_obj; - ide_hwif_t *hwif = drive->hwif; - struct device *dev = hwif->gendev.parent; int err = -ENODEV; - int port; *gtf_length = 0; *gtf_address = 0UL; *obj_loc = 0UL; - if (ide_noacpi) - return 0; - - if (!dev) { - DEBPRINT("no PCI device for %s\n", hwif->name); - goto out; - } - - if (!hwif->acpidata) { - DEBPRINT("no ACPI data for %s\n", hwif->name); - goto out; - } - - port = hwif->channel ? drive->dn - 2: drive->dn; - - DEBPRINT("ENTER: %s at %s, port#: %d, hard_port#: %d\n", - hwif->name, dev_name(dev), port, hwif->channel); - - if ((drive->dev_flags & IDE_DFLAG_PRESENT) == 0) { - DEBPRINT("%s drive %d:%d not present\n", - hwif->name, hwif->channel, port); - goto out; - } - - /* Get this drive's _ADR info. if not already known. */ if (!drive->acpidata->obj_handle) { - drive->acpidata->obj_handle = ide_acpi_drive_get_handle(drive); - if (!drive->acpidata->obj_handle) { - DEBPRINT("No ACPI object found for %s\n", - drive->name); - goto out; - } + DEBPRINT("No ACPI object found for %s\n", drive->name); + goto out; } /* Setting up output buffer */ @@ -355,43 +282,6 @@ out: } /** - * taskfile_load_raw - send taskfile registers to drive - * @drive: drive to which output is sent - * @gtf: raw ATA taskfile register set (0x1f1 - 0x1f7) - * - * Outputs IDE taskfile to the drive. - */ -static int taskfile_load_raw(ide_drive_t *drive, - const struct taskfile_array *gtf) -{ - ide_task_t args; - int err = 0; - - DEBPRINT("(0x1f1-1f7): hex: " - "%02x %02x %02x %02x %02x %02x %02x\n", - gtf->tfa[0], gtf->tfa[1], gtf->tfa[2], - gtf->tfa[3], gtf->tfa[4], gtf->tfa[5], gtf->tfa[6]); - - memset(&args, 0, sizeof(ide_task_t)); - - /* convert gtf to IDE Taskfile */ - memcpy(&args.tf_array[7], >f->tfa, 7); - args.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE; - - if (!ide_acpigtf) { - DEBPRINT("_GTF execution disabled\n"); - return err; - } - - err = ide_no_data_taskfile(drive, &args); - if (err) - printk(KERN_ERR "%s: ide_no_data_taskfile failed: %u\n", - __func__, err); - - return err; -} - -/** * do_drive_set_taskfiles - write the drive taskfile settings from _GTF * @drive: the drive to which the taskfile command should be sent * @gtf_length: total number of bytes of _GTF taskfiles @@ -404,43 +294,41 @@ static int do_drive_set_taskfiles(ide_drive_t *drive, unsigned int gtf_length, unsigned long gtf_address) { - int rc = -ENODEV, err; + int rc = 0, err; int gtf_count = gtf_length / REGS_PER_GTF; int ix; - struct taskfile_array *gtf; - - if (ide_noacpi) - return 0; - - DEBPRINT("ENTER: %s, hard_port#: %d\n", drive->name, drive->dn); - - if ((drive->dev_flags & IDE_DFLAG_PRESENT) == 0) - goto out; - - if (!gtf_count) /* shouldn't be here */ - goto out; DEBPRINT("total GTF bytes=%u (0x%x), gtf_count=%d, addr=0x%lx\n", gtf_length, gtf_length, gtf_count, gtf_address); - if (gtf_length % REGS_PER_GTF) { - printk(KERN_ERR "%s: unexpected GTF length (%d)\n", - __func__, gtf_length); - goto out; - } - - rc = 0; + /* send all taskfile registers (0x1f1-0x1f7) *in*that*order* */ for (ix = 0; ix < gtf_count; ix++) { - gtf = (struct taskfile_array *) - (gtf_address + ix * REGS_PER_GTF); + u8 *gtf = (u8 *)(gtf_address + ix * REGS_PER_GTF); + ide_task_t task; - /* send all TaskFile registers (0x1f1-0x1f7) *in*that*order* */ - err = taskfile_load_raw(drive, gtf); - if (err) + DEBPRINT("(0x1f1-1f7): " + "hex: %02x %02x %02x %02x %02x %02x %02x\n", + gtf[0], gtf[1], gtf[2], + gtf[3], gtf[4], gtf[5], gtf[6]); + + if (!ide_acpigtf) { + DEBPRINT("_GTF execution disabled\n"); + continue; + } + + /* convert GTF to taskfile */ + memset(&task, 0, sizeof(ide_task_t)); + memcpy(&task.tf_array[7], gtf, REGS_PER_GTF); + task.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE; + + err = ide_no_data_taskfile(drive, &task); + if (err) { + printk(KERN_ERR "%s: ide_no_data_taskfile failed: %u\n", + __func__, err); rc = err; + } } -out: return rc; } @@ -647,26 +535,23 @@ void ide_acpi_set_state(ide_hwif_t *hwif, int on) DEBPRINT("no ACPI data for %s\n", hwif->name); return; } + /* channel first and then drives for power on and verse versa for power off */ if (on) acpi_bus_set_power(hwif->acpidata->obj_handle, ACPI_STATE_D0); - ide_port_for_each_dev(i, drive, hwif) { - if (!drive->acpidata->obj_handle) - drive->acpidata->obj_handle = ide_acpi_drive_get_handle(drive); - - if (drive->acpidata->obj_handle && - (drive->dev_flags & IDE_DFLAG_PRESENT)) { + ide_port_for_each_present_dev(i, drive, hwif) { + if (drive->acpidata->obj_handle) acpi_bus_set_power(drive->acpidata->obj_handle, - on? ACPI_STATE_D0: ACPI_STATE_D3); - } + on ? ACPI_STATE_D0 : ACPI_STATE_D3); } + if (!on) acpi_bus_set_power(hwif->acpidata->obj_handle, ACPI_STATE_D3); } /** - * ide_acpi_init - initialize the ACPI link for an IDE interface + * ide_acpi_init_port - initialize the ACPI link for an IDE interface * @hwif: target IDE interface (channel) * * The ACPI spec is not quite clear when the drive identify buffer @@ -676,10 +561,8 @@ void ide_acpi_set_state(ide_hwif_t *hwif, int on) * So we get the information during startup; but this means that * any changes during run-time will be lost after resume. */ -void ide_acpi_init(ide_hwif_t *hwif) +void ide_acpi_init_port(ide_hwif_t *hwif) { - ide_acpi_blacklist(); - hwif->acpidata = kzalloc(sizeof(struct ide_acpi_hwif_link), GFP_KERNEL); if (!hwif->acpidata) return; @@ -708,15 +591,24 @@ void ide_acpi_port_init_devices(ide_hwif_t *hwif) hwif->devices[0]->acpidata = &hwif->acpidata->master; hwif->devices[1]->acpidata = &hwif->acpidata->slave; - /* - * Send IDENTIFY for each drive - */ - ide_port_for_each_dev(i, drive, hwif) { - memset(drive->acpidata, 0, sizeof(*drive->acpidata)); + /* get _ADR info for each device */ + ide_port_for_each_present_dev(i, drive, hwif) { + acpi_handle dev_handle; - if ((drive->dev_flags & IDE_DFLAG_PRESENT) == 0) - continue; + DEBPRINT("ENTER: %s at channel#: %d port#: %d\n", + drive->name, hwif->channel, drive->dn & 1); + + /* TBD: could also check ACPI object VALID bits */ + dev_handle = acpi_get_child(hwif->acpidata->obj_handle, + drive->dn & 1); + + DEBPRINT("drive %s handle 0x%p\n", drive->name, dev_handle); + + drive->acpidata->obj_handle = dev_handle; + } + /* send IDENTIFY for each device */ + ide_port_for_each_present_dev(i, drive, hwif) { err = taskfile_lib_get_identify(drive, drive->acpidata->idbuff); if (err) DEBPRINT("identify device %s failed (%d)\n", @@ -736,9 +628,7 @@ void ide_acpi_port_init_devices(ide_hwif_t *hwif) ide_acpi_get_timing(hwif); ide_acpi_push_timing(hwif); - ide_port_for_each_dev(i, drive, hwif) { - if (drive->dev_flags & IDE_DFLAG_PRESENT) - /* Execute ACPI startup code */ - ide_acpi_exec_tfs(drive); + ide_port_for_each_present_dev(i, drive, hwif) { + ide_acpi_exec_tfs(drive); } } diff --git a/drivers/ide/ide-atapi.c b/drivers/ide/ide-atapi.c index e9d042dba0e..6adc5b4a440 100644 --- a/drivers/ide/ide-atapi.c +++ b/drivers/ide/ide-atapi.c @@ -149,7 +149,10 @@ static void ide_queue_pc_head(ide_drive_t *drive, struct gendisk *disk, memcpy(rq->cmd, pc->c, 12); if (drive->media == ide_tape) rq->cmd[13] = REQ_IDETAPE_PC1; - ide_do_drive_cmd(drive, rq); + + drive->hwif->rq = NULL; + + elv_add_request(drive->queue, rq, ELEVATOR_INSERT_FRONT, 0); } /* @@ -297,6 +300,21 @@ int ide_cd_get_xferlen(struct request *rq) } EXPORT_SYMBOL_GPL(ide_cd_get_xferlen); +void ide_read_bcount_and_ireason(ide_drive_t *drive, u16 *bcount, u8 *ireason) +{ + ide_task_t task; + + memset(&task, 0, sizeof(task)); + task.tf_flags = IDE_TFLAG_IN_LBAH | IDE_TFLAG_IN_LBAM | + IDE_TFLAG_IN_NSECT; + + drive->hwif->tp_ops->tf_read(drive, &task); + + *bcount = (task.tf.lbah << 8) | task.tf.lbam; + *ireason = task.tf.nsect & 3; +} +EXPORT_SYMBOL_GPL(ide_read_bcount_and_ireason); + /* * This is the usual interrupt handler which will be called during a packet * command. We will transfer some of the data (as requested by the drive) @@ -456,6 +474,25 @@ next_irq: return ide_started; } +static void ide_pktcmd_tf_load(ide_drive_t *drive, u32 tf_flags, u16 bcount) +{ + ide_hwif_t *hwif = drive->hwif; + ide_task_t task; + u8 dma = drive->dma; + + memset(&task, 0, sizeof(task)); + task.tf_flags = IDE_TFLAG_OUT_LBAH | IDE_TFLAG_OUT_LBAM | + IDE_TFLAG_OUT_FEATURE | tf_flags; + task.tf.feature = dma; /* Use PIO/DMA */ + task.tf.lbam = bcount & 0xff; + task.tf.lbah = (bcount >> 8) & 0xff; + + ide_tf_dump(drive->name, &task.tf); + hwif->tp_ops->set_irq(hwif, 1); + SELECT_MASK(drive, 0); + hwif->tp_ops->tf_load(drive, &task); +} + static u8 ide_read_ireason(ide_drive_t *drive) { ide_task_t task; @@ -629,7 +666,7 @@ ide_startstop_t ide_issue_pc(ide_drive_t *drive) : WAIT_TAPE_CMD; } - ide_pktcmd_tf_load(drive, tf_flags, bcount, drive->dma); + ide_pktcmd_tf_load(drive, tf_flags, bcount); /* Issue the packet command */ if (drive->atapi_flags & IDE_AFLAG_DRQ_INTERRUPT) { diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c index ddfbea41d29..2177cd11664 100644 --- a/drivers/ide/ide-cd.c +++ b/drivers/ide/ide-cd.c @@ -242,7 +242,9 @@ static void cdrom_queue_request_sense(ide_drive_t *drive, void *sense, ide_debug_log(IDE_DBG_SENSE, "failed_cmd: 0x%x\n", failed_command->cmd[0]); - ide_do_drive_cmd(drive, rq); + drive->hwif->rq = NULL; + + elv_add_request(drive->queue, rq, ELEVATOR_INSERT_FRONT, 0); } static void cdrom_end_request(ide_drive_t *drive, int uptodate) diff --git a/drivers/ide/ide-devsets.c b/drivers/ide/ide-devsets.c new file mode 100644 index 00000000000..7c3953414d4 --- /dev/null +++ b/drivers/ide/ide-devsets.c @@ -0,0 +1,190 @@ + +#include <linux/kernel.h> +#include <linux/ide.h> + +DEFINE_MUTEX(ide_setting_mtx); + +ide_devset_get(io_32bit, io_32bit); + +static int set_io_32bit(ide_drive_t *drive, int arg) +{ + if (drive->dev_flags & IDE_DFLAG_NO_IO_32BIT) + return -EPERM; + + if (arg < 0 || arg > 1 + (SUPPORT_VLB_SYNC << 1)) + return -EINVAL; + + drive->io_32bit = arg; + + return 0; +} + +ide_devset_get_flag(ksettings, IDE_DFLAG_KEEP_SETTINGS); + +static int set_ksettings(ide_drive_t *drive, int arg) +{ + if (arg < 0 || arg > 1) + return -EINVAL; + + if (arg) + drive->dev_flags |= IDE_DFLAG_KEEP_SETTINGS; + else + drive->dev_flags &= ~IDE_DFLAG_KEEP_SETTINGS; + + return 0; +} + +ide_devset_get_flag(using_dma, IDE_DFLAG_USING_DMA); + +static int set_using_dma(ide_drive_t *drive, int arg) +{ +#ifdef CONFIG_BLK_DEV_IDEDMA + int err = -EPERM; + + if (arg < 0 || arg > 1) + return -EINVAL; + + if (ata_id_has_dma(drive->id) == 0) + goto out; + + if (drive->hwif->dma_ops == NULL) + goto out; + + err = 0; + + if (arg) { + if (ide_set_dma(drive)) + err = -EIO; + } else + ide_dma_off(drive); + +out: + return err; +#else + if (arg < 0 || arg > 1) + return -EINVAL; + + return -EPERM; +#endif +} + +/* + * handle HDIO_SET_PIO_MODE ioctl abusers here, eventually it will go away + */ +static int set_pio_mode_abuse(ide_hwif_t *hwif, u8 req_pio) +{ + switch (req_pio) { + case 202: + case 201: + case 200: + case 102: + case 101: + case 100: + return (hwif->host_flags & IDE_HFLAG_ABUSE_DMA_MODES) ? 1 : 0; + case 9: + case 8: + return (hwif->host_flags & IDE_HFLAG_ABUSE_PREFETCH) ? 1 : 0; + case 7: + case 6: + return (hwif->host_flags & IDE_HFLAG_ABUSE_FAST_DEVSEL) ? 1 : 0; + default: + return 0; + } +} + +static int set_pio_mode(ide_drive_t *drive, int arg) +{ + ide_hwif_t *hwif = drive->hwif; + const struct ide_port_ops *port_ops = hwif->port_ops; + + if (arg < 0 || arg > 255) + return -EINVAL; + + if (port_ops == NULL || port_ops->set_pio_mode == NULL || + (hwif->host_flags & IDE_HFLAG_NO_SET_MODE)) + return -ENOSYS; + + if (set_pio_mode_abuse(drive->hwif, arg)) { + if (arg == 8 || arg == 9) { + unsigned long flags; + + /* take lock for IDE_DFLAG_[NO_]UNMASK/[NO_]IO_32BIT */ + spin_lock_irqsave(&hwif->lock, flags); + port_ops->set_pio_mode(drive, arg); + spin_unlock_irqrestore(&hwif->lock, flags); + } els |