diff options
Diffstat (limited to 'drivers/ide')
40 files changed, 1165 insertions, 794 deletions
diff --git a/drivers/ide/Kconfig b/drivers/ide/Kconfig index b6fb167e20f6..e23bc0d62159 100644 --- a/drivers/ide/Kconfig +++ b/drivers/ide/Kconfig @@ -4,6 +4,8 @@ # Andre Hedrick <andre@linux-ide.org> # +if BLOCK + menu "ATA/ATAPI/MFM/RLL support" config IDE @@ -54,7 +56,7 @@ if IDE config IDE_MAX_HWIFS int "Max IDE interfaces" - depends on ALPHA || SUPERH || IA64 + depends on ALPHA || SUPERH || IA64 || EMBEDDED default 4 help This is the maximum number of IDE hardware interfaces that will @@ -387,14 +389,6 @@ config BLK_DEV_RZ1000 Linux. This may slow disk throughput by a few percent, but at least things will operate 100% reliably. -config BLK_DEV_SL82C105 - tristate "Winbond SL82c105 support" - depends on PCI && (PPC || ARM) && BLK_DEV_IDEPCI - help - If you have a Winbond SL82c105 IDE controller, say Y here to enable - special configuration for this chip. This is common on various CHRP - motherboards, but could be used elsewhere. If in doubt, say Y. - config BLK_DEV_IDEDMA_PCI bool "Generic PCI bus-master DMA support" depends on PCI && BLK_DEV_IDEPCI @@ -592,6 +586,12 @@ config BLK_DEV_HPT366 ide-probe at boot. It is reported to support DVD II drives, by the manufacturer. +config BLK_DEV_JMICRON + tristate "JMicron JMB36x support" + help + Basic support for the JMicron ATA controllers. For full support + use the libata drivers. + config BLK_DEV_SC1200 tristate "National SCx200 chipset support" help @@ -606,15 +606,6 @@ config BLK_DEV_PIIX the kernel to change PIO, DMA and UDMA speeds and to configure the chip to optimum performance. -config BLK_DEV_IT8172 - bool "IT8172 IDE support" - depends on (MIPS_ITE8172 || MIPS_IVR) - help - Say Y here to support the on-board IDE controller on the Integrated - Technology Express, Inc. ITE8172 SBC. Vendor page at - <http://www.ite.com.tw/ia/brief_it8172bsp.htm>; picture of the - board at <http://www.mvista.com/partners/semiconductor/ite.html>. - config BLK_DEV_IT821X tristate "IT821X IDE support" help @@ -713,6 +704,14 @@ config BLK_DEV_SIS5513 Please read the comments at the top of <file:drivers/ide/pci/sis5513.c>. +config BLK_DEV_SL82C105 + tristate "Winbond SL82c105 support" + depends on (PPC || ARM) + help + If you have a Winbond SL82c105 IDE controller, say Y here to enable + special configuration for this chip. This is common on various CHRP + motherboards, but could be used elsewhere. If in doubt, say Y. + config BLK_DEV_SLC90E66 tristate "SLC90E66 chipset support" help @@ -1082,3 +1081,5 @@ config BLK_DEV_HD endif endmenu + +endif diff --git a/drivers/ide/h8300/ide-h8300.c b/drivers/ide/h8300/ide-h8300.c index 15955996a1f3..608ca871744b 100644 --- a/drivers/ide/h8300/ide-h8300.c +++ b/drivers/ide/h8300/ide-h8300.c @@ -1,5 +1,5 @@ /* - * drivers/ide/ide-h8300.c + * drivers/ide/h8300/ide-h8300.c * H8/300 generic IDE interface */ diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c index 654d4cd09847..5969cec58dc1 100644 --- a/drivers/ide/ide-cd.c +++ b/drivers/ide/ide-cd.c @@ -372,7 +372,7 @@ static int cdrom_log_sense(ide_drive_t *drive, struct request *rq, { int log = 0; - if (!sense || !rq || (rq->flags & REQ_QUIET)) + if (!sense || !rq || (rq->cmd_flags & REQ_QUIET)) return 0; switch (sense->sense_key) { @@ -597,7 +597,7 @@ static void cdrom_prepare_request(ide_drive_t *drive, struct request *rq) struct cdrom_info *cd = drive->driver_data; ide_init_drive_cmd(rq); - rq->flags = REQ_PC; + rq->cmd_type = REQ_TYPE_ATA_PC; rq->rq_disk = cd->disk; } @@ -617,7 +617,7 @@ static void cdrom_queue_request_sense(ide_drive_t *drive, void *sense, rq->cmd[0] = GPCMD_REQUEST_SENSE; rq->cmd[4] = rq->data_len = 18; - rq->flags = REQ_SENSE; + rq->cmd_type = REQ_TYPE_SENSE; /* NOTE! Save the failed command in "rq->buffer" */ rq->buffer = (void *) failed_command; @@ -630,10 +630,10 @@ static void cdrom_end_request (ide_drive_t *drive, int uptodate) struct request *rq = HWGROUP(drive)->rq; int nsectors = rq->hard_cur_sectors; - if ((rq->flags & REQ_SENSE) && uptodate) { + if (blk_sense_request(rq) && uptodate) { /* - * For REQ_SENSE, "rq->buffer" points to the original failed - * request + * For REQ_TYPE_SENSE, "rq->buffer" points to the original + * failed request */ struct request *failed = (struct request *) rq->buffer; struct cdrom_info *info = drive->driver_data; @@ -687,8 +687,15 @@ static void ide_dump_status_no_sense(ide_drive_t *drive, const char *msg, u8 sta static int cdrom_decode_status(ide_drive_t *drive, int good_stat, int *stat_ret) { struct request *rq = HWGROUP(drive)->rq; + ide_hwif_t *hwif = HWIF(drive); int stat, err, sense_key; + /* We may have bogus DMA interrupts in PIO state here */ + if (HWIF(drive)->dma_status && hwif->atapi_irq_bogon) { + stat = hwif->INB(hwif->dma_status); + /* Should we force the bit as well ? */ + hwif->OUTB(stat, hwif->dma_status); + } /* Check for errors. */ stat = HWIF(drive)->INB(IDE_STATUS_REG); if (stat_ret) @@ -706,17 +713,17 @@ static int cdrom_decode_status(ide_drive_t *drive, int good_stat, int *stat_ret) return 1; } - if (rq->flags & REQ_SENSE) { + if (blk_sense_request(rq)) { /* We got an error trying to get sense info from the drive (probably while trying to recover from a former error). Just give up. */ - rq->flags |= REQ_FAILED; + rq->cmd_flags |= REQ_FAILED; cdrom_end_request(drive, 0); ide_error(drive, "request sense failure", stat); return 1; - } else if (rq->flags & (REQ_PC | REQ_BLOCK_PC)) { + } else if (blk_pc_request(rq) || rq->cmd_type == REQ_TYPE_ATA_PC) { /* All other functions, except for READ. */ unsigned long flags; @@ -724,7 +731,7 @@ static int cdrom_decode_status(ide_drive_t *drive, int good_stat, int *stat_ret) * if we have an error, pass back CHECK_CONDITION as the * scsi status byte */ - if ((rq->flags & REQ_BLOCK_PC) && !rq->errors) + if (blk_pc_request(rq) && !rq->errors) rq->errors = SAM_STAT_CHECK_CONDITION; /* Check for tray open. */ @@ -735,12 +742,12 @@ static int cdrom_decode_status(ide_drive_t *drive, int good_stat, int *stat_ret) cdrom_saw_media_change (drive); /*printk("%s: media changed\n",drive->name);*/ return 0; - } else if (!(rq->flags & REQ_QUIET)) { + } else if (!(rq->cmd_flags & REQ_QUIET)) { /* Otherwise, print an error. */ ide_dump_status(drive, "packet command error", stat); } - rq->flags |= REQ_FAILED; + rq->cmd_flags |= REQ_FAILED; /* * instead of playing games with moving completions around, @@ -881,7 +888,7 @@ static int cdrom_timer_expiry(ide_drive_t *drive) wait = ATAPI_WAIT_PC; break; default: - if (!(rq->flags & REQ_QUIET)) + if (!(rq->cmd_flags & REQ_QUIET)) printk(KERN_INFO "ide-cd: cmd 0x%x timed out\n", rq->cmd[0]); wait = 0; break; @@ -1124,7 +1131,7 @@ static ide_startstop_t cdrom_read_intr (ide_drive_t *drive) if (rq->current_nr_sectors > 0) { printk (KERN_ERR "%s: cdrom_read_intr: data underrun (%d blocks)\n", drive->name, rq->current_nr_sectors); - rq->flags |= REQ_FAILED; + rq->cmd_flags |= REQ_FAILED; cdrom_end_request(drive, 0); } else cdrom_end_request(drive, 1); @@ -1456,7 +1463,7 @@ static ide_startstop_t cdrom_pc_intr (ide_drive_t *drive) printk ("%s: cdrom_pc_intr: data underrun %d\n", drive->name, pc->buflen); */ - rq->flags |= REQ_FAILED; + rq->cmd_flags |= REQ_FAILED; cdrom_end_request(drive, 0); } return ide_stopped; @@ -1509,7 +1516,7 @@ static ide_startstop_t cdrom_pc_intr (ide_drive_t *drive) rq->data += thislen; rq->data_len -= thislen; - if (rq->flags & REQ_SENSE) + if (blk_sense_request(rq)) rq->sense_len += thislen; } else { confused: @@ -1517,7 +1524,7 @@ confused: "appears confused (ireason = 0x%02x). " "Trying to recover by ending request.\n", drive->name, ireason); - rq->flags |= REQ_FAILED; + rq->cmd_flags |= REQ_FAILED; cdrom_end_request(drive, 0); return ide_stopped; } @@ -1546,7 +1553,7 @@ static ide_startstop_t cdrom_do_packet_command (ide_drive_t *drive) struct cdrom_info *info = drive->driver_data; info->dma = 0; - rq->flags &= ~REQ_FAILED; + rq->cmd_flags &= ~REQ_FAILED; len = rq->data_len; /* Start sending the command to the drive. */ @@ -1558,7 +1565,7 @@ static int cdrom_queue_packet_command(ide_drive_t *drive, struct request *rq) { struct request_sense sense; int retries = 10; - unsigned int flags = rq->flags; + unsigned int flags = rq->cmd_flags; if (rq->sense == NULL) rq->sense = &sense; @@ -1567,14 +1574,14 @@ static int cdrom_queue_packet_command(ide_drive_t *drive, struct request *rq) do { int error; unsigned long time = jiffies; - rq->flags = flags; + rq->cmd_flags = flags; error = ide_do_drive_cmd(drive, rq, ide_wait); time = jiffies - time; /* FIXME: we should probably abort/retry or something * in case of failure */ - if (rq->flags & REQ_FAILED) { + if (rq->cmd_flags & REQ_FAILED) { /* The request failed. Retry if it was due to a unit attention status (usually means media was changed). */ @@ -1596,10 +1603,10 @@ static int cdrom_queue_packet_command(ide_drive_t *drive, struct request *rq) } /* End of retry loop. */ - } while ((rq->flags & REQ_FAILED) && retries >= 0); + } while ((rq->cmd_flags & REQ_FAILED) && retries >= 0); /* Return an error if the command failed. */ - return (rq->flags & REQ_FAILED) ? -EIO : 0; + return (rq->cmd_flags & REQ_FAILED) ? -EIO : 0; } /* @@ -1963,7 +1970,7 @@ static ide_startstop_t cdrom_do_block_pc(ide_drive_t *drive, struct request *rq) { struct cdrom_info *info = drive->driver_data; - rq->flags |= REQ_QUIET; + rq->cmd_flags |= REQ_QUIET; info->dma = 0; @@ -2023,11 +2030,12 @@ ide_do_rw_cdrom (ide_drive_t *drive, struct request *rq, sector_t block) } info->last_block = block; return action; - } else if (rq->flags & (REQ_PC | REQ_SENSE)) { + } else if (rq->cmd_type == REQ_TYPE_SENSE || + rq->cmd_type == REQ_TYPE_ATA_PC) { return cdrom_do_packet_command(drive); - } else if (rq->flags & REQ_BLOCK_PC) { + } else if (blk_pc_request(rq)) { return cdrom_do_block_pc(drive, rq); - } else if (rq->flags & REQ_SPECIAL) { + } else if (blk_special_request(rq)) { /* * right now this can only be a reset... */ @@ -2105,7 +2113,7 @@ static int cdrom_check_status(ide_drive_t *drive, struct request_sense *sense) req.sense = sense; req.cmd[0] = GPCMD_TEST_UNIT_READY; - req.flags |= REQ_QUIET; + req.cmd_flags |= REQ_QUIET; #if ! STANDARD_ATAPI /* the Sanyo 3 CD changer uses byte 7 of TEST_UNIT_READY to @@ -2207,7 +2215,7 @@ static int cdrom_read_capacity(ide_drive_t *drive, unsigned long *capacity, req.cmd[0] = GPCMD_READ_CDVD_CAPACITY; req.data = (char *)&capbuf; req.data_len = sizeof(capbuf); - req.flags |= REQ_QUIET; + req.cmd_flags |= REQ_QUIET; stat = cdrom_queue_packet_command(drive, &req); if (stat == 0) { @@ -2230,7 +2238,7 @@ static int cdrom_read_tocentry(ide_drive_t *drive, int trackno, int msf_flag, req.sense = sense; req.data = buf; req.data_len = buflen; - req.flags |= REQ_QUIET; + req.cmd_flags |= REQ_QUIET; req.cmd[0] = GPCMD_READ_TOC_PMA_ATIP; req.cmd[6] = trackno; req.cmd[7] = (buflen >> 8); @@ -2531,7 +2539,7 @@ static int ide_cdrom_packet(struct cdrom_device_info *cdi, req.timeout = cgc->timeout; if (cgc->quiet) - req.flags |= REQ_QUIET; + req.cmd_flags |= REQ_QUIET; req.sense = cgc->sense; cgc->stat = cdrom_queue_packet_command(drive, &req); @@ -2629,7 +2637,8 @@ int ide_cdrom_reset (struct cdrom_device_info *cdi) int ret; cdrom_prepare_request(drive, &req); - req.flags = REQ_SPECIAL | REQ_QUIET; + req.cmd_type = REQ_TYPE_SPECIAL; + req.cmd_flags = REQ_QUIET; ret = ide_do_drive_cmd(drive, &req, ide_wait); /* @@ -3116,9 +3125,9 @@ static int ide_cdrom_prep_pc(struct request *rq) static int ide_cdrom_prep_fn(request_queue_t *q, struct request *rq) { - if (rq->flags & REQ_CMD) + if (blk_fs_request(rq)) return ide_cdrom_prep_fs(q, rq); - else if (rq->flags & REQ_BLOCK_PC) + else if (blk_pc_request(rq)) return ide_cdrom_prep_pc(rq); return 0; diff --git a/drivers/ide/ide-disk.c b/drivers/ide/ide-disk.c index 7cf3eb023521..0a05a377d66a 100644 --- a/drivers/ide/ide-disk.c +++ b/drivers/ide/ide-disk.c @@ -699,7 +699,8 @@ static void idedisk_prepare_flush(request_queue_t *q, struct request *rq) rq->cmd[0] = WIN_FLUSH_CACHE; - rq->flags |= REQ_DRIVE_TASK; + rq->cmd_type = REQ_TYPE_ATA_TASK; + rq->cmd_flags |= REQ_SOFTBARRIER; rq->buffer = rq->cmd; } @@ -740,7 +741,7 @@ static int set_multcount(ide_drive_t *drive, int arg) if (drive->special.b.set_multmode) return -EBUSY; ide_init_drive_cmd (&rq); - rq.flags = REQ_DRIVE_CMD; + rq.cmd_type = REQ_TYPE_ATA_CMD; drive->mult_req = arg; drive->special.b.set_multmode = 1; (void) ide_do_drive_cmd (drive, &rq, ide_wait); diff --git a/drivers/ide/ide-dma.c b/drivers/ide/ide-dma.c index 7c3a13e1cf64..56efed6742d4 100644 --- a/drivers/ide/ide-dma.c +++ b/drivers/ide/ide-dma.c @@ -145,14 +145,12 @@ int ide_in_drive_list(struct hd_driveid *id, const struct drive_list_entry *driv { for ( ; drive_table->id_model ; drive_table++) if ((!strcmp(drive_table->id_model, id->model)) && - ((strstr(drive_table->id_firmware, id->fw_rev)) || + ((strstr(id->fw_rev, drive_table->id_firmware)) || (!strcmp(drive_table->id_firmware, "ALL")))) return 1; return 0; } -EXPORT_SYMBOL_GPL(ide_in_drive_list); - /** * ide_dma_intr - IDE DMA interrupt handler * @drive: the drive the interrupt is for @@ -205,7 +203,7 @@ int ide_build_sglist(ide_drive_t *drive, struct request *rq) ide_hwif_t *hwif = HWIF(drive); struct scatterlist *sg = hwif->sg_table; - BUG_ON((rq->flags & REQ_DRIVE_TASKFILE) && rq->nr_sectors > 256); + BUG_ON((rq->cmd_type == REQ_TYPE_ATA_TASKFILE) && rq->nr_sectors > 256); ide_map_sg(drive, rq); @@ -798,26 +796,23 @@ static int ide_release_dma_engine(ide_hwif_t *hwif) static int ide_release_iomio_dma(ide_hwif_t *hwif) { - if ((hwif->dma_extra) && (hwif->channel == 0)) - release_region((hwif->dma_base + 16), hwif->dma_extra); release_region(hwif->dma_base, 8); - if (hwif->dma_base2) - release_region(hwif->dma_base, 8); + if (hwif->extra_ports) + release_region(hwif->extra_base, hwif->extra_ports); return 1; } /* * Needed for allowing full modular support of ide-driver */ -int ide_release_dma (ide_hwif_t *hwif) +int ide_release_dma(ide_hwif_t *hwif) { + ide_release_dma_engine(hwif); + if (hwif->mmio == 2) return 1; - if (hwif->chipset == ide_etrax100) - return 1; - - ide_release_dma_engine(hwif); - return ide_release_iomio_dma(hwif); + else + return ide_release_iomio_dma(hwif); } static int ide_allocate_dma_engine(ide_hwif_t *hwif) @@ -829,10 +824,9 @@ static int ide_allocate_dma_engine(ide_hwif_t *hwif) if (hwif->dmatable_cpu) return 0; - printk(KERN_ERR "%s: -- Error, unable to allocate%s DMA table(s).\n", - hwif->cds->name, !hwif->dmatable_cpu ? " CPU" : ""); + printk(KERN_ERR "%s: -- Error, unable to allocate DMA table.\n", + hwif->cds->name); - ide_release_dma_engine(hwif); return 1; } @@ -840,9 +834,7 @@ static int ide_mapped_mmio_dma(ide_hwif_t *hwif, unsigned long base, unsigned in { printk(KERN_INFO " %s: MMIO-DMA ", hwif->name); - hwif->dma_base = base; - if (hwif->cds->extra && hwif->channel == 0) - hwif->dma_extra = hwif->cds->extra; + hwif->dma_base = base; if(hwif->mate) hwif->dma_master = (hwif->channel) ? hwif->mate->dma_base : base; @@ -854,29 +846,33 @@ static int ide_mapped_mmio_dma(ide_hwif_t *hwif, unsigned long base, unsigned in static int ide_iomio_dma(ide_hwif_t *hwif, unsigned long base, unsigned int ports) { printk(KERN_INFO " %s: BM-DMA at 0x%04lx-0x%04lx", - hwif->name, base, base + ports - 1); + hwif->name, base, base + ports - 1); + if (!request_region(base, ports, hwif->name)) { printk(" -- Error, ports in use.\n"); return 1; } + hwif->dma_base = base; - if ((hwif->cds->extra) && (hwif->channel == 0)) { - request_region(base+16, hwif->cds->extra, hwif->cds->name); - hwif->dma_extra = hwif->cds->extra; + + if (hwif->cds->extra) { + hwif->extra_base = base + (hwif->channel ? 8 : 16); + + if (!hwif->mate || !hwif->mate->extra_ports) { + if (!request_region(hwif->extra_base, + hwif->cds->extra, hwif->cds->name)) { + printk(" -- Error, extra ports in use.\n"); + release_region(base, ports); + return 1; + } + hwif->extra_ports = hwif->cds->extra; + } } - + if(hwif->mate) - hwif->dma_master = (hwif->channel) ? hwif->mate->dma_base : base; + hwif->dma_master = (hwif->channel) ? hwif->mate->dma_base:base; else hwif->dma_master = base; - if (hwif->dma_base2) { - if (!request_region(hwif->dma_base2, ports, hwif->name)) - { - printk(" -- Error, secondary ports in use.\n"); - release_region(base, ports); - return 1; - } - } return 0; } diff --git a/drivers/ide/ide-floppy.c b/drivers/ide/ide-floppy.c index adbe9f76a505..e3a267622bb6 100644 --- a/drivers/ide/ide-floppy.c +++ b/drivers/ide/ide-floppy.c @@ -588,7 +588,7 @@ static int idefloppy_do_end_request(ide_drive_t *drive, int uptodate, int nsecs) /* Why does this happen? */ if (!rq) return 0; - if (!(rq->flags & REQ_SPECIAL)) { //if (!IDEFLOPPY_RQ_CMD (rq->cmd)) { + if (!blk_special_request(rq)) { /* our real local end request function */ ide_end_request(drive, uptodate, nsecs); return 0; @@ -689,7 +689,7 @@ static void idefloppy_queue_pc_head (ide_drive_t *drive,idefloppy_pc_t *pc,struc ide_init_drive_cmd(rq); rq->buffer = (char *) pc; - rq->flags = REQ_SPECIAL; //rq->cmd = IDEFLOPPY_PC_RQ; + rq->cmd_type = REQ_TYPE_SPECIAL; rq->rq_disk = floppy->disk; (void) ide_do_drive_cmd(drive, rq, ide_preempt); } @@ -1250,7 +1250,7 @@ static void idefloppy_create_rw_cmd (idefloppy_floppy_t *floppy, idefloppy_pc_t pc->callback = &idefloppy_rw_callback; pc->rq = rq; pc->b_count = cmd == READ ? 0 : rq->bio->bi_size; - if (rq->flags & REQ_RW) + if (rq->cmd_flags & REQ_RW) set_bit(PC_WRITING, &pc->flags); pc->buffer = NULL; pc->request_transfer = pc->buffer_size = blocks * floppy->block_size; @@ -1281,8 +1281,7 @@ static ide_startstop_t idefloppy_do_request (ide_drive_t *drive, struct request idefloppy_pc_t *pc; unsigned long block = (unsigned long)block_s; - debug_log(KERN_INFO "rq_status: %d, dev: %s, flags: %lx, errors: %d\n", - rq->rq_status, + debug_log(KERN_INFO "dev: %s, flags: %lx, errors: %d\n", rq->rq_disk ? rq->rq_disk->disk_name : "?", rq->flags, rq->errors); debug_log(KERN_INFO "sector: %ld, nr_sectors: %ld, " @@ -1303,7 +1302,7 @@ static ide_startstop_t idefloppy_do_request (ide_drive_t *drive, struct request idefloppy_do_end_request(drive, 0, 0); return ide_stopped; } - if (rq->flags & REQ_CMD) { + if (blk_fs_request(rq)) { if (((long)rq->sector % floppy->bs_factor) || (rq->nr_sectors % floppy->bs_factor)) { printk("%s: unsupported r/w request size\n", @@ -1313,9 +1312,9 @@ static ide_startstop_t idefloppy_do_request (ide_drive_t *drive, struct request } pc = idefloppy_next_pc_storage(drive); idefloppy_create_rw_cmd(floppy, pc, rq, block); - } else if (rq->flags & REQ_SPECIAL) { + } else if (blk_special_request(rq)) { pc = (idefloppy_pc_t *) rq->buffer; - } else if (rq->flags & REQ_BLOCK_PC) { + } else if (blk_pc_request(rq)) { pc = idefloppy_next_pc_storage(drive); if (idefloppy_blockpc_cmd(floppy, pc, rq)) { idefloppy_do_end_request(drive, 0, 0); @@ -1343,7 +1342,7 @@ static int idefloppy_queue_pc_tail (ide_drive_t *drive,idefloppy_pc_t *pc) ide_init_drive_cmd (&rq); rq.buffer = (char *) pc; - rq.flags = REQ_SPECIAL; // rq.cmd = IDEFLOPPY_PC_RQ; + rq.cmd_type = REQ_TYPE_SPECIAL; rq.rq_disk = floppy->disk; return ide_do_drive_cmd(drive, &rq, ide_wait); @@ -1636,7 +1635,7 @@ static int idefloppy_begin_format(ide_drive_t *drive, int __user *arg) /* ** Get ATAPI_FORMAT_UNIT progress indication. ** -** Userland gives a pointer to an int. The int is set to a progresss +** Userland gives a pointer to an int. The int is set to a progress ** indicator 0-65536, with 65536=100%. ** ** If the drive does not support format progress indication, we just check diff --git a/drivers/ide/ide-io.c b/drivers/ide/ide-io.c index fb6795236e76..2614f41b5074 100644 --- a/drivers/ide/ide-io.c +++ b/drivers/ide/ide-io.c @@ -59,8 +59,6 @@ static int __ide_end_request(ide_drive_t *drive, struct request *rq, { int ret = 1; - BUG_ON(!(rq->flags & REQ_STARTED)); - /* * if failfast is set on a request, override number of sectors and * complete the whole request right now @@ -82,7 +80,8 @@ static int __ide_end_request(ide_drive_t *drive, struct request *rq, if (!end_that_request_first(rq, uptodate, nr_sectors)) { add_disk_randomness(rq->rq_disk); - blkdev_dequeue_request(rq); + if (!list_empty(&rq->queuelist)) + blkdev_dequeue_request(rq); HWGROUP(drive)->rq = NULL; end_that_request_last(rq, uptodate); ret = 0; @@ -135,13 +134,14 @@ enum { ide_pm_flush_cache = ide_pm_state_start_suspend, idedisk_pm_standby, - idedisk_pm_idle = ide_pm_state_start_resume, + idedisk_pm_restore_pio = ide_pm_state_start_resume, + idedisk_pm_idle, ide_pm_restore_dma, }; static void ide_complete_power_step(ide_drive_t *drive, struct request *rq, u8 stat, u8 error) { - struct request_pm_state *pm = rq->end_io_data; + struct request_pm_state *pm = rq->data; if (drive->media != ide_disk) return; @@ -156,7 +156,10 @@ static void ide_complete_power_step(ide_drive_t *drive, struct request *rq, u8 s case idedisk_pm_standby: /* Suspend step 2 (standby) complete */ pm->pm_step = ide_pm_state_completed; break; - case idedisk_pm_idle: /* Resume step 1 (idle) complete */ + case idedisk_pm_restore_pio: /* Resume step 1 complete */ + pm->pm_step = idedisk_pm_idle; + break; + case idedisk_pm_idle: /* Resume step 2 (idle) complete */ pm->pm_step = ide_pm_restore_dma; break; } @@ -164,14 +167,17 @@ static void ide_complete_power_step(ide_drive_t *drive, struct request *rq, u8 s static ide_startstop_t ide_start_power_step(ide_drive_t *drive, struct request *rq) { - struct request_pm_state *pm = rq->end_io_data; + struct request_pm_state *pm = rq->data; ide_task_t *args = rq->special; memset(args, 0, sizeof(*args)); if (drive->media != ide_disk) { - /* skip idedisk_pm_idle for ATAPI devices */ - if (pm->pm_step == idedisk_pm_idle) + /* + * skip idedisk_pm_restore_pio and idedisk_pm_idle for ATAPI + * devices + */ + if (pm->pm_step == idedisk_pm_restore_pio) pm->pm_step = ide_pm_restore_dma; } @@ -198,13 +204,19 @@ static ide_startstop_t ide_start_power_step(ide_drive_t *drive, struct request * args->handler = &task_no_data_intr; return do_rw_taskfile(drive, args); - case idedisk_pm_idle: /* Resume step 1 (idle) */ + case idedisk_pm_restore_pio: /* Resume step 1 (restore PIO) */ + if (drive->hwif->tuneproc != NULL) + drive->hwif->tuneproc(drive, 255); + ide_complete_power_step(drive, rq, 0, 0); + return ide_stopped; + + case idedisk_pm_idle: /* Resume step 2 (idle) */ args->tfRegister[IDE_COMMAND_OFFSET] = WIN_IDLEIMMEDIATE; args->command_type = IDE_DRIVE_TASK_NO_DATA; args->handler = task_no_data_intr; return do_rw_taskfile(drive, args); - case ide_pm_restore_dma: /* Resume step 2 (restore DMA) */ + case ide_pm_restore_dma: /* Resume step 3 (restore DMA) */ /* * Right now, all we do is call hwif->ide_dma_check(drive), * we could be smarter and check for current xfer_speed @@ -244,7 +256,7 @@ int ide_end_dequeued_request(ide_drive_t *drive, struct request *rq, spin_lock_irqsave(&ide_lock, flags); - BUG_ON(!(rq->flags & REQ_STARTED)); + BUG_ON(!blk_rq_started(rq)); /* * if failfast is set on a request, override number of sectors and @@ -366,7 +378,7 @@ void ide_end_drive_cmd (ide_drive_t *drive, u8 stat, u8 err) rq = HWGROUP(drive)->rq; spin_unlock_irqrestore(&ide_lock, flags); - if (rq->flags & REQ_DRIVE_CMD) { + if (rq->cmd_type == REQ_TYPE_ATA_CMD) { u8 *args = (u8 *) rq->buffer; if (rq->errors == 0) rq->errors = !OK_STAT(stat,READY_STAT,BAD_STAT); @@ -376,7 +388,7 @@ void ide_end_drive_cmd (ide_drive_t *drive, u8 stat, u8 err) args[1] = err; args[2] = hwif->INB(IDE_NSECTOR_REG); } - } else if (rq->flags & REQ_DRIVE_TASK) { + } else if (rq->cmd_type == REQ_TYPE_ATA_TASK) { u8 *args = (u8 *) rq->buffer; if (rq->errors == 0) rq->errors = !OK_STAT(stat,READY_STAT,BAD_STAT); @@ -390,7 +402,7 @@ void ide_end_drive_cmd (ide_drive_t *drive, u8 stat, u8 err) args[5] = hwif->INB(IDE_HCYL_REG); args[6] = hwif->INB(IDE_SELECT_REG); } - } else if (rq->flags & REQ_DRIVE_TASKFILE) { + } else if (rq->cmd_type == REQ_TYPE_ATA_TASKFILE) { ide_task_t *args = (ide_task_t *) rq->special; if (rq->errors == 0) rq->errors = !OK_STAT(stat,READY_STAT,BAD_STAT); @@ -421,7 +433,7 @@ void ide_end_drive_cmd (ide_drive_t *drive, u8 stat, u8 err) } } } else if (blk_pm_request(rq)) { - struct request_pm_state *pm = rq->end_io_data; + struct request_pm_state *pm = rq->data; #ifdef DEBUG_PM printk("%s: complete_power_step(step: %d, stat: %x, err: %x)\n", drive->name, rq->pm->pm_step, stat, err); @@ -587,7 +599,7 @@ ide_startstop_t ide_error (ide_drive_t *drive, const char *msg, u8 stat) return ide_stopped; /* retry only "normal" I/O: */ - if (rq->flags & (REQ_DRIVE_CMD | REQ_DRIVE_TASK | REQ_DRIVE_TASKFILE)) { + if (!blk_fs_request(rq)) { rq->errors = 1; ide_end_drive_cmd(drive, stat, err); return ide_stopped; @@ -638,7 +650,7 @@ ide_startstop_t ide_abort(ide_drive_t *drive, const char *msg) return ide_stopped; /* retry only "normal" I/O: */ - if (rq->flags & (REQ_DRIVE_CMD | REQ_DRIVE_TASK | REQ_DRIVE_TASKFILE)) { + if (!blk_fs_request(rq)) { rq->errors = 1; ide_end_drive_cmd(drive, BUSY_STAT, 0); return ide_stopped; @@ -808,7 +820,7 @@ void ide_map_sg(ide_drive_t *drive, struct request *rq) if (hwif->sg_mapped) /* needed by ide-scsi */ return; - if ((rq->flags & REQ_DRIVE_TASKFILE) == 0) { + if (rq->cmd_type != REQ_TYPE_ATA_TASKFILE) { hwif->sg_nents = blk_rq_map_sg(drive->queue, rq, sg); } else { sg_init_one(sg, rq->buffer, rq->nr_sectors * SECTOR_SIZE); @@ -844,7 +856,7 @@ static ide_startstop_t execute_drive_cmd (ide_drive_t *drive, struct request *rq) { ide_hwif_t *hwif = HWIF(drive); - if (rq->flags & REQ_DRIVE_TASKFILE) { + if (rq->cmd_type == REQ_TYPE_ATA_TASKFILE) { ide_task_t *args = rq->special; if (!args) @@ -866,7 +878,7 @@ static ide_startstop_t execute_drive_cmd (ide_drive_t *drive, if (args->tf_out_flags.all != 0) return flagged_taskfile(drive, args); return do_rw_taskfile(drive, args); - } else if (rq->flags & REQ_DRIVE_TASK) { + } else if (rq->cmd_type == REQ_TYPE_ATA_TASK) { u8 *args = rq->buffer; u8 sel; @@ -892,7 +904,7 @@ static ide_startstop_t execute_drive_cmd (ide_drive_t *drive, hwif->OUTB(sel, IDE_SELECT_REG); ide_cmd(drive, args[0], args[2], &drive_cmd_intr); return ide_started; - } else if (rq->flags & REQ_DRIVE_CMD) { + } else if (rq->cmd_type == REQ_TYPE_ATA_CMD) { u8 *args = rq->buffer; if (!args) @@ -933,7 +945,7 @@ done: static void ide_check_pm_state(ide_drive_t *drive, struct request *rq) { - struct request_pm_state *pm = rq->end_io_data; + struct request_pm_state *pm = rq->data; if (blk_pm_suspend_request(rq) && pm->pm_step == ide_pm_state_start_suspend) @@ -980,7 +992,7 @@ static ide_startstop_t start_request (ide_drive_t *drive, struct request *rq) ide_startstop_t startstop; sector_t block; - BUG_ON(!(rq->flags & REQ_STARTED)); + BUG_ON(!blk_rq_started(rq)); #ifdef DEBUG printk("%s: start_request: current=0x%08lx\n", @@ -1013,12 +1025,12 @@ static ide_startstop_t start_request (ide_drive_t *drive, struct request *rq) if (!drive->special.all) { ide_driver_t *drv; - if (rq->flags & (REQ_DRIVE_CMD | REQ_DRIVE_TASK)) - return execute_drive_cmd(drive, rq); - else if (rq->flags & REQ_DRIVE_TASKFILE) + if (rq->cmd_type == REQ_TYPE_ATA_CMD || + rq->cmd_type == REQ_TYPE_ATA_TASK || + rq->cmd_type == REQ_TYPE_ATA_TASKFILE) return execute_drive_cmd(drive, rq); else if (blk_pm_request(rq)) { - struct request_pm_state *pm = rq->end_io_data; + struct request_pm_state *pm = rq->data; #ifdef DEBUG_PM printk("%s: start_power_step(step: %d)\n", drive->name, rq->pm->pm_step); @@ -1264,7 +1276,7 @@ static void ide_do_request (ide_hwgroup_t *hwgroup, int masked_irq) * We count how many times we loop here to make sure we service * all drives in the hwgroup without looping for ever */ - if (drive->blocked && !blk_pm_request(rq) && !(rq->flags & REQ_PREEMPT)) { + if (drive->blocked && !blk_pm_request(rq) && !(rq->cmd_flags & REQ_PREEMPT)) { drive = drive->next ? drive->next : hwgroup->drive; if (loops++ < 4 && !blk_queue_plugged(drive->queue)) goto again; @@ -1346,6 +1358,10 @@ static ide_startstop_t ide_dma_timeout_retry(ide_drive_t *drive, int error) * make sure request is sane */ rq = HWGROUP(drive)->rq; + + if (!rq) + goto out; + HWGROUP(drive)->rq = NULL; rq->errors = 0; @@ -1546,7 +1562,7 @@ static void unexpected_intr (int irq, ide_hwgroup_t *hwgroup) * on the hwgroup and the process begins again. */ -irqreturn_t ide_intr (int irq, void *dev_id, struct pt_regs *regs) +irqreturn_t ide_intr (int irq, void *dev_id) { unsigned long flags; ide_hwgroup_t *hwgroup = (ide_hwgroup_t *)dev_id; @@ -1670,7 +1686,7 @@ irqreturn_t ide_intr (int irq, void *dev_id, struct pt_regs *regs) void ide_init_drive_cmd (struct request *rq) { memset(rq, 0, sizeof(*rq)); - rq->flags = REQ_DRIVE_CMD; + rq->cmd_type = REQ_TYPE_ATA_CMD; rq->ref_count = 1; } @@ -1710,7 +1726,6 @@ int ide_do_drive_cmd (ide_drive_t *drive, struct request *rq, ide_action_t actio int must_wait = (action == ide_wait || action == ide_head_wait); rq->errors = 0; - rq->rq_status = RQ_ACTIVE; /* * we need to hold an extra reference to request for safe inspection @@ -1718,7 +1733,7 @@ int ide_do_drive_cmd (ide_drive_t *drive, struct request *rq, ide_action_t actio */ if (must_wait) { rq->ref_count++; - rq->waiting = &wait; + rq->end_io_data = &wait; rq->end_io = blk_end_sync_rq; } @@ -1727,7 +1742,7 @@ int ide_do_drive_cmd (ide_drive_t *drive, struct request *rq, ide_action_t actio hwgroup->rq = NULL; if (action == ide_preempt || action == ide_head_wait) { where = ELEVATOR_INSERT_FRONT; - rq->flags |= REQ_PREEMPT; + rq->cmd_flags |= REQ_PREEMPT; } __elv_add_request(drive->queue, rq, where, 0); ide_do_request(hwgroup, IDE_NO_IRQ); @@ -1736,7 +1751,6 @@ int ide_do_drive_cmd (ide_drive_t *drive, struct request *rq, ide_action_t actio err = 0; if (must_wait) { wait_for_completion(&wait); - rq->waiting = NULL; if (rq->errors) err = -EIO; diff --git a/drivers/ide/ide-iops.c b/drivers/ide/ide-iops.c index 77703acaec17..badde6331775 100644 --- a/drivers/ide/ide-iops.c +++ b/drivers/ide/ide-iops.c @@ -998,6 +998,7 @@ static ide_startstop_t atapi_reset_pollfunc (ide_drive_t *drive) } /* done polling */ hwgroup->polling = 0; + hwgroup->resetting = 0; return ide_stopped; } @@ -1057,6 +1058,7 @@ static ide_startstop_t reset_pollfunc (ide_drive_t *drive) } } hwgroup->polling = 0; /* done polling */ + hwgroup->resetting = 0; /* done reset attempt */ return ide_stopped; } @@ -1143,6 +1145,7 @@ static ide_startstop_t do_reset1 (ide_drive_t *drive, int do_not_try_atapi) /* For an ATAPI device, first try an ATAPI SRST. */ if (drive->media != ide_disk && !do_not_try_atapi) { + hwgroup->resetting = 1; pre_reset(drive); SELECT_DRIVE(drive); udelay (20); @@ -1168,6 +1171,7 @@ static ide_startstop_t do_reset1 (ide_drive_t *drive, int do_not_try_atapi) return ide_stopped; } + hwgroup->resetting = 1; /* * Note that we also set nIEN while resetting the device, * to mask unwanted interrupts from the interface during the reset. diff --git a/drivers/ide/ide-lib.c b/drivers/ide/ide-lib.c index 1feff23487d4..8237d89eec6e 100644 --- a/drivers/ide/ide-lib.c +++ b/drivers/ide/ide-lib.c @@ -71,75 +71,96 @@ EXPORT_SYMBOL(ide_xfer_verbose); /** * ide_dma_speed - compute DMA speed * @drive: drive - * @mode; intended mode + * @mode: modes available * * Checks the drive capabilities and returns the speed to use - * for the transfer. Returns -1 if the requested mode is unknown - * (eg PIO) + * for the DMA transfer. Returns 0 if the drive is incapable + * of DMA transfers. */ u8 ide_dma_speed(ide_drive_t *drive, u8 mode) { struct hd_driveid *id = drive->id; ide_hwif_t *hwif = HWIF(drive); + u8 ultra_mask, mwdma_mask, swdma_mask; u8 speed = 0; if (drive->media != ide_disk && hwif->atapi_dma == 0) return 0; - switch(mode) { - case 0x04: - if ((id->dma_ultra & 0x0040) && - (id->dma_ultra & hwif->ultra_mask)) - { speed = XFER_UDMA_6; break; } - case 0x03: - if ((id->dma_ultra & 0x0020) && - (id->dma_ultra & hwif->ultra_mask)) - { speed = XFER_UDMA_5; break; } - case 0x02: - if ((id->dma_ultra & 0x0010) && - (id->dma_ultra & hwif->ultra_mask)) - { speed = XFER_UDMA_4; break; } - if ((id->dma_ultra & 0x0008) && - (id->dma_ultra & hwif->ultra_mask)) - { speed = XFER_UDMA_3; break; } - case 0x01: - if ((id->dma_ultra & 0x0004) && - (id->dma_ultra & hwif->ultra_mask)) - { speed = XFER_UDMA_2; break; } - if ((id->dma_ultra & 0x0002) && - (id->dma_ultra & hwif->ultra_mask)) - { speed = XFER_UDMA_1; break; } - if ((id->dma_ultra & 0x0001) && - (id->dma_ultra & hwif->ultra_mask)) - { speed = XFER_UDMA_0; break; } - case 0x00: - if ((id->dma_mword & 0x0004) && - (id->dma_mword & hwif->mwdma_mask)) - { speed = XFER_MW_DMA_2; break; } - if ((id->dma_mword & 0x0002) && - (id->dma_mword & hwif->mwdma_mask)) - { speed = XFER_MW_DMA_1; break; } - if ((id->dma_mword & 0x0001) && - (id->dma_mword & hwif->mwdma_mask)) - { speed = XFER_MW_DMA_0; break; } - if ((id->dma_1word & 0x0004) && - (id->dma_1word & hwif->swdma_mask)) - { speed = XFER_SW_DMA_2; break; } - if ((id->dma_1word & 0x0002) && - (id->dma_1word & hwif->swdma_mask)) - { speed = XFER_SW_DMA_1; break; } - if ((id->dma_1word & 0x0001) && - (id->dma_1word & hwif->swdma_mask)) - { speed = XFER_SW_DMA_0; break; } - } + /* Capable of UltraDMA modes? */ + ultra_mask = id->dma_ultra & hwif->ultra_mask; + + if (!(id->field_valid & 4)) + mode = 0; /* fallback to MW/SW DMA if no UltraDMA */ + + switch (mode) { + case 4: + if (ultra_mask & 0x40) { + speed = XFER_UDMA_6; + break; + } + case 3: + if (ultra_mask & 0x20) { + speed = XFER_UDMA_5; + break; + } + case 2: + if (ultra_mask & 0x10) { + speed = XFER_UDMA_4; + break; + } + if (ultra_mask & 0x08) { + speed = XFER_UDMA_3; + break; + } + case 1: + if (ultra_mask & 0x04) { + speed = XFER_UDMA_2; + break; + } + if (ultra_mask & 0x02) { + speed = XFER_UDMA_1; + break; + } + if (ultra_mask & 0x01) { + speed = XFER_UDMA_0; + break; + } + case 0: + mwdma_mask = id->dma_mword & hwif->mwdma_mask; -// printk("%s: %s: mode 0x%02x, speed 0x%02x\n", -// __FUNCTION__, drive->name, mode, speed); + if (mwdma_mask & 0x04) { + speed = XFER_MW_DMA_2; + break; + } + if (mwdma_mask & 0x02) { + speed = XFER_MW_DMA_1; + break; + } + if (mwdma_mask & 0x01) { + speed = XFER_MW_DMA_0; + break; + } + + swdma_mask = id->dma_1word & hwif->swdma_mask; + + if (swdma_mask & 0x04) { + speed = XFER_SW_DMA_2; + break; + } + if (swdma_mask & 0x02) { + speed = XFER_SW_DMA_1; + break; + } + if (swdma_mask & 0x01) { + speed = XFER_SW_DMA_0; + break; + } + } return speed; } - EXPORT_SYMBOL(ide_dma_speed); @@ -456,13 +477,14 @@ static void ide_dump_opcode(ide_drive_t *drive) spin_unlock(&ide_lock); if (!rq) return; - if (rq->flags & (REQ_DRIVE_CMD | REQ_DRIVE_TASK)) { + if (rq->cmd_type == REQ_TYPE_ATA_CMD || + rq->cmd_type == REQ_TYPE_ATA_TASK) { char *args = rq->buffer; if (args) { opcode = args[0]; found = 1; } - } else if (rq->flags & REQ_DRIVE_TASKFILE) { + } else if (rq->cmd_type == REQ_TYPE_ATA_TASKFILE) { ide_task_t *args = rq->special; if (args) { task_struct_t *tf = (task_struct_t *) args->tfRegister; diff --git a/drivers/ide/ide-probe.c b/drivers/ide/ide-probe.c index 9cadf0106c6c..5a5c565a32a8 100644 --- a/drivers/ide/ide-probe.c +++ b/drivers/ide/ide-probe.c @@ -623,6 +623,8 @@ static void hwif_release_dev (struct device *dev) static void hwif_register (ide_hwif_t *hwif) { + int ret; + /* register with global device tree */ strlcpy(hwif->gendev.bus_id,hwif->name,BUS_ID_SIZE); hwif->gendev.driver_data = hwif; @@ -634,7 +636,10 @@ static void hwif_register (ide_hwif_t *hwif) hwif->gendev.parent = NULL; } hwif->gendev.release = hwif_release_dev; - device_register(&hwif->gendev); + ret = device_register(&hwif->gendev); + if (ret < 0) + printk(KERN_WARNING "IDE: %s: device_register error: %d\n", + __FUNCTION__, ret); } static int wait_hwif_ready(ide_hwif_t *hwif) @@ -884,13 +889,19 @@ int probe_hwif_init_with_fixup(ide_hwif_t *hwif, void (*fixup)(ide_hwif_t *hwif) if (hwif->present) { u16 unit = 0; + int ret; + for (unit = 0; unit < MAX_DRIVES; ++unit) { ide_drive_t *drive = &hwif->drives[unit]; /* For now don't attach absent drives, we may want them on default or a new "empty" class for hotplug reprobing ? */ if (drive->present) { - device_register(&drive->gendev); + ret = device_register(&drive->gendev); + if (ret < 0) + printk(KERN_WARNING "IDE: %s: " + "device_register error: %d\n", + __FUNCTION__, ret); } } } @@ -989,10 +1000,6 @@ static int ide_init_queue(ide_drive_t *drive) /* needs drive->queue to be set */ ide_toggle_bounce(drive, 1); - /* enable led activity for disk drives only */ - if (drive->media == ide_disk && hwif->led_act) - blk_queue_activity_fn(q, hwif->led_act, drive); - return 0; } @@ -1409,8 +1416,14 @@ int ideprobe_init (void) if (hwif->chipset == ide_unknown || hwif->chipset == ide_forced) hwif->chipset = ide_generic; for (unit = 0; unit < MAX_DRIVES; ++unit) - if (hwif->drives[unit].present) - device_register(&hwif->drives[unit].gendev); + if (hwif->drives[unit].present) { + int ret = device_register( + &hwif->drives[unit].gendev); + if (ret < 0) + printk(KERN_WARNING "IDE: %s: " + "device_register error: %d\n", + __FUNCTION__, ret); + } } } return 0; diff --git a/drivers/ide/ide-proc.c b/drivers/ide/ide-proc.c index 41b74b13a00c..aa049dab3d95 100644 --- a/drivers/ide/ide-proc.c +++ b/drivers/ide/ide-proc.c @@ -326,15 +326,24 @@ static int ide_replace_subdriver(ide_drive_t *drive, const char *driver) { struct device *dev = &drive->gendev; int ret = 1; + int err; down_write(&dev->bus->subsys.rwsem); device_release_driver(dev); /* FIXME: device can still be in use by previous driver */ strlcpy(drive->driver_req, driver, sizeof(drive->driver_req)); - device_attach(dev); + err = device_attach(dev); + if (err < 0) + printk(KERN_WARNING "IDE: %s: device_attach error: %d\n", + __FUNCTION__, err); drive->driver_req[0] = 0; - if (dev->driver == NULL) - device_attach(dev); + if (dev->driver == NULL) { + err = device_attach(dev); + if (err < 0) + printk(KERN_WARNING + "IDE: %s: device_attach(2) error: %d\n", + __FUNCTION__, err); + } if (dev->driver && !strcmp(dev->driver->name, driver)) ret = 0; up_write(&dev->bus->subsys.rwsem); @@ -526,7 +535,12 @@ static int proc_print_driver(struct device_driver *drv, void *data) static int ide_drivers_show(struct seq_file *s, void *p) { - bus_for_each_drv(&ide_bus_type, NULL, s, proc_print_driver); + int err; + + err = bus_for_each_drv(&ide_bus_type, NULL, s, proc_print_driver); + if (err < 0) + printk(KERN_WARNING "IDE: %s: bus_for_each_drv error: %d\n", + __FUNCTION__, err); return 0; } diff --git a/drivers/ide/ide-tape.c b/drivers/ide/ide-tape.c index 7067ab997927..e2f4bb549063 100644 --- a/drivers/ide/ide-tape.c +++ b/drivers/ide/ide-tape.c @@ -1776,7 +1776,7 @@ static void idetape_create_request_sense_cmd (idetape_pc_t *pc) static void idetape_init_rq(struct request *rq, u8 cmd) { memset(rq, 0, sizeof(*rq)); - rq->flags = REQ_SPECIAL; + rq->cmd_type = REQ_TYPE_SPECIAL; rq->cmd[0] = cmd; } @@ -2423,8 +2423,8 @@ static ide_startstop_t idetape_do_request(ide_drive_t *drive, #if IDETAPE_DEBUG_LOG #if 0 if (tape->debug_level >= 5) - printk(KERN_INFO "ide-tape: rq_status: %d, " - "dev: %s, cmd: %ld, errors: %d\n", rq->rq_status, + printk(KERN_INFO "ide-tape: %d, " + "dev: %s, cmd: %ld, errors: %d\n", rq->rq_disk->disk_name, rq->cmd[0], rq->errors); #endif if (tape->debug_level >= 2) @@ -2433,12 +2433,12 @@ static ide_startstop_t idetape_do_request(ide_drive_t *drive, rq->sector, rq->nr_sectors, rq->current_nr_sectors); #endif /* IDETAPE_DEBUG_LOG */ - if ((rq->flags & REQ_SPECIAL) == 0) { + if (!blk_special_request(rq)) { /* * We do not support buffer cache originated requests. */ printk(KERN_NOTICE "ide-tape: %s: Unsupported request in " - "request queue (%ld)\n", drive->name, rq->flags); + "request queue (%d)\n", drive->name, rq->cmd_type); ide_end_request(drive, 0, 0); return ide_stopped; } @@ -2764,16 +2764,16 @@ static void idetape_add_stage_tail (ide_drive_t *drive,idetape_stage_t *stage) */ static void idetape_wait_for_request (ide_drive_t *drive, struct request *rq) { - DECLARE_COMPLETION(wait); + DECLARE_COMPLETION_ONSTACK(wait); idetape_tape_t *tape = drive->driver_data; #if IDETAPE_DEBUG_BUGS - if (rq == NULL || (rq->flags & REQ_SPECIAL) == 0) { + if (rq == NULL || !blk_special_request(rq)) { printk (KERN_ERR "ide-tape: bug: Trying to sleep on non-valid request\n"); return; } #endif /* IDETAPE_DEBUG_BUGS */ - rq->waiting = &wait; + rq->end_io_data = &wait; rq->end_io = blk_end_sync_rq; spin_unlock_irq(&tape->spinlock); wait_for_completion(&wait); diff --git a/drivers/ide/ide-taskfile.c b/drivers/ide/ide-taskfile.c index 97a9244312fc..30175c7688e8 100644 --- a/drivers/ide/ide-taskfile.c +++ b/drivers/ide/ide-taskfile.c @@ -363,7 +363,7 @@ static ide_startstop_t task_error(ide_drive_t *drive, struct request *rq, static void task_end_request(ide_drive_t *drive, struct request *rq, u8 stat) { - if (rq->flags & REQ_DRIVE_TASKFILE) { + if (rq->cmd_type == REQ_TYPE_ATA_TASKFILE) { ide_task_t *task = rq->special; if (task->tf_out_flags.all) { @@ -474,7 +474,7 @@ static int ide_diag_taskfile(ide_drive_t *drive, ide_task_t *args, unsigned long struct request rq; memset(&rq, 0, sizeof(rq)); - rq.flags = REQ_DRIVE_TASKFILE; + rq.cmd_type = REQ_TYPE_ATA_TASKFILE; rq.buffer = buf; /* @@ -499,7 +499,7 @@ static int ide_diag_taskfile(ide_drive_t *drive, ide_task_t *args, unsigned long rq.hard_cur_sectors = rq.current_nr_sectors = rq.nr_sectors; if (args->command_type == IDE_DRIVE_TASK_RAW_WRITE) - rq.flags |= REQ_RW; + rq.cmd_flags |= REQ_RW; } rq.special = args; @@ -524,8 +524,8 @@ int ide_taskfile_ioctl (ide_drive_t *drive, unsigned int cmd, unsigned long arg) task_ioreg_t *hobsptr = args.hobRegister; int err = 0; int tasksize = sizeof(struct ide_task_request_s); - int taskin = 0; - int taskout = 0; + unsigned int taskin = 0; + unsigned int taskout = 0; u8 io_32bit = drive->io_32bit; char __user *buf = (char __user *)arg; @@ -538,8 +538,13 @@ int ide_taskfile_ioctl (ide_drive_t *drive, unsigned int cmd, unsigned long arg) return -EFAULT; } - taskout = (int) req_task->out_size; - taskin = (int) req_task->in_size; + taskout = req_task->out_size; + taskin = req_task->in_size; + + if (taskin > 65536 || taskout > 65536) { + err = -EINVAL; + goto abort; + } if (taskout) { int outtotal = tasksize; @@ -737,7 +742,7 @@ static int ide_wait_cmd_task(ide_drive_t *drive, u8 *buf) struct request rq; ide_init_drive_cmd(&rq); - rq.flags = REQ_DRIVE_TASK; + rq.cmd_type = REQ_TYPE_ATA_TASK; rq.buffer = buf; return ide_do_drive_cmd(drive, &rq, ide_wait); } diff --git a/drivers/ide/ide.c b/drivers/ide/ide.c index 9c8468de1a75..16890769dca6 100644 --- a/drivers/ide/ide.c +++ b/drivers/ide/ide.c @@ -450,7 +450,7 @@ void ide_hwif_release_regions(ide_hwif_t *hwif) * @hwif: hwif to update * @tmp_hwif: template * - * Restore hwif to a previous state by copying most settngs + * Restore hwif to a previous state by copying most settings * from the template. */ @@ -539,9 +539,10 @@ static void ide_hwif_restore(ide_hwif_t *hwif, ide_hwif_t *tmp_hwif) hwif->dma_vendor3 = tmp_hwif->dma_vendor3; hwif->dma_prdtable = tmp_hwif->dma_prdtable; - hwif->dma_extra = tmp_hwif->dma_extra; hwif->config_data = tmp_hwif->config_data; hwif->select_data = tmp_hwif->select_data; + hwif->extra_base = tmp_hwif->extra_base; + hwif->extra_ports = tmp_hwif->extra_ports; hwif->autodma = tmp_hwif->autodma; hwif->udma_four = tmp_hwif->udma_four; hwif->no_dsc = tmp_hwif->no_dsc; @@ -550,7 +551,7 @@ static void ide_hwif_restore(ide_hwif_t *hwif, ide_hwif_t *tmp_hwif) } /** - * ide_unregister - free an ide interface + * ide_unregister - free an IDE interface * @index: index of interface (will change soon to a pointer) * * Perform the final unregister of an IDE interface. At the moment @@ -563,8 +564,8 @@ static void ide_hwif_restore(ide_hwif_t *hwif, ide_hwif_t *tmp_hwif) * deadlocking the IDE layer. The shutdown callback is called * before we take the lock and free resources. It is up to the * caller to be sure there is no pending I/O here, and that - * the interfce will not be reopened (present/vanishing locking - * isnt yet done btw). After we commit to the final kill we + * the interface will not be reopened (present/vanishing locking + * isn't yet done BTW). After we commit to the final kill we * call the cleanup callback with the ide locks held. * * Unregister restores the hwif structures to the default state. @@ -674,6 +675,9 @@ void ide_unregister(unsigned int index) hwif->dma_status = 0; hwif->dma_vendor3 = 0; hwif->dma_prdtable = 0; + + hwif->extra_base = 0; + hwif->extra_ports = 0; } /* copy original settings */ @@ -969,8 +973,8 @@ ide_settings_t *ide_find_setting_by_name (ide_drive_t *drive, char *name) * @drive: drive * * Automatically remove all the driver specific settings for this - * drive. This function may sleep and must not be called from IRQ - * context. The caller must hold ide_setting_sem. + * drive. This function may not be called from IRQ context. The + * caller must hold ide_setting_sem. */ static void auto_remove_settings (ide_drive_t *drive) @@ -1217,9 +1221,9 @@ static int generic_ide_suspend(struct device *dev, pm_message_t mesg) memset(&rq, 0, sizeof(rq)); memset(&rqpm, 0, sizeof(rqpm)); memset(&args, 0, sizeof(args)); - rq.flags = REQ_PM_SUSPEND; + rq.cmd_type = REQ_TYPE_PM_SUSPEND; rq.special = &args; - rq.end_io_data = &rqpm; + rq.data = &rqpm; rqpm.pm_step = ide_pm_state_start_suspend; if (mesg.event == PM_EVENT_PRETHAW) mesg.event = PM_EVENT_FREEZE; @@ -1238,9 +1242,9 @@ static int generic_ide_resume(struct device *dev) memset(&rq, 0, sizeof(rq)); memset(&rqpm, 0, sizeof(rqpm)); memset(&args, 0, sizeof(args)); - rq.flags = REQ_PM_RESUME; + rq.cmd_type = REQ_TYPE_PM_RESUME; rq.special = &args; - rq.end_io_data = &rqpm; + rq.data = &rqpm; rqpm.pm_step = ide_pm_state_start_resume; rqpm.pm_state = PM_EVENT_ON; @@ -1360,6 +1364,11 @@ int generic_ide_ioctl(ide_drive_t *drive, struct file *file, struct block_device spin_lock_irqsave(&ide_lock, flags); + if (HWGROUP(drive)->resetting) { + spin_unlock_irqrestore(&ide_lock, flags); + return -EBUSY; + } + ide_abort(drive, "drive reset"); BUG_ON(HWGROUP(drive)->handler); @@ -1865,11 +1874,22 @@ void ide_unregister_subdriver(ide_drive_t *drive, ide_driver_t *driver) { unsigned long flags; - down(&ide_setting_sem); - spin_lock_irqsave(&ide_lock, flags); #ifdef CONFIG_PROC_FS ide_remove_proc_entries(drive->proc, driver->proc); #endif + down(&ide_setting_sem); + spin_lock_irqsave(&ide_lock, flags); + /* + * ide_setting_sem protects the settings list + * ide_lock protects the use of settings + * + * so we need to hold both, ide_settings_sem because we want to + * modify the settings list, and ide_lock because we cannot take + * a setting out that is being used. + * + * OTOH both ide_{read,write}_setting are only ever used under + * ide_setting_sem. + */ auto_remove_settings(drive); spin_unlock_irqrestore(&ide_lock, flags); up(&ide_setting_sem); @@ -1993,10 +2013,16 @@ EXPORT_SYMBOL_GPL(ide_bus_type); */ static int __init ide_init(void) { + int ret; + printk(KERN_INFO "Uniform Multi-Platform E-IDE driver " REVISION "\n"); system_bus_speed = ide_system_bus_speed(); - bus_register(&ide_bus_type); + ret = bus_register(&ide_bus_type); + if (ret < 0) { + printk(KERN_WARNING "IDE: bus_register error: %d\n", ret); + return ret; + } init_ide_data(); diff --git a/drivers/ide/legacy/hd.c b/drivers/ide/legacy/hd.c index aebecd8f51cc..45ed03591cd8 100644 --- a/drivers/ide/legacy/hd.c +++ b/drivers/ide/legacy/hd.c @@ -459,7 +459,7 @@ ok_to_read: #ifdef DEBUG printk("%s: read: sector %ld, remaining = %ld, buffer=%p\n", req->rq_disk->disk_name, req->sector, req->nr_sectors, - req->buffer+512)); + req->buffer+512); #endif if (req->current_nr_sectors <= 0) end_request(req, 1); @@ -626,7 +626,7 @@ repeat: req->rq_disk->disk_name, (req->cmd == READ)?"read":"writ", cyl, head, sec, nsect, req->buffer); #endif - if (req->flags & REQ_CMD) { + if (blk_fs_request(req)) { switch (rq_data_dir(req)) { case READ: hd_out(disk,nsect,sec,head,cyl,WIN_READ,&read_intr); @@ -673,7 +673,7 @@ static int hd_getgeo(struct block_device *bdev, struct hd_geometry *geo) * be forgotten about... */ -static irqreturn_t hd_interrupt(int irq, void *dev_id, struct pt_regs *regs) +static irqreturn_t hd_interrupt(int irq, void *dev_id) { void (*handler)(void) = do_hd; diff --git a/drivers/ide/legacy/ide-cs.c b/drivers/ide/legacy/ide-cs.c index 602797a44208..7efd28ac21ed 100644 --- a/drivers/ide/legacy/ide-cs.c +++ b/drivers/ide/legacy/ide-cs.c @@ -120,7 +120,7 @@ static int ide_probe(struct pcmcia_device *link) link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO; link->io.Attributes2 = IO_DATA_PATH_WIDTH_8; link->io.IOAddrLines = 3; - link->irq.Attributes = IRQ_TYPE_EXCLUSIVE; + link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING; link->irq.IRQInfo1 = IRQ_LEVEL_ID; link->conf.Attributes = CONF_ENABLE_IRQ; link->conf.IntType = INT_MEMORY_AND_IO; @@ -192,20 +192,10 @@ static int ide_config(struct pcmcia_device *link) tuple.TupleOffset = 0; tuple.TupleDataMax = 255; tuple.Attributes = 0; - tuple.DesiredTuple = CISTPL_CONFIG; - CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); - CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple)); - CS_CHECK(ParseTuple, pcmcia_parse_tuple(link, &tuple, &stk->parse)); - link->conf.ConfigBase = stk->parse.config.base; - link->conf.Present = stk->parse.config.rmask[0]; - - tuple.DesiredTuple = CISTPL_MANFID; - if (!pcmcia_get_first_tuple(link, &tuple) && - !pcmcia_get_tuple_data(link, &tuple) && - !pcmcia_parse_tuple(link, &tuple, &stk->parse)) - is_kme = ((stk->parse.manfid.manf == MANFID_KME) && - ((stk->parse.manfid.card == PRODID_KME_KXLC005_A) || - (stk->parse.manfid.card == PRODID_KME_KXLC005_B))); + + is_kme = ((link->manf_id == MANFID_KME) && + ((link->card_id == PRODID_KME_KXLC005_A) || + (link->card_id == PRODID_KME_KXLC005_B))); /* Not sure if this is right... look up the current Vcc */ CS_CHECK(GetConfigurationInfo, pcmcia_get_configuration_info(link, &stk->conf)); @@ -398,13 +388,20 @@ static struct pcmcia_device_id ide_ids[] = { PCMCIA_DEVICE_PROD_ID12("IO DATA", "PCIDE", 0x547e66dc, 0x5c5ab149), PCMCIA_DEVICE_PROD_ID12("IO DATA", "PCIDEII", 0x547e66dc, 0xb3662674), PCMCIA_DEVICE_PROD_ID12("LOOKMEET", "CBIDE2 ", 0xe37be2b5, 0x8671043b), + PCMCIA_DEVICE_PROD_ID12("M-Systems", "CF500", 0x7ed2ad87, 0x7a13045c), PCMCIA_DEVICE_PROD_ID2("NinjaATA-", 0xebe0bd79), PCMCIA_DEVICE_PROD_ID12("PCMCIA", "CD-ROM", 0x281f1c5d, 0x66536591), PCMCIA_DEVICE_PROD_ID12("PCMCIA", "PnPIDE", 0x281f1c5d, 0x0c694728), PCMCIA_DEVICE_PROD_ID12("SHUTTLE TECHNOLOGY LTD.", "PCCARD-IDE/ATAPI Adapter", 0x4a3f0ba0, 0x322560e1), + PCMCIA_DEVICE_PROD_ID12("SEAGATE", "ST1", 0x87c1b330, 0xe1f30883), + PCMCIA_DEVICE_PROD_ID12("SAMSUNG", "04/05/06", 0x43d74cb4, 0x6a22777d), + PCMCIA_DEVICE_PROD_ID12("SMI VENDOR", "SMI PRODUCT", 0x30896c92, 0x703cc5f6), PCMCIA_DEVICE_PROD_ID12("TOSHIBA", "MK2001MPL", 0xb4585a1a, 0x3489e003), PCMCIA_DEVICE_PROD_ID1("TRANSCEND 512M ", 0xd0909443), + PCMCIA_DEVICE_PROD_ID12("TRANSCEND", "TS1GCF80", 0x709b1bf1, 0x2a54d4b1), + PCMCIA_DEVICE_PROD_ID12("TRANSCEND", "TS4GCF120", 0x709b1bf1, 0xf54a91c8), PCMCIA_DEVICE_PROD_ID12("WIT", "IDE16", 0x244e5994, 0x3e232852), + PCMCIA_DEVICE_PROD_ID12("WEIDA", "TWTTI", 0xcc7cf69c, 0x212bb918), PCMCIA_DEVICE_PROD_ID1("STI Flash", 0xe4a13209), PCMCIA_DEVICE_PROD_ID12("STI", "Flash 5.0", 0xbf2df18d, 0x8cb57a0e), PCMCIA_MFC_DEVICE_PROD_ID12(1, "SanDisk", "ConnectPlus", 0x7a954bd9, 0x74be00c6), diff --git a/drivers/ide/legacy/macide.c b/drivers/ide/legacy/macide.c index d655da749144..b1730d7e414c 100644 --- a/drivers/ide/legacy/macide.c +++ b/drivers/ide/legacy/macide.c @@ -78,7 +78,7 @@ int macide_ack_intr(ide_hwif_t* hwif) } #ifdef CONFIG_BLK_DEV_MAC_MEDIABAY -static void macide_mediabay_interrupt(int irq, void *dev_id, struct pt_regs *regs) +static void macide_mediabay_interrupt(int irq, void *dev_id) { int state = baboon->mb_status & 0x04; diff --git a/drivers/ide/mips/swarm.c b/drivers/ide/mips/swarm.c index 66f6064f4640..09c9e7936b0d 100644 --- a/drivers/ide/mips/swarm.c +++ b/drivers/ide/mips/swarm.c @@ -4,6 +4,7 @@ * Author: Manish Lachwani, mlachwani@mvista.com * Copyright (C) 2004 MIPS Technologies, Inc. All rights reserved. * Author: Maciej W. Rozycki <macro@mips.com> + * Copyright (c) 2006 Maciej W. Rozycki * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -127,6 +128,7 @@ static int __devinit swarm_ide_probe(struct device *dev) memcpy(hwif->io_ports, hwif->hw.io_ports, sizeof(hwif->io_ports)); hwif->irq = hwif->hw.irq; + probe_hwif_init(hwif); dev_set_drvdata(dev, hwif); return 0; diff --git a/drivers/ide/pci/Makefile b/drivers/ide/pci/Makefile index f35d684edc25..fef08960aa4c 100644 --- a/drivers/ide/pci/Makefile +++ b/drivers/ide/pci/Makefile @@ -12,8 +12,8 @@ obj-$(CONFIG_BLK_DEV_CY82C693) += cy82c693.o obj-$(CONFIG_BLK_DEV_HPT34X) += hpt34x.o obj-$(CONFIG_BLK_DEV_HPT366) += hpt366.o #obj-$(CONFIG_BLK_DEV_HPT37X) += hpt37x.o -obj-$(CONFIG_BLK_DEV_IT8172) += it8172.o obj-$(CONFIG_BLK_DEV_IT821X) += it821x.o +obj-$(CONFIG_BLK_DEV_JMICRON) += jmicron.o obj-$(CONFIG_BLK_DEV_NS87415) += ns87415.o obj-$(CONFIG_BLK_DEV_OPTI621) += opti621.o obj-$(CONFIG_BLK_DEV_PDC202XX_OLD) += pdc202xx_old.o diff --git a/drivers/ide/pci/alim15x3.c b/drivers/ide/pci/alim15x3.c index d419e4bb54f4..89109be5162c 100644 --- a/drivers/ide/pci/alim15x3.c +++ b/drivers/ide/pci/alim15x3.c @@ -586,11 +586,11 @@ static unsigned int __devinit init_chipset_ali15x3 (struct pci_dev *dev, const c { unsigned long flags; u8 tmpbyte; - struct pci_dev *north = pci_find_slot(0, PCI_DEVFN(0,0)); + struct pci_dev *north = pci_get_slot(dev->bus, PCI_DEVFN(0,0)); pci_read_config_byte(dev, PCI_REVISION_ID, &m5229_revision); - isa_dev = pci_find_device(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M1533, NULL); + isa_dev = pci_get_device(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M1533, NULL); #if defined(DISPLAY_ALI_TIMINGS) && defined(CONFIG_PROC_FS) if (!ali_proc) { @@ -613,8 +613,7 @@ static unsigned int __devinit init_chipset_ali15x3 (struct pci_dev *dev, const c * clear bit 7 */ pci_write_config_byte(dev, 0x4b, tmpbyte & 0x7F); - local_irq_restore(flags); - return 0; + goto out; } /* @@ -637,10 +636,8 @@ static unsigned int __devinit init_chipset_ali15x3 (struct pci_dev *dev, const c * box without a device at 0:0.0. The ALi bridge will be at * 0:0.0 so if we didn't find one we know what is cooking. */ - if (north && north->vendor != PCI_VENDOR_ID_AL) { - local_irq_restore(flags); - return 0; - } + if (north && north->vendor != PCI_VENDOR_ID_AL) + goto out; if (m5229_revision < 0xC5 && isa_dev) { @@ -661,6 +658,9 @@ static unsigned int __devinit init_chipset_ali15x3 (struct pci_dev *dev, const c pci_write_config_byte(isa_dev, 0x79, tmpbyte | 0x02); } } +out: + pci_dev_put(north); + pci_dev_put(isa_dev); local_irq_restore(flags); return 0; } diff --git a/drivers/ide/pci/amd74xx.c b/drivers/ide/pci/amd74xx.c index 2b0ea8b6608d..753fe0e21456 100644 --- a/drivers/ide/pci/amd74xx.c +++ b/drivers/ide/pci/amd74xx.c @@ -75,6 +75,7 @@ static struct amd_ide_chip { { PCI_DEVICE_ID_NVIDIA_NFORCE_MCP55_IDE, 0x50, AMD_UDMA_133 }, { PCI_DEVICE_ID_NVIDIA_NFORCE_MCP61_IDE, 0x50, AMD_UDMA_133 }, { PCI_DEVICE_ID_NVIDIA_NFORCE_MCP65_IDE, 0x50, AMD_UDMA_133 }, + { PCI_DEVICE_ID_NVIDIA_NFORCE_MCP67_IDE, 0x50, AMD_UDMA_133 }, { PCI_DEVICE_ID_AMD_CS5536_IDE, 0x40, AMD_UDMA_100 }, { 0 } }; @@ -491,7 +492,8 @@ static ide_pci_device_t amd74xx_chipsets[] __devinitdata = { /* 16 */ DECLARE_NV_DEV("NFORCE-MCP55"), /* 17 */ DECLARE_NV_DEV("NFORCE-MCP61"), /* 18 */ DECLARE_NV_DEV("NFORCE-MCP65"), - /* 19 */ DECLARE_AMD_DEV("AMD5536"), + /* 19 */ DECLARE_NV_DEV("NFORCE-MCP67"), + /* 20 */ DECLARE_AMD_DEV("AMD5536"), }; static int __devinit amd74xx_probe(struct pci_dev *dev, const struct pci_device_id *id) @@ -530,7 +532,8 @@ static struct pci_device_id amd74xx_pci_tbl[] = { { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP55_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 16 }, { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP61_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 17 }, { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP65_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 18 }, - { PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_CS5536_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 19 }, + { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP67_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 19 }, + { PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_CS5536_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 20 }, { 0, }, }; MODULE_DEVICE_TABLE(pci, amd74xx_pci_tbl); diff --git a/drivers/ide/pci/atiixp.c b/drivers/ide/pci/atiixp.c index a574de5f0835..d55b938b1aeb 100644 --- a/drivers/ide/pci/atiixp.c +++ b/drivers/ide/pci/atiixp.c @@ -318,6 +318,20 @@ static void __devinit init_hwif_atiixp(ide_hwif_t *hwif) hwif->drives[0].autodma = hwif->autodma; } +static void __devinit init_hwif_sb600_legacy(ide_hwif_t *hwif) +{ + + hwif->atapi_dma = 1; + hwif->ultra_mask = 0x7f; + hwif->mwdma_mask = 0x07; + hwif->swdma_mask = 0x07; + + if (!noautodma) + hwif->autodma = 1; + hwif->drives[0].autodma = hwif->autodma; + hwif->drives[1].autodma = hwif->autodma; +} + static ide_pci_device_t atiixp_pci_info[] __devinitdata = { { /* 0 */ .name = "ATIIXP", @@ -326,6 +340,12 @@ static ide_pci_device_t atiixp_pci_info[] __devinitdata = { .autodma = AUTODMA, .enablebits = {{0x48,0x01,0x00}, {0x48,0x08,0x00}}, .bootable = ON_BOARD, + },{ /* 1 */ + .name = "ATI SB600 SATA Legacy IDE", + .init_hwif = init_hwif_sb600_legacy, + .channels = 2, + .autodma = AUTODMA, + .bootable = ON_BOARD, } }; @@ -348,6 +368,7 @@ static struct pci_device_id atiixp_pci_tbl[] = { { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP300_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP400_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP600_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, + { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP600_SATA, PCI_ANY_ID, PCI_ANY_ID, (PCI_CLASS_STORAGE_IDE<<8)|0x8a, 0xffff05, 1}, { 0, }, }; MODULE_DEVICE_TABLE(pci, atiixp_pci_tbl); diff --git a/drivers/ide/pci/cs5530.c b/drivers/ide/pci/cs5530.c index 380bb28c7c54..ae405fa32236 100644 --- a/drivers/ide/pci/cs5530.c +++ b/drivers/ide/pci/cs5530.c @@ -222,23 +222,23 @@ static unsigned int __devinit init_chipset_cs5530 (struct pci_dev *dev, const ch unsigned long flags; dev = NULL; - while ((dev = pci_find_device(PCI_VENDOR_ID_CYRIX, PCI_ANY_ID, dev)) != NULL) { + while ((dev = pci_get_device(PCI_VENDOR_ID_CYRIX, PCI_ANY_ID, dev)) != NULL) { switch (dev->device) { case PCI_DEVICE_ID_CYRIX_PCI_MASTER: - master_0 = dev; + master_0 = pci_dev_get(dev); break; case PCI_DEVICE_ID_CYRIX_5530_LEGACY: - cs5530_0 = dev; + cs5530_0 = pci_dev_get(dev); break; } } if (!master_0) { printk(KERN_ERR "%s: unable to locate PCI MASTER function\n", name); - return 0; + goto out; } if (!cs5530_0) { printk(KERN_ERR "%s: unable to locate CS5530 LEGACY function\n", name); - return 0; + goto out; } spin_lock_irqsave(&ide_lock, flags); @@ -296,6 +296,9 @@ static unsigned int __devinit init_chipset_cs5530 (struct pci_dev *dev, const ch spin_unlock_irqrestore(&ide_lock, flags); +out: + pci_dev_put(master_0); + pci_dev_put(cs5530_0); return 0; } diff --git a/drivers/ide/pci/cy82c693.c b/drivers/ide/pci/cy82c693.c index 120929fbe7a3..64330c459bd4 100644 --- a/drivers/ide/pci/cy82c693.c +++ b/drivers/ide/pci/cy82c693.c @@ -281,7 +281,7 @@ static void cy82c693_tune_drive (ide_drive_t *drive, u8 pio) /* select primary or secondary channel */ if (hwif->index > 0) { /* drive is on the secondary channel */ - dev = pci_find_slot(dev->bus->number, dev->devfn+1); + dev = pci_get_slot(dev->bus, dev->devfn+1); if (!dev) { printk(KERN_ERR "%s: tune_drive: " "Cannot find secondary interface!\n", @@ -500,8 +500,9 @@ static int __devinit cy82c693_init_one(struct pci_dev *dev, const struct pci_dev Function 1 is primary IDE channel, function 2 - secondary. */ if ((dev->class >> 8) == PCI_CLASS_STORAGE_IDE && PCI_FUNC(dev->devfn) == 1) { - dev2 = pci_find_slot(dev->bus->number, dev->devfn + 1); + dev2 = pci_get_slot(dev->bus, dev->devfn + 1); ret = ide_setup_pci_devices(dev, dev2, d); + /* We leak pci refs here but thats ok - we can't be unloaded */ } return ret; } diff --git a/drivers/ide/pci/generic.c b/drivers/ide/pci/generic.c index 78810ba982e9..9f306880491a 100644 --- a/drivers/ide/pci/generic.c +++ b/drivers/ide/pci/generic.c @@ -23,7 +23,6 @@ #undef REALLY_SLOW_IO /* most systems can safely undef this */ -#include <linux/config.h> /* for CONFIG_BLK_DEV_IDEPCI */ #include <linux/types.h> #include <linux/module.h> #include <linux/kernel.h> @@ -41,6 +40,10 @@ static int ide_generic_all; /* Set to claim all devices */ +/* + * the module_param_named() was added for the modular case + * the __setup() is left as compatibility for existing setups + */ #ifndef MODULE static int __init ide_generic_all_on(char *unused) { @@ -50,6 +53,8 @@ static int __init ide_generic_all_on(char *unused) } __setup("all-generic-ide", ide_generic_all_on); #endif +module_param_named(all_generic_ide, ide_generic_all, bool, 0444); +MODULE_PARM_DESC(all_generic_ide, "IDE generic will claim all unknown PCI IDE storage controllers."); static void __devinit init_hwif_generic (ide_hwif_t *hwif) { @@ -242,13 +247,17 @@ static int __devinit generic_init_one(struct pci_dev *dev, const struct pci_devi (!(PCI_FUNC(dev->devfn) & 1))) goto out; - if (dev->vendor == PCI_VENDOR_ID_JMICRON && PCI_FUNC(dev->devfn) != 1) - goto out; + if (dev->vendor == PCI_VENDOR_ID_JMICRON) { + if (dev->device != PCI_DEVICE_ID_JMICRON_JMB368 && PCI_FUNC(dev->devfn) != 1) + goto out; + } - pci_read_config_word(dev, PCI_COMMAND, &command); - if (!(command & PCI_COMMAND_IO)) { - printk(KERN_INFO "Skipping disabled %s IDE controller.\n", d->name); - goto out; + if (dev->vendor != PCI_VENDOR_ID_JMICRON) { + pci_read_config_word(dev, PCI_COMMAND, &command); + if (!(command & PCI_COMMAND_IO)) { + printk(KERN_INFO "Skipping disabled %s IDE controller.\n", d->name); + goto out; + } } ret = ide_setup_pci_device(dev, d); out: diff --git a/drivers/ide/pci/it8172.c b/drivers/ide/pci/it8172.c deleted file mode 100644 index 0fc89fafad65..000000000000 --- a/drivers/ide/pci/it8172.c +++ /dev/null @@ -1,307 +0,0 @@ -/* - * - * BRIEF MODULE DESCRIPTION - * IT8172 IDE controller support - * - * Copyright 2000 MontaVista Software Inc. - * Author: MontaVista Software, Inc. - * stevel@mvista.com or source@mvista.com - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN - * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#include <linux/module.h> -#include <linux/types.h> -#include <linux/kernel.h> -#include <linux/ioport.h> -#include <linux/pci.h> -#include <linux/hdreg.h> -#include <linux/ide.h> -#include <linux/delay.h> -#include <linux/init.h> - -#include <asm/io.h> -#include <asm/it8172/it8172_int.h> - -/* - * Prototypes - */ -static u8 it8172_ratemask (ide_drive_t *drive) -{ - return 1; -} - -static void it8172_tune_drive (ide_drive_t *drive, u8 pio) -{ - ide_hwif_t *hwif = HWIF(drive); - struct pci_dev *dev = hwif->pci_dev; - int is_slave = (&hwif->drives[1] == drive); - unsigned long flags; - u16 drive_enables; - u32 drive_timing; - - pio = ide_get_best_pio_mode(drive, pio, 4, NULL); - spin_lock_irqsave(&ide_lock, flags); - pci_read_config_word(dev, 0x40, &drive_enables); - pci_read_config_dword(dev, 0x44, &drive_timing); - - /* - * FIX! The DIOR/DIOW pulse width and recovery times in port 0x44 - * are being left at the default values of 8 PCI clocks (242 nsec - * for a 33 MHz clock). These can be safely shortened at higher - * PIO modes. The DIOR/DIOW pulse width and recovery times only - * apply to PIO modes, not to the DMA modes. - */ - - /* - * Enable port 0x44. The IT8172G spec is confused; it calls - * this register the "Slave IDE Timing Register", but in fact, - * it controls timing for both master and slave drives. - */ - drive_enables |= 0x4000; - - if (is_slave) { - drive_enables &= 0xc006; - if (pio > 1) - /* enable prefetch and IORDY sample-point */ - drive_enables |= 0x0060; - } else { - drive_enables &= 0xc060; - if (pio > 1) - /* enable prefetch and IORDY sample-point */ - drive_enables |= 0x0006; - } - - pci_write_config_word(dev, 0x40, drive_enables); - spin_unlock_irqrestore(&ide_lock, flags); -} - -static u8 it8172_dma_2_pio (u8 xfer_rate) -{ - switch(xfer_rate) { - case XFER_UDMA_5: - case XFER_UDMA_4: - case XFER_UDMA_3: - case XFER_UDMA_2: - case XFER_UDMA_1: - case XFER_UDMA_0: - case XFER_MW_DMA_2: - case XFER_PIO_4: - return 4; - case XFER_MW_DMA_1: - case XFER_PIO_3: - return 3; - case XFER_SW_DMA_2: - case XFER_PIO_2: - return 2; - case XFER_MW_DMA_0: - case XFER_SW_DMA_1: - case XFER_SW_DMA_0: - case XFER_PIO_1: - case XFER_PIO_0: - case XFER_PIO_SLOW: - default: - return 0; - } -} - -static int it8172_tune_chipset (ide_drive_t *drive, u8 xferspeed) -{ - ide_hwif_t *hwif = HWIF(drive); - struct pci_dev *dev = hwif->pci_dev; - u8 speed = ide_rate_filter(it8172_ratemask(drive), xferspeed); - int a_speed = 3 << (drive->dn * 4); - int u_flag = 1 << drive->dn; - int u_speed = 0; - u8 reg48, reg4a; - - pci_read_config_byte(dev, 0x48, ®48); - pci_read_config_byte(dev, 0x4a, ®4a); - - /* - * Setting the DMA cycle time to 2 or 3 PCI clocks (60 and 91 nsec - * at 33 MHz PCI clock) seems to cause BadCRC errors during DMA - * transfers on some drives, even though both numbers meet the minimum - * ATAPI-4 spec of 73 and 54 nsec for UDMA 1 and 2 respectively. - * So the faster times are just commented out here. The good news is - * that the slower cycle time has very little affect on transfer - * performance. - */ - - switch(speed) { - case XFER_UDMA_4: - case XFER_UDMA_2: //u_speed = 2 << (drive->dn * 4); break; - case XFER_UDMA_5: - case XFER_UDMA_3: - case XFER_UDMA_1: //u_speed = 1 << (drive->dn * 4); break; - case XFER_UDMA_0: u_speed = 0 << (drive->dn * 4); break; - case XFER_MW_DMA_2: - case XFER_MW_DMA_1: - case XFER_MW_DMA_0: - case XFER_SW_DMA_2: break; - case XFER_PIO_4: - case XFER_PIO_3: - case XFER_PIO_2: - case XFER_PIO_0: break; - default: return -1; - } - - if (speed >= XFER_UDMA_0) { - pci_write_config_byte(dev, 0x48, reg48 | u_flag); - reg4a &= ~a_speed; - pci_write_config_byte(dev, 0x4a, reg4a | u_speed); - } else { - pci_write_config_byte(dev, 0x48, reg48 & ~u_flag); - pci_write_config_byte(dev, 0x4a, reg4a & ~a_speed); - } - - it8172_tune_drive(drive, it8172_dma_2_pio(speed)); - return (ide_config_drive_speed(drive, speed)); -} - -static int it8172_config_chipset_for_dma (ide_drive_t *drive) -{ - u8 speed = ide_dma_speed(drive, it8172_ratemask(drive)); - - if (!(speed)) { - u8 tspeed = ide_get_best_pio_mode(drive, 255, 4, NULL); - speed = it8172_dma_2_pio(XFER_PIO_0 + tspeed); - } - - (void) it8172_tune_chipset(drive, speed); - return ide_dma_enable(drive); -} - -static int it8172_config_drive_xfer_rate (ide_drive_t *drive) -{ - ide_hwif_t *hwif = HWIF(drive); - struct hd_driveid *id = drive->id; - - drive->init_speed = 0; - - if (id && (id->capability & 1) && drive->autodma) { - - if (ide_use_dma(drive)) { - if (it8172_config_chipset_for_dma(drive)) - return hwif->ide_dma_on(drive); - } - - goto fast_ata_pio; - - } else if ((id->capability & 8) || (id->field_valid & 2)) { -fast_ata_pio: - it8172_tune_drive(drive, 5); - return hwif->ide_dma_off_quietly(drive); - } - /* IORDY not supported */ - return 0; -} - -static unsigned int __devinit init_chipset_it8172 (struct pci_dev *dev, const char *name) -{ - unsigned char progif; - - /* - * Place both IDE interfaces into PCI "native" mode - */ - pci_read_config_byte(dev, PCI_CLASS_PROG, &progif); - pci_write_config_byte(dev, PCI_CLASS_PROG, progif | 0x05); - - return IT8172_IDE_IRQ; -} - - -static void __devinit init_hwif_it8172 (ide_hwif_t *hwif) -{ - struct pci_dev* dev = hwif->pci_dev; - unsigned long cmdBase, ctrlBase; - - hwif->autodma = 0; - hwif->tuneproc = &it8172_tune_drive; - hwif->speedproc = &it8172_tune_chipset; - - cmdBase = dev->resource[0].start; - ctrlBase = dev->resource[1].start; - - ide_init_hwif_ports(&hwif->hw, cmdBase, ctrlBase | 2, NULL); - memcpy(hwif->io_ports, hwif->hw.io_ports, sizeof(hwif->io_ports)); - hwif->noprobe = 0; - - if (!hwif->dma_base) { - hwif->drives[0].autotune = 1; - hwif->drives[1].autotune = 1; - return; - } - - hwif->atapi_dma = 1; - hwif->ultra_mask = 0x07; - hwif->mwdma_mask = 0x06; - hwif->swdma_mask = 0x04; - - hwif->ide_dma_check = &it8172_config_drive_xfer_rate; - if (!noautodma) - hwif->autodma = 1; - hwif->drives[0].autodma = hwif->autodma; - hwif->drives[1].autodma = hwif->autodma; -} - -static ide_pci_device_t it8172_chipsets[] __devinitdata = { - { /* 0 */ - .name = "IT8172G", - .init_chipset = init_chipset_it8172, - .init_hwif = init_hwif_it8172, - .channels = 2, - .autodma = AUTODMA, - .enablebits = {{0x00,0x00,0x00}, {0x40,0x00,0x01}}, - .bootable = ON_BOARD, - } -}; - -static int __devinit it8172_init_one(struct pci_dev *dev, const struct pci_device_id *id) -{ - if ((!(PCI_FUNC(dev->devfn) & 1) || - (!((dev->class >> 8) == PCI_CLASS_STORAGE_IDE)))) - return -ENODEV; /* IT8172 is more than an IDE controller */ - return ide_setup_pci_device(dev, &it8172_chipsets[id->driver_data]); -} - -static struct pci_device_id it8172_pci_tbl[] = { - { PCI_VENDOR_ID_ITE, PCI_DEVICE_ID_ITE_IT8172G, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - { 0, }, -}; -MODULE_DEVICE_TABLE(pci, it8172_pci_tbl); - -static struct pci_driver driver = { - .name = "IT8172_IDE", - .id_table = it8172_pci_tbl, - .probe = it8172_init_one, -}; - -static int it8172_ide_init(void) -{ - return ide_pci_register_driver(&driver); -} - -module_init(it8172_ide_init); - -MODULE_AUTHOR("SteveL@mvista.com"); -MODULE_DESCRIPTION("PCI driver module for ITE 8172 IDE"); -MODULE_LICENSE("GPL"); diff --git a/drivers/ide/pci/jmicron.c b/drivers/ide/pci/jmicron.c new file mode 100644 index 000000000000..c1cec236ecf0 --- /dev/null +++ b/drivers/ide/pci/jmicron.c @@ -0,0 +1,268 @@ + +/* + * Copyright (C) 2006 Red Hat <alan@redhat.com> + * + * May be copied or modified under the terms of the GNU General Public License + */ + +#include <linux/types.h> +#include <linux/module.h> +#include <linux/pci.h> +#include <linux/delay.h> +#include <linux/hdreg.h> +#include <linux/ide.h> +#include <linux/init.h> + +#include <asm/io.h> + +typedef enum { + PORT_PATA0 = 0, + PORT_PATA1 = 1, + PORT_SATA = 2, +} port_type; + +/** + * jmicron_ratemask - Compute available modes + * @drive: IDE drive + * + * Compute the available speeds for the devices on the interface. This + * is all modes to ATA133 clipped by drive cable setup. + */ + +static u8 jmicron_ratemask(ide_drive_t *drive) +{ + u8 mode = 4; + if (!eighty_ninty_three(drive)) + mode = min(mode, (u8)1); + return mode; +} + +/** + * ata66_jmicron - Cable check + * @hwif: IDE port + * + * Return 1 if the cable is 80pin + */ + +static int __devinit ata66_jmicron(ide_hwif_t *hwif) +{ + struct pci_dev *pdev = hwif->pci_dev; + + u32 control; + u32 control5; + + int port = hwif->channel; + port_type port_map[2]; + + pci_read_config_dword(pdev, 0x40, &control); + + /* There are two basic mappings. One has the two SATA ports merged + as master/slave and the secondary as PATA, the other has only the + SATA port mapped */ + if (control & (1 << 23)) { + port_map[0] = PORT_SATA; + port_map[1] = PORT_PATA0; + } else { + port_map[0] = PORT_SATA; + port_map[1] = PORT_SATA; + } + + /* The 365/366 may have this bit set to map the second PATA port + as the internal primary channel */ + pci_read_config_dword(pdev, 0x80, &control5); + if (control5 & (1<<24)) + port_map[0] = PORT_PATA1; + + /* The two ports may then be logically swapped by the firmware */ + if (control & (1 << 22)) + port = port ^ 1; + + /* + * Now we know which physical port we are talking about we can + * actually do our cable checking etc. Thankfully we don't need + * to do the plumbing for other cases. + */ + switch (port_map[port]) + { + case PORT_PATA0: + if (control & (1 << 3)) /* 40/80 pin primary */ + return 1; + return 0; + case PORT_PATA1: + if (control5 & (1 << 19)) /* 40/80 pin secondary */ + return 0; + return 1; + case PORT_SATA: + return 1; + } +} + +static void jmicron_tuneproc (ide_drive_t *drive, byte mode_wanted) +{ + return; +} + +/** + * config_jmicron_chipset_for_pio - set drive timings + * @drive: drive to tune + * @speed we want + * + */ + +static void config_jmicron_chipset_for_pio (ide_drive_t *drive, byte set_speed) +{ + u8 speed = XFER_PIO_0 + ide_get_best_pio_mode(drive, 255, 5, NULL); + if (set_speed) + (void) ide_config_drive_speed(drive, speed); +} + +/** + * jmicron_tune_chipset - set controller timings + * @drive: Drive to set up + * @xferspeed: speed we want to achieve + * + * As the JMicron snoops for timings all we actually need to do is + * make sure we don't set an invalid mode. We do need to honour + * the cable detect here. + */ + +static int jmicron_tune_chipset (ide_drive_t *drive, byte xferspeed) +{ + + u8 speed = ide_rate_filter(jmicron_ratemask(drive), xferspeed); + + return ide_config_drive_speed(drive, speed); +} + +/** + * config_chipset_for_dma - configure for DMA + * @drive: drive to configure + * + * As the JMicron snoops for timings all we actually need to do is + * make sure we don't set an invalid mode. + */ + +static int config_chipset_for_dma (ide_drive_t *drive) +{ + u8 speed = ide_dma_speed(drive, jmicron_ratemask(drive)); + + config_jmicron_chipset_for_pio(drive, !speed); + jmicron_tune_chipset(drive, speed); + return ide_dma_enable(drive); +} + +/** + * jmicron_configure_drive_for_dma - set up for DMA transfers + * @drive: drive we are going to set up + * + * As the JMicron snoops for timings all we actually need to do is + * make sure we don't set an invalid mode. + */ + +static int jmicron_config_drive_for_dma (ide_drive_t *drive) +{ + ide_hwif_t *hwif = drive->hwif; + + if (ide_use_dma(drive)) { + if (config_chipset_for_dma(drive)) + return hwif->ide_dma_on(drive); + } + config_jmicron_chipset_for_pio(drive, 1); + return hwif->ide_dma_off_quietly(drive); +} + +/** + * init_hwif_jmicron - set up hwif structs + * @hwif: interface to set up + * + * Minimal set up is required for the Jmicron hardware. + */ + +static void __devinit init_hwif_jmicron(ide_hwif_t *hwif) +{ + hwif->speedproc = &jmicron_tune_chipset; + hwif->tuneproc = &jmicron_tuneproc; + + hwif->drives[0].autotune = 1; + hwif->drives[1].autotune = 1; + + if (!hwif->dma_base) + goto fallback; + + hwif->atapi_dma = 1; + hwif->ultra_mask = 0x7f; + hwif->mwdma_mask = 0x07; + + hwif->ide_dma_check = &jmicron_config_drive_for_dma; + if (!(hwif->udma_four)) + hwif->udma_four = ata66_jmicron(hwif); + + hwif->autodma = 1; + hwif->drives[0].autodma = hwif->autodma; + hwif->drives[1].autodma = hwif->autodma; + return; +fallback: + hwif->autodma = 0; + return; +} + +#define DECLARE_JMB_DEV(name_str) \ + { \ + .name = name_str, \ + .init_hwif = init_hwif_jmicron, \ + .channels = 2, \ + .autodma = AUTODMA, \ + .bootable = ON_BOARD, \ + .enablebits = { {0x40, 1, 1}, {0x40, 0x10, 0x10} }, \ + } + +static ide_pci_device_t jmicron_chipsets[] __devinitdata = { + /* 0 */ DECLARE_JMB_DEV("JMB361"), + /* 1 */ DECLARE_JMB_DEV("JMB363"), + /* 2 */ DECLARE_JMB_DEV("JMB365"), + /* 3 */ DECLARE_JMB_DEV("JMB366"), + /* 4 */ DECLARE_JMB_DEV("JMB368"), +}; + +/** + * jmicron_init_one - pci layer discovery entry + * @dev: PCI device + * @id: ident table entry + * + * Called by the PCI code when it finds a Jmicron controller. + * We then use the IDE PCI generic helper to do most of the work. + */ + +static int __devinit jmicron_init_one(struct pci_dev *dev, const struct pci_device_id *id) +{ + ide_setup_pci_device(dev, &jmicron_chipsets[id->driver_data]); + return 0; +} + +static struct pci_device_id jmicron_pci_tbl[] = { + { PCI_DEVICE(PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB361), 0}, + { PCI_DEVICE(PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB363), 1}, + { PCI_DEVICE(PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB365), 2}, + { PCI_DEVICE(PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB366), 3}, + { PCI_DEVICE(PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB368), 4}, + { 0, }, +}; + +MODULE_DEVICE_TABLE(pci, jmicron_pci_tbl); + +static struct pci_driver driver = { + .name = "JMicron IDE", + .id_table = jmicron_pci_tbl, + .probe = jmicron_init_one, +}; + +static int __init jmicron_ide_init(void) +{ + return ide_pci_register_driver(&driver); +} + +module_init(jmicron_ide_init); + +MODULE_AUTHOR("Alan Cox"); +MODULE_DESCRIPTION("PCI driver module for the JMicron in legacy modes"); +MODULE_LICENSE("GPL"); diff --git a/drivers/ide/pci/pdc202xx_new.c b/drivers/ide/pci/pdc202xx_new.c index 6c097e80b4df..7cb48576e479 100644 --- a/drivers/ide/pci/pdc202xx_new.c +++ b/drivers/ide/pci/pdc202xx_new.c @@ -9,6 +9,7 @@ * Split from: * linux/drivers/ide/pdc202xx.c Version 0.35 Mar. 30, 2002 * Copyright (C) 1998-2002 Andre Hedrick <andre@linux-ide.org> + * Copyright (C) 2005-2006 MontaVista Software, Inc. * Portions Copyright (C) 1999 Promise Technology, Inc. * Author: Frank Tiernan (frankt@promise.com) * Released under terms of General Public License @@ -38,6 +39,14 @@ #define PDC202_DEBUG_CABLE 0 +#undef DEBUG + +#ifdef DEBUG +#define DBG(fmt, args...) printk("%s: " fmt, __FUNCTION__, ## args) +#else +#define DBG(fmt, args...) +#endif + static const char *pdc_quirk_drives[] = { "QUANTUM FIREBALLlct08 08", "QUANTUM FIREBALLP KA6.4", @@ -50,37 +59,11 @@ static const char *pdc_quirk_drives[] = { NULL }; -#define set_2regs(a, b) \ - do { \ - hwif->OUTB((a + adj), indexreg); \ - hwif->OUTB(b, datareg); \ - } while(0) - -#define set_ultra(a, b, c) \ - do { \ - set_2regs(0x10,(a)); \ - set_2regs(0x11,(b)); \ - set_2regs(0x12,(c)); \ - } while(0) - -#define set_ata2(a, b) \ - do { \ - set_2regs(0x0e,(a)); \ - set_2regs(0x0f,(b)); \ - } while(0) - -#define set_pio(a, b, c) \ - do { \ - set_2regs(0x0c,(a)); \ - set_2regs(0x0d,(b)); \ - set_2regs(0x13,(c)); \ - } while(0) - -static u8 pdcnew_ratemask (ide_drive_t *drive) +static u8 max_dma_rate(struct pci_dev *pdev) { u8 mode; - switch(HWIF(drive)->pci_dev->device) { + switch(pdev->device) { case PCI_DEVICE_ID_PROMISE_20277: case PCI_DEVICE_ID_PROMISE_20276: case PCI_DEVICE_ID_PROMISE_20275: @@ -95,12 +78,21 @@ static u8 pdcnew_ratemask (ide_drive_t *drive) default: return 0; } - if (!eighty_ninty_three(drive)) - mode = min(mode, (u8)1); + return mode; } -static int check_in_drive_lists (ide_drive_t *drive, const char **list) +static u8 pdcnew_ratemask(ide_drive_t *drive) +{ + u8 mode = max_dma_rate(HWIF(drive)->pci_dev); + + if (!eighty_ninty_three(drive)) + mode = min_t(u8, mode, 1); + + return mode; +} + +static int check_in_drive_lists(ide_drive_t *drive, const char **list) { struct hd_driveid *id = drive->id; @@ -120,43 +112,141 @@ static int check_in_drive_lists (ide_drive_t *drive, const char **list) return 0; } -static int pdcnew_new_tune_chipset (ide_drive_t *drive, u8 xferspeed) +/** + * get_indexed_reg - Get indexed register + * @hwif: for the port address + * @index: index of the indexed register + */ +static u8 get_indexed_reg(ide_hwif_t *hwif, u8 index) +{ + u8 value; + + hwif->OUTB(index, hwif->dma_vendor1); + value = hwif->INB(hwif->dma_vendor3); + + DBG("index[%02X] value[%02X]\n", index, value); + return value; +} + +/** + * set_indexed_reg - Set indexed register + * @hwif: for the port address + * @index: index of the indexed register + */ +static void set_indexed_reg(ide_hwif_t *hwif, u8 index, u8 value) +{ + hwif->OUTB(index, hwif->dma_vendor1); + hwif->OUTB(value, hwif->dma_vendor3); + DBG("index[%02X] value[%02X]\n", index, value); +} + +/* + * ATA Timing Tables based on 133 MHz PLL output clock. + * + * If the PLL outputs 100 MHz clock, the ASIC hardware will set + * the timing registers automatically when "set features" command is + * issued to the device. However, if the PLL output clock is 133 MHz, + * the following tables must be used. + */ +static struct pio_timing { + u8 reg0c, reg0d, reg13; +} pio_timings [] = { + { 0xfb, 0x2b, 0xac }, /* PIO mode 0, IORDY off, Prefetch off */ + { 0x46, 0x29, 0xa4 }, /* PIO mode 1, IORDY off, Prefetch off */ + { 0x23, 0x26, 0x64 }, /* PIO mode 2, IORDY off, Prefetch off */ + { 0x27, 0x0d, 0x35 }, /* PIO mode 3, IORDY on, Prefetch off */ + { 0x23, 0x09, 0x25 }, /* PIO mode 4, IORDY on, Prefetch off */ +}; + +static struct mwdma_timing { + u8 reg0e, reg0f; +} mwdma_timings [] = { + { 0xdf, 0x5f }, /* MWDMA mode 0 */ + { 0x6b, 0x27 }, /* MWDMA mode 1 */ + { 0x69, 0x25 }, /* MWDMA mode 2 */ +}; + +static struct udma_timing { + u8 reg10, reg11, reg12; +} udma_timings [] = { + { 0x4a, 0x0f, 0xd5 }, /* UDMA mode 0 */ + { 0x3a, 0x0a, 0xd0 }, /* UDMA mode 1 */ + { 0x2a, 0x07, 0xcd }, /* UDMA mode 2 */ + { 0x1a, 0x05, 0xcd }, /* UDMA mode 3 */ + { 0x1a, 0x03, 0xcd }, /* UDMA mode 4 */ + { 0x1a, 0x02, 0xcb }, /* UDMA mode 5 */ + { 0x1a, 0x01, 0xcb }, /* UDMA mode 6 */ +}; + +static int pdcnew_tune_chipset(ide_drive_t *drive, u8 speed) { ide_hwif_t *hwif = HWIF(drive); - unsigned long indexreg = hwif->dma_vendor1; - unsigned long datareg = hwif->dma_vendor3; - u8 thold = 0x10; - u8 adj = (drive->dn%2) ? 0x08 : 0x00; - u8 speed = ide_rate_filter(pdcnew_ratemask(drive), xferspeed); - - if (speed == XFER_UDMA_2) { - hwif->OUTB((thold + adj), indexreg); - hwif->OUTB((hwif->INB(datareg) & 0x7f), datareg); - } + u8 adj = (drive->dn & 1) ? 0x08 : 0x00; + int err; - switch (speed) { - case XFER_UDMA_7: - speed = XFER_UDMA_6; - case XFER_UDMA_6: set_ultra(0x1a, 0x01, 0xcb); break; - case XFER_UDMA_5: set_ultra(0x1a, 0x02, 0xcb); break; - case XFER_UDMA_4: set_ultra(0x1a, 0x03, 0xcd); break; - case XFER_UDMA_3: set_ultra(0x1a, 0x05, 0xcd); break; - case XFER_UDMA_2: set_ultra(0x2a, 0x07, 0xcd); break; - case XFER_UDMA_1: set_ultra(0x3a, 0x0a, 0xd0); break; - case XFER_UDMA_0: set_ultra(0x4a, 0x0f, 0xd5); break; - case XFER_MW_DMA_2: set_ata2(0x69, 0x25); break; - case XFER_MW_DMA_1: set_ata2(0x6b, 0x27); break; - case XFER_MW_DMA_0: set_ata2(0xdf, 0x5f); break; - case XFER_PIO_4: set_pio(0x23, 0x09, 0x25); break; - case XFER_PIO_3: set_pio(0x27, 0x0d, 0x35); break; - case XFER_PIO_2: set_pio(0x23, 0x26, 0x64); break; - case XFER_PIO_1: set_pio(0x46, 0x29, 0xa4); break; - case XFER_PIO_0: set_pio(0xfb, 0x2b, 0xac); break; - default: - ; - } + speed = ide_rate_filter(pdcnew_ratemask(drive), speed); + + /* + * Issue SETFEATURES_XFER to the drive first. PDC202xx hardware will + * automatically set the timing registers based on 100 MHz PLL output. + */ + err = ide_config_drive_speed(drive, speed); + + /* + * As we set up the PLL to output 133 MHz for UltraDMA/133 capable + * chips, we must override the default register settings... + */ + if (max_dma_rate(hwif->pci_dev) == 4) { + u8 mode = speed & 0x07; + + switch (speed) { + case XFER_UDMA_6: + case XFER_UDMA_5: + case XFER_UDMA_4: + case XFER_UDMA_3: + case XFER_UDMA_2: + case XFER_UDMA_1: + case XFER_UDMA_0: + set_indexed_reg(hwif, 0x10 + adj, + udma_timings[mode].reg10); + set_indexed_reg(hwif, 0x11 + adj, + udma_timings[mode].reg11); + set_indexed_reg(hwif, 0x12 + adj, + udma_timings[mode].reg12); + break; + + case XFER_MW_DMA_2: + case XFER_MW_DMA_1: + case XFER_MW_DMA_0: + set_indexed_reg(hwif, 0x0e + adj, + mwdma_timings[mode].reg0e); + set_indexed_reg(hwif, 0x0f + adj, + mwdma_timings[mode].reg0f); + break; + case XFER_PIO_4: + case XFER_PIO_3: + case XFER_PIO_2: + case XFER_PIO_1: + case XFER_PIO_0: + set_indexed_reg(hwif, 0x0c + adj, + pio_timings[mode].reg0c); + set_indexed_reg(hwif, 0x0d + adj, + pio_timings[mode].reg0d); + set_indexed_reg(hwif, 0x13 + adj, + pio_timings[mode].reg13); + break; + default: + printk(KERN_ERR "pdc202xx_new: " + "Unknown speed %d ignored\n", speed); + } + } else if (speed == XFER_UDMA_2) { + /* Set tHOLD bit to 0 if using UDMA mode 2 */ + u8 tmp = get_indexed_reg(hwif, 0x10 + adj); - return (ide_config_drive_speed(drive, speed)); + set_indexed_reg(hwif, 0x10 + adj, tmp & 0x7f); + } + + return err; } /* 0 1 2 3 4 5 6 7 8 @@ -168,55 +258,55 @@ static int pdcnew_new_tune_chipset (ide_drive_t *drive, u8 xferspeed) */ static void pdcnew_tune_drive(ide_drive_t *drive, u8 pio) { - u8 speed; - - if (pio == 5) pio = 4; - speed = XFER_PIO_0 + ide_get_best_pio_mode(drive, 255, pio, NULL); - - (void)pdcnew_new_tune_chipset(drive, speed); + pio = ide_get_best_pio_mode(drive, pio, 4, NULL); + (void)pdcnew_tune_chipset(drive, XFER_PIO_0 + pio); } -static u8 pdcnew_new_cable_detect (ide_hwif_t *hwif) +static u8 pdcnew_cable_detect(ide_hwif_t *hwif) { - hwif->OUTB(0x0b, hwif->dma_vendor1); - return ((u8)((hwif->INB(hwif->dma_vendor3) & 0x04))); + return get_indexed_reg(hwif, 0x0b) & 0x04; } -static int config_chipset_for_dma (ide_drive_t *drive) + +static int config_chipset_for_dma(ide_drive_t *drive) { struct hd_driveid *id = drive->id; ide_hwif_t *hwif = HWIF(drive); - u8 speed = -1; - u8 cable; - - u8 ultra_66 = ((id->dma_ultra & 0x0010) || - (id->dma_ultra & 0x0008)) ? 1 : 0; - - cable = pdcnew_new_cable_detect(hwif); + u8 ultra_66 = (id->dma_ultra & 0x0078) ? 1 : 0; + u8 cable = pdcnew_cable_detect(hwif); + u8 speed; if (ultra_66 && cable) { - printk(KERN_WARNING "Warning: %s channel requires an 80-pin cable for operation.\n", hwif->channel ? "Secondary":"Primary"); + printk(KERN_WARNING "Warning: %s channel " + "requires an 80-pin cable for operation.\n", + hwif->channel ? "Secondary" : "Primary"); printk(KERN_WARNING "%s reduced to Ultra33 mode.\n", drive->name); } if (drive->media != ide_disk) return 0; - if (id->capability & 4) { /* IORDY_EN & PREFETCH_EN */ - hwif->OUTB((0x13 + ((drive->dn%2) ? 0x08 : 0x00)), hwif->dma_vendor1); - hwif->OUTB((hwif->INB(hwif->dma_vendor3)|0x03), hwif->dma_vendor3); + + if (id->capability & 4) { + /* + * Set IORDY_EN & PREFETCH_EN (this seems to have + * NO real effect since this register is reloaded + * by hardware when the transfer mode is selected) + */ + u8 tmp, adj = (drive->dn & 1) ? 0x08 : 0x00; + + tmp = get_indexed_reg(hwif, 0x13 + adj); + set_indexed_reg(hwif, 0x13 + adj, tmp | 0x03); } speed = ide_dma_speed(drive, pdcnew_ratemask(drive)); - if (!(speed)) { - hwif->tuneproc(drive, 5); + if (!speed) return 0; - } (void) hwif->speedproc(drive, speed); return ide_dma_enable(drive); } -static int pdcnew_config_drive_xfer_rate (ide_drive_t *drive) +static int pdcnew_config_drive_xfer_rate(ide_drive_t *drive) { ide_hwif_t *hwif = HWIF(drive); struct hd_driveid *id = drive->id; @@ -234,16 +324,16 @@ static int pdcnew_config_drive_xfer_rate (ide_drive_t *drive) } else if ((id->capability & 8) || (id->field_valid & 2)) { fast_ata_pio: - hwif->tuneproc(drive, 5); + hwif->tuneproc(drive, 255); return hwif->ide_dma_off_quietly(drive); } /* IORDY not supported */ return 0; } -static int pdcnew_quirkproc (ide_drive_t *drive) +static int pdcnew_quirkproc(ide_drive_t *drive) { - return ((int) check_in_drive_lists(drive, pdc_quirk_drives)); + return check_in_drive_lists(drive, pdc_quirk_drives); } static int pdcnew_ide_dma_lostirq(ide_drive_t *drive) @@ -260,21 +350,100 @@ static int pdcnew_ide_dma_timeout(ide_drive_t *drive) return __ide_dma_timeout(drive); } -static void pdcnew_new_reset (ide_drive_t *drive) +static void pdcnew_reset(ide_drive_t *drive) { /* * Deleted this because it is redundant from the caller. */ - printk(KERN_WARNING "PDC202XX: %s channel reset.\n", + printk(KERN_WARNING "pdc202xx_new: %s channel reset.\n", HWIF(drive)->channel ? "Secondary" : "Primary"); } +/** + * read_counter - Read the byte count registers + * @dma_base: for the port address + */ +static long __devinit read_counter(u32 dma_base) +{ + u32 pri_dma_base = dma_base, sec_dma_base = dma_base + 0x08; + u8 cnt0, cnt1, cnt2, cnt3; + long count = 0, last; + int retry = 3; + + do { + last = count; + + /* Read the current count */ + outb(0x20, pri_dma_base + 0x01); + cnt0 = inb(pri_dma_base + 0x03); + outb(0x21, pri_dma_base + 0x01); + cnt1 = inb(pri_dma_base + 0x03); + outb(0x20, sec_dma_base + 0x01); + cnt2 = inb(sec_dma_base + 0x03); + outb(0x21, sec_dma_base + 0x01); + cnt3 = inb(sec_dma_base + 0x03); + + count = (cnt3 << 23) | (cnt2 << 15) | (cnt1 << 8) | cnt0; + + /* + * The 30-bit decrementing counter is read in 4 pieces. + * Incorrect value may be read when the most significant bytes + * are changing... + */ + } while (retry-- && (((last ^ count) & 0x3fff8000) || last < count)); + + DBG("cnt0[%02X] cnt1[%02X] cnt2[%02X] cnt3[%02X]\n", + cnt0, cnt1, cnt2, cnt3); + + return count; +} + +/** + * detect_pll_input_clock - Detect the PLL input clock in Hz. + * @dma_base: for the port address + * E.g. 16949000 on 33 MHz PCI bus, i.e. half of the PCI clock. + */ +static long __devinit detect_pll_input_clock(unsigned long dma_base) +{ + long start_count, end_count; + long pll_input; + u8 scr1; + + start_count = read_counter(dma_base); + + /* Start the test mode */ + outb(0x01, dma_base + 0x01); + scr1 = inb(dma_base + 0x03); + DBG("scr1[%02X]\n", scr1); + outb(scr1 | 0x40, dma_base + 0x03); + + /* Let the counter run for 10 ms. */ + mdelay(10); + + end_count = read_counter(dma_base); + + /* Stop the test mode */ + outb(0x01, dma_base + 0x01); + scr1 = inb(dma_base + 0x03); + DBG("scr1[%02X]\n", scr1); + outb(scr1 & ~0x40, dma_base + 0x03); + + /* + * Calculate the input clock in Hz + * (the clock counter is 30 bit wide and counts down) + */ + pll_input = ((start_count - end_count) & 0x3ffffff) * 100; + + DBG("start[%ld] end[%ld]\n", start_count, end_count); + + return pll_input; +} + #ifdef CONFIG_PPC_PMAC static void __devinit apple_kiwi_init(struct pci_dev *pdev) { struct device_node *np = pci_device_to_OF_node(pdev); unsigned int class_rev = 0; - void __iomem *mmio; u8 conf; if (np == NULL || !device_is_compatible(np, "kiwi-root")) @@ -285,30 +454,20 @@ static void __devinit apple_kiwi_init(struct pci_dev *pdev) if (class_rev >= 0x03) { /* Setup chip magic config stuff (from darwin) */ - pci_read_config_byte(pdev, 0x40, &conf); - pci_write_config_byte(pdev, 0x40, conf | 0x01); - } - mmio = ioremap(pci_resource_start(pdev, 5), - pci_resource_len(pdev, 5)); - - /* Setup some PLL stuffs */ - switch (pdev->device) { - case PCI_DEVICE_ID_PROMISE_20270: - writew(0x0d2b, mmio + 0x1202); - mdelay(30); - break; - case PCI_DEVICE_ID_PROMISE_20271: - writew(0x0826, mmio + 0x1202); - mdelay(30); - break; + pci_read_config_byte (pdev, 0x40, &conf); + pci_write_config_byte(pdev, 0x40, (conf | 0x01)); } - - iounmap(mmio); } #endif /* CONFIG_PPC_PMAC */ static unsigned int __devinit init_chipset_pdcnew(struct pci_dev *dev, const char *name) { + unsigned long dma_base = pci_resource_start(dev, 4); + unsigned long sec_dma_base = dma_base + 0x08; + long pll_input, pll_output, ratio; + int f, r; + u8 pll_ctl0, pll_ctl1; + if (dev->resource[PCI_ROM_RESOURCE].start) { pci_write_config_dword(dev, PCI_ROM_ADDRESS, dev->resource[PCI_ROM_RESOURCE].start | PCI_ROM_ADDRESS_ENABLE); @@ -320,6 +479,106 @@ static unsigned int __devinit init_chipset_pdcnew(struct pci_dev *dev, const cha apple_kiwi_init(dev); #endif + /* Calculate the required PLL output frequency */ + switch(max_dma_rate(dev)) { + case 4: /* it's 133 MHz for Ultra133 chips */ + pll_output = 133333333; + break; + case 3: /* and 100 MHz for Ultra100 chips */ + default: + pll_output = 100000000; + break; + } + + /* + * Detect PLL input clock. + * On some systems, where PCI bus is running at non-standard clock rate + * (e.g. 25 or 40 MHz), we have to adjust the cycle time. + * PDC20268 and newer chips employ PLL circuit to help correct timing + * registers setting. + */ + pll_input = detect_pll_input_clock(dma_base); + printk("%s: PLL input clock is %ld kHz\n", name, pll_input / 1000); + + /* Sanity check */ + if (unlikely(pll_input < 5000000L || pll_input > 70000000L)) { + printk(KERN_ERR "%s: Bad PLL input clock %ld Hz, giving up!\n", + name, pll_input); + goto out; + } + +#ifdef DEBUG + DBG("pll_output is %ld Hz\n", pll_output); + + /* Show the current clock value of PLL control register + * (maybe already configured by the BIOS) + */ + outb(0x02, sec_dma_base + 0x01); + pll_ctl0 = inb(sec_dma_base + 0x03); + outb(0x03, sec_dma_base + 0x01); + pll_ctl1 = inb(sec_dma_base + 0x03); + + DBG("pll_ctl[%02X][%02X]\n", pll_ctl0, pll_ctl1); +#endif + + /* + * Calculate the ratio of F, R and NO + * POUT = (F + 2) / (( R + 2) * NO) + */ + ratio = pll_output / (pll_input / 1000); + if (ratio < 8600L) { /* 8.6x */ + /* Using NO = 0x01, R = 0x0d */ + r = 0x0d; + } else if (ratio < 12900L) { /* 12.9x */ + /* Using NO = 0x01, R = 0x08 */ + r = 0x08; + } else if (ratio < 16100L) { /* 16.1x */ + /* Using NO = 0x01, R = 0x06 */ + r = 0x06; + } else if (ratio < 64000L) { /* 64x */ + r = 0x00; + } else { + /* Invalid ratio */ + printk(KERN_ERR "%s: Bad ratio %ld, giving up!\n", name, ratio); + goto out; + } + + f = (ratio * (r + 2)) / 1000 - 2; + + DBG("F[%d] R[%d] ratio*1000[%ld]\n", f, r, ratio); + + if (unlikely(f < 0 || f > 127)) { + /* Invalid F */ + printk(KERN_ERR "%s: F[%d] invalid!\n", name, f); + goto out; + } + + pll_ctl0 = (u8) f; + pll_ctl1 = (u8) r; + + DBG("Writing pll_ctl[%02X][%02X]\n", pll_ctl0, pll_ctl1); + + outb(0x02, sec_dma_base + 0x01); + outb(pll_ctl0, sec_dma_base + 0x03); + outb(0x03, sec_dma_base + 0x01); + outb(pll_ctl1, sec_dma_base + 0x03); + + /* Wait the PLL circuit to be stable */ + mdelay(30); + +#ifdef DEBUG + /* + * Show the current clock value of PLL control register + */ + outb(0x02, sec_dma_base + 0x01); + pll_ctl0 = inb(sec_dma_base + 0x03); + outb(0x03, sec_dma_base + 0x01); + pll_ctl1 = inb(sec_dma_base + 0x03); + + DBG("pll_ctl[%02X][%02X]\n", pll_ctl0, pll_ctl1); +#endif + + out: return dev->irq; } @@ -329,8 +588,8 @@ static void __devinit init_hwif_pdc202new(ide_hwif_t *hwif) hwif->tuneproc = &pdcnew_tune_drive; hwif->quirkproc = &pdcnew_quirkproc; - hwif->speedproc = &pdcnew_new_tune_chipset; - hwif->resetproc = &pdcnew_new_reset; + hwif->speedproc = &pdcnew_tune_chipset; + hwif->resetproc = &pdcnew_reset; hwif->drives[0].autotune = hwif->drives[1].autotune = 1; @@ -342,11 +601,14 @@ static void __devinit init_hwif_pdc202new(ide_hwif_t *hwif) hwif->ide_dma_check = &pdcnew_config_drive_xfer_rate; hwif->ide_dma_lostirq = &pdcnew_ide_dma_lostirq; hwif->ide_dma_timeout = &pdcnew_ide_dma_timeout; - if (!(hwif->udma_four)) - hwif->udma_four = (pdcnew_new_cable_detect(hwif)) ? 0 : 1; + + if (!hwif->udma_four) + hwif->udma_four = pdcnew_cable_detect(hwif) ? 0 : 1; + if (!noautodma) hwif->autodma = 1; hwif->drives[0].autodma = hwif->drives[1].autodma = hwif->autodma; + #if PDC202_DEBUG_CABLE printk(KERN_DEBUG "%s: %s-pin cable\n", hwif->name, hwif->udma_four ? "80" : "40"); @@ -362,6 +624,7 @@ static int __devinit init_setup_pdc20270(struct pci_dev *dev, ide_pci_device_t *d) { struct pci_dev *findev = NULL; + int ret; if ((dev->bus->self && dev->bus->self->vendor == PCI_VENDOR_ID_DEC) && @@ -369,14 +632,16 @@ static int __devinit init_setup_pdc20270(struct pci_dev *dev, if (PCI_SLOT(dev->devfn) & 2) return -ENODEV; d->extra = 0; - while ((findev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, findev)) != NULL) { + while ((findev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, findev)) != NULL) { if ((findev->vendor == dev->vendor) && (findev->device == dev->device) && (PCI_SLOT(findev->devfn) & 2)) { if (findev->irq != dev->irq) { findev->irq = dev->irq; } - return ide_setup_pci_devices(dev, findev, d); + ret = ide_setup_pci_devices(dev, findev, d); + pci_dev_put(findev); + return ret; } } } diff --git a/drivers/ide/pci/pdc202xx_old.c b/drivers/ide/pci/pdc202xx_old.c index b46022a11bef..184cdacddeb6 100644 --- a/drivers/ide/pci/pdc202xx_old.c +++ b/drivers/ide/pci/pdc202xx_old.c @@ -154,7 +154,8 @@ static int pdc202xx_tune_chipset (ide_drive_t *drive, u8 xferspeed) u8 AP, BP, CP, DP; u8 TA = 0, TB = 0, TC = 0; - if ((drive->media != ide_disk) && (speed < XFER_SW_DMA_0)) + if (drive->media != ide_disk && + drive->media != ide_cdrom && speed < XFER_SW_DMA_0) return -1; pci_read_config_dword(dev, drive_pci, &drive_conf); @@ -330,14 +331,12 @@ static int config_chipset_for_dma (ide_drive_t *drive) chipset_is_set: - if (drive->media == ide_disk) { - pci_read_config_byte(dev, (drive_pci), &AP); - if (id->capability & 4) /* IORDY_EN */ - pci_write_config_byte(dev, (drive_pci), AP|IORDY_EN); - pci_read_config_byte(dev, (drive_pci), &AP); - if (drive->media == ide_disk) /* PREFETCH_EN */ - pci_write_config_byte(dev, (drive_pci), AP|PREFETCH_EN); - } + pci_read_config_byte(dev, (drive_pci), &AP); + if (id->capability & 4) /* IORDY_EN */ + pci_write_config_byte(dev, (drive_pci), AP|IORDY_EN); + pci_read_config_byte(dev, (drive_pci), &AP); + if (drive->media == ide_disk) /* PREFETCH_EN */ + pci_write_config_byte(dev, (drive_pci), AP|PREFETCH_EN); speed = ide_dma_speed(drive, pdc202xx_ratemask(drive)); @@ -385,7 +384,7 @@ static void pdc202xx_old_ide_dma_start(ide_drive_t *drive) { if (drive->current_speed > XFER_UDMA_2) pdc_old_enable_66MHz_clock(drive->hwif); - if (drive->addressing == 1) { + if (drive->media != ide_disk || drive->addressing == 1) { struct request *rq = HWGROUP(drive)->rq; ide_hwif_t *hwif = HWIF(drive); unsigned long high_16 = hwif->dma_master; @@ -405,7 +404,7 @@ static void pdc202xx_old_ide_dma_start(ide_drive_t *drive) static int pdc202xx_old_ide_dma_end(ide_drive_t *drive) { - if (drive->addressing == 1) { + if (drive->media != ide_disk || drive->addressing == 1) { ide_hwif_t *hwif = HWIF(drive); unsigned long high_16 = hwif->dma_master; unsigned long atapi_reg = high_16 + (hwif->channel ? 0x24 : 0x20); @@ -519,6 +518,7 @@ static void __devinit init_hwif_pdc202xx(ide_hwif_t *hwif) hwif->ultra_mask = 0x3f; hwif->mwdma_mask = 0x07; hwif->swdma_mask = 0x07; + hwif->atapi_dma = 1; hwif->err_stops_fifo = 1; diff --git a/drivers/ide/pci/piix.c b/drivers/ide/pci/piix.c index 50332ddd5ddb..b1e9a8eba6b6 100644 --- a/drivers/ide/pci/piix.c +++ b/drivers/ide/pci/piix.c @@ -222,13 +222,15 @@ static void piix_tune_drive (ide_drive_t *drive, u8 pio) u16 master_data; u8 slave_data; static DEFINE_SPINLOCK(tune_lock); + int control = 0; /* ISP RTC */ - u8 timings[][2] = { { 0, 0 }, - { 0, 0 }, - { 1, 0 }, - { 2, 1 }, - { 2, 3 }, }; + static const u8 timings[][2]= { + { 0, 0 }, + { 0, 0 }, + { 1, 0 }, + { 2, 1 }, + { 2, 3 }, }; pio = ide_get_best_pio_mode(drive, pio, 5, NULL); @@ -239,19 +241,30 @@ static void piix_tune_drive (ide_drive_t *drive, u8 pio) */ spin_lock_irqsave(&tune_lock, flags); pci_read_config_word(dev, master_port, &master_data); + + if (pio >= 2) + control |= 1; /* Programmable timing on */ + if (drive->media == ide_disk) + control |= 4; /* Prefetch, post write */ + if (pio >= 3) + control |= 2; /* IORDY */ if (is_slave) { master_data = master_data | 0x4000; - if (pio > 1) + if (pio > 1) { /* enable PPE, IE and TIME */ - master_data = master_data | 0x0070; + master_data = master_data | (control << 4); + } else { + master_data &= ~0x0070; + } pci_read_config_byte(dev, slave_port, &slave_data); slave_data = slave_data & (hwif->channel ? 0x0f : 0xf0); slave_data = slave_data | (((timings[pio][0] << 2) | timings[pio][1]) << (hwif->channel ? 4 : 0)); } else { master_data = master_data & 0xccf8; - if (pio > 1) + if (pio > 1) { /* enable PPE, IE and TIME */ - master_data = master_data | 0x0007; + master_data = master_data | control; + } master_data = master_data | (timings[pio][0] << 12) | (timings[pio][1] << 8); } pci_write_config_word(dev, master_port, master_data); @@ -492,6 +505,10 @@ static void __devinit init_hwif_piix(ide_hwif_t *hwif) /* This is a painful system best to let it self tune for now */ return; } + /* ESB2 appears to generate spurious DMA interrupts in PIO mode + when in native mode */ + if (hwif->pci_dev->device == PCI_DEVICE_ID_INTEL_ESB2_18) + hwif->atapi_irq_bogon = 1; hwif->autodma = 0; hwif->tuneproc = &piix_tune_drive; @@ -615,7 +632,7 @@ static void __devinit piix_check_450nx(void) struct pci_dev *pdev = NULL; u16 cfg; u8 rev; - while((pdev=pci_find_device(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82454NX, pdev))!=NULL) + while((pdev=pci_get_device(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82454NX, pdev))!=NULL) { /* Look for 450NX PXB. Check for problem configurations A PCI quirk checks bit 6 already */ diff --git a/drivers/ide/pci/rz1000.c b/drivers/ide/pci/rz1000.c index 608cd7609072..5f6950c2d1d1 100644 --- a/drivers/ide/pci/rz1000.c +++ b/drivers/ide/pci/rz1000.c @@ -17,7 +17,6 @@ #undef REALLY_SLOW_IO /* most systems can safely undef this */ -#include <linux/config.h> /* for CONFIG_BLK_DEV_IDEPCI */ #include <linux/types.h> #include <linux/module.h> #include <linux/kernel.h> diff --git a/drivers/ide/pci/sc1200.c b/drivers/ide/pci/sc1200.c index fc2b5496b6d2..ff80937d94dd 100644 --- a/drivers/ide/pci/sc1200.c +++ b/drivers/ide/pci/sc1200.c @@ -323,6 +323,7 @@ static void sc1200_tuneproc (ide_drive_t *drive, byte pio) /* mode=255 means "au } } +#ifdef CONFIG_PM static ide_hwif_t *lookup_pci_dev (ide_hwif_t *prev, struct pci_dev *dev) { int h; @@ -451,6 +452,7 @@ static int sc1200_resume (struct pci_dev *dev) } return 0; } +#endif /* * This gets invoked by the IDE driver once for each channel, @@ -499,8 +501,10 @@ static struct pci_driver driver = { .name = "SC1200_IDE", .id_table = sc1200_pci_tbl, .probe = sc1200_init_one, +#ifdef CONFIG_PM .suspend = sc1200_suspend, .resume = sc1200_resume, +#endif }; static int sc1200_ide_init(void) diff --git a/drivers/ide/pci/serverworks.c b/drivers/ide/pci/serverworks.c index f063d954236c..057548d07205 100644 --- a/drivers/ide/pci/serverworks.c +++ b/drivers/ide/pci/serverworks.c @@ -359,7 +359,7 @@ static unsigned int __devinit init_chipset_svwks (struct pci_dev *dev, const cha /* OSB4 : South Bridge and IDE */ if (dev->device == PCI_DEVICE_ID_SERVERWORKS_OSB4IDE) { - isa_dev = pci_find_device(PCI_VENDOR_ID_SERVERWORKS, + isa_dev = pci_get_device(PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_OSB4, NULL); if (isa_dev) { pci_read_config_dword(isa_dev, 0x64, ®); @@ -380,7 +380,7 @@ static unsigned int __devinit init_chipset_svwks (struct pci_dev *dev, const cha if (!(PCI_FUNC(dev->devfn) & 1)) { struct pci_dev * findev = NULL; u32 reg4c = 0; - findev = pci_find_device(PCI_VENDOR_ID_SERVERWORKS, + findev = pci_get_device(PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_CSB5, NULL); if (findev) { pci_read_config_dword(findev, 0x4C, ®4c); @@ -388,6 +388,7 @@ static unsigned int __devinit init_chipset_svwks (struct pci_dev *dev, const cha reg4c |= 0x00000040; reg4c |= 0x00000020; pci_write_config_dword(findev, 0x4C, reg4c); + pci_dev_put(findev); } outb_p(0x06, 0x0c00); dev->irq = inb_p(0x0c01); @@ -395,12 +396,13 @@ static unsigned int __devinit init_chipset_svwks (struct pci_dev *dev, const cha struct pci_dev * findev = NULL; u8 reg41 = 0; - findev = pci_find_device(PCI_VENDOR_ID_SERVERWORKS, + findev = pci_get_device(PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_CSB6, NULL); if (findev) { pci_read_config_byte(findev, 0x41, ®41); reg41 &= ~0x40; pci_write_config_byte(findev, 0x41, reg41); + pci_dev_put(findev); } /* * This is a device pin issue on CSB6. diff --git a/drivers/ide/pci/sgiioc4.c b/drivers/ide/pci/sgiioc4.c index d8a0d87df734..cfad09accf52 100644 --- a/drivers/ide/pci/sgiioc4.c +++ b/drivers/ide/pci/sgiioc4.c @@ -220,7 +220,7 @@ sgiioc4_ide_dma_end(ide_drive_t * drive) ide_hwif_t *hwif = HWIF(drive); u64 dma_base = hwif->dma_base; int dma_stat = 0; - unsigned long *ending_dma = (unsigned long *) hwif->dma_base2; + unsigned long *ending_dma = ide_get_hwifdata(hwif); hwif->OUTL(IOC4_S_DMA_STOP, dma_base + IOC4_DMA_CTRL * 4); @@ -369,6 +369,7 @@ ide_dma_sgiioc4(ide_hwif_t * hwif, unsigned long dma_base) { void __iomem *virt_dma_base; int num_ports = sizeof (ioc4_dma_regs_t); + void *pad; printk(KERN_INFO "%s: BM-DMA at 0x%04lx-0x%04lx\n", hwif->name, dma_base, dma_base + num_ports - 1); @@ -400,17 +401,14 @@ ide_dma_sgiioc4(ide_hwif_t * hwif, unsigned long dma_base) hwif->sg_max_nents = IOC4_PRD_ENTRIES; - hwif->dma_base2 = (unsigned long) - pci_alloc_consistent(hwif->pci_dev, - IOC4_IDE_CACHELINE_SIZE, - (dma_addr_t *) &(hwif->dma_status)); + pad = pci_alloc_consistent(hwif->pci_dev, IOC4_IDE_CACHELINE_SIZE, + (dma_addr_t *) &(hwif->dma_status)); - if (!hwif->dma_base2) - goto dma_base2alloc_failure; - - return; + if (pad) { + ide_set_hwifdata(hwif, pad); + return; + } -dma_base2alloc_failure: pci_free_consistent(hwif->pci_dev, IOC4_PRD_ENTRIES * IOC4_PRD_BYTES, hwif->dmatable_cpu, hwif->dmatable_dma); @@ -476,7 +474,7 @@ sgiioc4_configure_for_dma(int dma_direction, ide_drive_t * drive) hwif->OUTL(dma_addr, dma_base + IOC4_DMA_PTR_L * 4); /* Address of the Ending DMA */ - memset((unsigned int *) hwif->dma_base2, 0, IOC4_IDE_CACHELINE_SIZE); + memset(ide_get_hwifdata(hwif), 0, IOC4_IDE_CACHELINE_SIZE); ending_dma_addr = cpu_to_le32(hwif->dma_status); hwif->OUTL(ending_dma_addr, dma_base + IOC4_DMA_END_ADDR * 4); @@ -770,14 +768,7 @@ ioc4_ide_init(void) return ioc4_register_submodule(&ioc4_ide_submodule); } -static void __devexit -ioc4_ide_exit(void) -{ - ioc4_unregister_submodule(&ioc4_ide_submodule); -} - -module_init(ioc4_ide_init); -module_exit(ioc4_ide_exit); +late_initcall(ioc4_ide_init); /* Call only after IDE init is done */ MODULE_AUTHOR("Aniket Malatpure/Jeremy Higdon"); MODULE_DESCRIPTION("IDE PCI driver module for SGI IOC4 Base-IO Card"); diff --git a/drivers/ide/pci/siimage.c b/drivers/ide/pci/siimage.c index 20b392948f36..697f566fb90a 100644 --- a/drivers/ide/pci/siimage.c +++ b/drivers/ide/pci/siimage.c @@ -898,7 +898,6 @@ static void __devinit init_mmio_iops_siimage(ide_hwif_t *hwif) base = (unsigned long) addr; hwif->dma_base = base + (ch ? 0x08 : 0x00); - hwif->dma_base2 = base + (ch ? 0x18 : 0x10); hwif->mmio = 2; } diff --git a/drivers/ide/pci/sis5513.c b/drivers/ide/pci/sis5513.c index f03196c5db37..6b313139b5e4 100644 --- a/drivers/ide/pci/sis5513.c +++ b/drivers/ide/pci/sis5513.c @@ -739,7 +739,7 @@ static unsigned int __devinit init_chipset_sis5513 (struct pci_dev *dev, const c for (i = 0; i < ARRAY_SIZE(SiSHostChipInfo) && !chipset_family; i++) { - host = pci_find_device(PCI_VENDOR_ID_SI, SiSHostChipInfo[i].host_id, NULL); + host = pci_get_device(PCI_VENDOR_ID_SI, SiSHostChipInfo[i].host_id, NULL); if (!host) continue; @@ -753,6 +753,7 @@ static unsigned int __devinit init_chipset_sis5513 (struct pci_dev *dev, const c if (hostrev >= 0x30) chipset_family = ATA_100a; } + pci_dev_put(host); printk(KERN_INFO "SIS5513: %s %s controller\n", SiSHostChipInfo[i].name, chipset_capability[chipset_family]); @@ -799,9 +800,10 @@ static unsigned int __devinit init_chipset_sis5513 (struct pci_dev *dev, const c if (trueid == 0x5517) { /* SiS 961/961B */ - lpc_bridge = pci_find_slot(0x00, 0x10); /* Bus 0, Dev 2, Fn 0 */ + lpc_bridge = pci_get_slot(dev->bus, 0x10); /* Bus 0, Dev 2, Fn 0 */ pci_read_config_byte(lpc_bridge, PCI_REVISION_ID, &sbrev); pci_read_config_byte(dev, 0x49, &prefctl); + pci_dev_put(lpc_bridge); if (sbrev == 0x10 && (prefctl & 0x80)) { printk(KERN_INFO "SIS5513: SiS 961B MuTIOL IDE UDMA133 controller\n"); diff --git a/drivers/ide/pci/sl82c105.c b/drivers/ide/pci/sl82c105.c index 0b4b60498515..5afefe8692fe 100644 --- a/drivers/ide/pci/sl82c105.c +++ b/drivers/ide/pci/sl82c105.c @@ -299,14 +299,14 @@ static void sl82c105_selectproc(ide_drive_t *drive) //DBG(("sl82c105_selectproc(drive:%s)\n", drive->name)); mask = hwif->channel ? CTRL_P1F16 : CTRL_P0F16; - old = val = *((u32 *)&hwif->hwif_data); + old = val = (u32)pci_get_drvdata(dev); if (drive->using_dma) val &= ~mask; else val |= mask; if (old != val) { pci_write_config_dword(dev, 0x40, val); - *((u32 *)&hwif->hwif_data) = val; + pci_set_drvdata(dev, (void *)val); } } @@ -316,14 +316,13 @@ static void sl82c105_selectproc(ide_drive_t *drive) */ static void sl82c105_resetproc(ide_drive_t *drive) { - ide_hwif_t *hwif = HWIF(drive); - struct pci_dev *dev = hwif->pci_dev; + struct pci_dev *dev = HWIF(drive)->pci_dev; u32 val; DBG(("sl82c105_resetproc(drive:%s)\n", drive->name)); pci_read_config_dword(dev, 0x40, &val); - *((u32 *)&hwif->hwif_data) = val; + pci_set_drvdata(dev, (void *)val); } /* @@ -394,6 +393,7 @@ static unsigned int __devinit init_chipset_sl82c105(struct pci_dev *dev, const c pci_read_config_dword(dev, 0x40, &val); val |= CTRL_P0EN | CTRL_P0F16 | CTRL_P1F16; pci_write_config_dword(dev, 0x40, val); + pci_set_drvdata(dev, (void *)val); return dev->irq; } @@ -404,30 +404,25 @@ static unsigned int __devinit init_chipset_sl82c105(struct pci_dev *dev, const c static void __devinit init_hwif_sl82c105(ide_hwif_t *hwif) { - struct pci_dev *dev = hwif->pci_dev; unsigned int rev; u8 dma_state; - u32 val; - + DBG(("init_hwif_sl82c105(hwif: ide%d)\n", hwif->index)); hwif->tuneproc = tune_sl82c105; hwif->selectproc = sl82c105_selectproc; hwif->resetproc = sl82c105_resetproc; - - /* Default to PIO 0 for fallback unless tuned otherwise, - * we always autotune PIO, this is done before DMA is - * checked, so there is no risk of accidentally disabling - * DMA - */ + + /* + * Default to PIO 0 for fallback unless tuned otherwise. + * We always autotune PIO, this is done before DMA is checked, + * so there's no risk of accidentally disabling DMA + */ hwif->drives[0].pio_speed = XFER_PIO_0; hwif->drives[0].autotune = 1; - hwif->drives[1].pio_speed = XFER_PIO_1; + hwif->drives[1].pio_speed = XFER_PIO_0; hwif->drives[1].autotune = 1; - pci_read_config_dword(dev, 0x40, &val); - *((u32 *)&hwif->hwif_data) = val; - hwif->atapi_dma = 0; hwif->mwdma_mask = 0; hwif->swdma_mask = 0; diff --git a/drivers/ide/pci/via82cxxx.c b/drivers/ide/pci/via82cxxx.c index 9b7589e8e93e..61f1a9665a7f 100644 --- a/drivers/ide/pci/via82cxxx.c +++ b/drivers/ide/pci/via82cxxx.c @@ -35,7 +35,7 @@ #include <linux/ide.h> #include <asm/io.h> -#ifdef CONFIG_PPC_MULTIPLATFORM +#ifdef CONFIG_PPC_CHRP #include <asm/processor.h> #endif @@ -248,7 +248,7 @@ static struct via_isa_bridge *via_config_find(struct pci_dev **isa) u8 t; for (via_config = via_isa_bridges; via_config->id; via_config++) - if ((*isa = pci_find_device(PCI_VENDOR_ID_VIA + + if ((*isa = pci_get_device(PCI_VENDOR_ID_VIA + !!(via_config->flags & VIA_BAD_ID), via_config->id, NULL))) { @@ -256,6 +256,7 @@ static struct via_isa_bridge *via_config_find(struct pci_dev **isa) if (t >= via_config->rev_min && t <= via_config->rev_max) break; + pci_dev_put(*isa); } return via_config; @@ -281,10 +282,11 @@ static unsigned int __devinit init_chipset_via82cxxx(struct pci_dev *dev, const * Find the ISA bridge to see how good the IDE is. */ via_config = via_config_find(&isa); - if (!via_config->id) { - printk(KERN_WARNING "VP_IDE: Unknown VIA SouthBridge, disabling DMA.\n"); - return -ENODEV; - } + + /* We checked this earlier so if it fails here deeep badness + is involved */ + + BUG_ON(!via_config->id); /* * Setup or disable Clk66 if appropriate @@ -361,6 +363,7 @@ static unsigned int __devinit init_chipset_via82cxxx(struct pci_dev *dev, const via_dma[via_config->flags & VIA_UDMA], pci_name(dev)); + pci_dev_put(isa); return 0; } @@ -439,7 +442,7 @@ static void __devinit init_hwif_via82cxxx(ide_hwif_t *hwif) hwif->speedproc = &via_set_drive; -#if defined(CONFIG_PPC_CHRP) && defined(CONFIG_PPC32) +#ifdef CONFIG_PPC_CHRP if(machine_is(chrp) && _chrp_type == _CHRP_Pegasos) { hwif->irq = hwif->channel ? 15 : 14; } @@ -491,6 +494,17 @@ static ide_pci_device_t via82cxxx_chipsets[] __devinitdata = { static int __devinit via_init_one(struct pci_dev *dev, const struct pci_device_id *id) { + struct pci_dev *isa = NULL; + struct via_isa_bridge *via_config; + /* + * Find the ISA bridge and check we know what it is. + */ + via_config = via_config_find(&isa); + pci_dev_put(isa); + if (!via_config->id) { + printk(KERN_WARNING "VP_IDE: Unknown VIA SouthBridge, disabling DMA.\n"); + return -ENODEV; + } return ide_setup_pci_device(dev, &via82cxxx_chipsets[id->driver_data]); } diff --git a/drivers/ide/ppc/pmac.c b/drivers/ide/ppc/pmac.c index 31ad79f52df7..91c5344a945d 100644 --- a/drivers/ide/ppc/pmac.c +++ b/drivers/ide/ppc/pmac.c @@ -1,5 +1,5 @@ /* - * linux/drivers/ide/ide-pmac.c + * linux/drivers/ide/ppc/pmac.c * * Support for IDE interfaces on PowerMacs. * These IDE interfaces are memory-mapped and have a DBDMA channel diff --git a/drivers/ide/setup-pci.c b/drivers/ide/setup-pci.c index eb0945284acc..695e23904d30 100644 --- a/drivers/ide/setup-pci.c +++ b/drivers/ide/setup-pci.c @@ -101,7 +101,7 @@ static ide_hwif_t *ide_match_hwif(unsigned long io_base, u8 bootable, const char return hwif; /* pick an unused entry */ } } - for (h = 0; h < 2; ++h) { + for (h = 0; h < 2 && h < MAX_HWIFS; ++h) { hwif = ide_hwifs + h; if (hwif->chipset == ide_unknown) return hwif; /* pick an unused entry */ @@ -795,24 +795,6 @@ int __ide_pci_register_driver(struct pci_driver *driver, struct module *module) EXPORT_SYMBOL_GPL(__ide_pci_register_driver); /** - * ide_unregister_pci_driver - unregister an IDE driver - * @driver: driver to remove - * - * Unregister a currently installed IDE driver. Returns are the same - * as for pci_unregister_driver - */ - -void ide_pci_unregister_driver(struct pci_driver *driver) -{ - if(!pre_init) - pci_unregister_driver(driver); - else - list_del(&driver->node); -} - -EXPORT_SYMBOL_GPL(ide_pci_unregister_driver); - -/** * ide_scan_pcidev - find an IDE driver for a device * @dev: PCI device to check * @@ -862,11 +844,11 @@ void __init ide_scan_pcibus (int scan_direction) pre_init = 0; if (!scan_direction) { - while ((dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) { + while ((dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) { ide_scan_pcidev(dev); } } else { - while ((dev = pci_find_device_reverse(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) { + while ((dev = pci_get_device_reverse(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) { ide_scan_pcidev(dev); } } |