From ad72cf9885c536e3adae03f8337557ac9dd1e4bb Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Fri, 2 Jul 2010 10:03:52 +0200 Subject: libata: take advantage of cmwq and remove concurrency limitations libata has two concurrency related limitations. a. ata_wq which is used for polling PIO has single thread per CPU. If there are multiple devices doing polling PIO on the same CPU, they can't be executed simultaneously. b. ata_aux_wq which is used for SCSI probing has single thread. In cases where SCSI probing is stalled for extended period of time which is possible for ATAPI devices, this will stall all probing. #a is solved by increasing maximum concurrency of ata_wq. Please note that polling PIO might be used under allocation path and thus needs to be served by a separate wq with a rescuer. #b is solved by using the default wq instead and achieving exclusion via per-port mutex. Signed-off-by: Tejun Heo Acked-by: Jeff Garzik --- drivers/ata/libata-core.c | 20 +++++--------------- drivers/ata/libata-eh.c | 4 ++-- drivers/ata/libata-scsi.c | 10 ++++++---- drivers/ata/libata-sff.c | 9 +-------- drivers/ata/libata.h | 1 - 5 files changed, 14 insertions(+), 30 deletions(-) (limited to 'drivers/ata') diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index ddf8e4862787..4f78741692dc 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c @@ -98,8 +98,6 @@ static unsigned long ata_dev_blacklisted(const struct ata_device *dev); unsigned int ata_print_id = 1; -struct workqueue_struct *ata_aux_wq; - struct ata_force_param { const char *name; unsigned int cbl; @@ -5611,6 +5609,7 @@ struct ata_port *ata_port_alloc(struct ata_host *host) ap->msg_enable = ATA_MSG_DRV | ATA_MSG_ERR | ATA_MSG_WARN; #endif + mutex_init(&ap->scsi_scan_mutex); INIT_DELAYED_WORK(&ap->hotplug_task, ata_scsi_hotplug); INIT_WORK(&ap->scsi_rescan_task, ata_scsi_dev_rescan); INIT_LIST_HEAD(&ap->eh_done_q); @@ -6549,29 +6548,20 @@ static int __init ata_init(void) ata_parse_force_param(); - ata_aux_wq = create_singlethread_workqueue("ata_aux"); - if (!ata_aux_wq) - goto fail; - rc = ata_sff_init(); - if (rc) - goto fail; + if (rc) { + kfree(ata_force_tbl); + return rc; + } printk(KERN_DEBUG "libata version " DRV_VERSION " loaded.\n"); return 0; - -fail: - kfree(ata_force_tbl); - if (ata_aux_wq) - destroy_workqueue(ata_aux_wq); - return rc; } static void __exit ata_exit(void) { ata_sff_exit(); kfree(ata_force_tbl); - destroy_workqueue(ata_aux_wq); } subsys_initcall(ata_init); diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c index f77a67303f8b..4d2af824dd23 100644 --- a/drivers/ata/libata-eh.c +++ b/drivers/ata/libata-eh.c @@ -727,7 +727,7 @@ void ata_scsi_error(struct Scsi_Host *host) if (ap->pflags & ATA_PFLAG_LOADING) ap->pflags &= ~ATA_PFLAG_LOADING; else if (ap->pflags & ATA_PFLAG_SCSI_HOTPLUG) - queue_delayed_work(ata_aux_wq, &ap->hotplug_task, 0); + schedule_delayed_work(&ap->hotplug_task, 0); if (ap->pflags & ATA_PFLAG_RECOVERED) ata_port_printk(ap, KERN_INFO, "EH complete\n"); @@ -2944,7 +2944,7 @@ static int ata_eh_revalidate_and_attach(struct ata_link *link, ehc->i.flags |= ATA_EHI_SETMODE; /* schedule the scsi_rescan_device() here */ - queue_work(ata_aux_wq, &(ap->scsi_rescan_task)); + schedule_work(&(ap->scsi_rescan_task)); } else if (dev->class == ATA_DEV_UNKNOWN && ehc->tries[dev->devno] && ata_class_enabled(ehc->classes[dev->devno])) { diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c index a54273d2c3c6..d75c9c479d1a 100644 --- a/drivers/ata/libata-scsi.c +++ b/drivers/ata/libata-scsi.c @@ -3435,7 +3435,7 @@ void ata_scsi_scan_host(struct ata_port *ap, int sync) " switching to async\n"); } - queue_delayed_work(ata_aux_wq, &ap->hotplug_task, + queue_delayed_work(system_long_wq, &ap->hotplug_task, round_jiffies_relative(HZ)); } @@ -3582,6 +3582,7 @@ void ata_scsi_hotplug(struct work_struct *work) } DPRINTK("ENTER\n"); + mutex_lock(&ap->scsi_scan_mutex); /* Unplug detached devices. We cannot use link iterator here * because PMP links have to be scanned even if PMP is @@ -3595,6 +3596,7 @@ void ata_scsi_hotplug(struct work_struct *work) /* scan for new ones */ ata_scsi_scan_host(ap, 0); + mutex_unlock(&ap->scsi_scan_mutex); DPRINTK("EXIT\n"); } @@ -3673,9 +3675,7 @@ static int ata_scsi_user_scan(struct Scsi_Host *shost, unsigned int channel, * @work: Pointer to ATA port to perform scsi_rescan_device() * * After ATA pass thru (SAT) commands are executed successfully, - * libata need to propagate the changes to SCSI layer. This - * function must be executed from ata_aux_wq such that sdev - * attach/detach don't race with rescan. + * libata need to propagate the changes to SCSI layer. * * LOCKING: * Kernel thread context (may sleep). @@ -3688,6 +3688,7 @@ void ata_scsi_dev_rescan(struct work_struct *work) struct ata_device *dev; unsigned long flags; + mutex_lock(&ap->scsi_scan_mutex); spin_lock_irqsave(ap->lock, flags); ata_for_each_link(link, ap, EDGE) { @@ -3707,6 +3708,7 @@ void ata_scsi_dev_rescan(struct work_struct *work) } spin_unlock_irqrestore(ap->lock, flags); + mutex_unlock(&ap->scsi_scan_mutex); } /** diff --git a/drivers/ata/libata-sff.c b/drivers/ata/libata-sff.c index efa4a18cfb9d..674c1436491f 100644 --- a/drivers/ata/libata-sff.c +++ b/drivers/ata/libata-sff.c @@ -3318,14 +3318,7 @@ void ata_sff_port_init(struct ata_port *ap) int __init ata_sff_init(void) { - /* - * FIXME: In UP case, there is only one workqueue thread and if you - * have more than one PIO device, latency is bloody awful, with - * occasional multi-second "hiccups" as one PIO device waits for - * another. It's an ugly wart that users DO occasionally complain - * about; luckily most users have at most one PIO polled device. - */ - ata_sff_wq = create_workqueue("ata_sff"); + ata_sff_wq = alloc_workqueue("ata_sff", WQ_RESCUER, WQ_MAX_ACTIVE); if (!ata_sff_wq) return -ENOMEM; diff --git a/drivers/ata/libata.h b/drivers/ata/libata.h index 4b84ed60324a..9ce1ecc63e39 100644 --- a/drivers/ata/libata.h +++ b/drivers/ata/libata.h @@ -54,7 +54,6 @@ enum { }; extern unsigned int ata_print_id; -extern struct workqueue_struct *ata_aux_wq; extern int atapi_passthru16; extern int libata_fua; extern int libata_noacpi; -- cgit v1.2.3 From ac8b422838046ffc26be4874a3cbae0d313f4209 Mon Sep 17 00:00:00 2001 From: Dominik Brodowski Date: Wed, 21 Jul 2010 22:38:13 +0200 Subject: pcmcia: remove cs_types.h Remove cs_types.h which is no longer needed: Most definitions aren't used at all, a few can be made away with, and two remaining definitions (typedefs, unfortunatley) may be moved to more specific places. CC: linux-ide@vger.kernel.org CC: linux-usb@vger.kernel.org CC: laforge@gnumonks.org CC: linux-mtd@lists.infradead.org CC: alsa-devel@alsa-project.org CC: linux-serial@vger.kernel.org Acked-by: Marcel Holtmann (for drivers/bluetooth/) Acked-by: David S. Miller Signed-off-by: Dominik Brodowski --- Documentation/pcmcia/driver-changes.txt | 5 +++ drivers/ata/pata_pcmcia.c | 1 - drivers/bluetooth/bluecard_cs.c | 1 - drivers/bluetooth/bt3c_cs.c | 1 - drivers/bluetooth/btuart_cs.c | 1 - drivers/bluetooth/dtl1_cs.c | 1 - drivers/char/pcmcia/cm4000_cs.c | 1 - drivers/char/pcmcia/cm4040_cs.c | 1 - drivers/char/pcmcia/ipwireless/main.h | 1 - drivers/char/pcmcia/ipwireless/tty.h | 1 - drivers/char/pcmcia/synclink_cs.c | 1 - drivers/ide/ide-cs.c | 1 - drivers/isdn/hardware/avm/avm_cs.c | 1 - drivers/isdn/hisax/avma1_cs.c | 1 - drivers/isdn/hisax/elsa_cs.c | 1 - drivers/isdn/hisax/sedlbauer_cs.c | 1 - drivers/isdn/hisax/teles_cs.c | 1 - drivers/mmc/host/sdricoh_cs.c | 1 - drivers/mtd/maps/pcmciamtd.c | 1 - drivers/net/pcmcia/3c574_cs.c | 1 - drivers/net/pcmcia/3c589_cs.c | 1 - drivers/net/pcmcia/axnet_cs.c | 1 - drivers/net/pcmcia/com20020_cs.c | 1 - drivers/net/pcmcia/fmvj18x_cs.c | 1 - drivers/net/pcmcia/ibmtr_cs.c | 1 - drivers/net/pcmcia/nmclan_cs.c | 1 - drivers/net/pcmcia/pcnet_cs.c | 5 +-- drivers/net/pcmcia/smc91c92_cs.c | 1 - drivers/net/pcmcia/xirc2ps_cs.c | 1 - drivers/net/wireless/airo_cs.c | 1 - drivers/net/wireless/atmel_cs.c | 1 - drivers/net/wireless/b43/pcmcia.c | 1 - drivers/net/wireless/hostap/hostap_cs.c | 3 +- drivers/net/wireless/libertas/if_cs.c | 1 - drivers/net/wireless/orinoco/orinoco_cs.c | 1 - drivers/net/wireless/orinoco/spectrum_cs.c | 1 - drivers/net/wireless/ray_cs.c | 1 - drivers/net/wireless/wl3501_cs.c | 10 +----- drivers/parport/parport_cs.c | 1 - drivers/pcmcia/au1000_generic.h | 1 - drivers/pcmcia/au1000_pb1x00.c | 2 -- drivers/pcmcia/cistpl.c | 1 - drivers/pcmcia/cs.c | 1 - drivers/pcmcia/db1xxx_ss.c | 1 - drivers/pcmcia/ds.c | 1 - drivers/pcmcia/i82092.c | 1 - drivers/pcmcia/i82365.c | 1 - drivers/pcmcia/m32r_cfc.c | 1 - drivers/pcmcia/m32r_pcc.c | 1 - drivers/pcmcia/m8xx_pcmcia.c | 1 - drivers/pcmcia/pcmcia_cis.c | 1 - drivers/pcmcia/pcmcia_resource.c | 1 - drivers/pcmcia/pd6729.c | 1 - drivers/pcmcia/pxa2xx_base.c | 1 - drivers/pcmcia/rsrc_iodyn.c | 1 - drivers/pcmcia/rsrc_mgr.c | 1 - drivers/pcmcia/rsrc_nonstatic.c | 1 - drivers/pcmcia/sa1100_generic.c | 1 - drivers/pcmcia/soc_common.h | 1 - drivers/pcmcia/socket_sysfs.c | 1 - drivers/pcmcia/tcic.c | 1 - drivers/pcmcia/xxs1500_ss.c | 1 - drivers/pcmcia/yenta_socket.c | 1 - drivers/scsi/pcmcia/aha152x_stub.c | 1 - drivers/scsi/pcmcia/fdomain_stub.c | 1 - drivers/scsi/pcmcia/nsp_cs.c | 1 - drivers/scsi/pcmcia/qlogic_stub.c | 1 - drivers/scsi/pcmcia/sym53c500_cs.c | 1 - drivers/serial/serial_cs.c | 1 - drivers/ssb/main.c | 1 - drivers/ssb/pcmcia.c | 1 - drivers/ssb/scan.c | 1 - drivers/staging/comedi/drivers/cb_das16_cs.c | 1 - drivers/staging/comedi/drivers/das08_cs.c | 1 - drivers/staging/comedi/drivers/ni_daq_700.c | 1 - drivers/staging/comedi/drivers/ni_daq_dio24.c | 1 - drivers/staging/comedi/drivers/ni_labpc_cs.c | 1 - drivers/staging/comedi/drivers/ni_mio_cs.c | 1 - drivers/staging/comedi/drivers/quatech_daqp_cs.c | 1 - drivers/staging/wlags49_h2/wl_cs.c | 1 - drivers/staging/wlags49_h2/wl_internal.h | 1 - drivers/telephony/ixj_pcmcia.c | 1 - drivers/usb/host/sl811_cs.c | 5 +-- include/pcmcia/cistpl.h | 2 ++ include/pcmcia/cs.h | 10 +----- include/pcmcia/cs_types.h | 40 ------------------------ include/pcmcia/ds.h | 3 +- include/pcmcia/ss.h | 1 - sound/pcmcia/pdaudiocf/pdaudiocf.h | 1 - sound/pcmcia/vx/vxpocket.h | 1 - 90 files changed, 14 insertions(+), 151 deletions(-) delete mode 100644 include/pcmcia/cs_types.h (limited to 'drivers/ata') diff --git a/Documentation/pcmcia/driver-changes.txt b/Documentation/pcmcia/driver-changes.txt index 61bc4e943116..ff5f0be2470a 100644 --- a/Documentation/pcmcia/driver-changes.txt +++ b/Documentation/pcmcia/driver-changes.txt @@ -1,4 +1,9 @@ This file details changes in 2.6 which affect PCMCIA card driver authors: +* No dev_info_t, no cs_types.h (as of 2.6.36) + dev_info_t and a few other typedefs are removed. No longer use them + in PCMCIA device drivers. Also, do not include pcmcia/cs_types.h, as + this file is gone. + * No dev_node_t (as of 2.6.35) There is no more need to fill out a "dev_node_t" structure. diff --git a/drivers/ata/pata_pcmcia.c b/drivers/ata/pata_pcmcia.c index 118c28e8abaf..3dcb2b1b60e9 100644 --- a/drivers/ata/pata_pcmcia.c +++ b/drivers/ata/pata_pcmcia.c @@ -34,7 +34,6 @@ #include #include -#include #include #include #include diff --git a/drivers/bluetooth/bluecard_cs.c b/drivers/bluetooth/bluecard_cs.c index 6d34f405a2f3..eb085de16713 100644 --- a/drivers/bluetooth/bluecard_cs.c +++ b/drivers/bluetooth/bluecard_cs.c @@ -39,7 +39,6 @@ #include #include -#include #include #include #include diff --git a/drivers/bluetooth/bt3c_cs.c b/drivers/bluetooth/bt3c_cs.c index 21e05fdc9121..457b603f8678 100644 --- a/drivers/bluetooth/bt3c_cs.c +++ b/drivers/bluetooth/bt3c_cs.c @@ -45,7 +45,6 @@ #include #include -#include #include #include #include diff --git a/drivers/bluetooth/btuart_cs.c b/drivers/bluetooth/btuart_cs.c index 4ed7288f99db..e7e0a17aecc2 100644 --- a/drivers/bluetooth/btuart_cs.c +++ b/drivers/bluetooth/btuart_cs.c @@ -41,7 +41,6 @@ #include #include -#include #include #include #include diff --git a/drivers/bluetooth/dtl1_cs.c b/drivers/bluetooth/dtl1_cs.c index ef044d55cb25..7c94aad0b791 100644 --- a/drivers/bluetooth/dtl1_cs.c +++ b/drivers/bluetooth/dtl1_cs.c @@ -41,7 +41,6 @@ #include #include -#include #include #include #include diff --git a/drivers/char/pcmcia/cm4000_cs.c b/drivers/char/pcmcia/cm4000_cs.c index e7956acf2ad6..a8be2a7906e0 100644 --- a/drivers/char/pcmcia/cm4000_cs.c +++ b/drivers/char/pcmcia/cm4000_cs.c @@ -34,7 +34,6 @@ #include #include -#include #include #include #include diff --git a/drivers/char/pcmcia/cm4040_cs.c b/drivers/char/pcmcia/cm4040_cs.c index c0775c844e08..44adae98c576 100644 --- a/drivers/char/pcmcia/cm4040_cs.c +++ b/drivers/char/pcmcia/cm4040_cs.c @@ -29,7 +29,6 @@ #include #include -#include #include #include #include diff --git a/drivers/char/pcmcia/ipwireless/main.h b/drivers/char/pcmcia/ipwireless/main.h index 96d0ef31b172..c207be87b597 100644 --- a/drivers/char/pcmcia/ipwireless/main.h +++ b/drivers/char/pcmcia/ipwireless/main.h @@ -21,7 +21,6 @@ #include #include -#include #include #include #include diff --git a/drivers/char/pcmcia/ipwireless/tty.h b/drivers/char/pcmcia/ipwireless/tty.h index 4da6c201f727..3e163d4cab15 100644 --- a/drivers/char/pcmcia/ipwireless/tty.h +++ b/drivers/char/pcmcia/ipwireless/tty.h @@ -21,7 +21,6 @@ #include #include -#include #include #include #include diff --git a/drivers/char/pcmcia/synclink_cs.c b/drivers/char/pcmcia/synclink_cs.c index 308903ec8bf8..522992ed6e49 100644 --- a/drivers/char/pcmcia/synclink_cs.c +++ b/drivers/char/pcmcia/synclink_cs.c @@ -70,7 +70,6 @@ #include #include -#include #include #include #include diff --git a/drivers/ide/ide-cs.c b/drivers/ide/ide-cs.c index 0b7815d2581c..27dbab84142c 100644 --- a/drivers/ide/ide-cs.c +++ b/drivers/ide/ide-cs.c @@ -43,7 +43,6 @@ #include #include -#include #include #include #include diff --git a/drivers/isdn/hardware/avm/avm_cs.c b/drivers/isdn/hardware/avm/avm_cs.c index f410d0eb2fef..e804a01ecdfb 100644 --- a/drivers/isdn/hardware/avm/avm_cs.c +++ b/drivers/isdn/hardware/avm/avm_cs.c @@ -20,7 +20,6 @@ #include #include -#include #include #include #include diff --git a/drivers/isdn/hisax/avma1_cs.c b/drivers/isdn/hisax/avma1_cs.c index a80a7617f16f..49e141e49aaf 100644 --- a/drivers/isdn/hisax/avma1_cs.c +++ b/drivers/isdn/hisax/avma1_cs.c @@ -20,7 +20,6 @@ #include #include -#include #include #include #include diff --git a/drivers/isdn/hisax/elsa_cs.c b/drivers/isdn/hisax/elsa_cs.c index 218927e3a4ea..425deea1dd69 100644 --- a/drivers/isdn/hisax/elsa_cs.c +++ b/drivers/isdn/hisax/elsa_cs.c @@ -46,7 +46,6 @@ #include #include -#include #include #include #include diff --git a/drivers/isdn/hisax/sedlbauer_cs.c b/drivers/isdn/hisax/sedlbauer_cs.c index 1f4feaab21af..5dbad966a29e 100644 --- a/drivers/isdn/hisax/sedlbauer_cs.c +++ b/drivers/isdn/hisax/sedlbauer_cs.c @@ -46,7 +46,6 @@ #include #include -#include #include #include #include diff --git a/drivers/isdn/hisax/teles_cs.c b/drivers/isdn/hisax/teles_cs.c index 5771955cc532..d3fb1b716800 100644 --- a/drivers/isdn/hisax/teles_cs.c +++ b/drivers/isdn/hisax/teles_cs.c @@ -27,7 +27,6 @@ #include #include -#include #include #include #include diff --git a/drivers/mmc/host/sdricoh_cs.c b/drivers/mmc/host/sdricoh_cs.c index e7507af3856e..7aa65bb2af4a 100644 --- a/drivers/mmc/host/sdricoh_cs.c +++ b/drivers/mmc/host/sdricoh_cs.c @@ -30,7 +30,6 @@ #include #include -#include #include #include #include diff --git a/drivers/mtd/maps/pcmciamtd.c b/drivers/mtd/maps/pcmciamtd.c index e699e6ac23df..79488164e432 100644 --- a/drivers/mtd/maps/pcmciamtd.c +++ b/drivers/mtd/maps/pcmciamtd.c @@ -16,7 +16,6 @@ #include #include -#include #include #include #include diff --git a/drivers/net/pcmcia/3c574_cs.c b/drivers/net/pcmcia/3c574_cs.c index 10ee106a1617..e249b898075c 100644 --- a/drivers/net/pcmcia/3c574_cs.c +++ b/drivers/net/pcmcia/3c574_cs.c @@ -87,7 +87,6 @@ earlier 3Com products. #include #include -#include #include #include #include diff --git a/drivers/net/pcmcia/3c589_cs.c b/drivers/net/pcmcia/3c589_cs.c index ce63c3773b4c..b0772df31057 100644 --- a/drivers/net/pcmcia/3c589_cs.c +++ b/drivers/net/pcmcia/3c589_cs.c @@ -41,7 +41,6 @@ #include #include -#include #include #include #include diff --git a/drivers/net/pcmcia/axnet_cs.c b/drivers/net/pcmcia/axnet_cs.c index 33525bf2a3d3..467fd4bfb2bd 100644 --- a/drivers/net/pcmcia/axnet_cs.c +++ b/drivers/net/pcmcia/axnet_cs.c @@ -39,7 +39,6 @@ #include #include "../8390.h" -#include #include #include #include diff --git a/drivers/net/pcmcia/com20020_cs.c b/drivers/net/pcmcia/com20020_cs.c index 5643f94541bc..99957af40329 100644 --- a/drivers/net/pcmcia/com20020_cs.c +++ b/drivers/net/pcmcia/com20020_cs.c @@ -43,7 +43,6 @@ #include #include -#include #include #include #include diff --git a/drivers/net/pcmcia/fmvj18x_cs.c b/drivers/net/pcmcia/fmvj18x_cs.c index 7c27c50211a5..95a991beaa30 100644 --- a/drivers/net/pcmcia/fmvj18x_cs.c +++ b/drivers/net/pcmcia/fmvj18x_cs.c @@ -49,7 +49,6 @@ #include #include -#include #include #include #include diff --git a/drivers/net/pcmcia/ibmtr_cs.c b/drivers/net/pcmcia/ibmtr_cs.c index 67ee9851a8ed..c36dcd14ec45 100644 --- a/drivers/net/pcmcia/ibmtr_cs.c +++ b/drivers/net/pcmcia/ibmtr_cs.c @@ -57,7 +57,6 @@ #include #include -#include #include #include #include diff --git a/drivers/net/pcmcia/nmclan_cs.c b/drivers/net/pcmcia/nmclan_cs.c index 9b63dec549cb..c0eacfae1512 100644 --- a/drivers/net/pcmcia/nmclan_cs.c +++ b/drivers/net/pcmcia/nmclan_cs.c @@ -146,7 +146,6 @@ Include Files #include #include -#include #include #include #include diff --git a/drivers/net/pcmcia/pcnet_cs.c b/drivers/net/pcmcia/pcnet_cs.c index bfdef72c5d5e..db6dbdabb702 100644 --- a/drivers/net/pcmcia/pcnet_cs.c +++ b/drivers/net/pcmcia/pcnet_cs.c @@ -42,7 +42,6 @@ #include #include "../8390.h" -#include #include #include #include @@ -113,8 +112,6 @@ static int setup_dma_config(struct pcmcia_device *link, int start_pg, static void pcnet_detach(struct pcmcia_device *p_dev); -static dev_info_t dev_info = "pcnet_cs"; - /*====================================================================*/ typedef struct hw_info_t { @@ -956,7 +953,7 @@ static int pcnet_open(struct net_device *dev) set_misc_reg(dev); outb_p(0xFF, nic_base + EN0_ISR); /* Clear bogus intr. */ - ret = request_irq(dev->irq, ei_irq_wrapper, IRQF_SHARED, dev_info, dev); + ret = request_irq(dev->irq, ei_irq_wrapper, IRQF_SHARED, dev->name, dev); if (ret) return ret; diff --git a/drivers/net/pcmcia/smc91c92_cs.c b/drivers/net/pcmcia/smc91c92_cs.c index 307cd1721e91..88f503a80a8e 100644 --- a/drivers/net/pcmcia/smc91c92_cs.c +++ b/drivers/net/pcmcia/smc91c92_cs.c @@ -44,7 +44,6 @@ #include #include -#include #include #include #include diff --git a/drivers/net/pcmcia/xirc2ps_cs.c b/drivers/net/pcmcia/xirc2ps_cs.c index b6c3644888cd..a7662f0832eb 100644 --- a/drivers/net/pcmcia/xirc2ps_cs.c +++ b/drivers/net/pcmcia/xirc2ps_cs.c @@ -82,7 +82,6 @@ #include #include -#include #include #include #include diff --git a/drivers/net/wireless/airo_cs.c b/drivers/net/wireless/airo_cs.c index 33bdc6a84e81..9389ba004fb9 100644 --- a/drivers/net/wireless/airo_cs.c +++ b/drivers/net/wireless/airo_cs.c @@ -32,7 +32,6 @@ #include #include -#include #include #include #include diff --git a/drivers/net/wireless/atmel_cs.c b/drivers/net/wireless/atmel_cs.c index c2746fc7f2be..91ee74a8801e 100644 --- a/drivers/net/wireless/atmel_cs.c +++ b/drivers/net/wireless/atmel_cs.c @@ -42,7 +42,6 @@ #include #include -#include #include #include #include diff --git a/drivers/net/wireless/b43/pcmcia.c b/drivers/net/wireless/b43/pcmcia.c index 0e99b634267c..f71bc7821378 100644 --- a/drivers/net/wireless/b43/pcmcia.c +++ b/drivers/net/wireless/b43/pcmcia.c @@ -26,7 +26,6 @@ #include #include -#include #include #include #include diff --git a/drivers/net/wireless/hostap/hostap_cs.c b/drivers/net/wireless/hostap/hostap_cs.c index 29b31a694b59..2f4b6d4350ab 100644 --- a/drivers/net/wireless/hostap/hostap_cs.c +++ b/drivers/net/wireless/hostap/hostap_cs.c @@ -12,7 +12,6 @@ #include #include -#include #include #include #include @@ -23,7 +22,7 @@ #include "hostap_wlan.h" -static dev_info_t dev_info = "hostap_cs"; +static char *dev_info = "hostap_cs"; MODULE_AUTHOR("Jouni Malinen"); MODULE_DESCRIPTION("Support for Intersil Prism2-based 802.11 wireless LAN " diff --git a/drivers/net/wireless/libertas/if_cs.c b/drivers/net/wireless/libertas/if_cs.c index 08e4e3908003..1d3a7e0e5f10 100644 --- a/drivers/net/wireless/libertas/if_cs.c +++ b/drivers/net/wireless/libertas/if_cs.c @@ -28,7 +28,6 @@ #include #include -#include #include #include #include diff --git a/drivers/net/wireless/orinoco/orinoco_cs.c b/drivers/net/wireless/orinoco/orinoco_cs.c index b16d5db52a4d..41ca4f1b395f 100644 --- a/drivers/net/wireless/orinoco/orinoco_cs.c +++ b/drivers/net/wireless/orinoco/orinoco_cs.c @@ -17,7 +17,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/net/wireless/orinoco/spectrum_cs.c b/drivers/net/wireless/orinoco/spectrum_cs.c index b51a9adc80f6..cad30e499dba 100644 --- a/drivers/net/wireless/orinoco/spectrum_cs.c +++ b/drivers/net/wireless/orinoco/spectrum_cs.c @@ -25,7 +25,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/net/wireless/ray_cs.c b/drivers/net/wireless/ray_cs.c index abff8934db13..165beb6af849 100644 --- a/drivers/net/wireless/ray_cs.c +++ b/drivers/net/wireless/ray_cs.c @@ -46,7 +46,6 @@ #include #include -#include #include #include #include diff --git a/drivers/net/wireless/wl3501_cs.c b/drivers/net/wireless/wl3501_cs.c index 376c6b964a9c..35f431bf97d6 100644 --- a/drivers/net/wireless/wl3501_cs.c +++ b/drivers/net/wireless/wl3501_cs.c @@ -48,7 +48,6 @@ #include -#include #include #include #include @@ -89,13 +88,6 @@ static int wl3501_config(struct pcmcia_device *link); static void wl3501_release(struct pcmcia_device *link); -/* - * The dev_info variable is the "key" that is used to match up this - * device driver with appropriate cards, through the card configuration - * database. - */ -static dev_info_t wl3501_dev_info = "wl3501_cs"; - static const struct { int reg_domain; int min, max, deflt; @@ -1421,7 +1413,7 @@ static struct iw_statistics *wl3501_get_wireless_stats(struct net_device *dev) static void wl3501_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info) { - strlcpy(info->driver, wl3501_dev_info, sizeof(info->driver)); + strlcpy(info->driver, "wl3501_cs", sizeof(info->driver)); } static const struct ethtool_ops ops = { diff --git a/drivers/parport/parport_cs.c b/drivers/parport/parport_cs.c index fd8cfe95f0a3..ee56fd66d5dc 100644 --- a/drivers/parport/parport_cs.c +++ b/drivers/parport/parport_cs.c @@ -48,7 +48,6 @@ #include #include -#include #include #include #include diff --git a/drivers/pcmcia/au1000_generic.h b/drivers/pcmcia/au1000_generic.h index a324d329dea6..67530cefcf3c 100644 --- a/drivers/pcmcia/au1000_generic.h +++ b/drivers/pcmcia/au1000_generic.h @@ -23,7 +23,6 @@ /* include the world */ -#include #include #include #include diff --git a/drivers/pcmcia/au1000_pb1x00.c b/drivers/pcmcia/au1000_pb1x00.c index 5a979cb8f3e6..807f2d75dad3 100644 --- a/drivers/pcmcia/au1000_pb1x00.c +++ b/drivers/pcmcia/au1000_pb1x00.c @@ -31,11 +31,9 @@ #include #include -#include #include #include #include -#include #include #include diff --git a/drivers/pcmcia/cistpl.c b/drivers/pcmcia/cistpl.c index 8844bc3e3118..ba4a5acc2e9a 100644 --- a/drivers/pcmcia/cistpl.c +++ b/drivers/pcmcia/cistpl.c @@ -27,7 +27,6 @@ #include #include -#include #include #include #include diff --git a/drivers/pcmcia/cs.c b/drivers/pcmcia/cs.c index efa30b84a75a..2ec8ac97445c 100644 --- a/drivers/pcmcia/cs.c +++ b/drivers/pcmcia/cs.c @@ -32,7 +32,6 @@ #include #include -#include #include #include #include diff --git a/drivers/pcmcia/db1xxx_ss.c b/drivers/pcmcia/db1xxx_ss.c index 0f4cc3f00028..27575e6378a1 100644 --- a/drivers/pcmcia/db1xxx_ss.c +++ b/drivers/pcmcia/db1xxx_ss.c @@ -29,7 +29,6 @@ #include #include -#include #include #include diff --git a/drivers/pcmcia/ds.c b/drivers/pcmcia/ds.c index 08617719d3a1..bacfc55f2026 100644 --- a/drivers/pcmcia/ds.c +++ b/drivers/pcmcia/ds.c @@ -26,7 +26,6 @@ #include #include -#include #include #include #include diff --git a/drivers/pcmcia/i82092.c b/drivers/pcmcia/i82092.c index 3003bb3dfcc0..05d0879ce935 100644 --- a/drivers/pcmcia/i82092.c +++ b/drivers/pcmcia/i82092.c @@ -15,7 +15,6 @@ #include #include -#include #include #include diff --git a/drivers/pcmcia/i82365.c b/drivers/pcmcia/i82365.c index 9e2a15628de5..61746bd598b3 100644 --- a/drivers/pcmcia/i82365.c +++ b/drivers/pcmcia/i82365.c @@ -50,7 +50,6 @@ #include #include -#include #include #include diff --git a/drivers/pcmcia/m32r_cfc.c b/drivers/pcmcia/m32r_cfc.c index 7e16ed8eb0a4..24de49925863 100644 --- a/drivers/pcmcia/m32r_cfc.c +++ b/drivers/pcmcia/m32r_cfc.c @@ -26,7 +26,6 @@ #include #include -#include #include #include diff --git a/drivers/pcmcia/m32r_pcc.c b/drivers/pcmcia/m32r_pcc.c index 6c5c3f910d71..8e4723844ad3 100644 --- a/drivers/pcmcia/m32r_pcc.c +++ b/drivers/pcmcia/m32r_pcc.c @@ -27,7 +27,6 @@ #include #include -#include #include #include diff --git a/drivers/pcmcia/m8xx_pcmcia.c b/drivers/pcmcia/m8xx_pcmcia.c index 25e5e30a18af..f2f90a7d3e12 100644 --- a/drivers/pcmcia/m8xx_pcmcia.c +++ b/drivers/pcmcia/m8xx_pcmcia.c @@ -59,7 +59,6 @@ #include #include -#include #include #include diff --git a/drivers/pcmcia/pcmcia_cis.c b/drivers/pcmcia/pcmcia_cis.c index 4a65eaf96b0a..0ac54da15885 100644 --- a/drivers/pcmcia/pcmcia_cis.c +++ b/drivers/pcmcia/pcmcia_cis.c @@ -19,7 +19,6 @@ #include #include -#include #include #include #include diff --git a/drivers/pcmcia/pcmcia_resource.c b/drivers/pcmcia/pcmcia_resource.c index a4cd9adfcbc0..2394de468602 100644 --- a/drivers/pcmcia/pcmcia_resource.c +++ b/drivers/pcmcia/pcmcia_resource.c @@ -25,7 +25,6 @@ #include -#include #include #include #include diff --git a/drivers/pcmcia/pd6729.c b/drivers/pcmcia/pd6729.c index b61a13663a0a..b8a869af0f44 100644 --- a/drivers/pcmcia/pd6729.c +++ b/drivers/pcmcia/pd6729.c @@ -17,7 +17,6 @@ #include #include -#include #include #include diff --git a/drivers/pcmcia/pxa2xx_base.c b/drivers/pcmcia/pxa2xx_base.c index df4532e91b1a..66c022579d9b 100644 --- a/drivers/pcmcia/pxa2xx_base.c +++ b/drivers/pcmcia/pxa2xx_base.c @@ -32,7 +32,6 @@ #include #include -#include #include #include diff --git a/drivers/pcmcia/rsrc_iodyn.c b/drivers/pcmcia/rsrc_iodyn.c index 6ed7bf171ca3..3b1dce2df26a 100644 --- a/drivers/pcmcia/rsrc_iodyn.c +++ b/drivers/pcmcia/rsrc_iodyn.c @@ -16,7 +16,6 @@ #include #include -#include #include #include #include diff --git a/drivers/pcmcia/rsrc_mgr.c b/drivers/pcmcia/rsrc_mgr.c index b12ecf7c32bf..b433a7995651 100644 --- a/drivers/pcmcia/rsrc_mgr.c +++ b/drivers/pcmcia/rsrc_mgr.c @@ -16,7 +16,6 @@ #include #include -#include #include #include #include diff --git a/drivers/pcmcia/rsrc_nonstatic.c b/drivers/pcmcia/rsrc_nonstatic.c index 13245a2986f3..0cca08ff65a8 100644 --- a/drivers/pcmcia/rsrc_nonstatic.c +++ b/drivers/pcmcia/rsrc_nonstatic.c @@ -28,7 +28,6 @@ #include -#include #include #include #include diff --git a/drivers/pcmcia/sa1100_generic.c b/drivers/pcmcia/sa1100_generic.c index edbd8c472628..e09851480295 100644 --- a/drivers/pcmcia/sa1100_generic.c +++ b/drivers/pcmcia/sa1100_generic.c @@ -35,7 +35,6 @@ #include #include -#include #include #include diff --git a/drivers/pcmcia/soc_common.h b/drivers/pcmcia/soc_common.h index e40824ce6b0b..3fba3a679128 100644 --- a/drivers/pcmcia/soc_common.h +++ b/drivers/pcmcia/soc_common.h @@ -11,7 +11,6 @@ /* include the world */ #include -#include #include #include #include diff --git a/drivers/pcmcia/socket_sysfs.c b/drivers/pcmcia/socket_sysfs.c index 80e36bc407da..cb0d3ace18bd 100644 --- a/drivers/pcmcia/socket_sysfs.c +++ b/drivers/pcmcia/socket_sysfs.c @@ -26,7 +26,6 @@ #include #include -#include #include #include #include diff --git a/drivers/pcmcia/tcic.c b/drivers/pcmcia/tcic.c index 56004a1b5bba..be0d841c7ebd 100644 --- a/drivers/pcmcia/tcic.c +++ b/drivers/pcmcia/tcic.c @@ -49,7 +49,6 @@ #include #include -#include #include #include #include "tcic.h" diff --git a/drivers/pcmcia/xxs1500_ss.c b/drivers/pcmcia/xxs1500_ss.c index 201ccfa1e97b..fa88c360c37a 100644 --- a/drivers/pcmcia/xxs1500_ss.c +++ b/drivers/pcmcia/xxs1500_ss.c @@ -17,7 +17,6 @@ #include #include -#include #include #include #include diff --git a/drivers/pcmcia/yenta_socket.c b/drivers/pcmcia/yenta_socket.c index f1d41374eea7..414d9a6f9a32 100644 --- a/drivers/pcmcia/yenta_socket.c +++ b/drivers/pcmcia/yenta_socket.c @@ -19,7 +19,6 @@ #include #include -#include #include #include diff --git a/drivers/scsi/pcmcia/aha152x_stub.c b/drivers/scsi/pcmcia/aha152x_stub.c index 9d70aef99227..b07b53ef3c00 100644 --- a/drivers/scsi/pcmcia/aha152x_stub.c +++ b/drivers/scsi/pcmcia/aha152x_stub.c @@ -49,7 +49,6 @@ #include #include "aha152x.h" -#include #include #include #include diff --git a/drivers/scsi/pcmcia/fdomain_stub.c b/drivers/scsi/pcmcia/fdomain_stub.c index 21b141151dfc..ee0489762539 100644 --- a/drivers/scsi/pcmcia/fdomain_stub.c +++ b/drivers/scsi/pcmcia/fdomain_stub.c @@ -46,7 +46,6 @@ #include #include "fdomain.h" -#include #include #include #include diff --git a/drivers/scsi/pcmcia/nsp_cs.c b/drivers/scsi/pcmcia/nsp_cs.c index 0f0e112c3f8e..d4142075be21 100644 --- a/drivers/scsi/pcmcia/nsp_cs.c +++ b/drivers/scsi/pcmcia/nsp_cs.c @@ -47,7 +47,6 @@ #include #include -#include #include #include #include diff --git a/drivers/scsi/pcmcia/qlogic_stub.c b/drivers/scsi/pcmcia/qlogic_stub.c index f0fc6baed9fc..c1cf7f43313b 100644 --- a/drivers/scsi/pcmcia/qlogic_stub.c +++ b/drivers/scsi/pcmcia/qlogic_stub.c @@ -48,7 +48,6 @@ #include #include "../qlogicfas408.h" -#include #include #include #include diff --git a/drivers/scsi/pcmcia/sym53c500_cs.c b/drivers/scsi/pcmcia/sym53c500_cs.c index a51164171179..bd79e45ab856 100644 --- a/drivers/scsi/pcmcia/sym53c500_cs.c +++ b/drivers/scsi/pcmcia/sym53c500_cs.c @@ -71,7 +71,6 @@ #include #include -#include #include #include #include diff --git a/drivers/serial/serial_cs.c b/drivers/serial/serial_cs.c index ab17c08ddc03..2b99c7baf35b 100644 --- a/drivers/serial/serial_cs.c +++ b/drivers/serial/serial_cs.c @@ -45,7 +45,6 @@ #include #include -#include #include #include #include diff --git a/drivers/ssb/main.c b/drivers/ssb/main.c index 51275aac5b34..06f04b42cb23 100644 --- a/drivers/ssb/main.c +++ b/drivers/ssb/main.c @@ -20,7 +20,6 @@ #include #include -#include #include #include #include diff --git a/drivers/ssb/pcmcia.c b/drivers/ssb/pcmcia.c index e72f4046a5e0..21520308178b 100644 --- a/drivers/ssb/pcmcia.c +++ b/drivers/ssb/pcmcia.c @@ -13,7 +13,6 @@ #include #include -#include #include #include #include diff --git a/drivers/ssb/scan.c b/drivers/ssb/scan.c index 0d6c0280eb34..9738cad4ba13 100644 --- a/drivers/ssb/scan.c +++ b/drivers/ssb/scan.c @@ -17,7 +17,6 @@ #include #include -#include #include #include #include diff --git a/drivers/staging/comedi/drivers/cb_das16_cs.c b/drivers/staging/comedi/drivers/cb_das16_cs.c index cfeb11f443e3..acef29ca212b 100644 --- a/drivers/staging/comedi/drivers/cb_das16_cs.c +++ b/drivers/staging/comedi/drivers/cb_das16_cs.c @@ -37,7 +37,6 @@ Status: experimental #include #include -#include #include #include #include diff --git a/drivers/staging/comedi/drivers/das08_cs.c b/drivers/staging/comedi/drivers/das08_cs.c index 8761a6d285dc..3eddb7c4b1b0 100644 --- a/drivers/staging/comedi/drivers/das08_cs.c +++ b/drivers/staging/comedi/drivers/das08_cs.c @@ -48,7 +48,6 @@ Command support does not exist, but could be added for this board. #include "das08.h" /* pcmcia includes */ -#include #include #include #include diff --git a/drivers/staging/comedi/drivers/ni_daq_700.c b/drivers/staging/comedi/drivers/ni_daq_700.c index 6ec77bf88c63..f3c4d2f929f8 100644 --- a/drivers/staging/comedi/drivers/ni_daq_700.c +++ b/drivers/staging/comedi/drivers/ni_daq_700.c @@ -47,7 +47,6 @@ IRQ is assigned but not used. #include -#include #include #include #include diff --git a/drivers/staging/comedi/drivers/ni_daq_dio24.c b/drivers/staging/comedi/drivers/ni_daq_dio24.c index e4865b1c2310..f0c4367dc10b 100644 --- a/drivers/staging/comedi/drivers/ni_daq_dio24.c +++ b/drivers/staging/comedi/drivers/ni_daq_dio24.c @@ -48,7 +48,6 @@ the PCMCIA interface. #include "8255.h" -#include #include #include #include diff --git a/drivers/staging/comedi/drivers/ni_labpc_cs.c b/drivers/staging/comedi/drivers/ni_labpc_cs.c index 163245ebb311..1ee78f806ed2 100644 --- a/drivers/staging/comedi/drivers/ni_labpc_cs.c +++ b/drivers/staging/comedi/drivers/ni_labpc_cs.c @@ -71,7 +71,6 @@ NI manuals: #include "comedi_fc.h" #include "ni_labpc.h" -#include #include #include #include diff --git a/drivers/staging/comedi/drivers/ni_mio_cs.c b/drivers/staging/comedi/drivers/ni_mio_cs.c index 3a46f0c0bff9..0bce220c47b5 100644 --- a/drivers/staging/comedi/drivers/ni_mio_cs.c +++ b/drivers/staging/comedi/drivers/ni_mio_cs.c @@ -48,7 +48,6 @@ See the notes in the ni_atmio.o driver. #include "ni_stc.h" #include "8255.h" -#include #include #include #include diff --git a/drivers/staging/comedi/drivers/quatech_daqp_cs.c b/drivers/staging/comedi/drivers/quatech_daqp_cs.c index a91db6c42028..67c0fa6a2b06 100644 --- a/drivers/staging/comedi/drivers/quatech_daqp_cs.c +++ b/drivers/staging/comedi/drivers/quatech_daqp_cs.c @@ -50,7 +50,6 @@ Devices: [Quatech] DAQP-208 (daqp), DAQP-308 #include "../comedidev.h" #include -#include #include #include #include diff --git a/drivers/staging/wlags49_h2/wl_cs.c b/drivers/staging/wlags49_h2/wl_cs.c index 10abd406b09b..afe457541172 100644 --- a/drivers/staging/wlags49_h2/wl_cs.c +++ b/drivers/staging/wlags49_h2/wl_cs.c @@ -83,7 +83,6 @@ #include #include -#include #include #include #include diff --git a/drivers/staging/wlags49_h2/wl_internal.h b/drivers/staging/wlags49_h2/wl_internal.h index d9a0ad039c19..02f0a20e178a 100644 --- a/drivers/staging/wlags49_h2/wl_internal.h +++ b/drivers/staging/wlags49_h2/wl_internal.h @@ -69,7 +69,6 @@ ******************************************************************************/ #include #ifdef BUS_PCMCIA -#include #include #include #include diff --git a/drivers/telephony/ixj_pcmcia.c b/drivers/telephony/ixj_pcmcia.c index 99cb2246ac72..f6c7e6fd7ee1 100644 --- a/drivers/telephony/ixj_pcmcia.c +++ b/drivers/telephony/ixj_pcmcia.c @@ -8,7 +8,6 @@ #include /* error codes */ #include -#include #include #include #include diff --git a/drivers/usb/host/sl811_cs.c b/drivers/usb/host/sl811_cs.c index 58cb73c8420a..acb7e255a837 100644 --- a/drivers/usb/host/sl811_cs.c +++ b/drivers/usb/host/sl811_cs.c @@ -20,7 +20,6 @@ #include #include -#include #include #include #include @@ -43,8 +42,6 @@ MODULE_LICENSE("GPL"); /* VARIABLES */ /*====================================================================*/ -static const char driver_name[DEV_NAME_LEN] = "sl811_cs"; - typedef struct local_info_t { struct pcmcia_device *p_dev; } local_info_t; @@ -246,7 +243,7 @@ MODULE_DEVICE_TABLE(pcmcia, sl811_ids); static struct pcmcia_driver sl811_cs_driver = { .owner = THIS_MODULE, .drv = { - .name = (char *)driver_name, + .name = "sl811_cs", }, .probe = sl811_cs_probe, .remove = sl811_cs_detach, diff --git a/include/pcmcia/cistpl.h b/include/pcmcia/cistpl.h index cfdd5af77dcc..1c5088c9f7bf 100644 --- a/include/pcmcia/cistpl.h +++ b/include/pcmcia/cistpl.h @@ -15,6 +15,8 @@ #ifndef _LINUX_CISTPL_H #define _LINUX_CISTPL_H +typedef unsigned char cisdata_t; + #define CISTPL_NULL 0x00 #define CISTPL_DEVICE 0x01 #define CISTPL_LONGLINK_CB 0x02 diff --git a/include/pcmcia/cs.h b/include/pcmcia/cs.h index c943c967ac7a..c78d9b112080 100644 --- a/include/pcmcia/cs.h +++ b/include/pcmcia/cs.h @@ -43,14 +43,6 @@ typedef struct conf_reg_t { #define CV_COPY_VALUE 0x08 #define CV_EXT_STATUS 0x10 -/* For GetFirst/NextClient */ -typedef struct client_req_t { - socket_t Socket; - u_int Attributes; -} client_req_t; - -#define CLIENT_THIS_SOCKET 0x01 - /* ModifyConfiguration */ typedef struct modconf_t { u_int Attributes; @@ -133,7 +125,7 @@ typedef struct io_req_t { /* For GetMemPage, MapMemPage */ typedef struct memreq_t { u_int CardOffset; - page_t Page; + u_short Page; } memreq_t; /* For ModifyWindow */ diff --git a/include/pcmcia/cs_types.h b/include/pcmcia/cs_types.h deleted file mode 100644 index f5e3b8386c8f..000000000000 --- a/include/pcmcia/cs_types.h +++ /dev/null @@ -1,40 +0,0 @@ -/* - * cs_types.h - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * The initial developer of the original code is David A. Hinds - * . Portions created by David A. Hinds - * are Copyright (C) 1999 David A. Hinds. All Rights Reserved. - * - * (C) 1999 David A. Hinds - */ - -#ifndef _LINUX_CS_TYPES_H -#define _LINUX_CS_TYPES_H - -#ifdef __KERNEL__ -#include -#else -#include -#endif - -typedef u_short socket_t; -typedef u_int event_t; -typedef u_char cisdata_t; -typedef u_short page_t; - -typedef unsigned long window_handle_t; - -struct region_t; -typedef struct region_t *memory_handle_t; - -#ifndef DEV_NAME_LEN -#define DEV_NAME_LEN 32 -#endif - -typedef char dev_info_t[DEV_NAME_LEN]; - -#endif /* _LINUX_CS_TYPES_H */ diff --git a/include/pcmcia/ds.h b/include/pcmcia/ds.h index 7d7721e86032..e614aa0ca2a2 100644 --- a/include/pcmcia/ds.h +++ b/include/pcmcia/ds.h @@ -20,7 +20,6 @@ #include #endif -#include #include #ifdef __KERNEL__ @@ -37,6 +36,8 @@ struct pcmcia_device; struct config_t; struct net_device; +typedef unsigned long window_handle_t; + /* dynamic device IDs for PCMCIA device drivers. See * Documentation/pcmcia/driver.txt for details. */ diff --git a/include/pcmcia/ss.h b/include/pcmcia/ss.h index aeac27109839..626b63c33d9e 100644 --- a/include/pcmcia/ss.h +++ b/include/pcmcia/ss.h @@ -19,7 +19,6 @@ #include /* task_struct, completion */ #include -#include #include #ifdef CONFIG_CARDBUS #include diff --git a/sound/pcmcia/pdaudiocf/pdaudiocf.h b/sound/pcmcia/pdaudiocf/pdaudiocf.h index a0a7ec64222a..5cc3e4573074 100644 --- a/sound/pcmcia/pdaudiocf/pdaudiocf.h +++ b/sound/pcmcia/pdaudiocf/pdaudiocf.h @@ -24,7 +24,6 @@ #include #include #include -#include #include #include #include diff --git a/sound/pcmcia/vx/vxpocket.h b/sound/pcmcia/vx/vxpocket.h index ea4df16a28ef..d9110669d042 100644 --- a/sound/pcmcia/vx/vxpocket.h +++ b/sound/pcmcia/vx/vxpocket.h @@ -23,7 +23,6 @@ #include -#include #include #include #include -- cgit v1.2.3 From 08354809d6c73eb73973e132502a0a4e53250971 Mon Sep 17 00:00:00 2001 From: Jassi Brar Date: Fri, 25 Jun 2010 18:21:19 +0900 Subject: ahci_platform: Provide for vendor specific init Some AHCI implementations may use Vendor Specific HBA[A0h, FFh] and/or Port[70h, 7Fh] registers to 'prepare' for initialization. For that, the platform needs memory mapped address of AHCI registers. This patch adds the 'mmio' argument and reorders the call to platform init function. Signed-off-by: Jassi Brar Signed-off-by: Jeff Garzik --- drivers/ata/ahci_platform.c | 25 +++++++++++++++---------- include/linux/ahci_platform.h | 4 +++- 2 files changed, 18 insertions(+), 11 deletions(-) (limited to 'drivers/ata') diff --git a/drivers/ata/ahci_platform.c b/drivers/ata/ahci_platform.c index 5e11b160f247..68ef6b563b7d 100644 --- a/drivers/ata/ahci_platform.c +++ b/drivers/ata/ahci_platform.c @@ -54,19 +54,13 @@ static int __init ahci_probe(struct platform_device *pdev) return -EINVAL; } - if (pdata && pdata->init) { - rc = pdata->init(dev); - if (rc) - return rc; - } - if (pdata && pdata->ata_port_info) pi = *pdata->ata_port_info; hpriv = devm_kzalloc(dev, sizeof(*hpriv), GFP_KERNEL); if (!hpriv) { - rc = -ENOMEM; - goto err0; + dev_err(dev, "can't alloc ahci_host_priv\n"); + return -ENOMEM; } hpriv->flags |= (unsigned long)pi.private_data; @@ -74,8 +68,19 @@ static int __init ahci_probe(struct platform_device *pdev) hpriv->mmio = devm_ioremap(dev, mem->start, resource_size(mem)); if (!hpriv->mmio) { dev_err(dev, "can't map %pR\n", mem); - rc = -ENOMEM; - goto err0; + return -ENOMEM; + } + + /* + * Some platforms might need to prepare for mmio region access, + * which could be done in the following init call. So, the mmio + * region shouldn't be accessed before init (if provided) has + * returned successfully. + */ + if (pdata && pdata->init) { + rc = pdata->init(dev, hpriv->mmio); + if (rc) + return rc; } ahci_save_initial_config(dev, hpriv, diff --git a/include/linux/ahci_platform.h b/include/linux/ahci_platform.h index f7dd576dd5a4..be3d9a77d6ed 100644 --- a/include/linux/ahci_platform.h +++ b/include/linux/ahci_platform.h @@ -15,11 +15,13 @@ #ifndef _AHCI_PLATFORM_H #define _AHCI_PLATFORM_H +#include + struct device; struct ata_port_info; struct ahci_platform_data { - int (*init)(struct device *dev); + int (*init)(struct device *dev, void __iomem *addr); void (*exit)(struct device *dev); const struct ata_port_info *ata_port_info; unsigned int force_port_map; -- cgit v1.2.3 From da10a2002cf25a11f18fa1b5e327b9ed717f819c Mon Sep 17 00:00:00 2001 From: Anton Vorontsov Date: Fri, 25 Jun 2010 16:20:53 +0400 Subject: ahci_platform: Remove unneeded ahci_driver.probe assignment The driver is using platform_driver_probe() during initialization, so ahci_driver.probe hook is never used. But it causes the following (harmless, luckily) section mismatch: WARNING: vmlinux.o(.data+0x2fb20): Section mismatch in reference from the variable ahci_driver to the function .init.text:ahci_probe() This patch removes the ahci_driver.probe assignment, thus fixes the warning. p.s. Note that there's another patch[1] from Rene Bolldorf that tried to solve the same issue by __refdata annotation. __refdata says that this reference is actually OK, but in fact it is not OK, because dereferencing .probe() will cause problems. So the proper fix is to remove the assignment. [1] http://kerneltrap.org/mailarchive/linux-kernel/2010/3/18/4549547 Signed-off-by: Anton Vorontsov Signed-off-by: Jeff Garzik --- drivers/ata/ahci_platform.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers/ata') diff --git a/drivers/ata/ahci_platform.c b/drivers/ata/ahci_platform.c index 68ef6b563b7d..4e97f33cca44 100644 --- a/drivers/ata/ahci_platform.c +++ b/drivers/ata/ahci_platform.c @@ -171,7 +171,6 @@ static int __devexit ahci_remove(struct platform_device *pdev) } static struct platform_driver ahci_driver = { - .probe = ahci_probe, .remove = __devexit_p(ahci_remove), .driver = { .name = "ahci", -- cgit v1.2.3 From bce036cea10a8dd21eb8c9bf1b641d8790429c8e Mon Sep 17 00:00:00 2001 From: Mark Lord Date: Thu, 1 Jul 2010 18:16:14 -0400 Subject: libata: glob_match for ata_device_blacklist (v2) Replace rudimentry pattern matching with more capable shell-style globbing. This will enable shrinking ata_device_blacklist[] table in subsequent patches, and helps with future editions to the table, such as matching only the end of a firmware revision string etc.. Signed-off-by: Mark Lord Signed-off-by: Jeff Garzik --- drivers/ata/libata-core.c | 78 ++++++++++++++++++++++++++++++++++------------- 1 file changed, 57 insertions(+), 21 deletions(-) (limited to 'drivers/ata') diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index ddf8e4862787..f8c72a1867fd 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c @@ -4326,29 +4326,65 @@ static const struct ata_blacklist_entry ata_device_blacklist [] = { { } }; -static int strn_pattern_cmp(const char *patt, const char *name, int wildchar) +/** + * glob_match - match a text string against a glob-style pattern + * @text: the string to be examined + * @pattern: the glob-style pattern to be matched against + * + * Either/both of text and pattern can be empty strings. + * + * Match text against a glob-style pattern, with wildcards and simple sets: + * + * ? matches any single character. + * * matches any run of characters. + * [xyz] matches a single character from the set: x, y, or z. + * + * Note: hyphenated ranges [0-9] are _not_ supported here. + * The special characters ?, [, or *, can be matched using a set, eg. [*] + * + * Example patterns: "SD1?", "SD1[012345]", "*R0", SD*1?[012]*xx" + * + * This function uses one level of recursion per '*' in pattern. + * Since it calls _nothing_ else, and has _no_ explicit local variables, + * this will not cause stack problems for any reasonable use here. + * + * RETURNS: + * 0 on match, 1 otherwise. + */ +static int glob_match (const char *text, const char *pattern) { - const char *p; - int len; - - /* - * check for trailing wildcard: *\0 - */ - p = strchr(patt, wildchar); - if (p && ((*(p + 1)) == 0)) - len = p - patt; - else { - len = strlen(name); - if (!len) { - if (!*patt) - return 0; - return -1; + do { + /* Match single character or a '?' wildcard */ + if (*text == *pattern || *pattern == '?') { + if (!*pattern++) + return 0; /* End of both strings: match */ + } else { + /* Match single char against a '[' bracketed ']' pattern set */ + if (!*text || *pattern != '[') + break; /* Not a pattern set */ + while (*++pattern && *pattern != ']' && *text != *pattern); + if (!*pattern || *pattern == ']') + return 1; /* No match */ + while (*pattern && *pattern++ != ']'); + } + } while (*++text && *pattern); + + /* Match any run of chars against a '*' wildcard */ + if (*pattern == '*') { + if (!*++pattern) + return 0; /* Match: avoid recursion at end of pattern */ + /* Loop to handle additional pattern chars after the wildcard */ + while (*text) { + if (glob_match(text, pattern) == 0) + return 0; /* Remainder matched */ + ++text; /* Absorb (match) this char and try again */ } } - - return strncmp(patt, name, len); + if (!*text && !*pattern) + return 0; /* End of both strings: match */ + return 1; /* No match */ } - + static unsigned long ata_dev_blacklisted(const struct ata_device *dev) { unsigned char model_num[ATA_ID_PROD_LEN + 1]; @@ -4359,10 +4395,10 @@ static unsigned long ata_dev_blacklisted(const struct ata_device *dev) ata_id_c_string(dev->id, model_rev, ATA_ID_FW_REV, sizeof(model_rev)); while (ad->model_num) { - if (!strn_pattern_cmp(ad->model_num, model_num, '*')) { + if (!glob_match(model_num, ad->model_num)) { if (ad->model_rev == NULL) return ad->horkage; - if (!strn_pattern_cmp(ad->model_rev, model_rev, '*')) + if (!glob_match(model_rev, ad->model_rev)) return ad->horkage; } ad++; -- cgit v1.2.3 From dbaf5083bf07a1c14b15828a3aac92f0ce11543c Mon Sep 17 00:00:00 2001 From: Mark Lord Date: Thu, 1 Jul 2010 18:17:21 -0400 Subject: libata: reduce blacklist size (v2) Take advantage of the new glob_match() function to reduce the blacklist size somewhat. There are further savings possible, but these are the most obvious biggies. Signed-off-by: Mark Lord Signed-off-by: Jeff Garzik --- drivers/ata/libata-core.c | 60 +++++------------------------------------------ 1 file changed, 6 insertions(+), 54 deletions(-) (limited to 'drivers/ata') diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index f8c72a1867fd..af02ff36cf2b 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c @@ -4211,70 +4211,22 @@ static const struct ata_blacklist_entry ata_device_blacklist [] = { { "OCZ CORE_SSD", "02.10104", ATA_HORKAGE_NONCQ }, /* Seagate NCQ + FLUSH CACHE firmware bug */ - { "ST31500341AS", "SD15", ATA_HORKAGE_NONCQ | - ATA_HORKAGE_FIRMWARE_WARN }, - { "ST31500341AS", "SD16", ATA_HORKAGE_NONCQ | - ATA_HORKAGE_FIRMWARE_WARN }, - { "ST31500341AS", "SD17", ATA_HORKAGE_NONCQ | - ATA_HORKAGE_FIRMWARE_WARN }, - { "ST31500341AS", "SD18", ATA_HORKAGE_NONCQ | - ATA_HORKAGE_FIRMWARE_WARN }, - { "ST31500341AS", "SD19", ATA_HORKAGE_NONCQ | + { "ST31500341AS", "SD1[56789]", ATA_HORKAGE_NONCQ | ATA_HORKAGE_FIRMWARE_WARN }, - { "ST31000333AS", "SD15", ATA_HORKAGE_NONCQ | - ATA_HORKAGE_FIRMWARE_WARN }, - { "ST31000333AS", "SD16", ATA_HORKAGE_NONCQ | - ATA_HORKAGE_FIRMWARE_WARN }, - { "ST31000333AS", "SD17", ATA_HORKAGE_NONCQ | - ATA_HORKAGE_FIRMWARE_WARN }, - { "ST31000333AS", "SD18", ATA_HORKAGE_NONCQ | - ATA_HORKAGE_FIRMWARE_WARN }, - { "ST31000333AS", "SD19", ATA_HORKAGE_NONCQ | + { "ST31000333AS", "SD1[56789]", ATA_HORKAGE_NONCQ | ATA_HORKAGE_FIRMWARE_WARN }, - { "ST3640623AS", "SD15", ATA_HORKAGE_NONCQ | - ATA_HORKAGE_FIRMWARE_WARN }, - { "ST3640623AS", "SD16", ATA_HORKAGE_NONCQ | - ATA_HORKAGE_FIRMWARE_WARN }, - { "ST3640623AS", "SD17", ATA_HORKAGE_NONCQ | - ATA_HORKAGE_FIRMWARE_WARN }, - { "ST3640623AS", "SD18", ATA_HORKAGE_NONCQ | - ATA_HORKAGE_FIRMWARE_WARN }, - { "ST3640623AS", "SD19", ATA_HORKAGE_NONCQ | + { "ST3640623AS", "SD1[56789]", ATA_HORKAGE_NONCQ | ATA_HORKAGE_FIRMWARE_WARN }, - { "ST3640323AS", "SD15", ATA_HORKAGE_NONCQ | - ATA_HORKAGE_FIRMWARE_WARN }, - { "ST3640323AS", "SD16", ATA_HORKAGE_NONCQ | - ATA_HORKAGE_FIRMWARE_WARN }, - { "ST3640323AS", "SD17", ATA_HORKAGE_NONCQ | - ATA_HORKAGE_FIRMWARE_WARN }, - { "ST3640323AS", "SD18", ATA_HORKAGE_NONCQ | - ATA_HORKAGE_FIRMWARE_WARN }, - { "ST3640323AS", "SD19", ATA_HORKAGE_NONCQ | + { "ST3640323AS", "SD1[56789]", ATA_HORKAGE_NONCQ | ATA_HORKAGE_FIRMWARE_WARN }, - { "ST3320813AS", "SD15", ATA_HORKAGE_NONCQ | - ATA_HORKAGE_FIRMWARE_WARN }, - { "ST3320813AS", "SD16", ATA_HORKAGE_NONCQ | - ATA_HORKAGE_FIRMWARE_WARN }, - { "ST3320813AS", "SD17", ATA_HORKAGE_NONCQ | - ATA_HORKAGE_FIRMWARE_WARN }, - { "ST3320813AS", "SD18", ATA_HORKAGE_NONCQ | - ATA_HORKAGE_FIRMWARE_WARN }, - { "ST3320813AS", "SD19", ATA_HORKAGE_NONCQ | + { "ST3320813AS", "SD1[56789]", ATA_HORKAGE_NONCQ | ATA_HORKAGE_FIRMWARE_WARN }, - { "ST3320613AS", "SD15", ATA_HORKAGE_NONCQ | - ATA_HORKAGE_FIRMWARE_WARN }, - { "ST3320613AS", "SD16", ATA_HORKAGE_NONCQ | - ATA_HORKAGE_FIRMWARE_WARN }, - { "ST3320613AS", "SD17", ATA_HORKAGE_NONCQ | - ATA_HORKAGE_FIRMWARE_WARN }, - { "ST3320613AS", "SD18", ATA_HORKAGE_NONCQ | - ATA_HORKAGE_FIRMWARE_WARN }, - { "ST3320613AS", "SD19", ATA_HORKAGE_NONCQ | + { "ST3320613AS", "SD1[56789]", ATA_HORKAGE_NONCQ | ATA_HORKAGE_FIRMWARE_WARN }, /* Blacklist entries taken from Silicon Image 3124/3132 -- cgit v1.2.3 From 7da4c935a2a2e3a6e86458d11b06a90a3649dc81 Mon Sep 17 00:00:00 2001 From: Mark Lord Date: Thu, 1 Jul 2010 18:18:12 -0400 Subject: libata: reduce blacklist size even more (v2) Take further advantage of the new glob_match() function to reduce the blacklist size. There are even more savings possible, but how far do we want to go with this? Signed-off-by: Mark Lord Signed-off-by: Jeff Garzik --- drivers/ata/libata-core.c | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) (limited to 'drivers/ata') diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index af02ff36cf2b..2984e45bc16b 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c @@ -4167,15 +4167,13 @@ static const struct ata_blacklist_entry ata_device_blacklist [] = { { "WDC AC23200L", "21.10N21", ATA_HORKAGE_NODMA }, { "Compaq CRD-8241B", NULL, ATA_HORKAGE_NODMA }, { "CRD-8400B", NULL, ATA_HORKAGE_NODMA }, - { "CRD-8480B", NULL, ATA_HORKAGE_NODMA }, - { "CRD-8482B", NULL, ATA_HORKAGE_NODMA }, + { "CRD-848[02]B", NULL, ATA_HORKAGE_NODMA }, { "CRD-84", NULL, ATA_HORKAGE_NODMA }, { "SanDisk SDP3B", NULL, ATA_HORKAGE_NODMA }, { "SanDisk SDP3B-64", NULL, ATA_HORKAGE_NODMA }, { "SANYO CD-ROM CRD", NULL, ATA_HORKAGE_NODMA }, { "HITACHI CDR-8", NULL, ATA_HORKAGE_NODMA }, - { "HITACHI CDR-8335", NULL, ATA_HORKAGE_NODMA }, - { "HITACHI CDR-8435", NULL, ATA_HORKAGE_NODMA }, + { "HITACHI CDR-8[34]35",NULL, ATA_HORKAGE_NODMA }, { "Toshiba CD-ROM XM-6202B", NULL, ATA_HORKAGE_NODMA }, { "TOSHIBA CD-ROM XM-1702BC", NULL, ATA_HORKAGE_NODMA }, { "CD-532E-A", NULL, ATA_HORKAGE_NODMA }, @@ -4255,12 +4253,7 @@ static const struct ata_blacklist_entry ata_device_blacklist [] = { /* Devices which get the IVB wrong */ { "QUANTUM FIREBALLlct10 05", "A03.0900", ATA_HORKAGE_IVB, }, /* Maybe we should just blacklist TSSTcorp... */ - { "TSSTcorp CDDVDW SH-S202H", "SB00", ATA_HORKAGE_IVB, }, - { "TSSTcorp CDDVDW SH-S202H", "SB01", ATA_HORKAGE_IVB, }, - { "TSSTcorp CDDVDW SH-S202J", "SB00", ATA_HORKAGE_IVB, }, - { "TSSTcorp CDDVDW SH-S202J", "SB01", ATA_HORKAGE_IVB, }, - { "TSSTcorp CDDVDW SH-S202N", "SB00", ATA_HORKAGE_IVB, }, - { "TSSTcorp CDDVDW SH-S202N", "SB01", ATA_HORKAGE_IVB, }, + { "TSSTcorp CDDVDW SH-S202[HJN]", "SB0[01]", ATA_HORKAGE_IVB, }, /* Devices that do not need bridging limits applied */ { "MTRON MSP-SATA*", NULL, ATA_HORKAGE_BRIDGE_OK, }, -- cgit v1.2.3 From 62936009f35a6659cc3ebe0d90c754182d60da73 Mon Sep 17 00:00:00 2001 From: Rupjyoti Sarmah Date: Tue, 6 Jul 2010 16:36:03 +0530 Subject: [libata] Add 460EX on-chip SATA driver, sata_dwc_460ex This patch enables the on-chip DWC SATA controller of the AppliedMicro processor 460EX. Signed-off-by: Rupjyoti Sarmah Signed-off-by: Mark Miesfeld Signed-off-by: Prodyut Hazarika Signed-off-by: Jeff Garzik --- drivers/ata/Kconfig | 9 + drivers/ata/Makefile | 1 + drivers/ata/sata_dwc_460ex.c | 1756 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 1766 insertions(+) create mode 100644 drivers/ata/sata_dwc_460ex.c (limited to 'drivers/ata') diff --git a/drivers/ata/Kconfig b/drivers/ata/Kconfig index aa85a98d3a4f..f06e313c997f 100644 --- a/drivers/ata/Kconfig +++ b/drivers/ata/Kconfig @@ -187,6 +187,15 @@ config ATA_PIIX If unsure, say N. +config SATA_DWC + tristate "DesignWare Cores SATA support" + depends on 460EX + help + This option enables support for the on-chip SATA controller of the + AppliedMicro processor 460EX. + + If unsure, say N. + config SATA_MV tristate "Marvell SATA support" help diff --git a/drivers/ata/Makefile b/drivers/ata/Makefile index 7ef89d73df63..d863e66f89a0 100644 --- a/drivers/ata/Makefile +++ b/drivers/ata/Makefile @@ -7,6 +7,7 @@ obj-$(CONFIG_SATA_AHCI_PLATFORM) += ahci_platform.o libahci.o obj-$(CONFIG_SATA_FSL) += sata_fsl.o obj-$(CONFIG_SATA_INIC162X) += sata_inic162x.o obj-$(CONFIG_SATA_SIL24) += sata_sil24.o +obj-$(CONFIG_SATA_DWC) += sata_dwc_460ex.o # SFF w/ custom DMA obj-$(CONFIG_PDC_ADMA) += pdc_adma.o diff --git a/drivers/ata/sata_dwc_460ex.c b/drivers/ata/sata_dwc_460ex.c new file mode 100644 index 000000000000..ea24c1e51be2 --- /dev/null +++ b/drivers/ata/sata_dwc_460ex.c @@ -0,0 +1,1756 @@ +/* + * drivers/ata/sata_dwc_460ex.c + * + * Synopsys DesignWare Cores (DWC) SATA host driver + * + * Author: Mark Miesfeld + * + * Ported from 2.6.19.2 to 2.6.25/26 by Stefan Roese + * Copyright 2008 DENX Software Engineering + * + * Based on versions provided by AMCC and Synopsys which are: + * Copyright 2006 Applied Micro Circuits Corporation + * COPYRIGHT (C) 2005 SYNOPSYS, INC. ALL RIGHTS RESERVED + * + * 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. + */ + +#ifdef CONFIG_SATA_DWC_DEBUG +#define DEBUG +#endif + +#ifdef CONFIG_SATA_DWC_VDEBUG +#define VERBOSE_DEBUG +#define DEBUG_NCQ +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include "libata.h" + +#include +#include + +#define DRV_NAME "sata-dwc" +#define DRV_VERSION "1.0" + +/* SATA DMA driver Globals */ +#define DMA_NUM_CHANS 1 +#define DMA_NUM_CHAN_REGS 8 + +/* SATA DMA Register definitions */ +#define AHB_DMA_BRST_DFLT 64 /* 16 data items burst length*/ + +struct dmareg { + u32 low; /* Low bits 0-31 */ + u32 high; /* High bits 32-63 */ +}; + +/* DMA Per Channel registers */ +struct dma_chan_regs { + struct dmareg sar; /* Source Address */ + struct dmareg dar; /* Destination address */ + struct dmareg llp; /* Linked List Pointer */ + struct dmareg ctl; /* Control */ + struct dmareg sstat; /* Source Status not implemented in core */ + struct dmareg dstat; /* Destination Status not implemented in core*/ + struct dmareg sstatar; /* Source Status Address not impl in core */ + struct dmareg dstatar; /* Destination Status Address not implemente */ + struct dmareg cfg; /* Config */ + struct dmareg sgr; /* Source Gather */ + struct dmareg dsr; /* Destination Scatter */ +}; + +/* Generic Interrupt Registers */ +struct dma_interrupt_regs { + struct dmareg tfr; /* Transfer Interrupt */ + struct dmareg block; /* Block Interrupt */ + struct dmareg srctran; /* Source Transfer Interrupt */ + struct dmareg dsttran; /* Dest Transfer Interrupt */ + struct dmareg error; /* Error */ +}; + +struct ahb_dma_regs { + struct dma_chan_regs chan_regs[DMA_NUM_CHAN_REGS]; + struct dma_interrupt_regs interrupt_raw; /* Raw Interrupt */ + struct dma_interrupt_regs interrupt_status; /* Interrupt Status */ + struct dma_interrupt_regs interrupt_mask; /* Interrupt Mask */ + struct dma_interrupt_regs interrupt_clear; /* Interrupt Clear */ + struct dmareg statusInt; /* Interrupt combined*/ + struct dmareg rq_srcreg; /* Src Trans Req */ + struct dmareg rq_dstreg; /* Dst Trans Req */ + struct dmareg rq_sgl_srcreg; /* Sngl Src Trans Req*/ + struct dmareg rq_sgl_dstreg; /* Sngl Dst Trans Req*/ + struct dmareg rq_lst_srcreg; /* Last Src Trans Req*/ + struct dmareg rq_lst_dstreg; /* Last Dst Trans Req*/ + struct dmareg dma_cfg; /* DMA Config */ + struct dmareg dma_chan_en; /* DMA Channel Enable*/ + struct dmareg dma_id; /* DMA ID */ + struct dmareg dma_test; /* DMA Test */ + struct dmareg res1; /* reserved */ + struct dmareg res2; /* reserved */ + /* + * DMA Comp Params + * Param 6 = dma_param[0], Param 5 = dma_param[1], + * Param 4 = dma_param[2] ... + */ + struct dmareg dma_params[6]; +}; + +/* Data structure for linked list item */ +struct lli { + u32 sar; /* Source Address */ + u32 dar; /* Destination address */ + u32 llp; /* Linked List Pointer */ + struct dmareg ctl; /* Control */ + struct dmareg dstat; /* Destination Status */ +}; + +enum { + SATA_DWC_DMAC_LLI_SZ = (sizeof(struct lli)), + SATA_DWC_DMAC_LLI_NUM = 256, + SATA_DWC_DMAC_LLI_TBL_SZ = (SATA_DWC_DMAC_LLI_SZ * \ + SATA_DWC_DMAC_LLI_NUM), + SATA_DWC_DMAC_TWIDTH_BYTES = 4, + SATA_DWC_DMAC_CTRL_TSIZE_MAX = (0x00000800 * \ + SATA_DWC_DMAC_TWIDTH_BYTES), +}; + +/* DMA Register Operation Bits */ +enum { + DMA_EN = 0x00000001, /* Enable AHB DMA */ + DMA_CTL_LLP_SRCEN = 0x10000000, /* Blk chain enable Src */ + DMA_CTL_LLP_DSTEN = 0x08000000, /* Blk chain enable Dst */ +}; + +#define DMA_CTL_BLK_TS(size) ((size) & 0x000000FFF) /* Blk Transfer size */ +#define DMA_CHANNEL(ch) (0x00000001 << (ch)) /* Select channel */ + /* Enable channel */ +#define DMA_ENABLE_CHAN(ch) ((0x00000001 << (ch)) | \ + ((0x000000001 << (ch)) << 8)) + /* Disable channel */ +#define DMA_DISABLE_CHAN(ch) (0x00000000 | ((0x000000001 << (ch)) << 8)) + /* Transfer Type & Flow Controller */ +#define DMA_CTL_TTFC(type) (((type) & 0x7) << 20) +#define DMA_CTL_SMS(num) (((num) & 0x3) << 25) /* Src Master Select */ +#define DMA_CTL_DMS(num) (((num) & 0x3) << 23)/* Dst Master Select */ + /* Src Burst Transaction Length */ +#define DMA_CTL_SRC_MSIZE(size) (((size) & 0x7) << 14) + /* Dst Burst Transaction Length */ +#define DMA_CTL_DST_MSIZE(size) (((size) & 0x7) << 11) + /* Source Transfer Width */ +#define DMA_CTL_SRC_TRWID(size) (((size) & 0x7) << 4) + /* Destination Transfer Width */ +#define DMA_CTL_DST_TRWID(size) (((size) & 0x7) << 1) + +/* Assign HW handshaking interface (x) to destination / source peripheral */ +#define DMA_CFG_HW_HS_DEST(int_num) (((int_num) & 0xF) << 11) +#define DMA_CFG_HW_HS_SRC(int_num) (((int_num) & 0xF) << 7) +#define DMA_LLP_LMS(addr, master) (((addr) & 0xfffffffc) | (master)) + +/* + * This define is used to set block chaining disabled in the control low + * register. It is already in little endian format so it can be &'d dirctly. + * It is essentially: cpu_to_le32(~(DMA_CTL_LLP_SRCEN | DMA_CTL_LLP_DSTEN)) + */ +enum { + DMA_CTL_LLP_DISABLE_LE32 = 0xffffffe7, + DMA_CTL_TTFC_P2M_DMAC = 0x00000002, /* Per to mem, DMAC cntr */ + DMA_CTL_TTFC_M2P_PER = 0x00000003, /* Mem to per, peripheral cntr */ + DMA_CTL_SINC_INC = 0x00000000, /* Source Address Increment */ + DMA_CTL_SINC_DEC = 0x00000200, + DMA_CTL_SINC_NOCHANGE = 0x00000400, + DMA_CTL_DINC_INC = 0x00000000, /* Destination Address Increment */ + DMA_CTL_DINC_DEC = 0x00000080, + DMA_CTL_DINC_NOCHANGE = 0x00000100, + DMA_CTL_INT_EN = 0x00000001, /* Interrupt Enable */ + +/* Channel Configuration Register high bits */ + DMA_CFG_FCMOD_REQ = 0x00000001, /* Flow Control - request based */ + DMA_CFG_PROTCTL = (0x00000003 << 2),/* Protection Control */ + +/* Channel Configuration Register low bits */ + DMA_CFG_RELD_DST = 0x80000000, /* Reload Dest / Src Addr */ + DMA_CFG_RELD_SRC = 0x40000000, + DMA_CFG_HS_SELSRC = 0x00000800, /* Software handshake Src/ Dest */ + DMA_CFG_HS_SELDST = 0x00000400, + DMA_CFG_FIFOEMPTY = (0x00000001 << 9), /* FIFO Empty bit */ + +/* Channel Linked List Pointer Register */ + DMA_LLP_AHBMASTER1 = 0, /* List Master Select */ + DMA_LLP_AHBMASTER2 = 1, + + SATA_DWC_MAX_PORTS = 1, + + SATA_DWC_SCR_OFFSET = 0x24, + SATA_DWC_REG_OFFSET = 0x64, +}; + +/* DWC SATA Registers */ +struct sata_dwc_regs { + u32 fptagr; /* 1st party DMA tag */ + u32 fpbor; /* 1st party DMA buffer offset */ + u32 fptcr; /* 1st party DMA Xfr count */ + u32 dmacr; /* DMA Control */ + u32 dbtsr; /* DMA Burst Transac size */ + u32 intpr; /* Interrupt Pending */ + u32 intmr; /* Interrupt Mask */ + u32 errmr; /* Error Mask */ + u32 llcr; /* Link Layer Control */ + u32 phycr; /* PHY Control */ + u32 physr; /* PHY Status */ + u32 rxbistpd; /* Recvd BIST pattern def register */ + u32 rxbistpd1; /* Recvd BIST data dword1 */ + u32 rxbistpd2; /* Recvd BIST pattern data dword2 */ + u32 txbistpd; /* Trans BIST pattern def register */ + u32 txbistpd1; /* Trans BIST data dword1 */ + u32 txbistpd2; /* Trans BIST data dword2 */ + u32 bistcr; /* BIST Control Register */ + u32 bistfctr; /* BIST FIS Count Register */ + u32 bistsr; /* BIST Status Register */ + u32 bistdecr; /* BIST Dword Error count register */ + u32 res[15]; /* Reserved locations */ + u32 testr; /* Test Register */ + u32 versionr; /* Version Register */ + u32 idr; /* ID Register */ + u32 unimpl[192]; /* Unimplemented */ + u32 dmadr[256]; /* FIFO Locations in DMA Mode */ +}; + +enum { + SCR_SCONTROL_DET_ENABLE = 0x00000001, + SCR_SSTATUS_DET_PRESENT = 0x00000001, + SCR_SERROR_DIAG_X = 0x04000000, +/* DWC SATA Register Operations */ + SATA_DWC_TXFIFO_DEPTH = 0x01FF, + SATA_DWC_RXFIFO_DEPTH = 0x01FF, + SATA_DWC_DMACR_TMOD_TXCHEN = 0x00000004, + SATA_DWC_DMACR_TXCHEN = (0x00000001 | SATA_DWC_DMACR_TMOD_TXCHEN), + SATA_DWC_DMACR_RXCHEN = (0x00000002 | SATA_DWC_DMACR_TMOD_TXCHEN), + SATA_DWC_DMACR_TXRXCH_CLEAR = SATA_DWC_DMACR_TMOD_TXCHEN, + SATA_DWC_INTPR_DMAT = 0x00000001, + SATA_DWC_INTPR_NEWFP = 0x00000002, + SATA_DWC_INTPR_PMABRT = 0x00000004, + SATA_DWC_INTPR_ERR = 0x00000008, + SATA_DWC_INTPR_NEWBIST = 0x00000010, + SATA_DWC_INTPR_IPF = 0x10000000, + SATA_DWC_INTMR_DMATM = 0x00000001, + SATA_DWC_INTMR_NEWFPM = 0x00000002, + SATA_DWC_INTMR_PMABRTM = 0x00000004, + SATA_DWC_INTMR_ERRM = 0x00000008, + SATA_DWC_INTMR_NEWBISTM = 0x00000010, + SATA_DWC_LLCR_SCRAMEN = 0x00000001, + SATA_DWC_LLCR_DESCRAMEN = 0x00000002, + SATA_DWC_LLCR_RPDEN = 0x00000004, +/* This is all error bits, zero's are reserved fields. */ + SATA_DWC_SERROR_ERR_BITS = 0x0FFF0F03 +}; + +#define SATA_DWC_SCR0_SPD_GET(v) (((v) >> 4) & 0x0000000F) +#define SATA_DWC_DMACR_TX_CLEAR(v) (((v) & ~SATA_DWC_DMACR_TXCHEN) |\ + SATA_DWC_DMACR_TMOD_TXCHEN) +#define SATA_DWC_DMACR_RX_CLEAR(v) (((v) & ~SATA_DWC_DMACR_RXCHEN) |\ + SATA_DWC_DMACR_TMOD_TXCHEN) +#define SATA_DWC_DBTSR_MWR(size) (((size)/4) & SATA_DWC_TXFIFO_DEPTH) +#define SATA_DWC_DBTSR_MRD(size) ((((size)/4) & SATA_DWC_RXFIFO_DEPTH)\ + << 16) +struct sata_dwc_device { + struct device *dev; /* generic device struct */ + struct ata_probe_ent *pe; /* ptr to probe-ent */ + struct ata_host *host; + u8 *reg_base; + struct sata_dwc_regs *sata_dwc_regs; /* DW Synopsys SATA specific */ + int irq_dma; +}; + +#define SATA_DWC_QCMD_MAX 32 + +struct sata_dwc_device_port { + struct sata_dwc_device *hsdev; + int cmd_issued[SATA_DWC_QCMD_MAX]; + struct lli *llit[SATA_DWC_QCMD_MAX]; /* DMA LLI table */ + dma_addr_t llit_dma[SATA_DWC_QCMD_MAX]; + u32 dma_chan[SATA_DWC_QCMD_MAX]; + int dma_pending[SATA_DWC_QCMD_MAX]; +}; + +/* + * Commonly used DWC SATA driver Macros + */ +#define HSDEV_FROM_HOST(host) ((struct sata_dwc_device *)\ + (host)->private_data) +#define HSDEV_FROM_AP(ap) ((struct sata_dwc_device *)\ + (ap)->host->private_data) +#define HSDEVP_FROM_AP(ap) ((struct sata_dwc_device_port *)\ + (ap)->private_data) +#define HSDEV_FROM_QC(qc) ((struct sata_dwc_device *)\ + (qc)->ap->host->private_data) +#define HSDEV_FROM_HSDEVP(p) ((struct sata_dwc_device *)\ + (hsdevp)->hsdev) + +enum { + SATA_DWC_CMD_ISSUED_NOT = 0, + SATA_DWC_CMD_ISSUED_PEND = 1, + SATA_DWC_CMD_ISSUED_EXEC = 2, + SATA_DWC_CMD_ISSUED_NODATA = 3, + + SATA_DWC_DMA_PENDING_NONE = 0, + SATA_DWC_DMA_PENDING_TX = 1, + SATA_DWC_DMA_PENDING_RX = 2, +}; + +struct sata_dwc_host_priv { + void __iomem *scr_addr_sstatus; + u32 sata_dwc_sactive_issued ; + u32 sata_dwc_sactive_queued ; + u32 dma_interrupt_count; + struct ahb_dma_regs *sata_dma_regs; + struct device *dwc_dev; +}; +struct sata_dwc_host_priv host_pvt; +/* + * Prototypes + */ +static void sata_dwc_bmdma_start_by_tag(struct ata_queued_cmd *qc, u8 tag); +static int sata_dwc_qc_complete(struct ata_port *ap, struct ata_queued_cmd *qc, + u32 check_status); +static void sata_dwc_dma_xfer_complete(struct ata_port *ap, u32 check_status); +static void sata_dwc_port_stop(struct ata_port *ap); +static void sata_dwc_clear_dmacr(struct sata_dwc_device_port *hsdevp, u8 tag); +static int dma_dwc_init(struct sata_dwc_device *hsdev, int irq); +static void dma_dwc_exit(struct sata_dwc_device *hsdev); +static int dma_dwc_xfer_setup(struct scatterlist *sg, int num_elems, + struct lli *lli, dma_addr_t dma_lli, + void __iomem *addr, int dir); +static void dma_dwc_xfer_start(int dma_ch); + +static void sata_dwc_tf_dump(struct ata_taskfile *tf) +{ + dev_vdbg(host_pvt.dwc_dev, "taskfile cmd: 0x%02x protocol: %s flags:" + "0x%lx device: %x\n", tf->command, ata_get_cmd_descript\ + (tf->protocol), tf->flags, tf->device); + dev_vdbg(host_pvt.dwc_dev, "feature: 0x%02x nsect: 0x%x lbal: 0x%x " + "lbam: 0x%x lbah: 0x%x\n", tf->feature, tf->nsect, tf->lbal, + tf->lbam, tf->lbah); + dev_vdbg(host_pvt.dwc_dev, "hob_feature: 0x%02x hob_nsect: 0x%x " + "hob_lbal: 0x%x hob_lbam: 0x%x hob_lbah: 0x%x\n", + tf->hob_feature, tf->hob_nsect, tf->hob_lbal, tf->hob_lbam, + tf->hob_lbah); +} + +/* + * Function: get_burst_length_encode + * arguments: datalength: length in bytes of data + * returns value to be programmed in register corrresponding to data length + * This value is effectively the log(base 2) of the length + */ +static int get_burst_length_encode(int datalength) +{ + int items = datalength >> 2; /* div by 4 to get lword count */ + + if (items >= 64) + return 5; + + if (items >= 32) + return 4; + + if (items >= 16) + return 3; + + if (items >= 8) + return 2; + + if (items >= 4) + return 1; + + return 0; +} + +static void clear_chan_interrupts(int c) +{ + out_le32(&(host_pvt.sata_dma_regs->interrupt_clear.tfr.low), + DMA_CHANNEL(c)); + out_le32(&(host_pvt.sata_dma_regs->interrupt_clear.block.low), + DMA_CHANNEL(c)); + out_le32(&(host_pvt.sata_dma_regs->interrupt_clear.srctran.low), + DMA_CHANNEL(c)); + out_le32(&(host_pvt.sata_dma_regs->interrupt_clear.dsttran.low), + DMA_CHANNEL(c)); + out_le32(&(host_pvt.sata_dma_regs->interrupt_clear.error.low), + DMA_CHANNEL(c)); +} + +/* + * Function: dma_request_channel + * arguments: None + * returns channel number if available else -1 + * This function assigns the next available DMA channel from the list to the + * requester + */ +static int dma_request_channel(void) +{ + int i; + + for (i = 0; i < DMA_NUM_CHANS; i++) { + if (!(in_le32(&(host_pvt.sata_dma_regs->dma_chan_en.low)) &\ + DMA_CHANNEL(i))) + return i; + } + dev_err(host_pvt.dwc_dev, "%s NO channel chan_en: 0x%08x\n", __func__, + in_le32(&(host_pvt.sata_dma_regs->dma_chan_en.low))); + return -1; +} + +/* + * Function: dma_dwc_interrupt + * arguments: irq, dev_id, pt_regs + * returns channel number if available else -1 + * Interrupt Handler for DW AHB SATA DMA + */ +static irqreturn_t dma_dwc_interrupt(int irq, void *hsdev_instance) +{ + int chan; + u32 tfr_reg, err_reg; + unsigned long flags; + struct sata_dwc_device *hsdev = + (struct sata_dwc_device *)hsdev_instance; + struct ata_host *host = (struct ata_host *)hsdev->host; + struct ata_port *ap; + struct sata_dwc_device_port *hsdevp; + u8 tag = 0; + unsigned int port = 0; + + spin_lock_irqsave(&host->lock, flags); + ap = host->ports[port]; + hsdevp = HSDEVP_FROM_AP(ap); + tag = ap->link.active_tag; + + tfr_reg = in_le32(&(host_pvt.sata_dma_regs->interrupt_status.tfr\ + .low)); + err_reg = in_le32(&(host_pvt.sata_dma_regs->interrupt_status.error\ + .low)); + + dev_dbg(ap->dev, "eot=0x%08x err=0x%08x pending=%d active port=%d\n", + tfr_reg, err_reg, hsdevp->dma_pending[tag], port); + + for (chan = 0; chan < DMA_NUM_CHANS; chan++) { + /* Check for end-of-transfer interrupt. */ + if (tfr_reg & DMA_CHANNEL(chan)) { + /* + * Each DMA command produces 2 interrupts. Only + * complete the command after both interrupts have been + * seen. (See sata_dwc_isr()) + */ + host_pvt.dma_interrupt_count++; + sata_dwc_clear_dmacr(hsdevp, tag); + + if (hsdevp->dma_pending[tag] == + SATA_DWC_DMA_PENDING_NONE) { + dev_err(ap->dev, "DMA not pending eot=0x%08x " + "err=0x%08x tag=0x%02x pending=%d\n", + tfr_reg, err_reg, tag, + hsdevp->dma_pending[tag]); + } + + if ((host_pvt.dma_interrupt_count % 2) == 0) + sata_dwc_dma_xfer_complete(ap, 1); + + /* Clear the interrupt */ + out_le32(&(host_pvt.sata_dma_regs->interrupt_clear\ + .tfr.low), + DMA_CHANNEL(chan)); + } + + /* Check for error interrupt. */ + if (err_reg & DMA_CHANNEL(chan)) { + /* TODO Need error handler ! */ + dev_err(ap->dev, "error interrupt err_reg=0x%08x\n", + err_reg); + + /* Clear the interrupt. */ + out_le32(&(host_pvt.sata_dma_regs->interrupt_clear\ + .error.low), + DMA_CHANNEL(chan)); + } + } + spin_unlock_irqrestore(&host->lock, flags); + return IRQ_HANDLED; +} + +/* + * Function: dma_request_interrupts + * arguments: hsdev + * returns status + * This function registers ISR for a particular DMA channel interrupt + */ +static int dma_request_interrupts(struct sata_dwc_device *hsdev, int irq) +{ + int retval = 0; + int chan; + + for (chan = 0; chan < DMA_NUM_CHANS; chan++) { + /* Unmask error interrupt */ + out_le32(&(host_pvt.sata_dma_regs)->interrupt_mask.error.low, + DMA_ENABLE_CHAN(chan)); + + /* Unmask end-of-transfer interrupt */ + out_le32(&(host_pvt.sata_dma_regs)->interrupt_mask.tfr.low, + DMA_ENABLE_CHAN(chan)); + } + + retval = request_irq(irq, dma_dwc_interrupt, 0, "SATA DMA", hsdev); + if (retval) { + dev_err(host_pvt.dwc_dev, "%s: could not get IRQ %d\n", + __func__, irq); + return -ENODEV; + } + + /* Mark this interrupt as requested */ + hsdev->irq_dma = irq; + return 0; +} + +/* + * Function: map_sg_to_lli + * The Synopsis driver has a comment proposing that better performance + * is possible by only enabling interrupts on the last item in the linked list. + * However, it seems that could be a problem if an error happened on one of the + * first items. The transfer would halt, but no error interrupt would occur. + * Currently this function sets interrupts enabled for each linked list item: + * DMA_CTL_INT_EN. + */ +static int map_sg_to_lli(struct scatterlist *sg, int num_elems, + struct lli *lli, dma_addr_t dma_lli, + void __iomem *dmadr_addr, int dir) +{ + int i, idx = 0; + int fis_len = 0; + dma_addr_t next_llp; + int bl; + + dev_dbg(host_pvt.dwc_dev, "%s: sg=%p nelem=%d lli=%p dma_lli=0x%08x" + " dmadr=0x%08x\n", __func__, sg, num_elems, lli, (u32)dma_lli, + (u32)dmadr_addr); + + bl = get_burst_length_encode(AHB_DMA_BRST_DFLT); + + for (i = 0; i < num_elems; i++, sg++) { + u32 addr, offset; + u32 sg_len, len; + + addr = (u32) sg_dma_address(sg); + sg_len = sg_dma_len(sg); + + dev_dbg(host_pvt.dwc_dev, "%s: elem=%d sg_addr=0x%x sg_len" + "=%d\n", __func__, i, addr, sg_len); + + while (sg_len) { + if (idx >= SATA_DWC_DMAC_LLI_NUM) { + /* The LLI table is not large enough. */ + dev_err(host_pvt.dwc_dev, "LLI table overrun " + "(idx=%d)\n", idx); + break; + } + len = (sg_len > SATA_DWC_DMAC_CTRL_TSIZE_MAX) ? + SATA_DWC_DMAC_CTRL_TSIZE_MAX : sg_len; + + offset = addr & 0xffff; + if ((offset + sg_len) > 0x10000) + len = 0x10000 - offset; + + /* + * Make sure a LLI block is not created that will span + * 8K max FIS boundary. If the block spans such a FIS + * boundary, there is a chance that a DMA burst will + * cross that boundary -- this results in an error in + * the host controller. + */ + if (fis_len + len > 8192) { + dev_dbg(host_pvt.dwc_dev, "SPLITTING: fis_len=" + "%d(0x%x) len=%d(0x%x)\n", fis_len, + fis_len, len, len); + len = 8192 - fis_len; + fis_len = 0; + } else { + fis_len += len; + } + if (fis_len == 8192) + fis_len = 0; + + /* + * Set DMA addresses and lower half of control register + * based on direction. + */ + if (dir == DMA_FROM_DEVICE) { + lli[idx].dar = cpu_to_le32(addr); + lli[idx].sar = cpu_to_le32((u32)dmadr_addr); + + lli[idx].ctl.low = cpu_to_le32( + DMA_CTL_TTFC(DMA_CTL_TTFC_P2M_DMAC) | + DMA_CTL_SMS(0) | + DMA_CTL_DMS(1) | + DMA_CTL_SRC_MSIZE(bl) | + DMA_CTL_DST_MSIZE(bl) | + DMA_CTL_SINC_NOCHANGE | + DMA_CTL_SRC_TRWID(2) | + DMA_CTL_DST_TRWID(2) | + DMA_CTL_INT_EN | + DMA_CTL_LLP_SRCEN | + DMA_CTL_LLP_DSTEN); + } else { /* DMA_TO_DEVICE */ + lli[idx].sar = cpu_to_le32(addr); + lli[idx].dar = cpu_to_le32((u32)dmadr_addr); + + lli[idx].ctl.low = cpu_to_le32( + DMA_CTL_TTFC(DMA_CTL_TTFC_M2P_PER) | + DMA_CTL_SMS(1) | + DMA_CTL_DMS(0) | + DMA_CTL_SRC_MSIZE(bl) | + DMA_CTL_DST_MSIZE(bl) | + DMA_CTL_DINC_NOCHANGE | + DMA_CTL_SRC_TRWID(2) | + DMA_CTL_DST_TRWID(2) | + DMA_CTL_INT_EN | + DMA_CTL_LLP_SRCEN | + DMA_CTL_LLP_DSTEN); + } + + dev_dbg(host_pvt.dwc_dev, "%s setting ctl.high len: " + "0x%08x val: 0x%08x\n", __func__, + len, DMA_CTL_BLK_TS(len / 4)); + + /* Program the LLI CTL high register */ + lli[idx].ctl.high = cpu_to_le32(DMA_CTL_BLK_TS\ + (len / 4)); + + /* Program the next pointer. The next pointer must be + * the physical address, not the virtual address. + */ + next_llp = (dma_lli + ((idx + 1) * sizeof(struct \ + lli))); + + /* The last 2 bits encode the list master select. */ + next_llp = DMA_LLP_LMS(next_llp, DMA_LLP_AHBMASTER2); + + lli[idx].llp = cpu_to_le32(next_llp); + idx++; + sg_len -= len; + addr += len; + } + } + + /* + * The last next ptr has to be zero and the last control low register + * has to have LLP_SRC_EN and LLP_DST_EN (linked list pointer source + * and destination enable) set back to 0 (disabled.) This is what tells + * the core that this is the last item in the linked list. + */ + if (idx) { + lli[idx-1].llp = 0x00000000; + lli[idx-1].ctl.low &= DMA_CTL_LLP_DISABLE_LE32; + + /* Flush cache to memory */ + dma_cache_sync(NULL, lli, (sizeof(struct lli) * idx), + DMA_BIDIRECTIONAL); + } + + return idx; +} + +/* + * Function: dma_dwc_xfer_start + * arguments: Channel number + * Return : None + * Enables the DMA channel + */ +static void dma_dwc_xfer_start(int dma_ch) +{ + /* Enable the DMA channel */ + out_le32(&(host_pvt.sata_dma_regs->dma_chan_en.low), + in_le32(&(host_pvt.sata_dma_regs->dma_chan_en.low)) | + DMA_ENABLE_CHAN(dma_ch)); +} + +static int dma_dwc_xfer_setup(struct scatterlist *sg, int num_elems, + struct lli *lli, dma_addr_t dma_lli, + void __iomem *addr, int dir) +{ + int dma_ch; + int num_lli; + /* Acquire DMA channel */ + dma_ch = dma_request_channel(); + if (dma_ch == -1) { + dev_err(host_pvt.dwc_dev, "%s: dma channel unavailable\n", + __func__); + return -EAGAIN; + } + + /* Convert SG list to linked list of items (LLIs) for AHB DMA */ + num_lli = map_sg_to_lli(sg, num_elems, lli, dma_lli, addr, dir); + + dev_dbg(host_pvt.dwc_dev, "%s sg: 0x%p, count: %d lli: %p dma_lli:" + " 0x%0xlx addr: %p lli count: %d\n", __func__, sg, num_elems, + lli, (u32)dma_lli, addr, num_lli); + + clear_chan_interrupts(dma_ch); + + /* Program the CFG register. */ + out_le32(&(host_pvt.sata_dma_regs->chan_regs[dma_ch].cfg.high), + DMA_CFG_PROTCTL | DMA_CFG_FCMOD_REQ); + out_le32(&(host_pvt.sata_dma_regs->chan_regs[dma_ch].cfg.low), 0); + + /* Program the address of the linked list */ + out_le32(&(host_pvt.sata_dma_regs->chan_regs[dma_ch].llp.low), + DMA_LLP_LMS(dma_lli, DMA_LLP_AHBMASTER2)); + + /* Program the CTL register with src enable / dst enable */ + out_le32(&(host_pvt.sata_dma_regs->chan_regs[dma_ch].ctl.low), + DMA_CTL_LLP_SRCEN | DMA_CTL_LLP_DSTEN); + return 0; +} + +/* + * Function: dma_dwc_exit + * arguments: None + * returns status + * This function exits the SATA DMA driver + */ +static void dma_dwc_exit(struct sata_dwc_device *hsdev) +{ + dev_dbg(host_pvt.dwc_dev, "%s:\n", __func__); + if (host_pvt.sata_dma_regs) + iounmap(host_pvt.sata_dma_regs); + + if (hsdev->irq_dma) + free_irq(hsdev->irq_dma, hsdev); +} + +/* + * Function: dma_dwc_init + * arguments: hsdev + * returns status + * This function initializes the SATA DMA driver + */ +static int dma_dwc_init(struct sata_dwc_device *hsdev, int irq) +{ + int err; + + err = dma_request_interrupts(hsdev, irq); + if (err) { + dev_err(host_pvt.dwc_dev, "%s: dma_request_interrupts returns" + " %d\n", __func__, err); + goto error_out; + } + + /* Enabe DMA */ + out_le32(&(host_pvt.sata_dma_regs->dma_cfg.low), DMA_EN); + + dev_notice(host_pvt.dwc_dev, "DMA initialized\n"); + dev_dbg(host_pvt.dwc_dev, "SATA DMA registers=0x%p\n", host_pvt.\ + sata_dma_regs); + + return 0; + +error_out: + dma_dwc_exit(hsdev); + + return err; +} + +static int sata_dwc_scr_read(struct ata_link *link, unsigned int scr, u32 *val) +{ + if (scr > SCR_NOTIFICATION) { + dev_err(link->ap->dev, "%s: Incorrect SCR offset 0x%02x\n", + __func__, scr); + return -EINVAL; + } + + *val = in_le32((void *)link->ap->ioaddr.scr_addr + (scr * 4)); + dev_dbg(link->ap->dev, "%s: id=%d reg=%d val=val=0x%08x\n", + __func__, link->ap->print_id, scr, *val); + + return 0; +} + +static int sata_dwc_scr_write(struct ata_link *link, unsigned int scr, u32 val) +{ + dev_dbg(link->ap->dev, "%s: id=%d reg=%d val=val=0x%08x\n", + __func__, link->ap->print_id, scr, val); + if (scr > SCR_NOTIFICATION) { + dev_err(link->ap->dev, "%s: Incorrect SCR offset 0x%02x\n", + __func__, scr); + return -EINVAL; + } + out_le32((void *)link->ap->ioaddr.scr_addr + (scr * 4), val); + + return 0; +} + +static u32 core_scr_read(unsigned int scr) +{ + return in_le32((void __iomem *)(host_pvt.scr_addr_sstatus) +\ + (scr * 4)); +} + +static void core_scr_write(unsigned int scr, u32 val) +{ + out_le32((void __iomem *)(host_pvt.scr_addr_sstatus) + (scr * 4), + val); +} + +static void clear_serror(void) +{ + u32 val; + val = core_scr_read(SCR_ERROR); + core_scr_write(SCR_ERROR, val); + +} + +static void clear_interrupt_bit(struct sata_dwc_device *hsdev, u32 bit) +{ + out_le32(&hsdev->sata_dwc_regs->intpr, + in_le32(&hsdev->sata_dwc_regs->intpr)); +} + +static u32 qcmd_tag_to_mask(u8 tag) +{ + return 0x00000001 << (tag & 0x1f); +} + +/* See ahci.c */ +static void sata_dwc_error_intr(struct ata_port *ap, + struct sata_dwc_device *hsdev, uint intpr) +{ + struct sata_dwc_device_port *hsdevp = HSDEVP_FROM_AP(ap); + struct ata_eh_info *ehi = &ap->link.eh_info; + unsigned int err_mask = 0, action = 0; + struct ata_queued_cmd *qc; + u32 serror; + u8 status, tag; + u32 err_reg; + + ata_ehi_clear_desc(ehi); + + serror = core_scr_read(SCR_ERROR); + status = ap->ops->sff_check_status(ap); + + err_reg = in_le32(&(host_pvt.sata_dma_regs->interrupt_status.error.\ + low)); + tag = ap->link.active_tag; + + dev_err(ap->dev, "%s SCR_ERROR=0x%08x intpr=0x%08x status=0x%08x " + "dma_intp=%d pending=%d issued=%d dma_err_status=0x%08x\n", + __func__, serror, intpr, status, host_pvt.dma_interrupt_count, + hsdevp->dma_pending[tag], hsdevp->cmd_issued[tag], err_reg); + + /* Clear error register and interrupt bit */ + clear_serror(); + clear_interrupt_bit(hsdev, SATA_DWC_INTPR_ERR); + + /* This is the only error happening now. TODO check for exact error */ + + err_mask |= AC_ERR_HOST_BUS; + action |= ATA_EH_RESET; + + /* Pass this on to EH */ + ehi->serror |= serror; + ehi->action |= action; + + qc = ata_qc_from_tag(ap, tag); + if (qc) + qc->err_mask |= err_mask; + else + ehi->err_mask |= err_mask; + + ata_port_abort(ap); +} + +/* + * Function : sata_dwc_isr + * arguments : irq, void *dev_instance, struct pt_regs *regs + * Return value : irqreturn_t - status of IRQ + * This Interrupt handler called via port ops registered function. + * .irq_handler = sata_dwc_isr + */ +static irqreturn_t sata_dwc_isr(int irq, void *dev_instance) +{ + struct ata_host *host = (struct ata_host *)dev_instance; + struct sata_dwc_device *hsdev = HSDEV_FROM_HOST(host); + struct ata_port *ap; + struct ata_queued_cmd *qc; + unsigned long flags; + u8 status, tag; + int handled, num_processed, port = 0; + uint intpr, sactive, sactive2, tag_mask; + struct sata_dwc_device_port *hsdevp; + host_pvt.sata_dwc_sactive_issued = 0; + + spin_lock_irqsave(&host->lock, flags); + + /* Read the interrupt register */ + intpr = in_le32(&hsdev->sata_dwc_regs->intpr); + + ap = host->ports[port]; + hsdevp = HSDEVP_FROM_AP(ap); + + dev_dbg(ap->dev, "%s intpr=0x%08x active_tag=%d\n", __func__, intpr, + ap->link.active_tag); + + /* Check for error interrupt */ + if (intpr & SATA_DWC_INTPR_ERR) { + sata_dwc_error_intr(ap, hsdev, intpr); + handled = 1; + goto DONE; + } + + /* Check for DMA SETUP FIS (FP DMA) interrupt */ + if (intpr & SATA_DWC_INTPR_NEWFP) { + clear_interrupt_bit(hsdev, SATA_DWC_INTPR_NEWFP); + + tag = (u8)(in_le32(&hsdev->sata_dwc_regs->fptagr)); + dev_dbg(ap->dev, "%s: NEWFP tag=%d\n", __func__, tag); + if (hsdevp->cmd_issued[tag] != SATA_DWC_CMD_ISSUED_PEND) + dev_warn(ap->dev, "CMD tag=%d not pending?\n", tag); + + host_pvt.sata_dwc_sactive_issued |= qcmd_tag_to_mask(tag); + + qc = ata_qc_from_tag(ap, tag); + /* + * Start FP DMA for NCQ command. At this point the tag is the + * active tag. It is the tag that matches the command about to + * be completed. + */ + qc->ap->link.active_tag = tag; + sata_dwc_bmdma_start_by_tag(qc, tag); + + handled = 1; + goto DONE; + } + sactive = core_scr_read(SCR_ACTIVE); + tag_mask = (host_pvt.sata_dwc_sactive_issued | sactive) ^ sactive; + + /* If no sactive issued and tag_mask is zero then this is not NCQ */ + if (host_pvt.sata_dwc_sactive_issued == 0 && tag_mask == 0) { + if (ap->link.active_tag == ATA_TAG_POISON) + tag = 0; + else + tag = ap->link.active_tag; + qc = ata_qc_from_tag(ap, tag); + + /* DEV interrupt w/ no active qc? */ + if (unlikely(!qc || (qc->tf.flags & ATA_TFLAG_POLLING))) { + dev_err(ap->dev, "%s interrupt with no active qc " + "qc=%p\n", __func__, qc); + ap->ops->sff_check_status(ap); + handled = 1; + goto DONE; + } + status = ap->ops->sff_check_status(ap); + + qc->ap->link.active_tag = tag; + hsdevp->cmd_issued[tag] = SATA_DWC_CMD_ISSUED_NOT; + + if (status & ATA_ERR) { + dev_dbg(ap->dev, "interrupt ATA_ERR (0x%x)\n", status); + sata_dwc_qc_complete(ap, qc, 1); + handled = 1; + goto DONE; + } + + dev_dbg(ap->dev, "%s non-NCQ cmd interrupt, protocol: %s\n", + __func__, ata_get_cmd_descript(qc->tf.protocol)); +DRVSTILLBUSY: + if (ata_is_dma(qc->tf.protocol)) { + /* + * Each DMA transaction produces 2 interrupts. The DMAC + * transfer complete interrupt and the SATA controller + * operation done interrupt. The command should be + * completed only after both interrupts are seen. + */ + host_pvt.dma_interrupt_count++; + if (hsdevp->dma_pending[tag] == \ + SATA_DWC_DMA_PENDING_NONE) { + dev_err(ap->dev, "%s: DMA not pending " + "intpr=0x%08x status=0x%08x pending" + "=%d\n", __func__, intpr, status, + hsdevp->dma_pending[tag]); + } + + if ((host_pvt.dma_interrupt_count % 2) == 0) + sata_dwc_dma_xfer_complete(ap, 1); + } else if (ata_is_pio(qc->tf.protocol)) { + ata_sff_hsm_move(ap, qc, status, 0); + handled = 1; + goto DONE; + } else { + if (unlikely(sata_dwc_qc_complete(ap, qc, 1))) + goto DRVSTILLBUSY; + } + + handled = 1; + goto DONE; + } + + /* + * This is a NCQ command. At this point we need to figure out for which + * tags we have gotten a completion interrupt. One interrupt may serve + * as completion for more than one operation when commands are queued + * (NCQ). We need to process each completed command. + */ + + /* process completed commands */ + sactive = core_scr_read(SCR_ACTIVE); + tag_mask = (host_pvt.sata_dwc_sactive_issued | sactive) ^ sactive; + + if (sactive != 0 || (host_pvt.sata_dwc_sactive_issued) > 1 || \ + tag_mask > 1) { + dev_dbg(ap->dev, "%s NCQ:sactive=0x%08x sactive_issued=0x%08x" + "tag_mask=0x%08x\n", __func__, sactive, + host_pvt.sata_dwc_sactive_issued, tag_mask); + } + + if ((tag_mask | (host_pvt.sata_dwc_sactive_issued)) != \ + (host_pvt.sata_dwc_sactive_issued)) { + dev_warn(ap->dev, "Bad tag mask? sactive=0x%08x " + "(host_pvt.sata_dwc_sactive_issued)=0x%08x tag_mask" + "=0x%08x\n", sactive, host_pvt.sata_dwc_sactive_issued, + tag_mask); + } + + /* read just to clear ... not bad if currently still busy */ + status = ap->ops->sff_check_status(ap); + dev_dbg(ap->dev, "%s ATA status register=0x%x\n", __func__, status); + + tag = 0; + num_processed = 0; + while (tag_mask) { + num_processed++; + while (!(tag_mask & 0x00000001)) { + tag++; + tag_mask <<= 1; + } + + tag_mask &= (~0x00000001); + qc = ata_qc_from_tag(ap, tag); + + /* To be picked up by completion functions */ + qc->ap->link.active_tag = tag; + hsdevp->cmd_issued[tag] = SATA_DWC_CMD_ISSUED_NOT; + + /* Let libata/scsi layers handle error */ + if (status & ATA_ERR) { + dev_dbg(ap->dev, "%s ATA_ERR (0x%x)\n", __func__, + status); + sata_dwc_qc_complete(ap, qc, 1); + handled = 1; + goto DONE; + } + + /* Process completed command */ + dev_dbg(ap->dev, "%s NCQ command, protocol: %s\n", __func__, + ata_get_cmd_descript(qc->tf.protocol)); + if (ata_is_dma(qc->tf.protocol)) { + host_pvt.dma_interrupt_count++; + if (hsdevp->dma_pending[tag] == \ + SATA_DWC_DMA_PENDING_NONE) + dev_warn(ap->dev, "%s: DMA not pending?\n", + __func__); + if ((host_pvt.dma_interrupt_count % 2) == 0) + sata_dwc_dma_xfer_complete(ap, 1); + } else { + if (unlikely(sata_dwc_qc_complete(ap, qc, 1))) + goto STILLBUSY; + } + continue; + +STILLBUSY: + ap->stats.idle_irq++; + dev_warn(ap->dev, "STILL BUSY IRQ ata%d: irq trap\n", + ap->print_id); + } /* while tag_mask */ + + /* + * Check to see if any commands completed while we were processing our + * initial set of completed commands (read status clears interrupts, + * so we might miss a completed command interrupt if one came in while + * we were processing --we read status as part of processing a completed + * command). + */ + sactive2 = core_scr_read(SCR_ACTIVE); + if (sactive2 != sactive) { + dev_dbg(ap->dev, "More completed - sactive=0x%x sactive2" + "=0x%x\n", sactive, sactive2); + } + handled = 1; + +DONE: + spin_unlock_irqrestore(&host->lock, flags); + return IRQ_RETVAL(handled); +} + +static void sata_dwc_clear_dmacr(struct sata_dwc_device_port *hsdevp, u8 tag) +{ + struct sata_dwc_device *hsdev = HSDEV_FROM_HSDEVP(hsdevp); + + if (hsdevp->dma_pending[tag] == SATA_DWC_DMA_PENDING_RX) { + out_le32(&(hsdev->sata_dwc_regs->dmacr), + SATA_DWC_DMACR_RX_CLEAR( + in_le32(&(hsdev->sata_dwc_regs->dmacr)))); + } else if (hsdevp->dma_pending[tag] == SATA_DWC_DMA_PENDING_TX) { + out_le32(&(hsdev->sata_dwc_regs->dmacr), + SATA_DWC_DMACR_TX_CLEAR( + in_le32(&(hsdev->sata_dwc_regs->dmacr)))); + } else { + /* + * This should not happen, it indicates the driver is out of + * sync. If it does happen, clear dmacr anyway. + */ + dev_err(host_pvt.dwc_dev, "%s DMA protocol RX and" + "TX DMA not pending tag=0x%02x pending=%d" + " dmacr: 0x%08x\n", __func__, tag, + hsdevp->dma_pending[tag], + in_le32(&(hsdev->sata_dwc_regs->dmacr))); + out_le32(&(hsdev->sata_dwc_regs->dmacr), + SATA_DWC_DMACR_TXRXCH_CLEAR); + } +} + +static void sata_dwc_dma_xfer_complete(struct ata_port *ap, u32 check_status) +{ + struct ata_queued_cmd *qc; + struct sata_dwc_device_port *hsdevp = HSDEVP_FROM_AP(ap); + struct sata_dwc_device *hsdev = HSDEV_FROM_AP(ap); + u8 tag = 0; + + tag = ap->link.active_tag; + qc = ata_qc_from_tag(ap, tag); + if (!qc) { + dev_err(ap->dev, "failed to get qc"); + return; + } + +#ifdef DEBUG_NCQ + if (tag > 0) { + dev_info(ap->dev, "%s tag=%u cmd=0x%02x dma dir=%s proto=%s " + "dmacr=0x%08x\n", __func__, qc->tag, qc->tf.command, + ata_get_cmd_descript(qc->dma_dir), + ata_get_cmd_descript(qc->tf.protocol), + in_le32(&(hsdev->sata_dwc_regs->dmacr))); + } +#endif + + if (ata_is_dma(qc->tf.protocol)) { + if (hsdevp->dma_pending[tag] == SATA_DWC_DMA_PENDING_NONE) { + dev_err(ap->dev, "%s DMA protocol RX and TX DMA not " + "pending dmacr: 0x%08x\n", __func__, + in_le32(&(hsdev->sata_dwc_regs->dmacr))); + } + + hsdevp->dma_pending[tag] = SATA_DWC_DMA_PENDING_NONE; + sata_dwc_qc_complete(ap, qc, check_status); + ap->link.active_tag = ATA_TAG_POISON; + } else { + sata_dwc_qc_complete(ap, qc, check_status); + } +} + +static int sata_dwc_qc_complete(struct ata_port *ap, struct ata_queued_cmd *qc, + u32 check_status) +{ + u8 status = 0; + u32 mask = 0x0; + u8 tag = qc->tag; + struct sata_dwc_device_port *hsdevp = HSDEVP_FROM_AP(ap); + host_pvt.sata_dwc_sactive_queued = 0; + dev_dbg(ap->dev, "%s checkstatus? %x\n", __func__, check_status); + + if (hsdevp->dma_pending[tag] == SATA_DWC_DMA_PENDING_TX) + dev_err(ap->dev, "TX DMA PENDING\n"); + else if (hsdevp->dma_pending[tag] == SATA_DWC_DMA_PENDING_RX) + dev_err(ap->dev, "RX DMA PENDING\n"); + dev_dbg(ap->dev, "QC complete cmd=0x%02x status=0x%02x ata%u:" + " protocol=%d\n", qc->tf.command, status, ap->print_id, + qc->tf.protocol); + + /* clear active bit */ + mask = (~(qcmd_tag_to_mask(tag))); + host_pvt.sata_dwc_sactive_queued = (host_pvt.sata_dwc_sactive_queued) \ + & mask; + host_pvt.sata_dwc_sactive_issued = (host_pvt.sata_dwc_sactive_issued) \ + & mask; + ata_qc_complete(qc); + return 0; +} + +static void sata_dwc_enable_interrupts(struct sata_dwc_device *hsdev) +{ + /* Enable selective interrupts by setting the interrupt maskregister*/ + out_le32(&hsdev->sata_dwc_regs->intmr, + SATA_DWC_INTMR_ERRM | + SATA_DWC_INTMR_NEWFPM | + SATA_DWC_INTMR_PMABRTM | + SATA_DWC_INTMR_DMATM); + /* + * Unmask the error bits that should trigger an error interrupt by + * setting the error mask register. + */ + out_le32(&hsdev->sata_dwc_regs->errmr, SATA_DWC_SERROR_ERR_BITS); + + dev_dbg(host_pvt.dwc_dev, "%s: INTMR = 0x%08x, ERRMR = 0x%08x\n", + __func__, in_le32(&hsdev->sata_dwc_regs->intmr), + in_le32(&hsdev->sata_dwc_regs->errmr)); +} + +static void sata_dwc_setup_port(struct ata_ioports *port, unsigned long base) +{ + port->cmd_addr = (void *)base + 0x00; + port->data_addr = (void *)base + 0x00; + + port->error_addr = (void *)base + 0x04; + port->feature_addr = (void *)base + 0x04; + + port->nsect_addr = (void *)base + 0x08; + + port->lbal_addr = (void *)base + 0x0c; + port->lbam_addr = (void *)base + 0x10; + port->lbah_addr = (void *)base + 0x14; + + port->device_addr = (void *)base + 0x18; + port->command_addr = (void *)base + 0x1c; + port->status_addr = (void *)base + 0x1c; + + port->altstatus_addr = (void *)base + 0x20; + port->ctl_addr = (void *)base + 0x20; +} + +/* + * Function : sata_dwc_port_start + * arguments : struct ata_ioports *port + * Return value : returns 0 if success, error code otherwise + * This function allocates the scatter gather LLI table for AHB DMA + */ +static int sata_dwc_port_start(struct ata_port *ap) +{ + int err = 0; + struct sata_dwc_device *hsdev; + struct sata_dwc_device_port *hsdevp = NULL; + struct device *pdev; + int i; + + hsdev = HSDEV_FROM_AP(ap); + + dev_dbg(ap->dev, "%s: port_no=%d\n", __func__, ap->port_no); + + hsdev->host = ap->host; + pdev = ap->host->dev; + if (!pdev) { + dev_err(ap->dev, "%s: no ap->host->dev\n", __func__); + err = -ENODEV; + goto CLEANUP; + } + + /* Allocate Port Struct */ + hsdevp = kzalloc(sizeof(*hsdevp), GFP_KERNEL); + if (!hsdevp) { + dev_err(ap->dev, "%s: kmalloc failed for hsdevp\n", __func__); + err = -ENOMEM; + goto CLEANUP; + } + hsdevp->hsdev = hsdev; + + for (i = 0; i < SATA_DWC_QCMD_MAX; i++) + hsdevp->cmd_issued[i] = SATA_DWC_CMD_ISSUED_NOT; + + ap->bmdma_prd = 0; /* set these so libata doesn't use them */ + ap->bmdma_prd_dma = 0; + + /* + * DMA - Assign scatter gather LLI table. We can't use the libata + * version since it's PRD is IDE PCI specific. + */ + for (i = 0; i < SATA_DWC_QCMD_MAX; i++) { + hsdevp->llit[i] = dma_alloc_coherent(pdev, + SATA_DWC_DMAC_LLI_TBL_SZ, + &(hsdevp->llit_dma[i]), + GFP_ATOMIC); + if (!hsdevp->llit[i]) { + dev_err(ap->dev, "%s: dma_alloc_coherent failed\n", + __func__); + err = -ENOMEM; + goto CLEANUP; + } + } + + if (ap->port_no == 0) { + dev_dbg(ap->dev, "%s: clearing TXCHEN, RXCHEN in DMAC\n", + __func__); + out_le32(&hsdev->sata_dwc_regs->dmacr, + SATA_DWC_DMACR_TXRXCH_CLEAR); + + dev_dbg(ap->dev, "%s: setting burst size in DBTSR\n", + __func__); + out_le32(&hsdev->sata_dwc_regs->dbtsr, + (SATA_DWC_DBTSR_MWR(AHB_DMA_BRST_DFLT) | + SATA_DWC_DBTSR_MRD(AHB_DMA_BRST_DFLT))); + } + + /* Clear any error bits before libata starts issuing commands */ + clear_serror(); + ap->private_data = hsdevp; + +CLEANUP: + if (err) { + sata_dwc_port_stop(ap); + dev_dbg(ap->dev, "%s: fail\n", __func__); + } else { + dev_dbg(ap->dev, "%s: done\n", __func__); + } + + return err; +} + +static void sata_dwc_port_stop(struct ata_port *ap) +{ + int i; + struct sata_dwc_device *hsdev = HSDEV_FROM_AP(ap); + struct sata_dwc_device_port *hsdevp = HSDEVP_FROM_AP(ap); + + dev_dbg(ap->dev, "%s: ap->id = %d\n", __func__, ap->print_id); + + if (hsdevp && hsdev) { + /* deallocate LLI table */ + for (i = 0; i < SATA_DWC_QCMD_MAX; i++) { + dma_free_coherent(ap->host->dev, + SATA_DWC_DMAC_LLI_TBL_SZ, + hsdevp->llit[i], hsdevp->llit_dma[i]); + } + + kfree(hsdevp); + } + ap->private_data = NULL; +} + +/* + * Function : sata_dwc_exec_command_by_tag + * arguments : ata_port *ap, ata_taskfile *tf, u8 tag, u32 cmd_issued + * Return value : None + * This function keeps track of individual command tag ids and calls + * ata_exec_command in libata + */ +static void sata_dwc_exec_command_by_tag(struct ata_port *ap, + struct ata_taskfile *tf, + u8 tag, u32 cmd_issued) +{ + unsigned long flags; + struct sata_dwc_device_port *hsdevp = HSDEVP_FROM_AP(ap); + + dev_dbg(ap->dev, "%s cmd(0x%02x): %s tag=%d\n", __func__, tf->command, + ata_get_cmd_descript(tf), tag); + + spin_lock_irqsave(&ap->host->lock, flags); + hsdevp->cmd_issued[tag] = cmd_issued; + spin_unlock_irqrestore(&ap->host->lock, flags); + /* + * Clear SError before executing a new command. + * sata_dwc_scr_write and read can not be used here. Clearing the PM + * managed SError register for the disk needs to be done before the + * task file is loaded. + */ + clear_serror(); + ata_sff_exec_command(ap, tf); +} + +static void sata_dwc_bmdma_setup_by_tag(struct ata_queued_cmd *qc, u8 tag) +{ + sata_dwc_exec_command_by_tag(qc->ap, &qc->tf, tag, + SATA_DWC_CMD_ISSUED_PEND); +} + +static void sata_dwc_bmdma_setup(struct ata_queued_cmd *qc) +{ + u8 tag = qc->tag; + + if (ata_is_ncq(qc->tf.protocol)) { + dev_dbg(qc->ap->dev, "%s: ap->link.sactive=0x%08x tag=%d\n", + __func__, qc->ap->link.sactive, tag); + } else { + tag = 0; + } + sata_dwc_bmdma_setup_by_tag(qc, tag); +} + +static void sata_dwc_bmdma_start_by_tag(struct ata_queued_cmd *qc, u8 tag) +{ + int start_dma; + u32 reg, dma_chan; + struct sata_dwc_device *hsdev = HSDEV_FROM_QC(qc); + struct ata_port *ap = qc->ap; + struct sata_dwc_device_port *hsdevp = HSDEVP_FROM_AP(ap); + int dir = qc->dma_dir; + dma_chan = hsdevp->dma_chan[tag]; + + if (hsdevp->cmd_issued[tag] != SATA_DWC_CMD_ISSUED_NOT) { + start_dma = 1; + if (dir == DMA_TO_DEVICE) + hsdevp->dma_pending[tag] = SATA_DWC_DMA_PENDING_TX; + else + hsdevp->dma_pending[tag] = SATA_DWC_DMA_PENDING_RX; + } else { + dev_err(ap->dev, "%s: Command not pending cmd_issued=%d " + "(tag=%d) DMA NOT started\n", __func__, + hsdevp->cmd_issued[tag], tag); + start_dma = 0; + } + + dev_dbg(ap->dev, "%s qc=%p tag: %x cmd: 0x%02x dma_dir: %s " + "start_dma? %x\n", __func__, qc, tag, qc->tf.command, + ata_get_cmd_descript(qc->dma_dir), start_dma); + sata_dwc_tf_dump(&(qc->tf)); + + if (start_dma) { + reg = core_scr_read(SCR_ERROR); + if (reg & SATA_DWC_SERROR_ERR_BITS) { + dev_err(ap->dev, "%s: ****** SError=0x%08x ******\n", + __func__, reg); + } + + if (dir == DMA_TO_DEVICE) + out_le32(&hsdev->sata_dwc_regs->dmacr, + SATA_DWC_DMACR_TXCHEN); + else + out_le32(&hsdev->sata_dwc_regs->dmacr, + SATA_DWC_DMACR_RXCHEN); + + /* Enable AHB DMA transfer on the specified channel */ + dma_dwc_xfer_start(dma_chan); + } +} + +static void sata_dwc_bmdma_start(struct ata_queued_cmd *qc) +{ + u8 tag = qc->tag; + + if (ata_is_ncq(qc->tf.protocol)) { + dev_dbg(qc->ap->dev, "%s: ap->link.sactive=0x%08x tag=%d\n", + __func__, qc->ap->link.sactive, tag); + } else { + tag = 0; + } + dev_dbg(qc->ap->dev, "%s\n", __func__); + sata_dwc_bmdma_start_by_tag(qc, tag); +} + +/* + * Function : sata_dwc_qc_prep_by_tag + * arguments : ata_queued_cmd *qc, u8 tag + * Return value : None + * qc_prep for a particular queued command based on tag + */ +static void sata_dwc_qc_prep_by_tag(struct ata_queued_cmd *qc, u8 tag) +{ + struct scatterlist *sg = qc->sg; + struct ata_port *ap = qc->ap; + u32 dma_chan; + struct sata_dwc_device *hsdev = HSDEV_FROM_AP(ap); + struct sata_dwc_device_port *hsdevp = HSDEVP_FROM_AP(ap); + int err; + + dev_dbg(ap->dev, "%s: port=%d dma dir=%s n_elem=%d\n", + __func__, ap->port_no, ata_get_cmd_descript(qc->dma_dir), + qc->n_elem); + + dma_chan = dma_dwc_xfer_setup(sg, qc->n_elem, hsdevp->llit[tag], + hsdevp->llit_dma[tag], + (void *__iomem)(&hsdev->sata_dwc_regs->\ + dmadr), qc->dma_dir); + if (dma_chan < 0) { + dev_err(ap->dev, "%s: dma_dwc_xfer_setup returns err %d\n", + __func__, err); + return; + } + hsdevp->dma_chan[tag] = dma_chan; +} + +static unsigned int sata_dwc_qc_issue(struct ata_queued_cmd *qc) +{ + u32 sactive; + u8 tag = qc->tag; + struct ata_port *ap = qc->ap; + +#ifdef DEBUG_NCQ + if (qc->tag > 0 || ap->link.sactive > 1) + dev_info(ap->dev, "%s ap id=%d cmd(0x%02x)=%s qc tag=%d " + "prot=%s ap active_tag=0x%08x ap sactive=0x%08x\n", + __func__, ap->print_id, qc->tf.command, + ata_get_cmd_descript(&qc->tf), + qc->tag, ata_get_cmd_descript(qc->tf.protocol), + ap->link.active_tag, ap->link.sactive); +#endif + + if (!ata_is_ncq(qc->tf.protocol)) + tag = 0; + sata_dwc_qc_prep_by_tag(qc, tag); + + if (ata_is_ncq(qc->tf.protocol)) { + sactive = core_scr_read(SCR_ACTIVE); + sactive |= (0x00000001 << tag); + core_scr_write(SCR_ACTIVE, sactive); + + dev_dbg(qc->ap->dev, "%s: tag=%d ap->link.sactive = 0x%08x " + "sactive=0x%08x\n", __func__, tag, qc->ap->link.sactive, + sactive); + + ap->ops->sff_tf_load(ap, &qc->tf); + sata_dwc_exec_command_by_tag(ap, &qc->tf, qc->tag, + SATA_DWC_CMD_ISSUED_PEND); + } else { + ata_sff_qc_issue(qc); + } + return 0; +} + +/* + * Function : sata_dwc_qc_prep + * arguments : ata_queued_cmd *qc + * Return value : None + * qc_prep for a particular queued command + */ + +static void sata_dwc_qc_prep(struct ata_queued_cmd *qc) +{ + if ((qc->dma_dir == DMA_NONE) || (qc->tf.protocol == ATA_PROT_PIO)) + return; + +#ifdef DEBUG_NCQ + if (qc->tag > 0) + dev_info(qc->ap->dev, "%s: qc->tag=%d ap->active_tag=0x%08x\n", + __func__, tag, qc->ap->link.active_tag); + + return ; +#endif +} + +static void sata_dwc_error_handler(struct ata_port *ap) +{ + ap->link.flags |= ATA_LFLAG_NO_HRST; + ata_sff_error_handler(ap); +} + +/* + * scsi mid-layer and libata interface structures + */ +static struct scsi_host_template sata_dwc_sht = { + ATA_NCQ_SHT(DRV_NAME), + /* + * test-only: Currently this driver doesn't handle NCQ + * correctly. We enable NCQ but set the queue depth to a + * max of 1. This will get fixed in in a future release. + */ + .sg_tablesize = LIBATA_MAX_PRD, + .can_queue = ATA_DEF_QUEUE, /* ATA_MAX_QUEUE */ + .dma_boundary = ATA_DMA_BOUNDARY, +}; + +static struct ata_port_operations sata_dwc_ops = { + .inherits = &ata_sff_port_ops, + + .error_handler = sata_dwc_error_handler, + + .qc_prep = sata_dwc_qc_prep, + .qc_issue = sata_dwc_qc_issue, + + .scr_read = sata_dwc_scr_read, + .scr_write = sata_dwc_scr_write, + + .port_start = sata_dwc_port_start, + .port_stop = sata_dwc_port_stop, + + .bmdma_setup = sata_dwc_bmdma_setup, + .bmdma_start = sata_dwc_bmdma_start, +}; + +static const struct ata_port_info sata_dwc_port_info[] = { + { + .flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | + ATA_FLAG_MMIO | ATA_FLAG_NCQ, + .pio_mask = 0x1f, /* pio 0-4 */ + .udma_mask = ATA_UDMA6, + .port_ops = &sata_dwc_ops, + }, +}; + +static int sata_dwc_probe(struct of_device *ofdev, + const struct of_device_id *match) +{ + struct sata_dwc_device *hsdev; + u32 idr, versionr; + char *ver = (char *)&versionr; + u8 *base = NULL; + int err = 0; + int irq, rc; + struct ata_host *host; + struct ata_port_info pi = sata_dwc_port_info[0]; + const struct ata_port_info *ppi[] = { &pi, NULL }; + + /* Allocate DWC SATA device */ + hsdev = kmalloc(sizeof(*hsdev), GFP_KERNEL); + if (hsdev == NULL) { + dev_err(&ofdev->dev, "kmalloc failed for hsdev\n"); + err = -ENOMEM; + goto error_out; + } + memset(hsdev, 0, sizeof(*hsdev)); + + /* Ioremap SATA registers */ + base = of_iomap(ofdev->dev.of_node, 0); + if (!base) { + dev_err(&ofdev->dev, "ioremap failed for SATA register" + " address\n"); + err = -ENODEV; + goto error_out; + } + hsdev->reg_base = base; + dev_dbg(&ofdev->dev, "ioremap done for SATA register address\n"); + + /* Synopsys DWC SATA specific Registers */ + hsdev->sata_dwc_regs = (void *__iomem)(base + SATA_DWC_REG_OFFSET); + + /* Allocate and fill host */ + host = ata_host_alloc_pinfo(&ofdev->dev, ppi, SATA_DWC_MAX_PORTS); + if (!host) { + dev_err(&ofdev->dev, "ata_host_alloc_pinfo failed\n"); + err = -ENOMEM; + goto error_out; + } + + host->private_data = hsdev; + + /* Setup port */ + host->ports[0]->ioaddr.cmd_addr = base; + host->ports[0]->ioaddr.scr_addr = base + SATA_DWC_SCR_OFFSET; + host_pvt.scr_addr_sstatus = base + SATA_DWC_SCR_OFFSET; + sata_dwc_setup_port(&host->ports[0]->ioaddr, (unsigned long)base); + + /* Read the ID and Version Registers */ + idr = in_le32(&hsdev->sata_dwc_regs->idr); + versionr = in_le32(&hsdev->sata_dwc_regs->versionr); + dev_notice(&ofdev->dev, "id %d, controller version %c.%c%c\n", + idr, ver[0], ver[1], ver[2]); + + /* Get SATA DMA interrupt number */ + irq = irq_of_parse_and_map(ofdev->dev.of_node, 1); + if (irq == NO_IRQ) { + dev_err(&ofdev->dev, "no SATA DMA irq\n"); + err = -ENODEV; + goto error_out; + } + + /* Get physical SATA DMA register base address */ + host_pvt.sata_dma_regs = of_iomap(ofdev->dev.of_node, 1); + if (!(host_pvt.sata_dma_regs)) { + dev_err(&ofdev->dev, "ioremap failed for AHBDMA register" + " address\n"); + err = -ENODEV; + goto error_out; + } + + /* Save dev for later use in dev_xxx() routines */ + host_pvt.dwc_dev = &ofdev->dev; + + /* Initialize AHB DMAC */ + dma_dwc_init(hsdev, irq); + + /* Enable SATA Interrupts */ + sata_dwc_enable_interrupts(hsdev); + + /* Get SATA interrupt number */ + irq = irq_of_parse_and_map(ofdev->dev.of_node, 0); + if (irq == NO_IRQ) { + dev_err(&ofdev->dev, "no SATA DMA irq\n"); + err = -ENODEV; + goto error_out; + } + + /* + * Now, register with libATA core, this will also initiate the + * device discovery process, invoking our port_start() handler & + * error_handler() to execute a dummy Softreset EH session + */ + rc = ata_host_activate(host, irq, sata_dwc_isr, 0, &sata_dwc_sht); + + if (rc != 0) + dev_err(&ofdev->dev, "failed to activate host"); + + dev_set_drvdata(&ofdev->dev, host); + return 0; + +error_out: + /* Free SATA DMA resources */ + dma_dwc_exit(hsdev); + + if (base) + iounmap(base); + return err; +} + +static int sata_dwc_remove(struct of_device *ofdev) +{ + struct device *dev = &ofdev->dev; + struct ata_host *host = dev_get_drvdata(dev); + struct sata_dwc_device *hsdev = host->private_data; + + ata_host_detach(host); + dev_set_drvdata(dev, NULL); + + /* Free SATA DMA resources */ + dma_dwc_exit(hsdev); + + iounmap(hsdev->reg_base); + kfree(hsdev); + kfree(host); + dev_dbg(&ofdev->dev, "done\n"); + return 0; +} + +static const struct of_device_id sata_dwc_match[] = { + { .compatible = "amcc,sata-460ex", }, + {} +}; +MODULE_DEVICE_TABLE(of, sata_dwc_match); + +static struct of_platform_driver sata_dwc_driver = { + .driver = { + .name = DRV_NAME, + .owner = THIS_MODULE, + .of_match_table = sata_dwc_match, + }, + .probe = sata_dwc_probe, + .remove = sata_dwc_remove, +}; + +static int __init sata_dwc_init(void) +{ + return of_register_platform_driver(&sata_dwc_driver); +} + +static void __exit sata_dwc_exit(void) +{ + of_unregister_platform_driver(&sata_dwc_driver); +} + +module_init(sata_dwc_init); +module_exit(sata_dwc_exit); + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Mark Miesfeld "); +MODULE_DESCRIPTION("DesignWare Cores SATA controller low lever driver"); +MODULE_VERSION(DRV_VERSION); -- cgit v1.2.3 From 155bf48f10fc3c8e0e3125e221981328cd925cf4 Mon Sep 17 00:00:00 2001 From: Abhilash Kesavan Date: Tue, 13 Jul 2010 13:23:05 +0900 Subject: [libata] Add Samsung PATA controller driver, pata_samsung_cf Adds support for the Samsung PATA controller. This driver is based on the Libata subsystem and references the earlier patches sent for IDE subsystem. Signed-off-by: Abhilash Kesavan Signed-off-by: Kukjin Kim Cc: Ben Dooks Acked-by: Sergei Shtylyov Signed-off-by: Jeff Garzik --- drivers/ata/Kconfig | 9 + drivers/ata/Makefile | 1 + drivers/ata/pata_samsung_cf.c | 683 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 693 insertions(+) create mode 100644 drivers/ata/pata_samsung_cf.c (limited to 'drivers/ata') diff --git a/drivers/ata/Kconfig b/drivers/ata/Kconfig index f06e313c997f..8fae6afd6a3d 100644 --- a/drivers/ata/Kconfig +++ b/drivers/ata/Kconfig @@ -805,6 +805,15 @@ config PATA_RZ1000 If unsure, say N. +config PATA_SAMSUNG_CF + tristate "Samsung SoC PATA support" + depends on SAMSUNG_DEV_IDE + help + This option enables basic support for Samsung's S3C/S5P board + PATA controllers via the new ATA layer + + If unsure, say N. + config PATA_WINBOND_VLB tristate "Winbond W83759A VLB PATA support (Experimental)" depends on ISA && EXPERIMENTAL diff --git a/drivers/ata/Makefile b/drivers/ata/Makefile index d863e66f89a0..6540632bda08 100644 --- a/drivers/ata/Makefile +++ b/drivers/ata/Makefile @@ -88,6 +88,7 @@ obj-$(CONFIG_PATA_OF_PLATFORM) += pata_of_platform.o obj-$(CONFIG_PATA_QDI) += pata_qdi.o obj-$(CONFIG_PATA_RB532) += pata_rb532_cf.o obj-$(CONFIG_PATA_RZ1000) += pata_rz1000.o +obj-$(CONFIG_PATA_SAMSUNG_CF) += pata_samsung_cf.o obj-$(CONFIG_PATA_WINBOND_VLB) += pata_winbond.o # Should be last but two libata driver diff --git a/drivers/ata/pata_samsung_cf.c b/drivers/ata/pata_samsung_cf.c new file mode 100644 index 000000000000..6f9cfb24b751 --- /dev/null +++ b/drivers/ata/pata_samsung_cf.c @@ -0,0 +1,683 @@ +/* + * Copyright (c) 2010 Samsung Electronics Co., Ltd. + * http://www.samsung.com + * + * PATA driver for Samsung SoCs. + * Supports CF Interface in True IDE mode. Currently only PIO mode has been + * implemented; UDMA support has to be added. + * + * Based on: + * PATA driver for AT91SAM9260 Static Memory Controller + * PATA driver for Toshiba SCC controller + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation. +*/ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#define DRV_NAME "pata_samsung_cf" +#define DRV_VERSION "0.1" + +enum s3c_cpu_type { + TYPE_S3C64XX, + TYPE_S5PC100, + TYPE_S5PV210, +}; + +/* + * struct s3c_ide_info - S3C PATA instance. + * @clk: The clock resource for this controller. + * @ide_addr: The area mapped for the hardware registers. + * @sfr_addr: The area mapped for the special function registers. + * @irq: The IRQ number we are using. + * @cpu_type: The exact type of this controller. + * @fifo_status_reg: The ATA_FIFO_STATUS register offset. + */ +struct s3c_ide_info { + struct clk *clk; + void __iomem *ide_addr; + void __iomem *sfr_addr; + unsigned int irq; + enum s3c_cpu_type cpu_type; + unsigned int fifo_status_reg; +}; + +static void pata_s3c_set_endian(void __iomem *s3c_ide_regbase, u8 mode) +{ + u32 reg = readl(s3c_ide_regbase + S3C_ATA_CFG); + reg = mode ? (reg & ~S3C_ATA_CFG_SWAP) : (reg | S3C_ATA_CFG_SWAP); + writel(reg, s3c_ide_regbase + S3C_ATA_CFG); +} + +static void pata_s3c_cfg_mode(void __iomem *s3c_ide_sfrbase) +{ + /* Select true-ide as the internal operating mode */ + writel(readl(s3c_ide_sfrbase + S3C_CFATA_MUX) | S3C_CFATA_MUX_TRUEIDE, + s3c_ide_sfrbase + S3C_CFATA_MUX); +} + +static unsigned long +pata_s3c_setup_timing(struct s3c_ide_info *info, const struct ata_timing *ata) +{ + int t1 = ata->setup; + int t2 = ata->act8b; + int t2i = ata->rec8b; + ulong piotime; + + piotime = ((t2i & 0xff) << 12) | ((t2 & 0xff) << 4) | (t1 & 0xf); + + return piotime; +} + +static void pata_s3c_set_piomode(struct ata_port *ap, struct ata_device *adev) +{ + struct s3c_ide_info *info = ap->host->private_data; + struct ata_timing timing; + int cycle_time; + ulong ata_cfg = readl(info->ide_addr + S3C_ATA_CFG); + ulong piotime; + + /* Enables IORDY if mode requires it */ + if (ata_pio_need_iordy(adev)) + ata_cfg |= S3C_ATA_CFG_IORDYEN; + else + ata_cfg &= ~S3C_ATA_CFG_IORDYEN; + + cycle_time = (int)(1000000000UL / clk_get_rate(info->clk)); + + ata_timing_compute(adev, adev->pio_mode, &timing, + cycle_time * 1000, 0); + + piotime = pata_s3c_setup_timing(info, &timing); + + writel(ata_cfg, info->ide_addr + S3C_ATA_CFG); + writel(piotime, info->ide_addr + S3C_ATA_PIO_TIME); +} + +/* + * Waits until the IDE controller is able to perform next read/write + * operation to the disk. Needed for 64XX series boards only. + */ +static int wait_for_host_ready(struct s3c_ide_info *info) +{ + ulong timeout; + void __iomem *fifo_reg = info->ide_addr + info->fifo_status_reg; + + /* wait for maximum of 20 msec */ + timeout = jiffies + msecs_to_jiffies(20); + while (time_before(jiffies, timeout)) { + if ((readl(fifo_reg) >> 28) == 0) + return 0; + } + return -EBUSY; +} + +/* + * Writes to one of the task file registers. + */ +static void ata_outb(struct ata_host *host, u8 addr, void __iomem *reg) +{ + struct s3c_ide_info *info = host->private_data; + + wait_for_host_ready(info); + writeb(addr, reg); +} + +/* + * Reads from one of the task file registers. + */ +static u8 ata_inb(struct ata_host *host, void __iomem *reg) +{ + struct s3c_ide_info *info = host->private_data; + u8 temp; + + wait_for_host_ready(info); + (void) readb(reg); + wait_for_host_ready(info); + temp = readb(info->ide_addr + S3C_ATA_PIO_RDATA); + return temp; +} + +/* + * pata_s3c_tf_load - send taskfile registers to host controller + */ +static void pata_s3c_tf_load(struct ata_port *ap, + const struct ata_taskfile *tf) +{ + struct ata_ioports *ioaddr = &ap->ioaddr; + unsigned int is_addr = tf->flags & ATA_TFLAG_ISADDR; + + if (tf->ctl != ap->last_ctl) { + ata_outb(ap->host, tf->ctl, ioaddr->ctl_addr); + ap->last_ctl = tf->ctl; + ata_wait_idle(ap); + } + + if (is_addr && (tf->flags & ATA_TFLAG_LBA48)) { + ata_outb(ap->host, tf->hob_feature, ioaddr->feature_addr); + ata_outb(ap->host, tf->hob_nsect, ioaddr->nsect_addr); + ata_outb(ap->host, tf->hob_lbal, ioaddr->lbal_addr); + ata_outb(ap->host, tf->hob_lbam, ioaddr->lbam_addr); + ata_outb(ap->host, tf->hob_lbah, ioaddr->lbah_addr); + } + + if (is_addr) { + ata_outb(ap->host, tf->feature, ioaddr->feature_addr); + ata_outb(ap->host, tf->nsect, ioaddr->nsect_addr); + ata_outb(ap->host, tf->lbal, ioaddr->lbal_addr); + ata_outb(ap->host, tf->lbam, ioaddr->lbam_addr); + ata_outb(ap->host, tf->lbah, ioaddr->lbah_addr); + } + + if (tf->flags & ATA_TFLAG_DEVICE) + ata_outb(ap->host, tf->device, ioaddr->device_addr); + + ata_wait_idle(ap); +} + +/* + * pata_s3c_tf_read - input device's ATA taskfile shadow registers + */ +static void pata_s3c_tf_read(struct ata_port *ap, struct ata_taskfile *tf) +{ + struct ata_ioports *ioaddr = &ap->ioaddr; + + tf->feature = ata_inb(ap->host, ioaddr->error_addr); + tf->nsect = ata_inb(ap->host, ioaddr->nsect_addr); + tf->lbal = ata_inb(ap->host, ioaddr->lbal_addr); + tf->lbam = ata_inb(ap->host, ioaddr->lbam_addr); + tf->lbah = ata_inb(ap->host, ioaddr->lbah_addr); + tf->device = ata_inb(ap->host, ioaddr->device_addr); + + if (tf->flags & ATA_TFLAG_LBA48) { + ata_outb(ap->host, tf->ctl | ATA_HOB, ioaddr->ctl_addr); + tf->hob_feature = ata_inb(ap->host, ioaddr->error_addr); + tf->hob_nsect = ata_inb(ap->host, ioaddr->nsect_addr); + tf->hob_lbal = ata_inb(ap->host, ioaddr->lbal_addr); + tf->hob_lbam = ata_inb(ap->host, ioaddr->lbam_addr); + tf->hob_lbah = ata_inb(ap->host, ioaddr->lbah_addr); + ata_outb(ap->host, tf->ctl, ioaddr->ctl_addr); + ap->last_ctl = tf->ctl; + } +} + +/* + * pata_s3c_exec_command - issue ATA command to host controller + */ +static void pata_s3c_exec_command(struct ata_port *ap, + const struct ata_taskfile *tf) +{ + ata_outb(ap->host, tf->command, ap->ioaddr.command_addr); + ata_sff_pause(ap); +} + +/* + * pata_s3c_check_status - Read device status register + */ +static u8 pata_s3c_check_status(struct ata_port *ap) +{ + return ata_inb(ap->host, ap->ioaddr.status_addr); +} + +/* + * pata_s3c_check_altstatus - Read alternate device status register + */ +static u8 pata_s3c_check_altstatus(struct ata_port *ap) +{ + return ata_inb(ap->host, ap->ioaddr.altstatus_addr); +} + +/* + * pata_s3c_data_xfer - Transfer data by PIO + */ +unsigned int pata_s3c_data_xfer(struct ata_device *dev, unsigned char *buf, + unsigned int buflen, int rw) +{ + struct ata_port *ap = dev->link->ap; + struct s3c_ide_info *info = ap->host->private_data; + void __iomem *data_addr = ap->ioaddr.data_addr; + unsigned int words = buflen >> 1, i; + u16 *data_ptr = (u16 *)buf; + + /* Requires wait same as in ata_inb/ata_outb */ + if (rw == READ) + for (i = 0; i < words; i++, data_ptr++) { + wait_for_host_ready(info); + (void) readw(data_addr); + wait_for_host_ready(info); + *data_ptr = readw(info->ide_addr + + S3C_ATA_PIO_RDATA); + } + else + for (i = 0; i < words; i++, data_ptr++) { + wait_for_host_ready(info); + writew(*data_ptr, data_addr); + } + + if (buflen & 0x01) + dev_err(ap->dev, "unexpected trailing data\n"); + + return words << 1; +} + +/* + * pata_s3c_dev_select - Select device on ATA bus + */ +static void pata_s3c_dev_select(struct ata_port *ap, unsigned int device) +{ + u8 tmp = ATA_DEVICE_OBS; + + if (device != 0) + tmp |= ATA_DEV1; + + ata_outb(ap->host, tmp, ap->ioaddr.device_addr); + ata_sff_pause(ap); +} + +/* + * pata_s3c_devchk - PATA device presence detection + */ +static unsigned int pata_s3c_devchk(struct ata_port *ap, + unsigned int device) +{ + struct ata_ioports *ioaddr = &ap->ioaddr; + u8 nsect, lbal; + + pata_s3c_dev_select(ap, device); + + ata_outb(ap->host, 0x55, ioaddr->nsect_addr); + ata_outb(ap->host, 0xaa, ioaddr->lbal_addr); + + ata_outb(ap->host, 0xaa, ioaddr->nsect_addr); + ata_outb(ap->host, 0x55, ioaddr->lbal_addr); + + ata_outb(ap->host, 0x55, ioaddr->nsect_addr); + ata_outb(ap->host, 0xaa, ioaddr->lbal_addr); + + nsect = ata_inb(ap->host, ioaddr->nsect_addr); + lbal = ata_inb(ap->host, ioaddr->lbal_addr); + + if ((nsect == 0x55) && (lbal == 0xaa)) + return 1; /* we found a device */ + + return 0; /* nothing found */ +} + +/* + * pata_s3c_wait_after_reset - wait for devices to become ready after reset + */ +static int pata_s3c_wait_after_reset(struct ata_link *link, + unsigned long deadline) +{ + int rc; + + msleep(ATA_WAIT_AFTER_RESET); + + /* always check readiness of the master device */ + rc = ata_sff_wait_ready(link, deadline); + /* -ENODEV means the odd clown forgot the D7 pulldown resistor + * and TF status is 0xff, bail out on it too. + */ + if (rc) + return rc; + + return 0; +} + +/* + * pata_s3c_bus_softreset - PATA device software reset + */ +static unsigned int pata_s3c_bus_softreset(struct ata_port *ap, + unsigned long deadline) +{ + struct ata_ioports *ioaddr = &ap->ioaddr; + + /* software reset. causes dev0 to be selected */ + ata_outb(ap->host, ap->ctl, ioaddr->ctl_addr); + udelay(20); + ata_outb(ap->host, ap->ctl | ATA_SRST, ioaddr->ctl_addr); + udelay(20); + ata_outb(ap->host, ap->ctl, ioaddr->ctl_addr); + ap->last_ctl = ap->ctl; + + return pata_s3c_wait_after_reset(&ap->link, deadline); +} + +/* + * pata_s3c_softreset - reset host port via ATA SRST + */ +static int pata_s3c_softreset(struct ata_link *link, unsigned int *classes, + unsigned long deadline) +{ + struct ata_port *ap = link->ap; + unsigned int devmask = 0; + int rc; + u8 err; + + /* determine if device 0 is present */ + if (pata_s3c_devchk(ap, 0)) + devmask |= (1 << 0); + + /* select device 0 again */ + pata_s3c_dev_select(ap, 0); + + /* issue bus reset */ + rc = pata_s3c_bus_softreset(ap, deadline); + /* if link is occupied, -ENODEV too is an error */ + if (rc && rc != -ENODEV) { + ata_link_printk(link, KERN_ERR, "SRST failed (errno=%d)\n", rc); + return rc; + } + + /* determine by signature whether we have ATA or ATAPI devices */ + classes[0] = ata_sff_dev_classify(&ap->link.device[0], + devmask & (1 << 0), &err); + + return 0; +} + +/* + * pata_s3c_set_devctl - Write device control register + */ +static void pata_s3c_set_devctl(struct ata_port *ap, u8 ctl) +{ + ata_outb(ap->host, ctl, ap->ioaddr.ctl_addr); +} + +static struct scsi_host_template pata_s3c_sht = { + ATA_PIO_SHT(DRV_NAME), +}; + +static struct ata_port_operations pata_s3c_port_ops = { + .inherits = &ata_sff_port_ops, + .sff_check_status = pata_s3c_check_status, + .sff_check_altstatus = pata_s3c_check_altstatus, + .sff_tf_load = pata_s3c_tf_load, + .sff_tf_read = pata_s3c_tf_read, + .sff_data_xfer = pata_s3c_data_xfer, + .sff_exec_command = pata_s3c_exec_command, + .sff_dev_select = pata_s3c_dev_select, + .sff_set_devctl = pata_s3c_set_devctl, + .softreset = pata_s3c_softreset, + .set_piomode = pata_s3c_set_piomode, +}; + +static struct ata_port_operations pata_s5p_port_ops = { + .inherits = &ata_sff_port_ops, + .set_piomode = pata_s3c_set_piomode, +}; + +static void pata_s3c_enable(void *s3c_ide_regbase, bool state) +{ + u32 temp = readl(s3c_ide_regbase + S3C_ATA_CTRL); + temp = state ? (temp | 1) : (temp & ~1); + writel(temp, s3c_ide_regbase + S3C_ATA_CTRL); +} + +static irqreturn_t pata_s3c_irq(int irq, void *dev_instance) +{ + struct ata_host *host = dev_instance; + struct s3c_ide_info *info = host->private_data; + u32 reg; + + reg = readl(info->ide_addr + S3C_ATA_IRQ); + writel(reg, info->ide_addr + S3C_ATA_IRQ); + + return ata_sff_interrupt(irq, dev_instance); +} + +static void pata_s3c_hwinit(struct s3c_ide_info *info, + struct s3c_ide_platdata *pdata) +{ + switch (info->cpu_type) { + case TYPE_S3C64XX: + /* Configure as big endian */ + pata_s3c_cfg_mode(info->sfr_addr); + pata_s3c_set_endian(info->ide_addr, 1); + pata_s3c_enable(info->ide_addr, true); + msleep(100); + + /* Remove IRQ Status */ + writel(0x1f, info->ide_addr + S3C_ATA_IRQ); + writel(0x1b, info->ide_addr + S3C_ATA_IRQ_MSK); + break; + + case TYPE_S5PC100: + pata_s3c_cfg_mode(info->sfr_addr); + /* FALLTHROUGH */ + + case TYPE_S5PV210: + /* Configure as little endian */ + pata_s3c_set_endian(info->ide_addr, 0); + pata_s3c_enable(info->ide_addr, true); + msleep(100); + + /* Remove IRQ Status */ + writel(0x3f, info->ide_addr + S3C_ATA_IRQ); + writel(0x3f, info->ide_addr + S3C_ATA_IRQ_MSK); + break; + + default: + BUG(); + } +} + +static int __init pata_s3c_probe(struct platform_device *pdev) +{ + struct s3c_ide_platdata *pdata = pdev->dev.platform_data; + struct device *dev = &pdev->dev; + struct s3c_ide_info *info; + struct resource *res; + struct ata_port *ap; + struct ata_host *host; + enum s3c_cpu_type cpu_type; + int ret; + + cpu_type = platform_get_device_id(pdev)->driver_data; + + info = devm_kzalloc(dev, sizeof(*info), GFP_KERNEL); + if (!info) { + dev_err(dev, "failed to allocate memory for device data\n"); + return -ENOMEM; + } + + info->irq = platform_get_irq(pdev, 0); + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (res == NULL) { + dev_err(dev, "failed to get mem resource\n"); + return -EINVAL; + } + + if (!devm_request_mem_region(dev, res->start, + resource_size(res), DRV_NAME)) { + dev_err(dev, "error requesting register region\n"); + return -EBUSY; + } + + info->ide_addr = devm_ioremap(dev, res->start, resource_size(res)); + if (!info->ide_addr) { + dev_err(dev, "failed to map IO base address\n"); + return -ENOMEM; + } + + info->clk = clk_get(&pdev->dev, "cfcon"); + if (IS_ERR(info->clk)) { + dev_err(dev, "failed to get access to cf controller clock\n"); + ret = PTR_ERR(info->clk); + info->clk = NULL; + return ret; + } + + clk_enable(info->clk); + + /* init ata host */ + host = ata_host_alloc(dev, 1); + if (!host) { + dev_err(dev, "failed to allocate ide host\n"); + ret = -ENOMEM; + goto stop_clk; + } + + ap = host->ports[0]; + ap->flags |= ATA_FLAG_MMIO; + ap->pio_mask = ATA_PIO4; + + if (cpu_type == TYPE_S3C64XX) { + ap->ops = &pata_s3c_port_ops; + info->sfr_addr = info->ide_addr + 0x1800; + info->ide_addr += 0x1900; + info->fifo_status_reg = 0x94; + } else if (cpu_type == TYPE_S5PC100) { + ap->ops = &pata_s5p_port_ops; + info->sfr_addr = info->ide_addr + 0x1800; + info->ide_addr += 0x1900; + info->fifo_status_reg = 0x84; + } else { + ap->ops = &pata_s5p_port_ops; + info->fifo_status_reg = 0x84; + } + + info->cpu_type = cpu_type; + + if (info->irq <= 0) { + ap->flags |= ATA_FLAG_PIO_POLLING; + info->irq = 0; + ata_port_desc(ap, "no IRQ, using PIO polling\n"); + } + + ap->ioaddr.cmd_addr = info->ide_addr + S3C_ATA_CMD; + ap->ioaddr.data_addr = info->ide_addr + S3C_ATA_PIO_DTR; + ap->ioaddr.error_addr = info->ide_addr + S3C_ATA_PIO_FED; + ap->ioaddr.feature_addr = info->ide_addr + S3C_ATA_PIO_FED; + ap->ioaddr.nsect_addr = info->ide_addr + S3C_ATA_PIO_SCR; + ap->ioaddr.lbal_addr = info->ide_addr + S3C_ATA_PIO_LLR; + ap->ioaddr.lbam_addr = info->ide_addr + S3C_ATA_PIO_LMR; + ap->ioaddr.lbah_addr = info->ide_addr + S3C_ATA_PIO_LHR; + ap->ioaddr.device_addr = info->ide_addr + S3C_ATA_PIO_DVR; + ap->ioaddr.status_addr = info->ide_addr + S3C_ATA_PIO_CSD; + ap->ioaddr.command_addr = info->ide_addr + S3C_ATA_PIO_CSD; + ap->ioaddr.altstatus_addr = info->ide_addr + S3C_ATA_PIO_DAD; + ap->ioaddr.ctl_addr = info->ide_addr + S3C_ATA_PIO_DAD; + + ata_port_desc(ap, "mmio cmd 0x%llx ", + (unsigned long long)res->start); + + host->private_data = info; + + if (pdata && pdata->setup_gpio) + pdata->setup_gpio(); + + /* Set endianness and enable the interface */ + pata_s3c_hwinit(info, pdata); + + platform_set_drvdata(pdev, host); + + return ata_host_activate(host, info->irq, + info->irq ? pata_s3c_irq : NULL, + 0, &pata_s3c_sht); + +stop_clk: + clk_disable(info->clk); + clk_put(info->clk); + return ret; +} + +static int __exit pata_s3c_remove(struct platform_device *pdev) +{ + struct ata_host *host = platform_get_drvdata(pdev); + struct s3c_ide_info *info = host->private_data; + + ata_host_detach(host); + + clk_disable(info->clk); + clk_put(info->clk); + + return 0; +} + +#ifdef CONFIG_PM +static int pata_s3c_suspend(struct device *dev) +{ + struct platform_device *pdev = to_platform_device(dev); + struct ata_host *host = platform_get_drvdata(pdev); + + return ata_host_suspend(host, PMSG_SUSPEND); +} + +static int pata_s3c_resume(struct device *dev) +{ + struct platform_device *pdev = to_platform_device(dev); + struct ata_host *host = platform_get_drvdata(pdev); + struct s3c_ide_platdata *pdata = pdev->dev.platform_data; + struct s3c_ide_info *info = host->private_data; + + pata_s3c_hwinit(info, pdata); + ata_host_resume(host); + + return 0; +} + +static const struct dev_pm_ops pata_s3c_pm_ops = { + .suspend = pata_s3c_suspend, + .resume = pata_s3c_resume, +}; +#endif + +/* driver device registration */ +static struct platform_device_id pata_s3c_driver_ids[] = { + { + .name = "s3c64xx-pata", + .driver_data = TYPE_S3C64XX, + }, { + .name = "s5pc100-pata", + .driver_data = TYPE_S5PC100, + }, { + .name = "s5pv210-pata", + .driver_data = TYPE_S5PV210, + }, + { } +}; + +MODULE_DEVICE_TABLE(platform, pata_s3c_driver_ids); + +static struct platform_driver pata_s3c_driver = { + .remove = __exit_p(pata_s3c_remove), + .id_table = pata_s3c_driver_ids, + .driver = { + .name = DRV_NAME, + .owner = THIS_MODULE, +#ifdef CONFIG_PM + .pm = &pata_s3c_pm_ops, +#endif + }, +}; + +static int __init pata_s3c_init(void) +{ + return platform_driver_probe(&pata_s3c_driver, pata_s3c_probe); +} + +static void __exit pata_s3c_exit(void) +{ + platform_driver_unregister(&pata_s3c_driver); +} + +module_init(pata_s3c_init); +module_exit(pata_s3c_exit); + +MODULE_AUTHOR("Abhilash Kesavan, "); +MODULE_DESCRIPTION("low-level driver for Samsung PATA controller"); +MODULE_LICENSE("GPL"); +MODULE_VERSION(DRV_VERSION); -- cgit v1.2.3 From acad76272c6df8ea1900da334764c05a528598c3 Mon Sep 17 00:00:00 2001 From: FUJITA Tomonori Date: Mon, 5 Jul 2010 15:45:20 +0900 Subject: [libata] add ATA_CMD_DSM to ata_get_cmd_descript Signed-off-by: FUJITA Tomonori Signed-off-by: Jeff Garzik --- drivers/ata/libata-eh.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/ata') diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c index f77a67303f8b..697474b625b7 100644 --- a/drivers/ata/libata-eh.c +++ b/drivers/ata/libata-eh.c @@ -2214,6 +2214,7 @@ const char *ata_get_cmd_descript(u8 command) { ATA_CMD_SMART, "SMART" }, { ATA_CMD_MEDIA_LOCK, "DOOR LOCK" }, { ATA_CMD_MEDIA_UNLOCK, "DOOR UNLOCK" }, + { ATA_CMD_DSM, "DATA SET MANAGEMENT" }, { ATA_CMD_CHK_MED_CRD_TYP, "CHECK MEDIA CARD TYPE" }, { ATA_CMD_CFA_REQ_EXT_ERR, "CFA REQUEST EXTENDED ERROR" }, { ATA_CMD_CFA_WRITE_NE, "CFA WRITE SECTORS WITHOUT ERASE" }, -- cgit v1.2.3 From b429dd5998d6037e0057564f3894f56aff64d661 Mon Sep 17 00:00:00 2001 From: "Justin P. Mattock" Date: Sat, 3 Jul 2010 07:29:25 -0700 Subject: [libata] ahci: Fix warning: comparison between 'enum ' and 'enum ' The below patch casts ATA_MAX_QUEUE to int because GCC will give a warning message about the two different enum blocks: CC drivers/ata/ahci.o drivers/ata/ahci.c: In function 'ahci_init_one': drivers/ata/ahci.c:1045:2: warning: comparison between 'enum ' and 'enum ' Signed-off-by: Justin P. Mattock Signed-off-by: Jeff Garzik --- drivers/ata/ahci.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/ata') diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c index f2522534ae63..fe75d8befc3a 100644 --- a/drivers/ata/ahci.c +++ b/drivers/ata/ahci.c @@ -1042,7 +1042,7 @@ static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) VPRINTK("ENTER\n"); - WARN_ON(ATA_MAX_QUEUE > AHCI_MAX_CMDS); + WARN_ON((int)ATA_MAX_QUEUE > AHCI_MAX_CMDS); if (!printed_version++) dev_printk(KERN_DEBUG, &pdev->dev, "version " DRV_VERSION "\n"); -- cgit v1.2.3 From 728e0eaf99631d197e5158e21b4a8c4335a39231 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Fri, 2 Jul 2010 14:41:24 +0200 Subject: ata_generic: drop hard coded DMA force logic for CENATEK Commit 1529c69adc (ata_generic: implement ATA_GEN_* flags and force enable DMA on MBP 7,1) implemented ATA_GEN_FORCE_DMA for forcing DMA mode and applied it to CENATEK but forgot to remove the original hard coded logic. This is removal of redundant logic and doesn't affect correctness. Signed-off-by: Tejun Heo Reported-by: Andy Whitcroft Signed-off-by: Jeff Garzik --- drivers/ata/ata_generic.c | 4 ---- 1 file changed, 4 deletions(-) (limited to 'drivers/ata') diff --git a/drivers/ata/ata_generic.c b/drivers/ata/ata_generic.c index 7107a6929deb..cc5f7726bde7 100644 --- a/drivers/ata/ata_generic.c +++ b/drivers/ata/ata_generic.c @@ -54,7 +54,6 @@ static int generic_set_mode(struct ata_link *link, struct ata_device **unused) const struct pci_device_id *id = ap->host->private_data; int dma_enabled = 0; struct ata_device *dev; - struct pci_dev *pdev = to_pci_dev(ap->host->dev); if (id->driver_data & ATA_GEN_FORCE_DMA) { dma_enabled = 0xff; @@ -63,9 +62,6 @@ static int generic_set_mode(struct ata_link *link, struct ata_device **unused) dma_enabled = ioread8(ap->ioaddr.bmdma_addr + ATA_DMA_STATUS); } - if (pdev->vendor == PCI_VENDOR_ID_CENATEK) - dma_enabled = 0xFF; - ata_for_each_dev(dev, link, ENABLED) { /* We don't really care */ dev->pio_mode = XFER_PIO_0; -- cgit v1.2.3 From 2f9e4d16c5b6f627670f1641b3f288d16d84b202 Mon Sep 17 00:00:00 2001 From: Mark Lord Date: Mon, 5 Jul 2010 10:25:45 -0400 Subject: libata: allow hyphenated pattern ranges Enable use of hyphenated pattern ranges in glob_match(), similar to how shell globbing works, and how developers might expect things to work. Signed-off-by: Mark Lord Signed-off-by: Jeff Garzik --- drivers/ata/libata-core.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) (limited to 'drivers/ata') diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index 2984e45bc16b..eefb948f0632 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c @@ -4283,11 +4283,13 @@ static const struct ata_blacklist_entry ata_device_blacklist [] = { * ? matches any single character. * * matches any run of characters. * [xyz] matches a single character from the set: x, y, or z. + * [a-d] matches a single character from the range: a, b, c, or d. + * [a-d0-9] matches a single character from either range. * - * Note: hyphenated ranges [0-9] are _not_ supported here. - * The special characters ?, [, or *, can be matched using a set, eg. [*] + * The special characters ?, [, -, or *, can be matched using a set, eg. [*] + * Behaviour with malformed patterns is undefined, though generally reasonable. * - * Example patterns: "SD1?", "SD1[012345]", "*R0", SD*1?[012]*xx" + * Example patterns: "SD1?", "SD1[0-5]", "*R0", SD*1?[012]*xx" * * This function uses one level of recursion per '*' in pattern. * Since it calls _nothing_ else, and has _no_ explicit local variables, @@ -4307,7 +4309,13 @@ static int glob_match (const char *text, const char *pattern) /* Match single char against a '[' bracketed ']' pattern set */ if (!*text || *pattern != '[') break; /* Not a pattern set */ - while (*++pattern && *pattern != ']' && *text != *pattern); + while (*++pattern && *pattern != ']' && *text != *pattern) { + if (*pattern == '-' && *(pattern - 1) != '[') + if (*text > *(pattern - 1) && *text < *(pattern + 1)) { + ++pattern; + break; + } + } if (!*pattern || *pattern == ']') return 1; /* No match */ while (*pattern && *pattern++ != ']'); -- cgit v1.2.3 From 4d1f9082251a835ea387b47bb9dd26980bf8e0d0 Mon Sep 17 00:00:00 2001 From: Mark Lord Date: Mon, 5 Jul 2010 18:53:37 -0400 Subject: [libata] update blacklist for new hyphenated pattern ranges (v2) Take further advantage of the new glob_match() function to reduce the blacklist size, this time making use of "character ranges" in the patterns. Signed-off-by: Mark Lord Signed-off-by: Jeff Garzik --- drivers/ata/libata-core.c | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) (limited to 'drivers/ata') diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index eefb948f0632..a0a4d6968400 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c @@ -4209,22 +4209,16 @@ static const struct ata_blacklist_entry ata_device_blacklist [] = { { "OCZ CORE_SSD", "02.10104", ATA_HORKAGE_NONCQ }, /* Seagate NCQ + FLUSH CACHE firmware bug */ - { "ST31500341AS", "SD1[56789]", ATA_HORKAGE_NONCQ | + { "ST31500341AS", "SD1[5-9]", ATA_HORKAGE_NONCQ | ATA_HORKAGE_FIRMWARE_WARN }, - { "ST31000333AS", "SD1[56789]", ATA_HORKAGE_NONCQ | + { "ST31000333AS", "SD1[5-9]", ATA_HORKAGE_NONCQ | ATA_HORKAGE_FIRMWARE_WARN }, - { "ST3640623AS", "SD1[56789]", ATA_HORKAGE_NONCQ | + { "ST3640[36]23AS", "SD1[5-9]", ATA_HORKAGE_NONCQ | ATA_HORKAGE_FIRMWARE_WARN }, - { "ST3640323AS", "SD1[56789]", ATA_HORKAGE_NONCQ | - ATA_HORKAGE_FIRMWARE_WARN }, - - { "ST3320813AS", "SD1[56789]", ATA_HORKAGE_NONCQ | - ATA_HORKAGE_FIRMWARE_WARN }, - - { "ST3320613AS", "SD1[56789]", ATA_HORKAGE_NONCQ | + { "ST3320[68]13AS", "SD1[5-9]", ATA_HORKAGE_NONCQ | ATA_HORKAGE_FIRMWARE_WARN }, /* Blacklist entries taken from Silicon Image 3124/3132 -- cgit v1.2.3 From 213373cf974fe69e78ec894b07f45ae2f5a3a078 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Tue, 20 Jul 2010 16:20:01 +0200 Subject: ata_piix: fix locking around SIDPR access SIDPR window registers are shared across ports and as each access is done in two steps, accesses to different ports under EH may race. This primarily is caused by incorrect host locking in EH context and should be fixed by defining locking requirements for each EH operation which can be used during EH and enforcing them but for now work around the problem by adding a dedicated SIDPR lock and grabbing it for each SIDPR access. Signed-off-by: Tejun Heo Reported-by: Mark Knecht Reported-by: Paul Check Cc: stable@kernel.org Signed-off-by: Jeff Garzik --- drivers/ata/ata_piix.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'drivers/ata') diff --git a/drivers/ata/ata_piix.c b/drivers/ata/ata_piix.c index 7409f98d2ae6..3971bc0a4838 100644 --- a/drivers/ata/ata_piix.c +++ b/drivers/ata/ata_piix.c @@ -158,6 +158,7 @@ struct piix_map_db { struct piix_host_priv { const int *map; u32 saved_iocfg; + spinlock_t sidpr_lock; /* FIXME: remove once locking in EH is fixed */ void __iomem *sidpr; }; @@ -951,12 +952,15 @@ static int piix_sidpr_scr_read(struct ata_link *link, unsigned int reg, u32 *val) { struct piix_host_priv *hpriv = link->ap->host->private_data; + unsigned long flags; if (reg >= ARRAY_SIZE(piix_sidx_map)) return -EINVAL; + spin_lock_irqsave(&hpriv->sidpr_lock, flags); piix_sidpr_sel(link, reg); *val = ioread32(hpriv->sidpr + PIIX_SIDPR_DATA); + spin_unlock_irqrestore(&hpriv->sidpr_lock, flags); return 0; } @@ -964,12 +968,15 @@ static int piix_sidpr_scr_write(struct ata_link *link, unsigned int reg, u32 val) { struct piix_host_priv *hpriv = link->ap->host->private_data; + unsigned long flags; if (reg >= ARRAY_SIZE(piix_sidx_map)) return -EINVAL; + spin_lock_irqsave(&hpriv->sidpr_lock, flags); piix_sidpr_sel(link, reg); iowrite32(val, hpriv->sidpr + PIIX_SIDPR_DATA); + spin_unlock_irqrestore(&hpriv->sidpr_lock, flags); return 0; } @@ -1566,6 +1573,7 @@ static int __devinit piix_init_one(struct pci_dev *pdev, hpriv = devm_kzalloc(dev, sizeof(*hpriv), GFP_KERNEL); if (!hpriv) return -ENOMEM; + spin_lock_init(&hpriv->sidpr_lock); /* Save IOCFG, this will be used for cable detection, quirk * detection and restoration on detach. This is necessary -- cgit v1.2.3 From af4d6e257dc36646bb62adececdd10ad83323788 Mon Sep 17 00:00:00 2001 From: Peter Huewe Date: Thu, 15 Jul 2010 20:39:43 +0200 Subject: ata: Convert pci_table entries to PCI_VDEVICE (if PCI_ANY_ID is used) This patch converts pci_table entries, where .subvendor=PCI_ANY_ID and .subdevice=PCI_ANY_ID, .class=0 and .class_mask=0, to use the PCI_VDEVICE macro, and thus improves readability. Signed-off-by: Peter Huewe Signed-off-by: Jeff Garzik --- drivers/ata/pata_scc.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers/ata') diff --git a/drivers/ata/pata_scc.c b/drivers/ata/pata_scc.c index d9db3f8d60ef..fe36966f7e34 100644 --- a/drivers/ata/pata_scc.c +++ b/drivers/ata/pata_scc.c @@ -168,8 +168,7 @@ static const unsigned long JCACTSELtbl[2][7] = { }; static const struct pci_device_id scc_pci_tbl[] = { - {PCI_VENDOR_ID_TOSHIBA_2, PCI_DEVICE_ID_TOSHIBA_SCC_ATA, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, + { PCI_VDEVICE(TOSHIBA_2, PCI_DEVICE_ID_TOSHIBA_SCC_ATA), 0}, { } /* terminate list */ }; -- cgit v1.2.3 From 752e386c247664152f2cce37915d1f50631d7f42 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Fri, 25 Jun 2010 15:02:59 +0200 Subject: sata_fsl,mv,nv: prepare for NCQ command completion update Make the following changes to prepare for NCQ command completion update. Changes made by this patch don't cause any functional difference. * sata_fsl_host_intr(): rename the local variable qc_active to done_mask as that's what it is. * mv_process_crpb_response(): restructure if clause for easier update. * nv_adma_interrupt(): drop unnecessary error variable. * nv_swncq_sdbfis(): drop unnecessary nr_done and return 0 on success. Typo fix. * nv_swncq_dmafis(): drop unused return value and return void. * nv_swncq_host_interrupt(): drop unnecessary return value handling. Signed-off-by: Tejun Heo Cc: Ashish Kalra Cc: Saeed Bishara Cc: Mark Lord Cc: Robert Hancock Signed-off-by: Jeff Garzik --- drivers/ata/sata_fsl.c | 20 ++++++++++---------- drivers/ata/sata_mv.c | 47 ++++++++++++++++++++++++----------------------- drivers/ata/sata_nv.c | 32 ++++++++++++++------------------ 3 files changed, 48 insertions(+), 51 deletions(-) (limited to 'drivers/ata') diff --git a/drivers/ata/sata_fsl.c b/drivers/ata/sata_fsl.c index 61c89b54ea23..18c986dbb7f1 100644 --- a/drivers/ata/sata_fsl.c +++ b/drivers/ata/sata_fsl.c @@ -1096,7 +1096,7 @@ static void sata_fsl_host_intr(struct ata_port *ap) { struct sata_fsl_host_priv *host_priv = ap->host->private_data; void __iomem *hcr_base = host_priv->hcr_base; - u32 hstatus, qc_active = 0; + u32 hstatus, done_mask = 0; struct ata_queued_cmd *qc; u32 SError; @@ -1116,28 +1116,28 @@ static void sata_fsl_host_intr(struct ata_port *ap) } /* Read command completed register */ - qc_active = ioread32(hcr_base + CC); + done_mask = ioread32(hcr_base + CC); VPRINTK("Status of all queues :\n"); - VPRINTK("qc_active/CC = 0x%x, CA = 0x%x, CE=0x%x,CQ=0x%x,apqa=0x%x\n", - qc_active, + VPRINTK("done_mask/CC = 0x%x, CA = 0x%x, CE=0x%x,CQ=0x%x,apqa=0x%x\n", + done_mask, ioread32(hcr_base + CA), ioread32(hcr_base + CE), ioread32(hcr_base + CQ), ap->qc_active); - if (qc_active & ap->qc_active) { + if (done_mask & ap->qc_active) { int i; /* clear CC bit, this will also complete the interrupt */ - iowrite32(qc_active, hcr_base + CC); + iowrite32(done_mask, hcr_base + CC); DPRINTK("Status of all queues :\n"); - DPRINTK("qc_active/CC = 0x%x, CA = 0x%x, CE=0x%x\n", - qc_active, ioread32(hcr_base + CA), + DPRINTK("done_mask/CC = 0x%x, CA = 0x%x, CE=0x%x\n", + done_mask, ioread32(hcr_base + CA), ioread32(hcr_base + CE)); for (i = 0; i < SATA_FSL_QUEUE_DEPTH; i++) { - if (qc_active & (1 << i)) { + if (done_mask & (1 << i)) { qc = ata_qc_from_tag(ap, i); if (qc) { ata_qc_complete(qc); @@ -1164,7 +1164,7 @@ static void sata_fsl_host_intr(struct ata_port *ap) /* Spurious Interrupt!! */ DPRINTK("spurious interrupt!!, CC = 0x%x\n", ioread32(hcr_base + CC)); - iowrite32(qc_active, hcr_base + CC); + iowrite32(done_mask, hcr_base + CC); return; } } diff --git a/drivers/ata/sata_mv.c b/drivers/ata/sata_mv.c index a476cd99b95d..9463c71dd38e 100644 --- a/drivers/ata/sata_mv.c +++ b/drivers/ata/sata_mv.c @@ -2716,34 +2716,35 @@ static void mv_err_intr(struct ata_port *ap) static void mv_process_crpb_response(struct ata_port *ap, struct mv_crpb *response, unsigned int tag, int ncq_enabled) { + u8 ata_status; + u16 edma_status = le16_to_cpu(response->flags); struct ata_queued_cmd *qc = ata_qc_from_tag(ap, tag); - if (qc) { - u8 ata_status; - u16 edma_status = le16_to_cpu(response->flags); - /* - * edma_status from a response queue entry: - * LSB is from EDMA_ERR_IRQ_CAUSE (non-NCQ only). - * MSB is saved ATA status from command completion. - */ - if (!ncq_enabled) { - u8 err_cause = edma_status & 0xff & ~EDMA_ERR_DEV; - if (err_cause) { - /* - * Error will be seen/handled by mv_err_intr(). - * So do nothing at all here. - */ - return; - } - } - ata_status = edma_status >> CRPB_FLAG_STATUS_SHIFT; - if (!ac_err_mask(ata_status)) - ata_qc_complete(qc); - /* else: leave it for mv_err_intr() */ - } else { + if (unlikely(!qc)) { ata_port_printk(ap, KERN_ERR, "%s: no qc for tag=%d\n", __func__, tag); + return; + } + + /* + * edma_status from a response queue entry: + * LSB is from EDMA_ERR_IRQ_CAUSE (non-NCQ only). + * MSB is saved ATA status from command completion. + */ + if (!ncq_enabled) { + u8 err_cause = edma_status & 0xff & ~EDMA_ERR_DEV; + if (err_cause) { + /* + * Error will be seen/handled by + * mv_err_intr(). So do nothing at all here. + */ + return; + } } + ata_status = edma_status >> CRPB_FLAG_STATUS_SHIFT; + if (!ac_err_mask(ata_status)) + ata_qc_complete(qc); + /* else: leave it for mv_err_intr() */ } static void mv_process_crpb_entries(struct ata_port *ap, struct mv_port_priv *pp) diff --git a/drivers/ata/sata_nv.c b/drivers/ata/sata_nv.c index 21161136cad0..cb89ef8d99d9 100644 --- a/drivers/ata/sata_nv.c +++ b/drivers/ata/sata_nv.c @@ -1018,7 +1018,7 @@ static irqreturn_t nv_adma_interrupt(int irq, void *dev_instance) NV_ADMA_STAT_CPBERR | NV_ADMA_STAT_CMD_COMPLETE)) { u32 check_commands = notifier_clears[i]; - int pos, error = 0; + int pos, rc; if (status & NV_ADMA_STAT_CPBERR) { /* check all active commands */ @@ -1030,10 +1030,12 @@ static irqreturn_t nv_adma_interrupt(int irq, void *dev_instance) } /* check CPBs for completed commands */ - while ((pos = ffs(check_commands)) && !error) { + while ((pos = ffs(check_commands))) { pos--; - error = nv_adma_check_cpb(ap, pos, + rc = nv_adma_check_cpb(ap, pos, notifier_error & (1 << pos)); + if (unlikely(rc)) + check_commands = 0; check_commands &= ~(1 << pos); } } @@ -2129,7 +2131,6 @@ static int nv_swncq_sdbfis(struct ata_port *ap) struct nv_swncq_port_priv *pp = ap->private_data; struct ata_eh_info *ehi = &ap->link.eh_info; u32 sactive; - int nr_done = 0; u32 done_mask; int i; u8 host_stat; @@ -2170,22 +2171,21 @@ static int nv_swncq_sdbfis(struct ata_port *ap) pp->dhfis_bits &= ~(1 << i); pp->dmafis_bits &= ~(1 << i); pp->sdbfis_bits |= (1 << i); - nr_done++; } } if (!ap->qc_active) { DPRINTK("over\n"); nv_swncq_pp_reinit(ap); - return nr_done; + return 0; } if (pp->qc_active & pp->dhfis_bits) - return nr_done; + return 0; if ((pp->ncq_flags & ncq_saw_backout) || (pp->qc_active ^ pp->dhfis_bits)) - /* if the controller cann't get a device to host register FIS, + /* if the controller can't get a device to host register FIS, * The driver needs to reissue the new command. */ lack_dhfis = 1; @@ -2202,7 +2202,7 @@ static int nv_swncq_sdbfis(struct ata_port *ap) if (lack_dhfis) { qc = ata_qc_from_tag(ap, pp->last_issue_tag); nv_swncq_issue_atacmd(ap, qc); - return nr_done; + return 0; } if (pp->defer_queue.defer_bits) { @@ -2212,7 +2212,7 @@ static int nv_swncq_sdbfis(struct ata_port *ap) nv_swncq_issue_atacmd(ap, qc); } - return nr_done; + return 0; } static inline u32 nv_swncq_tag(struct ata_port *ap) @@ -2224,7 +2224,7 @@ static inline u32 nv_swncq_tag(struct ata_port *ap) return (tag & 0x1f); } -static int nv_swncq_dmafis(struct ata_port *ap) +static void nv_swncq_dmafis(struct ata_port *ap) { struct ata_queued_cmd *qc; unsigned int rw; @@ -2239,7 +2239,7 @@ static int nv_swncq_dmafis(struct ata_port *ap) qc = ata_qc_from_tag(ap, tag); if (unlikely(!qc)) - return 0; + return; rw = qc->tf.flags & ATA_TFLAG_WRITE; @@ -2254,8 +2254,6 @@ static int nv_swncq_dmafis(struct ata_port *ap) dmactl |= ATA_DMA_WR; iowrite8(dmactl | ATA_DMA_START, ap->ioaddr.bmdma_addr + ATA_DMA_CMD); - - return 1; } static void nv_swncq_host_interrupt(struct ata_port *ap, u16 fis) @@ -2265,7 +2263,6 @@ static void nv_swncq_host_interrupt(struct ata_port *ap, u16 fis) struct ata_eh_info *ehi = &ap->link.eh_info; u32 serror; u8 ata_stat; - int rc = 0; ata_stat = ap->ops->sff_check_status(ap); nv_swncq_irq_clear(ap, fis); @@ -2310,8 +2307,7 @@ static void nv_swncq_host_interrupt(struct ata_port *ap, u16 fis) "dhfis 0x%X dmafis 0x%X sactive 0x%X\n", ap->print_id, pp->qc_active, pp->dhfis_bits, pp->dmafis_bits, readl(pp->sactive_block)); - rc = nv_swncq_sdbfis(ap); - if (rc < 0) + if (nv_swncq_sdbfis(ap) < 0) goto irq_error; } @@ -2348,7 +2344,7 @@ static void nv_swncq_host_interrupt(struct ata_port *ap, u16 fis) */ pp->dmafis_bits |= (0x1 << nv_swncq_tag(ap)); pp->ncq_flags |= ncq_saw_dmas; - rc = nv_swncq_dmafis(ap); + nv_swncq_dmafis(ap); } irq_exit: -- cgit v1.2.3 From 9a017a910346afd88ec2e065989903bf211a7d37 Mon Sep 17 00:00:00 2001 From: Dominik Brodowski Date: Sat, 24 Jul 2010 15:58:54 +0200 Subject: pcmcia: do not use io_req_t after call to pcmcia_request_io() After pcmcia_request_io(), do not make use of the values stored in io_req_t, but instead use those found in struct pcmcia_device->resource[]. CC: netdev@vger.kernel.org CC: linux-wireless@vger.kernel.org CC: linux-ide@vger.kernel.org CC: linux-usb@vger.kernel.org CC: laforge@gnumonks.org CC: linux-mtd@lists.infradead.org CC: alsa-devel@alsa-project.org CC: linux-serial@vger.kernel.org Acked-by: Marcel Holtmann (for drivers/bluetooth/) Signed-off-by: Dominik Brodowski --- drivers/ata/pata_pcmcia.c | 8 ++++---- drivers/bluetooth/bluecard_cs.c | 18 ++++++++--------- drivers/bluetooth/bt3c_cs.c | 8 ++++---- drivers/bluetooth/btuart_cs.c | 12 ++++++------ drivers/bluetooth/dtl1_cs.c | 13 ++++++------ drivers/char/pcmcia/cm4000_cs.c | 12 ++++++------ drivers/char/pcmcia/cm4040_cs.c | 16 +++++++-------- drivers/char/pcmcia/ipwireless/main.c | 10 ++++------ drivers/char/pcmcia/synclink_cs.c | 7 +++---- drivers/ide/ide-cs.c | 8 ++++---- drivers/isdn/hardware/avm/avm_cs.c | 9 +++++---- drivers/isdn/hisax/avma1_cs.c | 8 +++++--- drivers/isdn/hisax/elsa_cs.c | 16 +++++++-------- drivers/isdn/hisax/sedlbauer_cs.c | 16 +++++++-------- drivers/isdn/hisax/teles_cs.c | 14 ++++++------- drivers/net/pcmcia/3c574_cs.c | 2 +- drivers/net/pcmcia/3c589_cs.c | 2 +- drivers/net/pcmcia/axnet_cs.c | 4 ++-- drivers/net/pcmcia/com20020_cs.c | 2 +- drivers/net/pcmcia/fmvj18x_cs.c | 6 +++--- drivers/net/pcmcia/ibmtr_cs.c | 2 +- drivers/net/pcmcia/nmclan_cs.c | 2 +- drivers/net/pcmcia/pcnet_cs.c | 4 ++-- drivers/net/pcmcia/smc91c92_cs.c | 18 ++++++++--------- drivers/net/pcmcia/xirc2ps_cs.c | 10 +++++----- drivers/net/wireless/airo_cs.c | 12 +++++------- drivers/net/wireless/atmel_cs.c | 2 +- drivers/net/wireless/hostap/hostap_cs.c | 18 ++++++++--------- drivers/net/wireless/libertas/if_cs.c | 7 +++---- drivers/net/wireless/orinoco/orinoco_cs.c | 5 +++-- drivers/net/wireless/orinoco/spectrum_cs.c | 5 +++-- drivers/net/wireless/wl3501_cs.c | 2 +- drivers/parport/parport_cs.c | 6 ++++-- drivers/scsi/pcmcia/aha152x_stub.c | 2 +- drivers/scsi/pcmcia/fdomain_stub.c | 4 ++-- drivers/scsi/pcmcia/nsp_cs.c | 25 ++++++++++++------------ drivers/scsi/pcmcia/qlogic_stub.c | 18 ++++++++--------- drivers/scsi/pcmcia/sym53c500_cs.c | 16 +++++++-------- drivers/serial/serial_cs.c | 22 ++++++++++----------- drivers/staging/comedi/drivers/cb_das16_cs.c | 12 +++++------- drivers/staging/comedi/drivers/das08_cs.c | 12 +++++------- drivers/staging/comedi/drivers/ni_daq_700.c | 12 +++++------- drivers/staging/comedi/drivers/ni_daq_dio24.c | 12 +++++------- drivers/staging/comedi/drivers/ni_labpc_cs.c | 12 +++++------- drivers/staging/comedi/drivers/ni_mio_cs.c | 2 +- drivers/staging/comedi/drivers/quatech_daqp_cs.c | 12 +++++------- drivers/staging/wlags49_h2/wl_cs.c | 2 +- drivers/telephony/ixj_pcmcia.c | 3 ++- drivers/usb/host/sl811_cs.c | 7 +++---- sound/pcmcia/pdaudiocf/pdaudiocf.c | 3 ++- sound/pcmcia/vx/vxpocket.c | 3 ++- 51 files changed, 223 insertions(+), 240 deletions(-) (limited to 'drivers/ata') diff --git a/drivers/ata/pata_pcmcia.c b/drivers/ata/pata_pcmcia.c index 3dcb2b1b60e9..1fcd0659b3f2 100644 --- a/drivers/ata/pata_pcmcia.c +++ b/drivers/ata/pata_pcmcia.c @@ -210,13 +210,13 @@ static int pcmcia_check_one_config(struct pcmcia_device *pdev, pdev->io.NumPorts2 = (stk->is_kme) ? 2 : 1; if (pcmcia_request_io(pdev, &pdev->io) != 0) return -ENODEV; - stk->ctl_base = pdev->io.BasePort2; + stk->ctl_base = pdev->resource[1]->start; } else if ((io->nwin == 1) && (io->win[0].len >= 16)) { pdev->io.NumPorts1 = io->win[0].len; pdev->io.NumPorts2 = 0; if (pcmcia_request_io(pdev, &pdev->io) != 0) return -ENODEV; - stk->ctl_base = pdev->io.BasePort1 + 0x0e; + stk->ctl_base = pdev->resource[0]->start + 0x0e; } else return -ENODEV; /* If we've got this far, we're done */ @@ -270,7 +270,7 @@ static int pcmcia_init_one(struct pcmcia_device *pdev) if (pcmcia_loop_config(pdev, pcmcia_check_one_config, stk)) goto failed; /* No suitable config found */ } - io_base = pdev->io.BasePort1; + io_base = pdev->resource[0]->start; ctl_base = stk->ctl_base; if (!pdev->irq) goto failed; @@ -293,7 +293,7 @@ static int pcmcia_init_one(struct pcmcia_device *pdev) /* FIXME: Could be more ports at base + 0x10 but we only deal with one right now */ - if (pdev->io.NumPorts1 >= 0x20) + if (resource_size(pdev->resource[0]) >= 0x20) n_ports = 2; if (pdev->manf_id == 0x0097 && pdev->card_id == 0x1620) diff --git a/drivers/bluetooth/bluecard_cs.c b/drivers/bluetooth/bluecard_cs.c index eb085de16713..24d2007139e8 100644 --- a/drivers/bluetooth/bluecard_cs.c +++ b/drivers/bluetooth/bluecard_cs.c @@ -159,7 +159,7 @@ static void bluecard_detach(struct pcmcia_device *p_dev); static void bluecard_activity_led_timeout(u_long arg) { bluecard_info_t *info = (bluecard_info_t *)arg; - unsigned int iobase = info->p_dev->io.BasePort1; + unsigned int iobase = info->p_dev->resource[0]->start; if (!test_bit(CARD_HAS_PCCARD_ID, &(info->hw_state))) return; @@ -176,7 +176,7 @@ static void bluecard_activity_led_timeout(u_long arg) static void bluecard_enable_activity_led(bluecard_info_t *info) { - unsigned int iobase = info->p_dev->io.BasePort1; + unsigned int iobase = info->p_dev->resource[0]->start; if (!test_bit(CARD_HAS_PCCARD_ID, &(info->hw_state))) return; @@ -232,7 +232,7 @@ static void bluecard_write_wakeup(bluecard_info_t *info) } do { - register unsigned int iobase = info->p_dev->io.BasePort1; + register unsigned int iobase = info->p_dev->resource[0]->start; register unsigned int offset; register unsigned char command; register unsigned long ready_bit; @@ -379,7 +379,7 @@ static void bluecard_receive(bluecard_info_t *info, unsigned int offset) return; } - iobase = info->p_dev->io.BasePort1; + iobase = info->p_dev->resource[0]->start; if (test_bit(XMIT_SENDING_READY, &(info->tx_state))) bluecard_enable_activity_led(info); @@ -508,7 +508,7 @@ static irqreturn_t bluecard_interrupt(int irq, void *dev_inst) if (!test_bit(CARD_READY, &(info->hw_state))) return IRQ_HANDLED; - iobase = info->p_dev->io.BasePort1; + iobase = info->p_dev->resource[0]->start; spin_lock(&(info->lock)); @@ -622,7 +622,7 @@ static int bluecard_hci_flush(struct hci_dev *hdev) static int bluecard_hci_open(struct hci_dev *hdev) { bluecard_info_t *info = (bluecard_info_t *)(hdev->driver_data); - unsigned int iobase = info->p_dev->io.BasePort1; + unsigned int iobase = info->p_dev->resource[0]->start; if (test_bit(CARD_HAS_PCCARD_ID, &(info->hw_state))) bluecard_hci_set_baud_rate(hdev, DEFAULT_BAUD_RATE); @@ -642,7 +642,7 @@ static int bluecard_hci_open(struct hci_dev *hdev) static int bluecard_hci_close(struct hci_dev *hdev) { bluecard_info_t *info = (bluecard_info_t *)(hdev->driver_data); - unsigned int iobase = info->p_dev->io.BasePort1; + unsigned int iobase = info->p_dev->resource[0]->start; if (!test_and_clear_bit(HCI_RUNNING, &(hdev->flags))) return 0; @@ -709,7 +709,7 @@ static int bluecard_hci_ioctl(struct hci_dev *hdev, unsigned int cmd, unsigned l static int bluecard_open(bluecard_info_t *info) { - unsigned int iobase = info->p_dev->io.BasePort1; + unsigned int iobase = info->p_dev->resource[0]->start; struct hci_dev *hdev; unsigned char id; @@ -828,7 +828,7 @@ static int bluecard_open(bluecard_info_t *info) static int bluecard_close(bluecard_info_t *info) { - unsigned int iobase = info->p_dev->io.BasePort1; + unsigned int iobase = info->p_dev->resource[0]->start; struct hci_dev *hdev = info->hdev; if (!hdev) diff --git a/drivers/bluetooth/bt3c_cs.c b/drivers/bluetooth/bt3c_cs.c index 457b603f8678..8ab494c0c17f 100644 --- a/drivers/bluetooth/bt3c_cs.c +++ b/drivers/bluetooth/bt3c_cs.c @@ -188,7 +188,7 @@ static void bt3c_write_wakeup(bt3c_info_t *info) return; do { - register unsigned int iobase = info->p_dev->io.BasePort1; + register unsigned int iobase = info->p_dev->resource[0]->start; register struct sk_buff *skb; register int len; @@ -226,7 +226,7 @@ static void bt3c_receive(bt3c_info_t *info) return; } - iobase = info->p_dev->io.BasePort1; + iobase = info->p_dev->resource[0]->start; avail = bt3c_read(iobase, 0x7006); //printk("bt3c_cs: receiving %d bytes\n", avail); @@ -347,7 +347,7 @@ static irqreturn_t bt3c_interrupt(int irq, void *dev_inst) /* our irq handler is shared */ return IRQ_NONE; - iobase = info->p_dev->io.BasePort1; + iobase = info->p_dev->resource[0]->start; spin_lock(&(info->lock)); @@ -480,7 +480,7 @@ static int bt3c_load_firmware(bt3c_info_t *info, const unsigned char *firmware, unsigned int iobase, size, addr, fcs, tmp; int i, err = 0; - iobase = info->p_dev->io.BasePort1; + iobase = info->p_dev->resource[0]->start; /* Reset */ bt3c_io_write(iobase, 0x8040, 0x0404); diff --git a/drivers/bluetooth/btuart_cs.c b/drivers/bluetooth/btuart_cs.c index e7e0a17aecc2..7e770d40368d 100644 --- a/drivers/bluetooth/btuart_cs.c +++ b/drivers/bluetooth/btuart_cs.c @@ -142,7 +142,7 @@ static void btuart_write_wakeup(btuart_info_t *info) } do { - register unsigned int iobase = info->p_dev->io.BasePort1; + register unsigned int iobase = info->p_dev->resource[0]->start; register struct sk_buff *skb; register int len; @@ -183,7 +183,7 @@ static void btuart_receive(btuart_info_t *info) return; } - iobase = info->p_dev->io.BasePort1; + iobase = info->p_dev->resource[0]->start; do { info->hdev->stat.byte_rx++; @@ -297,7 +297,7 @@ static irqreturn_t btuart_interrupt(int irq, void *dev_inst) /* our irq handler is shared */ return IRQ_NONE; - iobase = info->p_dev->io.BasePort1; + iobase = info->p_dev->resource[0]->start; spin_lock(&(info->lock)); @@ -354,7 +354,7 @@ static void btuart_change_speed(btuart_info_t *info, unsigned int speed) return; } - iobase = info->p_dev->io.BasePort1; + iobase = info->p_dev->resource[0]->start; spin_lock_irqsave(&(info->lock), flags); @@ -478,7 +478,7 @@ static int btuart_hci_ioctl(struct hci_dev *hdev, unsigned int cmd, unsigned lon static int btuart_open(btuart_info_t *info) { unsigned long flags; - unsigned int iobase = info->p_dev->io.BasePort1; + unsigned int iobase = info->p_dev->resource[0]->start; struct hci_dev *hdev; spin_lock_init(&(info->lock)); @@ -548,7 +548,7 @@ static int btuart_open(btuart_info_t *info) static int btuart_close(btuart_info_t *info) { unsigned long flags; - unsigned int iobase = info->p_dev->io.BasePort1; + unsigned int iobase = info->p_dev->resource[0]->start; struct hci_dev *hdev = info->hdev; if (!hdev) diff --git a/drivers/bluetooth/dtl1_cs.c b/drivers/bluetooth/dtl1_cs.c index 7c94aad0b791..bfe9313516fb 100644 --- a/drivers/bluetooth/dtl1_cs.c +++ b/drivers/bluetooth/dtl1_cs.c @@ -149,7 +149,7 @@ static void dtl1_write_wakeup(dtl1_info_t *info) } do { - register unsigned int iobase = info->p_dev->io.BasePort1; + register unsigned int iobase = info->p_dev->resource[0]->start; register struct sk_buff *skb; register int len; @@ -214,7 +214,7 @@ static void dtl1_receive(dtl1_info_t *info) return; } - iobase = info->p_dev->io.BasePort1; + iobase = info->p_dev->resource[0]->start; do { info->hdev->stat.byte_rx++; @@ -301,7 +301,7 @@ static irqreturn_t dtl1_interrupt(int irq, void *dev_inst) /* our irq handler is shared */ return IRQ_NONE; - iobase = info->p_dev->io.BasePort1; + iobase = info->p_dev->resource[0]->start; spin_lock(&(info->lock)); @@ -461,7 +461,7 @@ static int dtl1_hci_ioctl(struct hci_dev *hdev, unsigned int cmd, unsigned long static int dtl1_open(dtl1_info_t *info) { unsigned long flags; - unsigned int iobase = info->p_dev->io.BasePort1; + unsigned int iobase = info->p_dev->resource[0]->start; struct hci_dev *hdev; spin_lock_init(&(info->lock)); @@ -508,7 +508,8 @@ static int dtl1_open(dtl1_info_t *info) outb(UART_LCR_WLEN8, iobase + UART_LCR); /* Reset DLAB */ outb((UART_MCR_DTR | UART_MCR_RTS | UART_MCR_OUT2), iobase + UART_MCR); - info->ri_latch = inb(info->p_dev->io.BasePort1 + UART_MSR) & UART_MSR_RI; + info->ri_latch = inb(info->p_dev->resource[0]->start + UART_MSR) + & UART_MSR_RI; /* Turn on interrupts */ outb(UART_IER_RLSI | UART_IER_RDI | UART_IER_THRI, iobase + UART_IER); @@ -533,7 +534,7 @@ static int dtl1_open(dtl1_info_t *info) static int dtl1_close(dtl1_info_t *info) { unsigned long flags; - unsigned int iobase = info->p_dev->io.BasePort1; + unsigned int iobase = info->p_dev->resource[0]->start; struct hci_dev *hdev = info->hdev; if (!hdev) diff --git a/drivers/char/pcmcia/cm4000_cs.c b/drivers/char/pcmcia/cm4000_cs.c index a8be2a7906e0..18484edc1259 100644 --- a/drivers/char/pcmcia/cm4000_cs.c +++ b/drivers/char/pcmcia/cm4000_cs.c @@ -421,7 +421,7 @@ static struct card_fixup card_fixups[] = { static void set_cardparameter(struct cm4000_dev *dev) { int i; - unsigned int iobase = dev->p_dev->io.BasePort1; + unsigned int iobase = dev->p_dev->resource[0]->start; u_int8_t stopbits = 0x02; /* ISO default */ DEBUGP(3, dev, "-> set_cardparameter\n"); @@ -454,7 +454,7 @@ static int set_protocol(struct cm4000_dev *dev, struct ptsreq *ptsreq) unsigned short num_bytes_read; unsigned char pts_reply[4]; ssize_t rc; - unsigned int iobase = dev->p_dev->io.BasePort1; + unsigned int iobase = dev->p_dev->resource[0]->start; rc = 0; @@ -663,7 +663,7 @@ static void terminate_monitor(struct cm4000_dev *dev) static void monitor_card(unsigned long p) { struct cm4000_dev *dev = (struct cm4000_dev *) p; - unsigned int iobase = dev->p_dev->io.BasePort1; + unsigned int iobase = dev->p_dev->resource[0]->start; unsigned short s; struct ptsreq ptsreq; int i, atrc; @@ -924,7 +924,7 @@ static ssize_t cmm_read(struct file *filp, __user char *buf, size_t count, loff_t *ppos) { struct cm4000_dev *dev = filp->private_data; - unsigned int iobase = dev->p_dev->io.BasePort1; + unsigned int iobase = dev->p_dev->resource[0]->start; ssize_t rc; int i, j, k; @@ -1047,7 +1047,7 @@ static ssize_t cmm_write(struct file *filp, const char __user *buf, size_t count, loff_t *ppos) { struct cm4000_dev *dev = filp->private_data; - unsigned int iobase = dev->p_dev->io.BasePort1; + unsigned int iobase = dev->p_dev->resource[0]->start; unsigned short s; unsigned char tmp; unsigned char infolen; @@ -1400,7 +1400,7 @@ static void stop_monitor(struct cm4000_dev *dev) static long cmm_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) { struct cm4000_dev *dev = filp->private_data; - unsigned int iobase = dev->p_dev->io.BasePort1; + unsigned int iobase = dev->p_dev->resource[0]->start; struct inode *inode = filp->f_path.dentry->d_inode; struct pcmcia_device *link; int size; diff --git a/drivers/char/pcmcia/cm4040_cs.c b/drivers/char/pcmcia/cm4040_cs.c index 44adae98c576..a6bbf199dde9 100644 --- a/drivers/char/pcmcia/cm4040_cs.c +++ b/drivers/char/pcmcia/cm4040_cs.c @@ -109,7 +109,7 @@ static inline unsigned char xinb(unsigned short port) static void cm4040_do_poll(unsigned long dummy) { struct reader_dev *dev = (struct reader_dev *) dummy; - unsigned int obs = xinb(dev->p_dev->io.BasePort1 + unsigned int obs = xinb(dev->p_dev->resource[0]->start + REG_OFFSET_BUFFER_STATUS); if ((obs & BSR_BULK_IN_FULL)) { @@ -140,7 +140,7 @@ static void cm4040_stop_poll(struct reader_dev *dev) static int wait_for_bulk_out_ready(struct reader_dev *dev) { int i, rc; - int iobase = dev->p_dev->io.BasePort1; + int iobase = dev->p_dev->resource[0]->start; for (i = 0; i < POLL_LOOP_COUNT; i++) { if ((xinb(iobase + REG_OFFSET_BUFFER_STATUS) @@ -170,7 +170,7 @@ static int wait_for_bulk_out_ready(struct reader_dev *dev) /* Write to Sync Control Register */ static int write_sync_reg(unsigned char val, struct reader_dev *dev) { - int iobase = dev->p_dev->io.BasePort1; + int iobase = dev->p_dev->resource[0]->start; int rc; rc = wait_for_bulk_out_ready(dev); @@ -188,7 +188,7 @@ static int write_sync_reg(unsigned char val, struct reader_dev *dev) static int wait_for_bulk_in_ready(struct reader_dev *dev) { int i, rc; - int iobase = dev->p_dev->io.BasePort1; + int iobase = dev->p_dev->resource[0]->start; for (i = 0; i < POLL_LOOP_COUNT; i++) { if ((xinb(iobase + REG_OFFSET_BUFFER_STATUS) @@ -218,7 +218,7 @@ static ssize_t cm4040_read(struct file *filp, char __user *buf, size_t count, loff_t *ppos) { struct reader_dev *dev = filp->private_data; - int iobase = dev->p_dev->io.BasePort1; + int iobase = dev->p_dev->resource[0]->start; size_t bytes_to_read; unsigned long i; size_t min_bytes_to_read; @@ -320,7 +320,7 @@ static ssize_t cm4040_write(struct file *filp, const char __user *buf, size_t count, loff_t *ppos) { struct reader_dev *dev = filp->private_data; - int iobase = dev->p_dev->io.BasePort1; + int iobase = dev->p_dev->resource[0]->start; ssize_t rc; int i; unsigned int bytes_to_write; @@ -567,8 +567,8 @@ static int reader_config(struct pcmcia_device *link, int devno) dev = link->priv; - DEBUGP(2, dev, "device " DEVICE_NAME "%d at 0x%.4x-0x%.4x\n", devno, - link->io.BasePort1, link->io.BasePort1+link->io.NumPorts1); + DEBUGP(2, dev, "device " DEVICE_NAME "%d at %pR\n", devno, + link->resource[0]); DEBUGP(2, dev, "<- reader_config (succ)\n"); return 0; diff --git a/drivers/char/pcmcia/ipwireless/main.c b/drivers/char/pcmcia/ipwireless/main.c index 63c32e3f23ba..9467994d556f 100644 --- a/drivers/char/pcmcia/ipwireless/main.c +++ b/drivers/char/pcmcia/ipwireless/main.c @@ -100,7 +100,8 @@ static int ipwireless_probe(struct pcmcia_device *p_dev, if (ret) return ret; - io_resource = request_region(p_dev->io.BasePort1, p_dev->io.NumPorts1, + io_resource = request_region(p_dev->resource[0]->start, + resource_size(p_dev->resource[0]), IPWIRELESS_PCCARD_NAME); if (cfg->mem.nwin == 0) @@ -197,7 +198,7 @@ static int config_ipwireless(struct ipw_dev *ipw) INIT_WORK(&ipw->work_reboot, signalled_reboot_work); - ipwireless_init_hardware_v1(ipw->hardware, link->io.BasePort1, + ipwireless_init_hardware_v1(ipw->hardware, link->resource[0]->start, ipw->attr_memory, ipw->common_memory, ipw->is_v2_card, signalled_reboot_callback, ipw); @@ -209,10 +210,7 @@ static int config_ipwireless(struct ipw_dev *ipw) printk(KERN_INFO IPWIRELESS_PCCARD_NAME ": Card type %s\n", ipw->is_v2_card ? "V2/V3" : "V1"); printk(KERN_INFO IPWIRELESS_PCCARD_NAME - ": I/O ports 0x%04x-0x%04x, irq %d\n", - (unsigned int) link->io.BasePort1, - (unsigned int) (link->io.BasePort1 + - link->io.NumPorts1 - 1), + ": I/O ports %pR, irq %d\n", link->resource[0], (unsigned int) link->irq); if (ipw->attr_memory && ipw->common_memory) printk(KERN_INFO IPWIRELESS_PCCARD_NAME diff --git a/drivers/char/pcmcia/synclink_cs.c b/drivers/char/pcmcia/synclink_cs.c index 522992ed6e49..8ded9b02b9b9 100644 --- a/drivers/char/pcmcia/synclink_cs.c +++ b/drivers/char/pcmcia/synclink_cs.c @@ -609,16 +609,15 @@ static int mgslpc_config(struct pcmcia_device *link) if (ret) goto failed; - info->io_base = link->io.BasePort1; + info->io_base = link->resource[0]->start; info->irq_level = link->irq; dev_info(&link->dev, "index 0x%02x:", link->conf.ConfigIndex); if (link->conf.Attributes & CONF_ENABLE_IRQ) printk(", irq %d", link->irq); - if (link->io.NumPorts1) - printk(", io 0x%04x-0x%04x", link->io.BasePort1, - link->io.BasePort1+link->io.NumPorts1-1); + if (link->resource[0]) + printk(", io %pR", link->resource[0]); printk("\n"); return 0; diff --git a/drivers/ide/ide-cs.c b/drivers/ide/ide-cs.c index 27dbab84142c..6be0e5f108b5 100644 --- a/drivers/ide/ide-cs.c +++ b/drivers/ide/ide-cs.c @@ -239,13 +239,13 @@ static int pcmcia_check_one_config(struct pcmcia_device *pdev, pdev->io.NumPorts2 = (stk->is_kme) ? 2 : 1; if (pcmcia_request_io(pdev, &pdev->io) != 0) return -ENODEV; - stk->ctl_base = pdev->io.BasePort2; + stk->ctl_base = pdev->resource[1]->start; } else if ((io->nwin == 1) && (io->win[0].len >= 16)) { pdev->io.NumPorts1 = io->win[0].len; pdev->io.NumPorts2 = 0; if (pcmcia_request_io(pdev, &pdev->io) != 0) return -ENODEV; - stk->ctl_base = pdev->io.BasePort1 + 0x0e; + stk->ctl_base = pdev->resource[0]->start + 0x0e; } else return -ENODEV; /* If we've got this far, we're done */ @@ -279,7 +279,7 @@ static int ide_config(struct pcmcia_device *link) if (pcmcia_loop_config(link, pcmcia_check_one_config, stk)) goto failed; /* No suitable config found */ } - io_base = link->io.BasePort1; + io_base = link->resource[0]->start; ctl_base = stk->ctl_base; if (!link->irq) @@ -296,7 +296,7 @@ static int ide_config(struct pcmcia_device *link) outb(0x81, ctl_base+1); host = idecs_register(io_base, ctl_base, link->irq, link); - if (host == NULL && link->io.NumPorts1 == 0x20) { + if (host == NULL && resource_size(link->resource[0]) == 0x20) { outb(0x02, ctl_base + 0x10); host = idecs_register(io_base + 0x10, ctl_base + 0x10, link->irq, link); diff --git a/drivers/isdn/hardware/avm/avm_cs.c b/drivers/isdn/hardware/avm/avm_cs.c index e804a01ecdfb..7c8c51f22003 100644 --- a/drivers/isdn/hardware/avm/avm_cs.c +++ b/drivers/isdn/hardware/avm/avm_cs.c @@ -191,9 +191,10 @@ static int avmcs_config(struct pcmcia_device *link) default: case AVM_CARDTYPE_B1: addcard = b1pcmcia_addcard_b1; break; } - if ((i = (*addcard)(link->io.BasePort1, link->irq)) < 0) { - dev_err(&link->dev, "avm_cs: failed to add AVM-Controller at i/o %#x, irq %d\n", - link->io.BasePort1, link->irq); + if ((i = (*addcard)(link->resource[0]->start, link->irq)) < 0) { + dev_err(&link->dev, + "avm_cs: failed to add AVM-Controller at i/o %#x, irq %d\n", + (unsigned int) link->resource[0]->start, link->irq); avmcs_release(link); return -ENODEV; } @@ -211,7 +212,7 @@ static int avmcs_config(struct pcmcia_device *link) static void avmcs_release(struct pcmcia_device *link) { - b1pcmcia_delcard(link->io.BasePort1, link->irq); + b1pcmcia_delcard(link->resource[0]->start, link->irq); pcmcia_disable_device(link); } /* avmcs_release */ diff --git a/drivers/isdn/hisax/avma1_cs.c b/drivers/isdn/hisax/avma1_cs.c index 49e141e49aaf..88899638f835 100644 --- a/drivers/isdn/hisax/avma1_cs.c +++ b/drivers/isdn/hisax/avma1_cs.c @@ -180,16 +180,18 @@ static int __devinit avma1cs_config(struct pcmcia_device *link) } printk(KERN_NOTICE "avma1_cs: checking at i/o %#x, irq %d\n", - link->io.BasePort1, link->irq); + (unsigned int) link->resource[0]->start, link->irq); icard.para[0] = link->irq; - icard.para[1] = link->io.BasePort1; + icard.para[1] = link->resource[0]->start; icard.protocol = isdnprot; icard.typ = ISDN_CTYPE_A1_PCMCIA; i = hisax_init_pcmcia(link, &busy, &icard); if (i < 0) { - printk(KERN_ERR "avma1_cs: failed to initialize AVM A1 PCMCIA %d at i/o %#x\n", i, link->io.BasePort1); + printk(KERN_ERR "avma1_cs: failed to initialize AVM A1 " + "PCMCIA %d at i/o %#x\n", i, + (unsigned int) link->resource[0]->start); avma1cs_release(link); return -ENODEV; } diff --git a/drivers/isdn/hisax/elsa_cs.c b/drivers/isdn/hisax/elsa_cs.c index 425deea1dd69..c10bfd3f4588 100644 --- a/drivers/isdn/hisax/elsa_cs.c +++ b/drivers/isdn/hisax/elsa_cs.c @@ -214,23 +214,21 @@ static int __devinit elsa_cs_config(struct pcmcia_device *link) link->conf.ConfigIndex); if (link->conf.Attributes & CONF_ENABLE_IRQ) printk(", irq %d", link->irq); - if (link->io.NumPorts1) - printk(", io 0x%04x-0x%04x", link->io.BasePort1, - link->io.BasePort1+link->io.NumPorts1-1); - if (link->io.NumPorts2) - printk(" & 0x%04x-0x%04x", link->io.BasePort2, - link->io.BasePort2+link->io.NumPorts2-1); + if (link->resource[0]) + printk(" & %pR", link->resource[0]); + if (link->resource[1]) + printk(" & %pR", link->resource[1]); printk("\n"); icard.para[0] = link->irq; - icard.para[1] = link->io.BasePort1; + icard.para[1] = link->resource[0]->start; icard.protocol = protocol; icard.typ = ISDN_CTYPE_ELSA_PCMCIA; i = hisax_init_pcmcia(link, &(((local_info_t*)link->priv)->busy), &icard); if (i < 0) { - printk(KERN_ERR "elsa_cs: failed to initialize Elsa PCMCIA %d at i/o %#x\n", - i, link->io.BasePort1); + printk(KERN_ERR "elsa_cs: failed to initialize Elsa " + "PCMCIA %d with %pR\n", i, link->resource[0]); elsa_cs_release(link); } else ((local_info_t*)link->priv)->cardnr = i; diff --git a/drivers/isdn/hisax/sedlbauer_cs.c b/drivers/isdn/hisax/sedlbauer_cs.c index 5dbad966a29e..cecb35ab9d3d 100644 --- a/drivers/isdn/hisax/sedlbauer_cs.c +++ b/drivers/isdn/hisax/sedlbauer_cs.c @@ -296,27 +296,25 @@ static int __devinit sedlbauer_config(struct pcmcia_device *link) printk(", Vpp %d.%d", link->conf.Vpp/10, link->conf.Vpp%10); if (link->conf.Attributes & CONF_ENABLE_IRQ) printk(", irq %d", link->irq); - if (link->io.NumPorts1) - printk(", io 0x%04x-0x%04x", link->io.BasePort1, - link->io.BasePort1+link->io.NumPorts1-1); - if (link->io.NumPorts2) - printk(" & 0x%04x-0x%04x", link->io.BasePort2, - link->io.BasePort2+link->io.NumPorts2-1); + if (link->resource[0]) + printk(" & %pR", link->resource[0]); + if (link->resource[1]) + printk(" & %pR", link->resource[1]); if (link->win) printk(", mem 0x%06lx-0x%06lx", req->Base, req->Base+req->Size-1); printk("\n"); icard.para[0] = link->irq; - icard.para[1] = link->io.BasePort1; + icard.para[1] = link->resource[0]->start; icard.protocol = protocol; icard.typ = ISDN_CTYPE_SEDLBAUER_PCMCIA; ret = hisax_init_pcmcia(link, &(((local_info_t *)link->priv)->stop), &icard); if (ret < 0) { - printk(KERN_ERR "sedlbauer_cs: failed to initialize SEDLBAUER PCMCIA %d at i/o %#x\n", - ret, link->io.BasePort1); + printk(KERN_ERR "sedlbauer_cs: failed to initialize SEDLBAUER PCMCIA %d with %pR\n", + ret, link->resource[0]); sedlbauer_release(link); return -ENODEV; } else diff --git a/drivers/isdn/hisax/teles_cs.c b/drivers/isdn/hisax/teles_cs.c index d3fb1b716800..3787fc70cf8f 100644 --- a/drivers/isdn/hisax/teles_cs.c +++ b/drivers/isdn/hisax/teles_cs.c @@ -194,23 +194,21 @@ static int __devinit teles_cs_config(struct pcmcia_device *link) link->conf.ConfigIndex); if (link->conf.Attributes & CONF_ENABLE_IRQ) printk(", irq %d", link->irq); - if (link->io.NumPorts1) - printk(", io 0x%04x-0x%04x", link->io.BasePort1, - link->io.BasePort1+link->io.NumPorts1-1); - if (link->io.NumPorts2) - printk(" & 0x%04x-0x%04x", link->io.BasePort2, - link->io.BasePort2+link->io.NumPorts2-1); + if (link->resource[0]) + printk(" & %pR", link->resource[0]); + if (link->resource[1]) + printk(" & %pR", link->resource[1]); printk("\n"); icard.para[0] = link->irq; - icard.para[1] = link->io.BasePort1; + icard.para[1] = link->resource[0]->start; icard.protocol = protocol; icard.typ = ISDN_CTYPE_TELESPCMCIA; i = hisax_init_pcmcia(link, &(((local_info_t*)link->priv)->busy), &icard); if (i < 0) { printk(KERN_ERR "teles_cs: failed to initialize Teles PCMCIA %d at i/o %#x\n", - i, link->io.BasePort1); + i, (unsigned int) link->resource[0]->start); teles_cs_release(link); return -ENODEV; } diff --git a/drivers/net/pcmcia/3c574_cs.c b/drivers/net/pcmcia/3c574_cs.c index e249b898075c..b5ea9b8cfd76 100644 --- a/drivers/net/pcmcia/3c574_cs.c +++ b/drivers/net/pcmcia/3c574_cs.c @@ -356,7 +356,7 @@ static int tc574_config(struct pcmcia_device *link) goto failed; dev->irq = link->irq; - dev->base_addr = link->io.BasePort1; + dev->base_addr = link->resource[0]->start; ioaddr = dev->base_addr; diff --git a/drivers/net/pcmcia/3c589_cs.c b/drivers/net/pcmcia/3c589_cs.c index b0772df31057..122ef4a9488c 100644 --- a/drivers/net/pcmcia/3c589_cs.c +++ b/drivers/net/pcmcia/3c589_cs.c @@ -298,7 +298,7 @@ static int tc589_config(struct pcmcia_device *link) goto failed; dev->irq = link->irq; - dev->base_addr = link->io.BasePort1; + dev->base_addr = link->resource[0]->start; ioaddr = dev->base_addr; EL3WINDOW(0); diff --git a/drivers/net/pcmcia/axnet_cs.c b/drivers/net/pcmcia/axnet_cs.c index ee0a6d036f94..c52fdf31cbfe 100644 --- a/drivers/net/pcmcia/axnet_cs.c +++ b/drivers/net/pcmcia/axnet_cs.c @@ -332,7 +332,7 @@ static int axnet_config(struct pcmcia_device *link) if (!link->irq) goto failed; - if (link->io.NumPorts2 == 8) { + if (resource_size(link->resource[1]) == 8) { link->conf.Attributes |= CONF_ENABLE_SPKR; link->conf.Status = CCSR_AUDIO_ENA; } @@ -342,7 +342,7 @@ static int axnet_config(struct pcmcia_device *link) goto failed; dev->irq = link->irq; - dev->base_addr = link->io.BasePort1; + dev->base_addr = link->resource[0]->start; if (!get_prom(link)) { printk(KERN_NOTICE "axnet_cs: this is not an AX88190 card!\n"); diff --git a/drivers/net/pcmcia/com20020_cs.c b/drivers/net/pcmcia/com20020_cs.c index 99957af40329..3b53818e3eef 100644 --- a/drivers/net/pcmcia/com20020_cs.c +++ b/drivers/net/pcmcia/com20020_cs.c @@ -266,7 +266,7 @@ static int com20020_config(struct pcmcia_device *link) goto failed; } - ioaddr = dev->base_addr = link->io.BasePort1; + ioaddr = dev->base_addr = link->resource[0]->start; dev_dbg(&link->dev, "got ioaddr %Xh\n", ioaddr); dev_dbg(&link->dev, "request IRQ %d\n", diff --git a/drivers/net/pcmcia/fmvj18x_cs.c b/drivers/net/pcmcia/fmvj18x_cs.c index 95a991beaa30..bba6369a028e 100644 --- a/drivers/net/pcmcia/fmvj18x_cs.c +++ b/drivers/net/pcmcia/fmvj18x_cs.c @@ -315,7 +315,7 @@ static int ungermann_try_io_port(struct pcmcia_device *link) if (ret == 0) { /* calculate ConfigIndex value */ link->conf.ConfigIndex = - ((link->io.BasePort1 & 0x0f0) >> 3) | 0x22; + ((link->resource[0]->start & 0x0f0) >> 3) | 0x22; return ret; } } @@ -436,9 +436,9 @@ static int fmvj18x_config(struct pcmcia_device *link) goto failed; dev->irq = link->irq; - dev->base_addr = link->io.BasePort1; + dev->base_addr = link->resource[0]->start; - if (link->io.BasePort2 != 0) { + if (resource_size(link->resource[1]) != 0) { ret = fmvj18x_setup_mfc(link); if (ret != 0) goto failed; } diff --git a/drivers/net/pcmcia/ibmtr_cs.c b/drivers/net/pcmcia/ibmtr_cs.c index c36dcd14ec45..e99abaa92be5 100644 --- a/drivers/net/pcmcia/ibmtr_cs.c +++ b/drivers/net/pcmcia/ibmtr_cs.c @@ -231,7 +231,7 @@ static int __devinit ibmtr_config(struct pcmcia_device *link) if (ret) goto failed; } - dev->base_addr = link->io.BasePort1; + dev->base_addr = link->resource[0]->start; ret = pcmcia_request_exclusive_irq(link, ibmtr_interrupt); if (ret) diff --git a/drivers/net/pcmcia/nmclan_cs.c b/drivers/net/pcmcia/nmclan_cs.c index c0d85af3e942..9980cbb81d34 100644 --- a/drivers/net/pcmcia/nmclan_cs.c +++ b/drivers/net/pcmcia/nmclan_cs.c @@ -655,7 +655,7 @@ static int nmclan_config(struct pcmcia_device *link) goto failed; dev->irq = link->irq; - dev->base_addr = link->io.BasePort1; + dev->base_addr = link->resource[0]->start; ioaddr = dev->base_addr; diff --git a/drivers/net/pcmcia/pcnet_cs.c b/drivers/net/pcmcia/pcnet_cs.c index db6dbdabb702..c9cd2377ef91 100644 --- a/drivers/net/pcmcia/pcnet_cs.c +++ b/drivers/net/pcmcia/pcnet_cs.c @@ -554,7 +554,7 @@ static int pcnet_config(struct pcmcia_device *link) if (!link->irq) goto failed; - if (link->io.NumPorts2 == 8) { + if (resource_size(link->resource[1]) == 8) { link->conf.Attributes |= CONF_ENABLE_SPKR; link->conf.Status = CCSR_AUDIO_ENA; } @@ -566,7 +566,7 @@ static int pcnet_config(struct pcmcia_device *link) if (ret) goto failed; dev->irq = link->irq; - dev->base_addr = link->io.BasePort1; + dev->base_addr = link->resource[0]->start; if (info->flags & HAS_MISC_REG) { if ((if_port == 1) || (if_port == 2)) dev->if_port = if_port; diff --git a/drivers/net/pcmcia/smc91c92_cs.c b/drivers/net/pcmcia/smc91c92_cs.c index 88f503a80a8e..1b0b3230dd71 100644 --- a/drivers/net/pcmcia/smc91c92_cs.c +++ b/drivers/net/pcmcia/smc91c92_cs.c @@ -457,7 +457,7 @@ static int mhz_mfc_config(struct pcmcia_device *link) if (pcmcia_loop_config(link, mhz_mfc_config_check, NULL)) return -ENODEV; - dev->base_addr = link->io.BasePort1; + dev->base_addr = link->resource[0]->start; /* Allocate a memory window, for accessing the ISR */ req.Attributes = WIN_DATA_WIDTH_8|WIN_MEMORY_TYPE_AM|WIN_ENABLE; @@ -545,7 +545,7 @@ static void mot_config(struct pcmcia_device *link) struct net_device *dev = link->priv; struct smc_private *smc = netdev_priv(dev); unsigned int ioaddr = dev->base_addr; - unsigned int iouart = link->io.BasePort2; + unsigned int iouart = link->resource[1]->start; /* Set UART base address and force map with COR bit 1 */ writeb(iouart & 0xff, smc->base + MOT_UART + CISREG_IOBASE_0); @@ -614,7 +614,7 @@ static int smc_config(struct pcmcia_device *link) link->io.NumPorts1 = 16; i = pcmcia_loop_config(link, smc_configcheck, NULL); if (!i) - dev->base_addr = link->io.BasePort1; + dev->base_addr = link->resource[0]->start; return i; } @@ -666,7 +666,7 @@ static int osi_config(struct pcmcia_device *link) link->io.NumPorts2 = 0; i = pcmcia_request_io(link, &link->io); } - dev->base_addr = link->io.BasePort1 + 0x10; + dev->base_addr = link->resource[0]->start + 0x10; return i; } @@ -683,7 +683,7 @@ static int osi_load_firmware(struct pcmcia_device *link) /* Download the Seven of Diamonds firmware */ for (i = 0; i < fw->size; i++) { - outb(fw->data[i], link->io.BasePort1 + 2); + outb(fw->data[i], link->resource[0]->start + 2); udelay(50); } release_firmware(fw); @@ -725,12 +725,12 @@ static int osi_setup(struct pcmcia_device *link, u_short manfid, u_short cardid) return rc; } else if (manfid == MANFID_OSITECH) { /* Make sure both functions are powered up */ - set_bits(0x300, link->io.BasePort1 + OSITECH_AUI_PWR); + set_bits(0x300, link->resource[0]->start + OSITECH_AUI_PWR); /* Now, turn on the interrupt for both card functions */ - set_bits(0x300, link->io.BasePort1 + OSITECH_RESET_ISR); + set_bits(0x300, link->resource[0]->start + OSITECH_RESET_ISR); dev_dbg(&link->dev, "AUI/PWR: %4.4x RESET/ISR: %4.4x\n", - inw(link->io.BasePort1 + OSITECH_AUI_PWR), - inw(link->io.BasePort1 + OSITECH_RESET_ISR)); + inw(link->resource[0]->start + OSITECH_AUI_PWR), + inw(link->resource[0]->start + OSITECH_RESET_ISR)); } return 0; } diff --git a/drivers/net/pcmcia/xirc2ps_cs.c b/drivers/net/pcmcia/xirc2ps_cs.c index e3a85ce89880..034920b459d1 100644 --- a/drivers/net/pcmcia/xirc2ps_cs.c +++ b/drivers/net/pcmcia/xirc2ps_cs.c @@ -877,13 +877,13 @@ xirc2ps_config(struct pcmcia_device * link) * the base address of the ethernet port (BasePort1) is written * to the BAR registers of the modem. */ - err = pcmcia_write_config_byte(link, CISREG_IOBASE_0, - link->io.BasePort2 & 0xff); + err = pcmcia_write_config_byte(link, CISREG_IOBASE_0, (u8) + link->resource[1]->start & 0xff); if (err) goto config_error; err = pcmcia_write_config_byte(link, CISREG_IOBASE_1, - (link->io.BasePort2 >> 8) & 0xff); + (link->resource[1]->start >> 8) & 0xff); if (err) goto config_error; @@ -907,7 +907,7 @@ xirc2ps_config(struct pcmcia_device * link) * part. */ writeb(0x47, local->dingo_ccr + CISREG_COR); - ioaddr = link->io.BasePort1; + ioaddr = link->resource[0]->start; writeb(ioaddr & 0xff , local->dingo_ccr + CISREG_IOBASE_0); writeb((ioaddr >> 8)&0xff , local->dingo_ccr + CISREG_IOBASE_1); @@ -954,7 +954,7 @@ xirc2ps_config(struct pcmcia_device * link) /* we can now register the device with the net subsystem */ dev->irq = link->irq; - dev->base_addr = link->io.BasePort1; + dev->base_addr = link->resource[0]->start; if (local->dingo) do_reset(dev, 1); /* a kludge to make the cem56 work */ diff --git a/drivers/net/wireless/airo_cs.c b/drivers/net/wireless/airo_cs.c index 9389ba004fb9..b7e7f5054e44 100644 --- a/drivers/net/wireless/airo_cs.c +++ b/drivers/net/wireless/airo_cs.c @@ -271,7 +271,7 @@ static int airo_config(struct pcmcia_device *link) goto failed; ((local_info_t *)link->priv)->eth_dev = init_airo_card(link->irq, - link->io.BasePort1, 1, &link->dev); + link->resource[0]->start, 1, &link->dev); if (!((local_info_t *)link->priv)->eth_dev) goto failed; @@ -281,12 +281,10 @@ static int airo_config(struct pcmcia_device *link) if (link->conf.Vpp) printk(", Vpp %d.%d", link->conf.Vpp/10, link->conf.Vpp%10); printk(", irq %d", link->irq); - if (link->io.NumPorts1) - printk(", io 0x%04x-0x%04x", link->io.BasePort1, - link->io.BasePort1+link->io.NumPorts1-1); - if (link->io.NumPorts2) - printk(" & 0x%04x-0x%04x", link->io.BasePort2, - link->io.BasePort2+link->io.NumPorts2-1); + if (link->resource[0]) + printk(" & %pR", link->resource[0]); + if (link->resource[1]) + printk(" & %pR", link->resource[1]); if (link->win) printk(", mem 0x%06lx-0x%06lx", req->Base, req->Base+req->Size-1); diff --git a/drivers/net/wireless/atmel_cs.c b/drivers/net/wireless/atmel_cs.c index 91ee74a8801e..65b3aed49e58 100644 --- a/drivers/net/wireless/atmel_cs.c +++ b/drivers/net/wireless/atmel_cs.c @@ -253,7 +253,7 @@ static int atmel_config(struct pcmcia_device *link) ((local_info_t*)link->priv)->eth_dev = init_atmel_card(link->irq, - link->io.BasePort1, + link->resource[0]->start, did ? did->driver_info : ATMEL_FW_TYPE_NONE, &link->dev, card_present, diff --git a/drivers/net/wireless/hostap/hostap_cs.c b/drivers/net/wireless/hostap/hostap_cs.c index 691293675a93..4e13cedb8235 100644 --- a/drivers/net/wireless/hostap/hostap_cs.c +++ b/drivers/net/wireless/hostap/hostap_cs.c @@ -227,7 +227,7 @@ static void sandisk_set_iobase(local_info_t *local) struct hostap_cs_priv *hw_priv = local->hw_priv; res = pcmcia_write_config_byte(hw_priv->link, 0x10, - hw_priv->link->io.BasePort1 & 0x00ff); + hw_priv->link->resource[0]->start & 0x00ff); if (res != 0) { printk(KERN_DEBUG "Prism3 SanDisk - failed to set I/O base 0 -" " res=%d\n", res); @@ -235,7 +235,7 @@ static void sandisk_set_iobase(local_info_t *local) udelay(10); res = pcmcia_write_config_byte(hw_priv->link, 0x12, - (hw_priv->link->io.BasePort1 >> 8) & 0x00ff); + (hw_priv->link->resource[0]->start >> 8) & 0x00ff); if (res != 0) { printk(KERN_DEBUG "Prism3 SanDisk - failed to set I/O base 1 -" " res=%d\n", res); @@ -265,7 +265,7 @@ static int sandisk_enable_wireless(struct net_device *dev) local_info_t *local = iface->local; struct hostap_cs_priv *hw_priv = local->hw_priv; - if (hw_priv->link->io.NumPorts1 < 0x42) { + if (resource_size(hw_priv->link->resource[0]) < 0x42) { /* Not enough ports to be SanDisk multi-function card */ ret = -ENODEV; goto done; @@ -604,7 +604,7 @@ static int prism2_config(struct pcmcia_device *link) goto failed_unlock; dev->irq = link->irq; - dev->base_addr = link->io.BasePort1; + dev->base_addr = link->resource[0]->start; spin_unlock_irqrestore(&local->irq_init_lock, flags); @@ -616,12 +616,10 @@ static int prism2_config(struct pcmcia_device *link) link->conf.Vpp % 10); if (link->conf.Attributes & CONF_ENABLE_IRQ) printk(", irq %d", link->irq); - if (link->io.NumPorts1) - printk(", io 0x%04x-0x%04x", link->io.BasePort1, - link->io.BasePort1+link->io.NumPorts1-1); - if (link->io.NumPorts2) - printk(" & 0x%04x-0x%04x", link->io.BasePort2, - link->io.BasePort2+link->io.NumPorts2-1); + if (link->resource[0]) + printk(" & %pR", link->resource[0]); + if (link->resource[1]) + printk(" & %pR", link->resource[1]); printk("\n"); local->shutdown = 0; diff --git a/drivers/net/wireless/libertas/if_cs.c b/drivers/net/wireless/libertas/if_cs.c index 1d3a7e0e5f10..be4c47594b59 100644 --- a/drivers/net/wireless/libertas/if_cs.c +++ b/drivers/net/wireless/libertas/if_cs.c @@ -853,7 +853,8 @@ static int if_cs_probe(struct pcmcia_device *p_dev) goto out1; /* Initialize io access */ - card->iobase = ioport_map(p_dev->io.BasePort1, p_dev->io.NumPorts1); + card->iobase = ioport_map(p_dev->resource[0]->start, + resource_size(p_dev->resource[0])); if (!card->iobase) { lbs_pr_err("error in ioport_map\n"); ret = -EIO; @@ -872,9 +873,7 @@ static int if_cs_probe(struct pcmcia_device *p_dev) } /* Finally, report what we've done */ - lbs_deb_cs("irq %d, io 0x%04x-0x%04x\n", - p_dev->irq, p_dev->io.BasePort1, - p_dev->io.BasePort1 + p_dev->io.NumPorts1 - 1); + lbs_deb_cs("irq %d, io %pR", p_dev->irq, p_dev->resource[0]); /* * Most of the libertas cards can do unaligned register access, but some diff --git a/drivers/net/wireless/orinoco/orinoco_cs.c b/drivers/net/wireless/orinoco/orinoco_cs.c index 41ca4f1b395f..6d514b5462fd 100644 --- a/drivers/net/wireless/orinoco/orinoco_cs.c +++ b/drivers/net/wireless/orinoco/orinoco_cs.c @@ -257,7 +257,8 @@ orinoco_cs_config(struct pcmcia_device *link) /* We initialize the hermes structure before completing PCMCIA * configuration just in case the interrupt handler gets * called. */ - mem = ioport_map(link->io.BasePort1, link->io.NumPorts1); + mem = ioport_map(link->resource[0]->start, + resource_size(link->resource[0])); if (!mem) goto failed; @@ -279,7 +280,7 @@ orinoco_cs_config(struct pcmcia_device *link) } /* Register an interface with the stack */ - if (orinoco_if_add(priv, link->io.BasePort1, + if (orinoco_if_add(priv, link->resource[0]->start, link->irq, NULL) != 0) { printk(KERN_ERR PFX "orinoco_if_add() failed\n"); goto failed; diff --git a/drivers/net/wireless/orinoco/spectrum_cs.c b/drivers/net/wireless/orinoco/spectrum_cs.c index 39399cd2e683..4f8f55eab955 100644 --- a/drivers/net/wireless/orinoco/spectrum_cs.c +++ b/drivers/net/wireless/orinoco/spectrum_cs.c @@ -319,7 +319,8 @@ spectrum_cs_config(struct pcmcia_device *link) /* We initialize the hermes structure before completing PCMCIA * configuration just in case the interrupt handler gets * called. */ - mem = ioport_map(link->io.BasePort1, link->io.NumPorts1); + mem = ioport_map(link->resource[0]->start, + resource_size(link->resource[0])); if (!mem) goto failed; @@ -346,7 +347,7 @@ spectrum_cs_config(struct pcmcia_device *link) } /* Register an interface with the stack */ - if (orinoco_if_add(priv, link->io.BasePort1, + if (orinoco_if_add(priv, link->resource[0]->start, link->irq, NULL) != 0) { printk(KERN_ERR PFX "orinoco_if_add() failed\n"); goto failed; diff --git a/drivers/net/wireless/wl3501_cs.c b/drivers/net/wireless/wl3501_cs.c index 35f431bf97d6..a32f220648c0 100644 --- a/drivers/net/wireless/wl3501_cs.c +++ b/drivers/net/wireless/wl3501_cs.c @@ -1960,7 +1960,7 @@ static int wl3501_config(struct pcmcia_device *link) goto failed; dev->irq = link->irq; - dev->base_addr = link->io.BasePort1; + dev->base_addr = link->resource[0]->start; SET_NETDEV_DEV(dev, &link->dev); if (register_netdev(dev)) { printk(KERN_NOTICE "wl3501_cs: register_netdev() failed\n"); diff --git a/drivers/parport/parport_cs.c b/drivers/parport/parport_cs.c index ee56fd66d5dc..fc1639c5ada6 100644 --- a/drivers/parport/parport_cs.c +++ b/drivers/parport/parport_cs.c @@ -177,12 +177,14 @@ static int parport_config(struct pcmcia_device *link) if (ret) goto failed; - p = parport_pc_probe_port(link->io.BasePort1, link->io.BasePort2, + p = parport_pc_probe_port(link->resource[0]->start, + link->resource[1]->start, link->irq, PARPORT_DMA_NONE, &link->dev, IRQF_SHARED); if (p == NULL) { printk(KERN_NOTICE "parport_cs: parport_pc_probe_port() at " - "0x%3x, irq %u failed\n", link->io.BasePort1, + "0x%3x, irq %u failed\n", + (unsigned int) link->resource[0]->start, link->irq); goto failed; } diff --git a/drivers/scsi/pcmcia/aha152x_stub.c b/drivers/scsi/pcmcia/aha152x_stub.c index b07b53ef3c00..3e040f503afa 100644 --- a/drivers/scsi/pcmcia/aha152x_stub.c +++ b/drivers/scsi/pcmcia/aha152x_stub.c @@ -167,7 +167,7 @@ static int aha152x_config_cs(struct pcmcia_device *link) /* Set configuration options for the aha152x driver */ memset(&s, 0, sizeof(s)); s.conf = "PCMCIA setup"; - s.io_port = link->io.BasePort1; + s.io_port = link->resource[0]->start; s.irq = link->irq; s.scsiid = host_id; s.reconnect = reconnect; diff --git a/drivers/scsi/pcmcia/fdomain_stub.c b/drivers/scsi/pcmcia/fdomain_stub.c index ee0489762539..49a9a0a60c82 100644 --- a/drivers/scsi/pcmcia/fdomain_stub.c +++ b/drivers/scsi/pcmcia/fdomain_stub.c @@ -137,10 +137,10 @@ static int fdomain_config(struct pcmcia_device *link) goto failed; /* A bad hack... */ - release_region(link->io.BasePort1, link->io.NumPorts1); + release_region(link->resource[0]->start, resource_size(link->resource[0])); /* Set configuration options for the fdomain driver */ - sprintf(str, "%d,%d", link->io.BasePort1, link->irq); + sprintf(str, "%d,%d", (unsigned int) link->resource[0]->start, link->irq); fdomain_setup(str); host = __fdomain_16x0_detect(&fdomain_driver_template); diff --git a/drivers/scsi/pcmcia/nsp_cs.c b/drivers/scsi/pcmcia/nsp_cs.c index d4142075be21..d929891809ab 100644 --- a/drivers/scsi/pcmcia/nsp_cs.c +++ b/drivers/scsi/pcmcia/nsp_cs.c @@ -1719,17 +1719,19 @@ static int nsp_cs_config(struct pcmcia_device *link) goto cs_failed; if (free_ports) { - if (link->io.BasePort1) { - release_region(link->io.BasePort1, link->io.NumPorts1); + if (link->resource[0]) { + release_region(link->resource[0]->start, + resource_size(link->resource[0])); } - if (link->io.BasePort2) { - release_region(link->io.BasePort2, link->io.NumPorts2); + if (link->resource[1]) { + release_region(link->resource[1]->start, + resource_size(link->resource[1])); } } /* Set port and IRQ */ - data->BaseAddress = link->io.BasePort1; - data->NumAddress = link->io.NumPorts1; + data->BaseAddress = link->resource[0]->start; + data->NumAddress = resource_size(link->resource[0]); data->IrqNumber = link->irq; nsp_dbg(NSP_DEBUG_INIT, "I/O[0x%x+0x%x] IRQ %d", @@ -1764,13 +1766,10 @@ static int nsp_cs_config(struct pcmcia_device *link) if (link->conf.Attributes & CONF_ENABLE_IRQ) { printk(", irq %d", link->irq); } - if (link->io.NumPorts1) { - printk(", io 0x%04x-0x%04x", link->io.BasePort1, - link->io.BasePort1+link->io.NumPorts1-1); - } - if (link->io.NumPorts2) - printk(" & 0x%04x-0x%04x", link->io.BasePort2, - link->io.BasePort2+link->io.NumPorts2-1); + if (link->resource[0]) + printk(", io %pR", link->resource[0]); + if (link->resource[1]) + printk(" & %pR", link->resource[1]); if (link->win) printk(", mem 0x%06lx-0x%06lx", cfg_mem->req.Base, cfg_mem->req.Base+cfg_mem->req.Size-1); diff --git a/drivers/scsi/pcmcia/qlogic_stub.c b/drivers/scsi/pcmcia/qlogic_stub.c index c1cf7f43313b..4e2b83f26232 100644 --- a/drivers/scsi/pcmcia/qlogic_stub.c +++ b/drivers/scsi/pcmcia/qlogic_stub.c @@ -215,18 +215,18 @@ static int qlogic_config(struct pcmcia_device * link) if ((info->manf_id == MANFID_MACNICA) || (info->manf_id == MANFID_PIONEER) || (info->manf_id == 0x0098)) { /* set ATAcmd */ - outb(0xb4, link->io.BasePort1 + 0xd); - outb(0x24, link->io.BasePort1 + 0x9); - outb(0x04, link->io.BasePort1 + 0xd); + outb(0xb4, link->resource[0]->start + 0xd); + outb(0x24, link->resource[0]->start + 0x9); + outb(0x04, link->resource[0]->start + 0xd); } /* The KXL-810AN has a bigger IO port window */ - if (link->io.NumPorts1 == 32) + if (resource_size(link->resource[0]) == 32) host = qlogic_detect(&qlogicfas_driver_template, link, - link->io.BasePort1 + 16, link->irq); + link->resource[0]->start + 16, link->irq); else host = qlogic_detect(&qlogicfas_driver_template, link, - link->io.BasePort1, link->irq); + link->resource[0]->start, link->irq); if (!host) { printk(KERN_INFO "%s: no SCSI devices found\n", qlogic_name); @@ -268,9 +268,9 @@ static int qlogic_resume(struct pcmcia_device *link) if ((info->manf_id == MANFID_MACNICA) || (info->manf_id == MANFID_PIONEER) || (info->manf_id == 0x0098)) { - outb(0x80, link->io.BasePort1 + 0xd); - outb(0x24, link->io.BasePort1 + 0x9); - outb(0x04, link->io.BasePort1 + 0xd); + outb(0x80, link->resource[0]->start + 0xd); + outb(0x24, link->resource[0]->start + 0x9); + outb(0x04, link->resource[0]->start + 0xd); } /* Ugggglllyyyy!!! */ qlogicfas408_bus_reset(NULL); diff --git a/drivers/scsi/pcmcia/sym53c500_cs.c b/drivers/scsi/pcmcia/sym53c500_cs.c index bd79e45ab856..d99c0cbad2de 100644 --- a/drivers/scsi/pcmcia/sym53c500_cs.c +++ b/drivers/scsi/pcmcia/sym53c500_cs.c @@ -733,9 +733,9 @@ SYM53C500_config(struct pcmcia_device *link) (info->manf_id == MANFID_PIONEER) || (info->manf_id == 0x0098)) { /* set ATAcmd */ - outb(0xb4, link->io.BasePort1 + 0xd); - outb(0x24, link->io.BasePort1 + 0x9); - outb(0x04, link->io.BasePort1 + 0xd); + outb(0xb4, link->resource[0]->start + 0xd); + outb(0x24, link->resource[0]->start + 0x9); + outb(0x04, link->resource[0]->start + 0xd); } /* @@ -748,7 +748,7 @@ SYM53C500_config(struct pcmcia_device *link) * 0x130, 0x230, 0x280, 0x290, * 0x320, 0x330, 0x340, 0x350 */ - port_base = link->io.BasePort1; + port_base = link->resource[0]->start; irq_level = link->irq; DEB(printk("SYM53C500: port_base=0x%x, irq=%d, fast_pio=%d\n", @@ -821,15 +821,15 @@ static int sym53c500_resume(struct pcmcia_device *link) if ((info->manf_id == MANFID_MACNICA) || (info->manf_id == MANFID_PIONEER) || (info->manf_id == 0x0098)) { - outb(0x80, link->io.BasePort1 + 0xd); - outb(0x24, link->io.BasePort1 + 0x9); - outb(0x04, link->io.BasePort1 + 0xd); + outb(0x80, link->resource[0]->start + 0xd); + outb(0x24, link->resource[0]->start + 0x9); + outb(0x04, link->resource[0]->start + 0xd); } /* * If things don't work after a "resume", * this is a good place to start looking. */ - SYM53C500_int_host_reset(link->io.BasePort1); + SYM53C500_int_host_reset(link->resource[0]->start); return 0; } diff --git a/drivers/serial/serial_cs.c b/drivers/serial/serial_cs.c index 2be8b107ed51..fe7adcdfde9e 100644 --- a/drivers/serial/serial_cs.c +++ b/drivers/serial/serial_cs.c @@ -463,13 +463,13 @@ static int simple_config(struct pcmcia_device *link) /* If the card is already configured, look up the port and irq */ if (link->function_config) { unsigned int port = 0; - if ((link->io.BasePort2 != 0) && - (link->io.NumPorts2 == 8)) { - port = link->io.BasePort2; + if ((link->resource[1]->end != 0) && + (resource_size(link->resource[1]) == 8)) { + port = link->resource[1]->end; info->slave = 1; } else if ((info->manfid == MANFID_OSITECH) && - (link->io.NumPorts1 == 0x40)) { - port = link->io.BasePort1 + 0x28; + (resource_size(link->resource[0]) == 0x40)) { + port = link->resource[0]->start + 0x28; info->slave = 1; } if (info->slave) { @@ -507,7 +507,7 @@ found_port: i = pcmcia_request_configuration(link, &link->conf); if (i != 0) return -1; - return setup_serial(link, info, link->io.BasePort1, link->irq); + return setup_serial(link, info, link->resource[0]->start, link->irq); } static int multi_config_check(struct pcmcia_device *p_dev, @@ -524,7 +524,7 @@ static int multi_config_check(struct pcmcia_device *p_dev, p_dev->io.BasePort1 = cf->io.win[0].base; p_dev->io.IOAddrLines = cf->io.flags & CISTPL_IO_LINES_MASK; if (!pcmcia_request_io(p_dev, &p_dev->io)) { - *base2 = p_dev->io.BasePort1 + 8; + *base2 = p_dev->resource[0]->start + 8; return 0; } } @@ -544,7 +544,7 @@ static int multi_config_check_notpicky(struct pcmcia_device *p_dev, p_dev->io.BasePort2 = cf->io.win[1].base; p_dev->io.IOAddrLines = cf->io.flags & CISTPL_IO_LINES_MASK; if (!pcmcia_request_io(p_dev, &p_dev->io)) { - *base2 = p_dev->io.BasePort2; + *base2 = p_dev->resource[1]->start; return 0; } } @@ -596,9 +596,9 @@ static int multi_config(struct pcmcia_device *link) link->conf.ConfigIndex == 3) { err = setup_serial(link, info, base2, link->irq); - base2 = link->io.BasePort1; + base2 = link->resource[0]->start;; } else { - err = setup_serial(link, info, link->io.BasePort1, + err = setup_serial(link, info, link->resource[0]->start, link->irq); } info->c950ctrl = base2; @@ -613,7 +613,7 @@ static int multi_config(struct pcmcia_device *link) return 0; } - setup_serial(link, info, link->io.BasePort1, link->irq); + setup_serial(link, info, link->resource[0]->start, link->irq); for (i = 0; i < info->multi - 1; i++) setup_serial(link, info, base2 + (8 * i), link->irq); diff --git a/drivers/staging/comedi/drivers/cb_das16_cs.c b/drivers/staging/comedi/drivers/cb_das16_cs.c index acef29ca212b..208f1b7a1312 100644 --- a/drivers/staging/comedi/drivers/cb_das16_cs.c +++ b/drivers/staging/comedi/drivers/cb_das16_cs.c @@ -170,7 +170,7 @@ static int das16cs_attach(struct comedi_device *dev, if (!link) return -EIO; - dev->iobase = link->io.BasePort1; + dev->iobase = link->resource[0]->start;; printk("I/O base=0x%04lx ", dev->iobase); printk("fingerprint:\n"); @@ -787,12 +787,10 @@ static void das16cs_pcmcia_config(struct pcmcia_device *link) dev_info(&link->dev, "index 0x%02x", link->conf.ConfigIndex); if (link->conf.Attributes & CONF_ENABLE_IRQ) printk(", irq %u", link->irq); - if (link->io.NumPorts1) - printk(", io 0x%04x-0x%04x", link->io.BasePort1, - link->io.BasePort1 + link->io.NumPorts1 - 1); - if (link->io.NumPorts2) - printk(" & 0x%04x-0x%04x", link->io.BasePort2, - link->io.BasePort2 + link->io.NumPorts2 - 1); + if (link->resource[0]) + printk(", io %pR", link->resource[0]); + if (link->resource[1]) + printk(", io %pR", link->resource[1]); printk("\n"); return; diff --git a/drivers/staging/comedi/drivers/das08_cs.c b/drivers/staging/comedi/drivers/das08_cs.c index 3eddb7c4b1b0..c4cfcffc633e 100644 --- a/drivers/staging/comedi/drivers/das08_cs.c +++ b/drivers/staging/comedi/drivers/das08_cs.c @@ -88,7 +88,7 @@ static int das08_cs_attach(struct comedi_device *dev, printk(" no pcmcia cards found\n"); return -EIO; } - iobase = link->io.BasePort1; + iobase = link->resource[0]->start; } else { printk(" bug! board does not have PCMCIA bustype\n"); return -EINVAL; @@ -283,12 +283,10 @@ static void das08_pcmcia_config(struct pcmcia_device *link) dev_info(&link->dev, "index 0x%02x", link->conf.ConfigIndex); if (link->conf.Attributes & CONF_ENABLE_IRQ) printk(", irq %u", link->irq); - if (link->io.NumPorts1) - printk(", io 0x%04x-0x%04x", link->io.BasePort1, - link->io.BasePort1 + link->io.NumPorts1 - 1); - if (link->io.NumPorts2) - printk(" & 0x%04x-0x%04x", link->io.BasePort2, - link->io.BasePort2 + link->io.NumPorts2 - 1); + if (link->resource[0]) + printk(", io %pR", link->resource[0]); + if (link->resource[1]) + printk(" & %pR", link->resource[1]); printk("\n"); return; diff --git a/drivers/staging/comedi/drivers/ni_daq_700.c b/drivers/staging/comedi/drivers/ni_daq_700.c index f3c4d2f929f8..6d569579d677 100644 --- a/drivers/staging/comedi/drivers/ni_daq_700.c +++ b/drivers/staging/comedi/drivers/ni_daq_700.c @@ -376,7 +376,7 @@ static int dio700_attach(struct comedi_device *dev, struct comedi_devconfig *it) link = pcmcia_cur_dev; /* XXX hack */ if (!link) return -EIO; - iobase = link->io.BasePort1; + iobase = link->resource[0]->start; #ifdef incomplete irq = link->irq; #endif @@ -644,12 +644,10 @@ static void dio700_config(struct pcmcia_device *link) dev_info(&link->dev, "index 0x%02x", link->conf.ConfigIndex); if (link->conf.Attributes & CONF_ENABLE_IRQ) printk(", irq %d", link->irq); - if (link->io.NumPorts1) - printk(", io 0x%04x-0x%04x", link->io.BasePort1, - link->io.BasePort1 + link->io.NumPorts1 - 1); - if (link->io.NumPorts2) - printk(" & 0x%04x-0x%04x", link->io.BasePort2, - link->io.BasePort2 + link->io.NumPorts2 - 1); + if (link->resource[0]) + printk(", io %pR", link->resource[0]); + if (link->resource[1]) + printk(" & %pR", link->resource[1]); if (link->win) printk(", mem 0x%06lx-0x%06lx", req.Base, req.Base + req.Size - 1); diff --git a/drivers/staging/comedi/drivers/ni_daq_dio24.c b/drivers/staging/comedi/drivers/ni_daq_dio24.c index f0c4367dc10b..29e1daf6a9e6 100644 --- a/drivers/staging/comedi/drivers/ni_daq_dio24.c +++ b/drivers/staging/comedi/drivers/ni_daq_dio24.c @@ -128,7 +128,7 @@ static int dio24_attach(struct comedi_device *dev, struct comedi_devconfig *it) link = pcmcia_cur_dev; /* XXX hack */ if (!link) return -EIO; - iobase = link->io.BasePort1; + iobase = link->resource[0]->start; #ifdef incomplete irq = link->irq; #endif @@ -396,12 +396,10 @@ static void dio24_config(struct pcmcia_device *link) dev_info(&link->dev, "index 0x%02x", link->conf.ConfigIndex); if (link->conf.Attributes & CONF_ENABLE_IRQ) printk(", irq %d", link->irq); - if (link->io.NumPorts1) - printk(", io 0x%04x-0x%04x", link->io.BasePort1, - link->io.BasePort1 + link->io.NumPorts1 - 1); - if (link->io.NumPorts2) - printk(" & 0x%04x-0x%04x", link->io.BasePort2, - link->io.BasePort2 + link->io.NumPorts2 - 1); + if (link->resource[0]) + printk(" & %pR", link->resource[0]); + if (link->resource[1]) + printk(" & %pR", link->resource[1]); if (link->win) printk(", mem 0x%06lx-0x%06lx", req.Base, req.Base + req.Size - 1); diff --git a/drivers/staging/comedi/drivers/ni_labpc_cs.c b/drivers/staging/comedi/drivers/ni_labpc_cs.c index 1ee78f806ed2..fb10987a97b2 100644 --- a/drivers/staging/comedi/drivers/ni_labpc_cs.c +++ b/drivers/staging/comedi/drivers/ni_labpc_cs.c @@ -142,7 +142,7 @@ static int labpc_attach(struct comedi_device *dev, struct comedi_devconfig *it) link = pcmcia_cur_dev; /* XXX hack */ if (!link) return -EIO; - iobase = link->io.BasePort1; + iobase = link->resource[0]->start; irq = link->irq; break; default: @@ -373,12 +373,10 @@ static void labpc_config(struct pcmcia_device *link) dev_info(&link->dev, "index 0x%02x", link->conf.ConfigIndex); if (link->conf.Attributes & CONF_ENABLE_IRQ) printk(", irq %d", link->irq); - if (link->io.NumPorts1) - printk(", io 0x%04x-0x%04x", link->io.BasePort1, - link->io.BasePort1 + link->io.NumPorts1 - 1); - if (link->io.NumPorts2) - printk(" & 0x%04x-0x%04x", link->io.BasePort2, - link->io.BasePort2 + link->io.NumPorts2 - 1); + if (link->resource[0]) + printk(" & %pR", link->resource[0]); + if (link->resource[1]) + printk(" & %pR", link->resource[1]); if (link->win) printk(", mem 0x%06lx-0x%06lx", req.Base, req.Base + req.Size - 1); diff --git a/drivers/staging/comedi/drivers/ni_mio_cs.c b/drivers/staging/comedi/drivers/ni_mio_cs.c index 0bce220c47b5..f37dc22b4dbc 100644 --- a/drivers/staging/comedi/drivers/ni_mio_cs.c +++ b/drivers/staging/comedi/drivers/ni_mio_cs.c @@ -355,7 +355,7 @@ static int mio_cs_attach(struct comedi_device *dev, struct comedi_devconfig *it) return -EIO; dev->driver = &driver_ni_mio_cs; - dev->iobase = link->io.BasePort1; + dev->iobase = link->resource[0]->start; irq = link->irq; diff --git a/drivers/staging/comedi/drivers/quatech_daqp_cs.c b/drivers/staging/comedi/drivers/quatech_daqp_cs.c index 67c0fa6a2b06..80b8d57c6842 100644 --- a/drivers/staging/comedi/drivers/quatech_daqp_cs.c +++ b/drivers/staging/comedi/drivers/quatech_daqp_cs.c @@ -871,7 +871,7 @@ static int daqp_attach(struct comedi_device *dev, struct comedi_devconfig *it) } } - dev->iobase = local->link->io.BasePort1; + dev->iobase = local->link->resource[0]->start; ret = alloc_subdevices(dev, 4); if (ret < 0) @@ -1153,12 +1153,10 @@ static void daqp_cs_config(struct pcmcia_device *link) dev_info(&link->dev, "index 0x%02x", link->conf.ConfigIndex); if (link->conf.Attributes & CONF_ENABLE_IRQ) printk(", irq %u", link->irq); - if (link->io.NumPorts1) - printk(", io 0x%04x-0x%04x", link->io.BasePort1, - link->io.BasePort1 + link->io.NumPorts1 - 1); - if (link->io.NumPorts2) - printk(" & 0x%04x-0x%04x", link->io.BasePort2, - link->io.BasePort2 + link->io.NumPorts2 - 1); + if (link->resource[0]) + printk(" & %pR", link->resource[0]); + if (link->resource[1]) + printk(" & %pR", link->resource[1]); printk("\n"); return; diff --git a/drivers/staging/wlags49_h2/wl_cs.c b/drivers/staging/wlags49_h2/wl_cs.c index afe457541172..23615378acf1 100644 --- a/drivers/staging/wlags49_h2/wl_cs.c +++ b/drivers/staging/wlags49_h2/wl_cs.c @@ -319,7 +319,7 @@ void wl_adapter_insert( struct pcmcia_device *link ) goto failed; dev->irq = link->irq; - dev->base_addr = link->io.BasePort1; + dev->base_addr = link->resource[0]->start; SET_NETDEV_DEV(dev, &link->dev); if (register_netdev(dev) != 0) { diff --git a/drivers/telephony/ixj_pcmcia.c b/drivers/telephony/ixj_pcmcia.c index f6c7e6fd7ee1..a801036392cd 100644 --- a/drivers/telephony/ixj_pcmcia.c +++ b/drivers/telephony/ixj_pcmcia.c @@ -150,7 +150,8 @@ static int ixj_config(struct pcmcia_device * link) /* * Register the card with the core. */ - j = ixj_pcmcia_probe(link->io.BasePort1, link->io.BasePort1 + 0x10); + j = ixj_pcmcia_probe(link->resource[0]->start, + link->resource[0]->start + 0x10); info->ndev = 1; ixj_get_serial(link, j); diff --git a/drivers/usb/host/sl811_cs.c b/drivers/usb/host/sl811_cs.c index acb7e255a837..22e04f206304 100644 --- a/drivers/usb/host/sl811_cs.c +++ b/drivers/usb/host/sl811_cs.c @@ -189,7 +189,7 @@ static int sl811_cs_config(struct pcmcia_device *link) goto failed; /* require an IRQ and two registers */ - if (!link->io.NumPorts1 || link->io.NumPorts1 < 2) + if (resource_size(link->resource[0]) < 2) goto failed; if (!link->irq) @@ -204,11 +204,10 @@ static int sl811_cs_config(struct pcmcia_device *link) if (link->conf.Vpp) printk(", Vpp %d.%d", link->conf.Vpp/10, link->conf.Vpp%10); printk(", irq %d", link->irq); - printk(", io 0x%04x-0x%04x", link->io.BasePort1, - link->io.BasePort1+link->io.NumPorts1-1); + printk(", io %pR", link->resource[0]); printk("\n"); - if (sl811_hc_init(parent, link->io.BasePort1, link->irq) + if (sl811_hc_init(parent, link->resource[0]->start, link->irq) < 0) { failed: printk(KERN_WARNING "sl811_cs_config failed\n"); diff --git a/sound/pcmcia/pdaudiocf/pdaudiocf.c b/sound/pcmcia/pdaudiocf/pdaudiocf.c index df110df52a8b..9f897bca0615 100644 --- a/sound/pcmcia/pdaudiocf/pdaudiocf.c +++ b/sound/pcmcia/pdaudiocf/pdaudiocf.c @@ -231,7 +231,8 @@ static int pdacf_config(struct pcmcia_device *link) if (ret) goto failed; - if (snd_pdacf_assign_resources(pdacf, link->io.BasePort1, link->irq) < 0) + if (snd_pdacf_assign_resources(pdacf, link->resource[0]->start, + link->irq) < 0) goto failed; return 0; diff --git a/sound/pcmcia/vx/vxpocket.c b/sound/pcmcia/vx/vxpocket.c index 624b47a85f0a..f23c235013a4 100644 --- a/sound/pcmcia/vx/vxpocket.c +++ b/sound/pcmcia/vx/vxpocket.c @@ -241,7 +241,8 @@ static int vxpocket_config(struct pcmcia_device *link) chip->dev = &link->dev; snd_card_set_dev(chip->card, chip->dev); - if (snd_vxpocket_assign_resources(chip, link->io.BasePort1, link->irq) < 0) + if (snd_vxpocket_assign_resources(chip, link->resource[0]->start, + link->irq) < 0) goto failed; return 0; -- cgit v1.2.3 From 90abdc3b973229bae98dd96649d9f7106cc177a4 Mon Sep 17 00:00:00 2001 From: Dominik Brodowski Date: Sat, 24 Jul 2010 17:23:51 +0200 Subject: pcmcia: do not use io_req_t when calling pcmcia_request_io() Instead of io_req_t, drivers are now requested to fill out struct pcmcia_device *p_dev->resource[0,1] for up to two ioport ranges. After a call to pcmcia_request_io(), the ports found there are reserved, after calling pcmcia_request_configuration(), they may be used. CC: netdev@vger.kernel.org CC: linux-wireless@vger.kernel.org CC: linux-ide@vger.kernel.org CC: linux-usb@vger.kernel.org CC: laforge@gnumonks.org CC: linux-mtd@lists.infradead.org CC: alsa-devel@alsa-project.org CC: linux-serial@vger.kernel.org CC: Michael Buesch Acked-by: Marcel Holtmann (for drivers/bluetooth/) Signed-off-by: Dominik Brodowski --- Documentation/pcmcia/driver-changes.txt | 7 ++++ drivers/ata/pata_pcmcia.c | 29 ++++++++-------- drivers/bluetooth/bluecard_cs.c | 13 ++++--- drivers/bluetooth/bt3c_cs.c | 18 +++++----- drivers/bluetooth/btuart_cs.c | 18 +++++----- drivers/bluetooth/dtl1_cs.c | 21 ++++++------ drivers/char/pcmcia/cm4000_cs.c | 17 ++++------ drivers/char/pcmcia/cm4040_cs.c | 20 ++++------- drivers/char/pcmcia/ipwireless/main.c | 10 +++--- drivers/char/pcmcia/synclink_cs.c | 21 +++++------- drivers/ide/ide-cs.c | 30 +++++++++-------- drivers/isdn/hardware/avm/avm_cs.c | 15 +++------ drivers/isdn/hisax/avma1_cs.c | 20 +++++------ drivers/isdn/hisax/elsa_cs.c | 15 +++++---- drivers/isdn/hisax/sedlbauer_cs.c | 28 +++++++-------- drivers/isdn/hisax/teles_cs.c | 15 +++++---- drivers/net/pcmcia/3c574_cs.c | 11 +++--- drivers/net/pcmcia/3c589_cs.c | 11 +++--- drivers/net/pcmcia/axnet_cs.c | 40 +++++++++++----------- drivers/net/pcmcia/com20020_cs.c | 19 ++++++----- drivers/net/pcmcia/fmvj18x_cs.c | 31 ++++++++--------- drivers/net/pcmcia/ibmtr_cs.c | 14 ++++---- drivers/net/pcmcia/nmclan_cs.c | 8 ++--- drivers/net/pcmcia/pcnet_cs.c | 40 +++++++++++----------- drivers/net/pcmcia/smc91c92_cs.c | 43 ++++++++++++------------ drivers/net/pcmcia/xirc2ps_cs.c | 34 +++++++++---------- drivers/net/wireless/airo_cs.c | 22 ++++++------ drivers/net/wireless/atmel_cs.c | 22 ++++++------ drivers/net/wireless/b43/pcmcia.c | 4 --- drivers/net/wireless/hostap/hostap_cs.c | 28 ++++++--------- drivers/net/wireless/libertas/if_cs.c | 8 ++--- drivers/net/wireless/orinoco/orinoco_cs.c | 24 ++++++------- drivers/net/wireless/orinoco/spectrum_cs.c | 24 ++++++------- drivers/net/wireless/ray_cs.c | 5 ++- drivers/net/wireless/wl3501_cs.c | 12 +++---- drivers/parport/parport_cs.c | 16 ++++----- drivers/pcmcia/pcmcia_resource.c | 37 ++++++-------------- drivers/scsi/pcmcia/aha152x_stub.c | 14 ++++---- drivers/scsi/pcmcia/fdomain_stub.c | 10 +++--- drivers/scsi/pcmcia/nsp_cs.c | 30 ++++++++--------- drivers/scsi/pcmcia/qlogic_stub.c | 14 ++++---- drivers/scsi/pcmcia/sym53c500_cs.c | 14 ++++---- drivers/serial/serial_cs.c | 37 ++++++++++---------- drivers/staging/comedi/drivers/cb_das16_cs.c | 24 ++++++------- drivers/staging/comedi/drivers/das08_cs.c | 23 ++++++------- drivers/staging/comedi/drivers/ni_daq_700.c | 24 ++++++------- drivers/staging/comedi/drivers/ni_daq_dio24.c | 24 ++++++------- drivers/staging/comedi/drivers/ni_labpc_cs.c | 24 ++++++------- drivers/staging/comedi/drivers/ni_mio_cs.c | 13 ++++--- drivers/staging/comedi/drivers/quatech_daqp_cs.c | 24 ++++++------- drivers/staging/wlags49_h2/wl_cs.c | 8 ++--- drivers/telephony/ixj_pcmcia.c | 16 ++++----- drivers/usb/host/sl811_cs.c | 12 +++---- include/pcmcia/cs.h | 17 ---------- include/pcmcia/ds.h | 21 ++++++++++-- sound/pcmcia/pdaudiocf/pdaudiocf.c | 6 ++-- sound/pcmcia/vx/vxpocket.c | 6 ++-- 57 files changed, 527 insertions(+), 584 deletions(-) (limited to 'drivers/ata') diff --git a/Documentation/pcmcia/driver-changes.txt b/Documentation/pcmcia/driver-changes.txt index ff5f0be2470a..26c0f9c00545 100644 --- a/Documentation/pcmcia/driver-changes.txt +++ b/Documentation/pcmcia/driver-changes.txt @@ -1,4 +1,11 @@ This file details changes in 2.6 which affect PCMCIA card driver authors: +* pcmcia_request_io changes (as of 2.6.36) + Instead of io_req_t, drivers are now requested to fill out + struct pcmcia_device *p_dev->resource[0,1] for up to two ioport + ranges. After a call to pcmcia_request_io(), the ports found there + are reserved, after calling pcmcia_request_configuration(), they may + be used. + * No dev_info_t, no cs_types.h (as of 2.6.36) dev_info_t and a few other typedefs are removed. No longer use them in PCMCIA device drivers. Also, do not include pcmcia/cs_types.h, as diff --git a/drivers/ata/pata_pcmcia.c b/drivers/ata/pata_pcmcia.c index 1fcd0659b3f2..e944aa0c5517 100644 --- a/drivers/ata/pata_pcmcia.c +++ b/drivers/ata/pata_pcmcia.c @@ -200,21 +200,23 @@ static int pcmcia_check_one_config(struct pcmcia_device *pdev, if ((cfg->io.nwin > 0) || (dflt->io.nwin > 0)) { cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt->io; - pdev->io.BasePort1 = io->win[0].base; - pdev->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK; - if (!(io->flags & CISTPL_IO_16BIT)) - pdev->io.Attributes1 = IO_DATA_PATH_WIDTH_8; + pdev->io_lines = io->flags & CISTPL_IO_LINES_MASK; + pdev->resource[0]->start = io->win[0].base; + if (!(io->flags & CISTPL_IO_16BIT)) { + pdev->resource[0]->flags &= ~IO_DATA_PATH_WIDTH; + pdev->resource[0]->flags |= IO_DATA_PATH_WIDTH_8; + } if (io->nwin == 2) { - pdev->io.NumPorts1 = 8; - pdev->io.BasePort2 = io->win[1].base; - pdev->io.NumPorts2 = (stk->is_kme) ? 2 : 1; - if (pcmcia_request_io(pdev, &pdev->io) != 0) + pdev->resource[0]->end = 8; + pdev->resource[1]->start = io->win[1].base; + pdev->resource[1]->end = (stk->is_kme) ? 2 : 1; + if (pcmcia_request_io(pdev) != 0) return -ENODEV; stk->ctl_base = pdev->resource[1]->start; } else if ((io->nwin == 1) && (io->win[0].len >= 16)) { - pdev->io.NumPorts1 = io->win[0].len; - pdev->io.NumPorts2 = 0; - if (pcmcia_request_io(pdev, &pdev->io) != 0) + pdev->resource[0]->end = io->win[0].len; + pdev->resource[1]->end = 0; + if (pcmcia_request_io(pdev) != 0) return -ENODEV; stk->ctl_base = pdev->resource[0]->start + 0x0e; } else @@ -245,9 +247,8 @@ static int pcmcia_init_one(struct pcmcia_device *pdev) struct ata_port_operations *ops = &pcmcia_port_ops; /* Set up attributes in order to probe card and get resources */ - pdev->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO; - pdev->io.Attributes2 = IO_DATA_PATH_WIDTH_8; - pdev->io.IOAddrLines = 3; + pdev->resource[0]->flags |= IO_DATA_PATH_WIDTH_AUTO; + pdev->resource[1]->flags |= IO_DATA_PATH_WIDTH_8; pdev->conf.Attributes = CONF_ENABLE_IRQ; pdev->conf.IntType = INT_MEMORY_AND_IO; diff --git a/drivers/bluetooth/bluecard_cs.c b/drivers/bluetooth/bluecard_cs.c index 24d2007139e8..d52e90a5a617 100644 --- a/drivers/bluetooth/bluecard_cs.c +++ b/drivers/bluetooth/bluecard_cs.c @@ -865,9 +865,6 @@ static int bluecard_probe(struct pcmcia_device *link) info->p_dev = link; link->priv = info; - link->io.Attributes1 = IO_DATA_PATH_WIDTH_8; - link->io.NumPorts1 = 8; - link->conf.Attributes = CONF_ENABLE_IRQ; link->conf.IntType = INT_MEMORY_AND_IO; @@ -890,12 +887,14 @@ static int bluecard_config(struct pcmcia_device *link) int i, n; link->conf.ConfigIndex = 0x20; - link->io.NumPorts1 = 64; - link->io.IOAddrLines = 6; + + link->resource[0]->flags |= IO_DATA_PATH_WIDTH_8; + link->resource[0]->end = 64; + link->io_lines = 6; for (n = 0; n < 0x400; n += 0x40) { - link->io.BasePort1 = n ^ 0x300; - i = pcmcia_request_io(link, &link->io); + link->resource[0]->start = n ^ 0x300; + i = pcmcia_request_io(link); if (i == 0) break; } diff --git a/drivers/bluetooth/bt3c_cs.c b/drivers/bluetooth/bt3c_cs.c index 8ab494c0c17f..7ab8f29d5e0d 100644 --- a/drivers/bluetooth/bt3c_cs.c +++ b/drivers/bluetooth/bt3c_cs.c @@ -657,8 +657,8 @@ static int bt3c_probe(struct pcmcia_device *link) info->p_dev = link; link->priv = info; - link->io.Attributes1 = IO_DATA_PATH_WIDTH_8; - link->io.NumPorts1 = 8; + link->resource[0]->flags |= IO_DATA_PATH_WIDTH_8; + link->resource[0]->end = 8; link->conf.Attributes = CONF_ENABLE_IRQ; link->conf.IntType = INT_MEMORY_AND_IO; @@ -683,14 +683,14 @@ static int bt3c_check_config(struct pcmcia_device *p_dev, { unsigned long try = (unsigned long) priv_data; + p_dev->io_lines = (try == 0) ? 16 : cf->io.flags & CISTPL_IO_LINES_MASK; + if (cf->vpp1.present & (1 << CISTPL_POWER_VNOM)) p_dev->conf.Vpp = cf->vpp1.param[CISTPL_POWER_VNOM] / 10000; if ((cf->io.nwin > 0) && (cf->io.win[0].len == 8) && (cf->io.win[0].base != 0)) { - p_dev->io.BasePort1 = cf->io.win[0].base; - p_dev->io.IOAddrLines = (try == 0) ? 16 : - cf->io.flags & CISTPL_IO_LINES_MASK; - if (!pcmcia_request_io(p_dev, &p_dev->io)) + p_dev->resource[0]->start = cf->io.win[0].base; + if (!pcmcia_request_io(p_dev)) return 0; } return -ENODEV; @@ -707,9 +707,9 @@ static int bt3c_check_config_notpicky(struct pcmcia_device *p_dev, if ((cf->io.nwin > 0) && ((cf->io.flags & CISTPL_IO_LINES_MASK) <= 3)) { for (j = 0; j < 5; j++) { - p_dev->io.BasePort1 = base[j]; - p_dev->io.IOAddrLines = base[j] ? 16 : 3; - if (!pcmcia_request_io(p_dev, &p_dev->io)) + p_dev->resource[0]->start = base[j]; + p_dev->io_lines = base[j] ? 16 : 3; + if (!pcmcia_request_io(p_dev)) return 0; } } diff --git a/drivers/bluetooth/btuart_cs.c b/drivers/bluetooth/btuart_cs.c index 7e770d40368d..1c4f5e863b03 100644 --- a/drivers/bluetooth/btuart_cs.c +++ b/drivers/bluetooth/btuart_cs.c @@ -586,8 +586,8 @@ static int btuart_probe(struct pcmcia_device *link) info->p_dev = link; link->priv = info; - link->io.Attributes1 = IO_DATA_PATH_WIDTH_8; - link->io.NumPorts1 = 8; + link->resource[0]->flags |= IO_DATA_PATH_WIDTH_8; + link->resource[0]->end = 8; link->conf.Attributes = CONF_ENABLE_IRQ; link->conf.IntType = INT_MEMORY_AND_IO; @@ -612,14 +612,14 @@ static int btuart_check_config(struct pcmcia_device *p_dev, { int *try = priv_data; + p_dev->io_lines = (try == 0) ? 16 : cf->io.flags & CISTPL_IO_LINES_MASK; + if (cf->vpp1.present & (1 << CISTPL_POWER_VNOM)) p_dev->conf.Vpp = cf->vpp1.param[CISTPL_POWER_VNOM] / 10000; if ((cf->io.nwin > 0) && (cf->io.win[0].len == 8) && (cf->io.win[0].base != 0)) { - p_dev->io.BasePort1 = cf->io.win[0].base; - p_dev->io.IOAddrLines = (*try == 0) ? 16 : - cf->io.flags & CISTPL_IO_LINES_MASK; - if (!pcmcia_request_io(p_dev, &p_dev->io)) + p_dev->resource[0]->start = cf->io.win[0].base; + if (!pcmcia_request_io(p_dev)) return 0; } return -ENODEV; @@ -636,9 +636,9 @@ static int btuart_check_config_notpicky(struct pcmcia_device *p_dev, if ((cf->io.nwin > 0) && ((cf->io.flags & CISTPL_IO_LINES_MASK) <= 3)) { for (j = 0; j < 5; j++) { - p_dev->io.BasePort1 = base[j]; - p_dev->io.IOAddrLines = base[j] ? 16 : 3; - if (!pcmcia_request_io(p_dev, &p_dev->io)) + p_dev->resource[0]->start = base[j]; + p_dev->io_lines = base[j] ? 16 : 3; + if (!pcmcia_request_io(p_dev)) return 0; } } diff --git a/drivers/bluetooth/dtl1_cs.c b/drivers/bluetooth/dtl1_cs.c index bfe9313516fb..18ecc5734e9f 100644 --- a/drivers/bluetooth/dtl1_cs.c +++ b/drivers/bluetooth/dtl1_cs.c @@ -572,8 +572,8 @@ static int dtl1_probe(struct pcmcia_device *link) info->p_dev = link; link->priv = info; - link->io.Attributes1 = IO_DATA_PATH_WIDTH_8; - link->io.NumPorts1 = 8; + link->resource[0]->flags |= IO_DATA_PATH_WIDTH_8; + link->resource[0]->end = 8; link->conf.Attributes = CONF_ENABLE_IRQ; link->conf.IntType = INT_MEMORY_AND_IO; @@ -597,14 +597,13 @@ static int dtl1_confcheck(struct pcmcia_device *p_dev, unsigned int vcc, void *priv_data) { - if ((cf->io.nwin == 1) && (cf->io.win[0].len > 8)) { - p_dev->io.BasePort1 = cf->io.win[0].base; - p_dev->io.NumPorts1 = cf->io.win[0].len; /*yo */ - p_dev->io.IOAddrLines = cf->io.flags & CISTPL_IO_LINES_MASK; - if (!pcmcia_request_io(p_dev, &p_dev->io)) - return 0; - } - return -ENODEV; + if ((cf->io.nwin != 1) || (cf->io.win[0].len <= 8)) + return -ENODEV; + + p_dev->resource[0]->start = cf->io.win[0].base; + p_dev->resource[0]->end = cf->io.win[0].len; /*yo */ + p_dev->io_lines = cf->io.flags & CISTPL_IO_LINES_MASK; + return pcmcia_request_io(p_dev); } static int dtl1_config(struct pcmcia_device *link) @@ -613,7 +612,7 @@ static int dtl1_config(struct pcmcia_device *link) int i; /* Look for a generic full-sized window */ - link->io.NumPorts1 = 8; + link->resource[0]->end = 8; if (pcmcia_loop_config(link, dtl1_confcheck, NULL) < 0) goto failed; diff --git a/drivers/char/pcmcia/cm4000_cs.c b/drivers/char/pcmcia/cm4000_cs.c index 18484edc1259..ec73d9f6d9ed 100644 --- a/drivers/char/pcmcia/cm4000_cs.c +++ b/drivers/char/pcmcia/cm4000_cs.c @@ -1751,17 +1751,12 @@ static int cm4000_config_check(struct pcmcia_device *p_dev, if (!cfg->io.nwin) return -ENODEV; - /* Get the IOaddr */ - p_dev->io.BasePort1 = cfg->io.win[0].base; - p_dev->io.NumPorts1 = cfg->io.win[0].len; - p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO; - if (!(cfg->io.flags & CISTPL_IO_8BIT)) - p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_16; - if (!(cfg->io.flags & CISTPL_IO_16BIT)) - p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_8; - p_dev->io.IOAddrLines = cfg->io.flags & CISTPL_IO_LINES_MASK; - - return pcmcia_request_io(p_dev, &p_dev->io); + p_dev->resource[0]->start = cfg->io.win[0].base; + p_dev->resource[0]->end = cfg->io.win[0].len; + p_dev->resource[0]->flags |= pcmcia_io_cfg_data_width(cfg->io.flags); + p_dev->io_lines = cfg->io.flags & CISTPL_IO_LINES_MASK; + + return pcmcia_request_io(p_dev); } static int cm4000_config(struct pcmcia_device * link, int devno) diff --git a/drivers/char/pcmcia/cm4040_cs.c b/drivers/char/pcmcia/cm4040_cs.c index a6bbf199dde9..815cde1d0570 100644 --- a/drivers/char/pcmcia/cm4040_cs.c +++ b/drivers/char/pcmcia/cm4040_cs.c @@ -527,16 +527,12 @@ static int cm4040_config_check(struct pcmcia_device *p_dev, return -ENODEV; /* Get the IOaddr */ - p_dev->io.BasePort1 = cfg->io.win[0].base; - p_dev->io.NumPorts1 = cfg->io.win[0].len; - p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO; - if (!(cfg->io.flags & CISTPL_IO_8BIT)) - p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_16; - if (!(cfg->io.flags & CISTPL_IO_16BIT)) - p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_8; - p_dev->io.IOAddrLines = cfg->io.flags & CISTPL_IO_LINES_MASK; - - rc = pcmcia_request_io(p_dev, &p_dev->io); + p_dev->resource[0]->start = cfg->io.win[0].base; + p_dev->resource[0]->end = cfg->io.win[0].len; + p_dev->resource[0]->flags |= pcmcia_io_cfg_data_width(cfg->io.flags); + p_dev->io_lines = cfg->io.flags & CISTPL_IO_LINES_MASK; + rc = pcmcia_request_io(p_dev); + dev_printk(KERN_INFO, &p_dev->dev, "pcmcia_request_io returned 0x%x\n", rc); return rc; @@ -548,10 +544,6 @@ static int reader_config(struct pcmcia_device *link, int devno) struct reader_dev *dev; int fail_rc; - link->io.BasePort2 = 0; - link->io.NumPorts2 = 0; - link->io.Attributes2 = 0; - if (pcmcia_loop_config(link, cm4040_config_check, NULL)) goto cs_release; diff --git a/drivers/char/pcmcia/ipwireless/main.c b/drivers/char/pcmcia/ipwireless/main.c index 9467994d556f..5f87b9f7b6d2 100644 --- a/drivers/char/pcmcia/ipwireless/main.c +++ b/drivers/char/pcmcia/ipwireless/main.c @@ -88,15 +88,15 @@ static int ipwireless_probe(struct pcmcia_device *p_dev, memreq_t memreq_common_memory; int ret; - p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO; - p_dev->io.BasePort1 = cfg->io.win[0].base; - p_dev->io.NumPorts1 = cfg->io.win[0].len; - p_dev->io.IOAddrLines = 16; + p_dev->resource[0]->flags |= IO_DATA_PATH_WIDTH_AUTO; + p_dev->resource[0]->start = cfg->io.win[0].base; + p_dev->resource[0]->end = cfg->io.win[0].len; /* 0x40 causes it to generate level mode interrupts. */ /* 0x04 enables IREQ pin. */ p_dev->conf.ConfigIndex = cfg->index | 0x44; - ret = pcmcia_request_io(p_dev, &p_dev->io); + p_dev->io_lines = 16; + ret = pcmcia_request_io(p_dev); if (ret) return ret; diff --git a/drivers/char/pcmcia/synclink_cs.c b/drivers/char/pcmcia/synclink_cs.c index 8ded9b02b9b9..9ecd6bef5d3b 100644 --- a/drivers/char/pcmcia/synclink_cs.c +++ b/drivers/char/pcmcia/synclink_cs.c @@ -571,18 +571,15 @@ static int mgslpc_ioprobe(struct pcmcia_device *p_dev, unsigned int vcc, void *priv_data) { - if (cfg->io.nwin > 0) { - p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO; - if (!(cfg->io.flags & CISTPL_IO_8BIT)) - p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_16; - if (!(cfg->io.flags & CISTPL_IO_16BIT)) - p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_8; - p_dev->io.IOAddrLines = cfg->io.flags & CISTPL_IO_LINES_MASK; - p_dev->io.BasePort1 = cfg->io.win[0].base; - p_dev->io.NumPorts1 = cfg->io.win[0].len; - return pcmcia_request_io(p_dev, &p_dev->io); - } - return -ENODEV; + if (!cfg->io.nwin) + return -ENODEV; + + p_dev->resource[0]->start = cfg->io.win[0].base; + p_dev->resource[0]->end = cfg->io.win[0].len; + p_dev->resource[0]->flags |= pcmcia_io_cfg_data_width(cfg->io.flags); + p_dev->io_lines = cfg->io.flags & CISTPL_IO_LINES_MASK; + + return pcmcia_request_io(p_dev); } static int mgslpc_config(struct pcmcia_device *link) diff --git a/drivers/ide/ide-cs.c b/drivers/ide/ide-cs.c index 6be0e5f108b5..2a4cb9c18f01 100644 --- a/drivers/ide/ide-cs.c +++ b/drivers/ide/ide-cs.c @@ -97,9 +97,8 @@ static int ide_probe(struct pcmcia_device *link) info->p_dev = link; link->priv = info; - link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO; - link->io.Attributes2 = IO_DATA_PATH_WIDTH_8; - link->io.IOAddrLines = 3; + link->resource[0]->flags |= IO_DATA_PATH_WIDTH_AUTO; + link->resource[1]->flags |= IO_DATA_PATH_WIDTH_8; link->conf.Attributes = CONF_ENABLE_IRQ; link->conf.IntType = INT_MEMORY_AND_IO; @@ -228,22 +227,25 @@ static int pcmcia_check_one_config(struct pcmcia_device *pdev, if ((cfg->io.nwin > 0) || (dflt->io.nwin > 0)) { cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt->io; + pdev->io_lines = io->flags & CISTPL_IO_LINES_MASK; + pdev->conf.ConfigIndex = cfg->index; - pdev->io.BasePort1 = io->win[0].base; - pdev->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK; - if (!(io->flags & CISTPL_IO_16BIT)) - pdev->io.Attributes1 = IO_DATA_PATH_WIDTH_8; + pdev->resource[0]->start = io->win[0].base; + if (!(io->flags & CISTPL_IO_16BIT)) { + pdev->resource[0]->flags &= ~IO_DATA_PATH_WIDTH; + pdev->resource[0]->flags |= IO_DATA_PATH_WIDTH_8; + } if (io->nwin == 2) { - pdev->io.NumPorts1 = 8; - pdev->io.BasePort2 = io->win[1].base; - pdev->io.NumPorts2 = (stk->is_kme) ? 2 : 1; - if (pcmcia_request_io(pdev, &pdev->io) != 0) + pdev->resource[0]->end = 8; + pdev->resource[1]->start = io->win[1].base; + pdev->resource[1]->end = (stk->is_kme) ? 2 : 1; + if (pcmcia_request_io(pdev) != 0) return -ENODEV; stk->ctl_base = pdev->resource[1]->start; } else if ((io->nwin == 1) && (io->win[0].len >= 16)) { - pdev->io.NumPorts1 = io->win[0].len; - pdev->io.NumPorts2 = 0; - if (pcmcia_request_io(pdev, &pdev->io) != 0) + pdev->resource[0]->end = io->win[0].len; + pdev->resource[1]->end = 0; + if (pcmcia_request_io(pdev) != 0) return -ENODEV; stk->ctl_base = pdev->resource[0]->start + 0x0e; } else diff --git a/drivers/isdn/hardware/avm/avm_cs.c b/drivers/isdn/hardware/avm/avm_cs.c index 7c8c51f22003..09b1795516f4 100644 --- a/drivers/isdn/hardware/avm/avm_cs.c +++ b/drivers/isdn/hardware/avm/avm_cs.c @@ -75,9 +75,8 @@ static int avmcs_probe(struct pcmcia_device *p_dev) { /* The io structure describes IO port mapping */ - p_dev->io.NumPorts1 = 16; - p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_8; - p_dev->io.NumPorts2 = 0; + p_dev->resource[0]->end = 16; + p_dev->resource[0]->flags |= IO_DATA_PATH_WIDTH_8; /* General socket configuration */ p_dev->conf.Attributes = CONF_ENABLE_IRQ; @@ -119,13 +118,9 @@ static int avmcs_configcheck(struct pcmcia_device *p_dev, if (cf->io.nwin <= 0) return -ENODEV; - p_dev->io.BasePort1 = cf->io.win[0].base; - p_dev->io.NumPorts1 = cf->io.win[0].len; - p_dev->io.NumPorts2 = 0; - printk(KERN_INFO "avm_cs: testing i/o %#x-%#x\n", - p_dev->io.BasePort1, - p_dev->io.BasePort1+p_dev->io.NumPorts1-1); - return pcmcia_request_io(p_dev, &p_dev->io); + p_dev->resource[0]->start = cf->io.win[0].base; + p_dev->resource[0]->end = cf->io.win[0].len; + return pcmcia_request_io(p_dev); } static int avmcs_config(struct pcmcia_device *link) diff --git a/drivers/isdn/hisax/avma1_cs.c b/drivers/isdn/hisax/avma1_cs.c index 88899638f835..94263c22b874 100644 --- a/drivers/isdn/hisax/avma1_cs.c +++ b/drivers/isdn/hisax/avma1_cs.c @@ -78,11 +78,10 @@ static int __devinit avma1cs_probe(struct pcmcia_device *p_dev) dev_dbg(&p_dev->dev, "avma1cs_attach()\n"); /* The io structure describes IO port mapping */ - p_dev->io.NumPorts1 = 16; - p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_8; - p_dev->io.NumPorts2 = 16; - p_dev->io.Attributes2 = IO_DATA_PATH_WIDTH_16; - p_dev->io.IOAddrLines = 5; + p_dev->resource[0]->end = 16; + p_dev->resource[0]->flags |= IO_DATA_PATH_WIDTH_8; + p_dev->resource[1]->end = 16; + p_dev->resource[1]->flags |= IO_DATA_PATH_WIDTH_16; /* General socket configuration */ p_dev->conf.Attributes = CONF_ENABLE_IRQ; @@ -126,13 +125,10 @@ static int avma1cs_configcheck(struct pcmcia_device *p_dev, if (cf->io.nwin <= 0) return -ENODEV; - p_dev->io.BasePort1 = cf->io.win[0].base; - p_dev->io.NumPorts1 = cf->io.win[0].len; - p_dev->io.NumPorts2 = 0; - printk(KERN_INFO "avma1_cs: testing i/o %#x-%#x\n", - p_dev->io.BasePort1, - p_dev->io.BasePort1+p_dev->io.NumPorts1-1); - return pcmcia_request_io(p_dev, &p_dev->io); + p_dev->resource[0]->start = cf->io.win[0].base; + p_dev->resource[0]->end = cf->io.win[0].len; + p_dev->io_lines = 5; + return pcmcia_request_io(p_dev); } diff --git a/drivers/isdn/hisax/elsa_cs.c b/drivers/isdn/hisax/elsa_cs.c index c10bfd3f4588..b3c08aaf41c4 100644 --- a/drivers/isdn/hisax/elsa_cs.c +++ b/drivers/isdn/hisax/elsa_cs.c @@ -126,9 +126,8 @@ static int __devinit elsa_cs_probe(struct pcmcia_device *link) and attributes of IO windows) are fixed by the nature of the device, and can be hard-wired here. */ - link->io.NumPorts1 = 8; - link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO; - link->io.IOAddrLines = 3; + link->resource[0]->end = 8; + link->resource[0]->flags |= IO_DATA_PATH_WIDTH_AUTO; link->conf.Attributes = CONF_ENABLE_IRQ; link->conf.IntType = INT_MEMORY_AND_IO; @@ -173,16 +172,18 @@ static int elsa_cs_configcheck(struct pcmcia_device *p_dev, { int j; + p_dev->io_lines = 3; + if ((cf->io.nwin > 0) && cf->io.win[0].base) { printk(KERN_INFO "(elsa_cs: looks like the 96 model)\n"); - p_dev->io.BasePort1 = cf->io.win[0].base; - if (!pcmcia_request_io(p_dev, &p_dev->io)) + p_dev->resource[0]->start = cf->io.win[0].base; + if (!pcmcia_request_io(p_dev)) return 0; } else { printk(KERN_INFO "(elsa_cs: looks like the 97 model)\n"); for (j = 0x2f0; j > 0x100; j -= 0x10) { - p_dev->io.BasePort1 = j; - if (!pcmcia_request_io(p_dev, &p_dev->io)) + p_dev->resource[0]->start = j; + if (!pcmcia_request_io(p_dev)) return 0; } } diff --git a/drivers/isdn/hisax/sedlbauer_cs.c b/drivers/isdn/hisax/sedlbauer_cs.c index cecb35ab9d3d..4755eb440f7e 100644 --- a/drivers/isdn/hisax/sedlbauer_cs.c +++ b/drivers/isdn/hisax/sedlbauer_cs.c @@ -129,9 +129,8 @@ static int __devinit sedlbauer_probe(struct pcmcia_device *link) /* from old sedl_cs */ /* The io structure describes IO port mapping */ - link->io.NumPorts1 = 8; - link->io.Attributes1 = IO_DATA_PATH_WIDTH_8; - link->io.IOAddrLines = 3; + link->resource[0]->end = 8; + link->resource[0]->flags |= IO_DATA_PATH_WIDTH_8; link->conf.Attributes = 0; link->conf.IntType = INT_MEMORY_AND_IO; @@ -201,23 +200,22 @@ static int sedlbauer_config_check(struct pcmcia_device *p_dev, p_dev->conf.Attributes |= CONF_ENABLE_IRQ; /* IO window settings */ - p_dev->io.NumPorts1 = p_dev->io.NumPorts2 = 0; + p_dev->resource[0]->end = p_dev->resource[1]->end = 0; if ((cfg->io.nwin > 0) || (dflt->io.nwin > 0)) { cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt->io; - p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO; - if (!(io->flags & CISTPL_IO_8BIT)) - p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_16; - if (!(io->flags & CISTPL_IO_16BIT)) - p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_8; - p_dev->io.BasePort1 = io->win[0].base; - p_dev->io.NumPorts1 = io->win[0].len; + p_dev->resource[0]->start = io->win[0].base; + p_dev->resource[0]->end = io->win[0].len; + p_dev->resource[0]->flags &= ~IO_DATA_PATH_WIDTH; + p_dev->resource[0]->flags |= + pcmcia_io_cfg_data_width(io->flags); if (io->nwin > 1) { - p_dev->io.Attributes2 = p_dev->io.Attributes1; - p_dev->io.BasePort2 = io->win[1].base; - p_dev->io.NumPorts2 = io->win[1].len; + p_dev->resource[1]->flags = p_dev->resource[0]->flags; + p_dev->resource[1]->start = io->win[1].base; + p_dev->resource[1]->end = io->win[1].len; } /* This reserves IO space but doesn't actually enable it */ - if (pcmcia_request_io(p_dev, &p_dev->io) != 0) + p_dev->io_lines = 3; + if (pcmcia_request_io(p_dev) != 0) return -ENODEV; } diff --git a/drivers/isdn/hisax/teles_cs.c b/drivers/isdn/hisax/teles_cs.c index 3787fc70cf8f..7296102ca255 100644 --- a/drivers/isdn/hisax/teles_cs.c +++ b/drivers/isdn/hisax/teles_cs.c @@ -106,9 +106,8 @@ static int __devinit teles_probe(struct pcmcia_device *link) and attributes of IO windows) are fixed by the nature of the device, and can be hard-wired here. */ - link->io.NumPorts1 = 96; - link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO; - link->io.IOAddrLines = 5; + link->resource[0]->end = 96; + link->resource[0]->flags |= IO_DATA_PATH_WIDTH_AUTO; link->conf.Attributes = CONF_ENABLE_IRQ; link->conf.IntType = INT_MEMORY_AND_IO; @@ -153,16 +152,18 @@ static int teles_cs_configcheck(struct pcmcia_device *p_dev, { int j; + p_dev->io_lines = 5; + if ((cf->io.nwin > 0) && cf->io.win[0].base) { printk(KERN_INFO "(teles_cs: looks like the 96 model)\n"); - p_dev->io.BasePort1 = cf->io.win[0].base; - if (!pcmcia_request_io(p_dev, &p_dev->io)) + p_dev->resource[0]->start = cf->io.win[0].base; + if (!pcmcia_request_io(p_dev)) return 0; } else { printk(KERN_INFO "(teles_cs: looks like the 97 model)\n"); for (j = 0x2f0; j > 0x100; j -= 0x10) { - p_dev->io.BasePort1 = j; - if (!pcmcia_request_io(p_dev, &p_dev->io)) + p_dev->resource[0]->start = j; + if (!pcmcia_request_io(p_dev)) return 0; } } diff --git a/drivers/net/pcmcia/3c574_cs.c b/drivers/net/pcmcia/3c574_cs.c index b5ea9b8cfd76..c683f77c6f42 100644 --- a/drivers/net/pcmcia/3c574_cs.c +++ b/drivers/net/pcmcia/3c574_cs.c @@ -278,8 +278,8 @@ static int tc574_probe(struct pcmcia_device *link) lp->p_dev = link; spin_lock_init(&lp->window_lock); - link->io.NumPorts1 = 32; - link->io.Attributes1 = IO_DATA_PATH_WIDTH_16; + link->resource[0]->end = 32; + link->resource[0]->flags |= IO_DATA_PATH_WIDTH_16; link->conf.Attributes = CONF_ENABLE_IRQ; link->conf.IntType = INT_MEMORY_AND_IO; link->conf.ConfigIndex = 1; @@ -337,10 +337,11 @@ static int tc574_config(struct pcmcia_device *link) dev_dbg(&link->dev, "3c574_config()\n"); - link->io.IOAddrLines = 16; + link->io_lines = 16; + for (i = j = 0; j < 0x400; j += 0x20) { - link->io.BasePort1 = j ^ 0x300; - i = pcmcia_request_io(link, &link->io); + link->resource[0]->start = j ^ 0x300; + i = pcmcia_request_io(link); if (i == 0) break; } diff --git a/drivers/net/pcmcia/3c589_cs.c b/drivers/net/pcmcia/3c589_cs.c index 122ef4a9488c..61f9cf2100ff 100644 --- a/drivers/net/pcmcia/3c589_cs.c +++ b/drivers/net/pcmcia/3c589_cs.c @@ -213,8 +213,8 @@ static int tc589_probe(struct pcmcia_device *link) lp->p_dev = link; spin_lock_init(&lp->lock); - link->io.NumPorts1 = 16; - link->io.Attributes1 = IO_DATA_PATH_WIDTH_16; + link->resource[0]->end = 16; + link->resource[0]->flags |= IO_DATA_PATH_WIDTH_16; link->conf.Attributes = CONF_ENABLE_IRQ; link->conf.IntType = INT_MEMORY_AND_IO; @@ -277,12 +277,13 @@ static int tc589_config(struct pcmcia_device *link) "3Com card??\n"); multi = (link->card_id == PRODID_3COM_3C562); + link->io_lines = 16; + /* For the 3c562, the base address must be xx00-xx7f */ - link->io.IOAddrLines = 16; for (i = j = 0; j < 0x400; j += 0x10) { if (multi && (j & 0x80)) continue; - link->io.BasePort1 = j ^ 0x300; - i = pcmcia_request_io(link, &link->io); + link->resource[0]->start = j ^ 0x300; + i = pcmcia_request_io(link); if (i == 0) break; } diff --git a/drivers/net/pcmcia/axnet_cs.c b/drivers/net/pcmcia/axnet_cs.c index c52fdf31cbfe..5f05ffb240cc 100644 --- a/drivers/net/pcmcia/axnet_cs.c +++ b/drivers/net/pcmcia/axnet_cs.c @@ -259,28 +259,30 @@ static int get_prom(struct pcmcia_device *link) static int try_io_port(struct pcmcia_device *link) { int j, ret; - if (link->io.NumPorts1 == 32) { - link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO; + link->resource[0]->flags &= ~IO_DATA_PATH_WIDTH; + link->resource[1]->flags &= ~IO_DATA_PATH_WIDTH; + if (link->resource[0]->end == 32) { + link->resource[0]->flags |= IO_DATA_PATH_WIDTH_AUTO; /* for master/slave multifunction cards */ - if (link->io.NumPorts2 > 0) - link->io.Attributes2 = IO_DATA_PATH_WIDTH_8; + if (link->resource[1]->end > 0) + link->resource[1]->flags |= IO_DATA_PATH_WIDTH_8; } else { /* This should be two 16-port windows */ - link->io.Attributes1 = IO_DATA_PATH_WIDTH_8; - link->io.Attributes2 = IO_DATA_PATH_WIDTH_16; + link->resource[0]->flags |= IO_DATA_PATH_WIDTH_8; + link->resource[1]->flags |= IO_DATA_PATH_WIDTH_16; } - if (link->io.BasePort1 == 0) { - link->io.IOAddrLines = 16; + if (link->resource[0]->start == 0) { for (j = 0; j < 0x400; j += 0x20) { - link->io.BasePort1 = j ^ 0x300; - link->io.BasePort2 = (j ^ 0x300) + 0x10; - ret = pcmcia_request_io(link, &link->io); + link->resource[0]->start = j ^ 0x300; + link->resource[1]->start = (j ^ 0x300) + 0x10; + link->io_lines = 16; + ret = pcmcia_request_io(link); if (ret == 0) return ret; } return ret; } else { - return pcmcia_request_io(link, &link->io); + return pcmcia_request_io(link); } } @@ -301,15 +303,15 @@ static int axnet_configcheck(struct pcmcia_device *p_dev, network function with window 0, and serial with window 1 */ if (io->nwin > 1) { i = (io->win[1].len > io->win[0].len); - p_dev->io.BasePort2 = io->win[1-i].base; - p_dev->io.NumPorts2 = io->win[1-i].len; + p_dev->resource[1]->start = io->win[1-i].base; + p_dev->resource[1]->end = io->win[1-i].len; } else { - i = p_dev->io.NumPorts2 = 0; + i = p_dev->resource[1]->end = 0; } - p_dev->io.BasePort1 = io->win[i].base; - p_dev->io.NumPorts1 = io->win[i].len; - p_dev->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK; - if (p_dev->io.NumPorts1 + p_dev->io.NumPorts2 >= 32) + p_dev->resource[0]->start = io->win[i].base; + p_dev->resource[0]->end = io->win[i].len; + p_dev->io_lines = io->flags & CISTPL_IO_LINES_MASK; + if (p_dev->resource[0]->end + p_dev->resource[1]->end >= 32) return try_io_port(p_dev); return -ENODEV; diff --git a/drivers/net/pcmcia/com20020_cs.c b/drivers/net/pcmcia/com20020_cs.c index 3b53818e3eef..3c400cfa82ae 100644 --- a/drivers/net/pcmcia/com20020_cs.c +++ b/drivers/net/pcmcia/com20020_cs.c @@ -158,9 +158,8 @@ static int com20020_probe(struct pcmcia_device *p_dev) /* fill in our module parameters as defaults */ dev->dev_addr[0] = node; - p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_8; - p_dev->io.NumPorts1 = 16; - p_dev->io.IOAddrLines = 16; + p_dev->resource[0]->flags |= IO_DATA_PATH_WIDTH_8; + p_dev->resource[0]->end = 16; p_dev->conf.Attributes = CONF_ENABLE_IRQ; p_dev->conf.IntType = INT_MEMORY_AND_IO; @@ -245,20 +244,24 @@ static int com20020_config(struct pcmcia_device *link) dev_dbg(&link->dev, "com20020_config\n"); - dev_dbg(&link->dev, "baseport1 is %Xh\n", link->io.BasePort1); + dev_dbg(&link->dev, "baseport1 is %Xh\n", + (unsigned int) link->resource[0]->start); + i = -ENODEV; - if (!link->io.BasePort1) + link->io_lines = 16; + + if (!link->resource[0]->start) { for (ioaddr = 0x100; ioaddr < 0x400; ioaddr += 0x10) { - link->io.BasePort1 = ioaddr; - i = pcmcia_request_io(link, &link->io); + link->resource[0]->start = ioaddr; + i = pcmcia_request_io(link); if (i == 0) break; } } else - i = pcmcia_request_io(link, &link->io); + i = pcmcia_request_io(link); if (i != 0) { diff --git a/drivers/net/pcmcia/fmvj18x_cs.c b/drivers/net/pcmcia/fmvj18x_cs.c index bba6369a028e..699304480aed 100644 --- a/drivers/net/pcmcia/fmvj18x_cs.c +++ b/drivers/net/pcmcia/fmvj18x_cs.c @@ -248,9 +248,8 @@ static int fmvj18x_probe(struct pcmcia_device *link) lp->base = NULL; /* The io structure describes IO port mapping */ - link->io.NumPorts1 = 32; - link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO; - link->io.IOAddrLines = 5; + link->resource[0]->end = 32; + link->resource[0]->flags |= IO_DATA_PATH_WIDTH_AUTO; /* General socket configuration */ link->conf.Attributes = CONF_ENABLE_IRQ; @@ -288,13 +287,13 @@ static int mfc_try_io_port(struct pcmcia_device *link) { 0x3f8, 0x2f8, 0x3e8, 0x2e8, 0x0 }; for (i = 0; i < 5; i++) { - link->io.BasePort2 = serial_base[i]; - link->io.Attributes2 = IO_DATA_PATH_WIDTH_8; - if (link->io.BasePort2 == 0) { - link->io.NumPorts2 = 0; + link->resource[1]->start = serial_base[i]; + link->resource[1]->flags |= IO_DATA_PATH_WIDTH_8; + if (link->resource[1]->start == 0) { + link->resource[1]->end = 0; printk(KERN_NOTICE "fmvj18x_cs: out of resource for serial\n"); } - ret = pcmcia_request_io(link, &link->io); + ret = pcmcia_request_io(link); if (ret == 0) return ret; } @@ -310,8 +309,8 @@ static int ungermann_try_io_port(struct pcmcia_device *link) 0x380,0x3c0 only for ioport. */ for (ioaddr = 0x300; ioaddr < 0x3e0; ioaddr += 0x20) { - link->io.BasePort1 = ioaddr; - ret = pcmcia_request_io(link, &link->io); + link->resource[0]->start = ioaddr; + ret = pcmcia_request_io(link); if (ret == 0) { /* calculate ConfigIndex value */ link->conf.ConfigIndex = @@ -345,6 +344,8 @@ static int fmvj18x_config(struct pcmcia_device *link) dev_dbg(&link->dev, "fmvj18x_config\n"); + link->io_lines = 5; + len = pcmcia_get_tuple(link, CISTPL_FUNCE, &buf); kfree(buf); @@ -363,20 +364,20 @@ static int fmvj18x_config(struct pcmcia_device *link) /* MultiFunction Card */ link->conf.ConfigBase = 0x800; link->conf.ConfigIndex = 0x47; - link->io.NumPorts2 = 8; + link->resource[1]->end = 8; } break; case MANFID_NEC: cardtype = NEC; /* MultiFunction Card */ link->conf.ConfigBase = 0x800; link->conf.ConfigIndex = 0x47; - link->io.NumPorts2 = 8; + link->resource[1]->end = 8; break; case MANFID_KME: cardtype = KME; /* MultiFunction Card */ link->conf.ConfigBase = 0x800; link->conf.ConfigIndex = 0x47; - link->io.NumPorts2 = 8; + link->resource[1]->end = 8; break; case MANFID_CONTEC: cardtype = CONTEC; @@ -417,14 +418,14 @@ static int fmvj18x_config(struct pcmcia_device *link) } } - if (link->io.NumPorts2 != 0) { + if (link->resource[1]->end != 0) { ret = mfc_try_io_port(link); if (ret != 0) goto failed; } else if (cardtype == UNGERMANN) { ret = ungermann_try_io_port(link); if (ret != 0) goto failed; } else { - ret = pcmcia_request_io(link, &link->io); + ret = pcmcia_request_io(link); if (ret) goto failed; } diff --git a/drivers/net/pcmcia/ibmtr_cs.c b/drivers/net/pcmcia/ibmtr_cs.c index e99abaa92be5..3fd859570db3 100644 --- a/drivers/net/pcmcia/ibmtr_cs.c +++ b/drivers/net/pcmcia/ibmtr_cs.c @@ -151,9 +151,8 @@ static int __devinit ibmtr_attach(struct pcmcia_device *link) link->priv = info; info->ti = netdev_priv(dev); - link->io.Attributes1 = IO_DATA_PATH_WIDTH_8; - link->io.NumPorts1 = 4; - link->io.IOAddrLines = 16; + link->resource[0]->flags |= IO_DATA_PATH_WIDTH_8; + link->resource[0]->end = 4; link->conf.Attributes = CONF_ENABLE_IRQ; link->conf.IntType = INT_MEMORY_AND_IO; link->conf.Present = PRESENT_OPTION; @@ -218,16 +217,17 @@ static int __devinit ibmtr_config(struct pcmcia_device *link) dev_dbg(&link->dev, "ibmtr_config\n"); link->conf.ConfigIndex = 0x61; + link->io_lines = 16; /* Determine if this is PRIMARY or ALTERNATE. */ /* Try PRIMARY card at 0xA20-0xA23 */ - link->io.BasePort1 = 0xA20; - i = pcmcia_request_io(link, &link->io); + link->resource[0]->start = 0xA20; + i = pcmcia_request_io(link); if (i != 0) { /* Couldn't get 0xA20-0xA23. Try ALTERNATE at 0xA24-0xA27. */ - link->io.BasePort1 = 0xA24; - ret = pcmcia_request_io(link, &link->io); + link->resource[0]->start = 0xA24; + ret = pcmcia_request_io(link); if (ret) goto failed; } diff --git a/drivers/net/pcmcia/nmclan_cs.c b/drivers/net/pcmcia/nmclan_cs.c index 9980cbb81d34..68f2deeb3ade 100644 --- a/drivers/net/pcmcia/nmclan_cs.c +++ b/drivers/net/pcmcia/nmclan_cs.c @@ -458,9 +458,8 @@ static int nmclan_probe(struct pcmcia_device *link) link->priv = dev; spin_lock_init(&lp->bank_lock); - link->io.NumPorts1 = 32; - link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO; - link->io.IOAddrLines = 5; + link->resource[0]->end = 32; + link->resource[0]->flags |= IO_DATA_PATH_WIDTH_AUTO; link->conf.Attributes = CONF_ENABLE_IRQ; link->conf.IntType = INT_MEMORY_AND_IO; link->conf.ConfigIndex = 1; @@ -644,7 +643,8 @@ static int nmclan_config(struct pcmcia_device *link) dev_dbg(&link->dev, "nmclan_config\n"); - ret = pcmcia_request_io(link, &link->io); + link->io_lines = 5; + ret = pcmcia_request_io(link); if (ret) goto failed; ret = pcmcia_request_exclusive_irq(link, mace_interrupt); diff --git a/drivers/net/pcmcia/pcnet_cs.c b/drivers/net/pcmcia/pcnet_cs.c index c9cd2377ef91..9c5fc9dfc55d 100644 --- a/drivers/net/pcmcia/pcnet_cs.c +++ b/drivers/net/pcmcia/pcnet_cs.c @@ -477,29 +477,31 @@ static hw_info_t *get_hwired(struct pcmcia_device *link) static int try_io_port(struct pcmcia_device *link) { int j, ret; - if (link->io.NumPorts1 == 32) { - link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO; - if (link->io.NumPorts2 > 0) { + link->resource[0]->flags &= ~IO_DATA_PATH_WIDTH; + link->resource[1]->flags &= ~IO_DATA_PATH_WIDTH; + if (link->resource[0]->end == 32) { + link->resource[0]->flags |= IO_DATA_PATH_WIDTH_AUTO; + if (link->resource[1]->end > 0) { /* for master/slave multifunction cards */ - link->io.Attributes2 = IO_DATA_PATH_WIDTH_8; + link->resource[1]->flags |= IO_DATA_PATH_WIDTH_8; } } else { /* This should be two 16-port windows */ - link->io.Attributes1 = IO_DATA_PATH_WIDTH_8; - link->io.Attributes2 = IO_DATA_PATH_WIDTH_16; + link->resource[0]->flags |= IO_DATA_PATH_WIDTH_8; + link->resource[1]->flags |= IO_DATA_PATH_WIDTH_16; } - if (link->io.BasePort1 == 0) { - link->io.IOAddrLines = 16; + if (link->resource[0]->start == 0) { for (j = 0; j < 0x400; j += 0x20) { - link->io.BasePort1 = j ^ 0x300; - link->io.BasePort2 = (j ^ 0x300) + 0x10; - ret = pcmcia_request_io(link, &link->io); + link->resource[0]->start = j ^ 0x300; + link->resource[1]->start = (j ^ 0x300) + 0x10; + link->io_lines = 16; + ret = pcmcia_request_io(link); if (ret == 0) return ret; } return ret; } else { - return pcmcia_request_io(link, &link->io); + return pcmcia_request_io(link); } } @@ -520,18 +522,18 @@ static int pcnet_confcheck(struct pcmcia_device *p_dev, network function with window 0, and serial with window 1 */ if (io->nwin > 1) { i = (io->win[1].len > io->win[0].len); - p_dev->io.BasePort2 = io->win[1-i].base; - p_dev->io.NumPorts2 = io->win[1-i].len; + p_dev->resource[1]->start = io->win[1-i].base; + p_dev->resource[1]->end = io->win[1-i].len; } else { - i = p_dev->io.NumPorts2 = 0; + i = p_dev->resource[1]->end = 0; } *has_shmem = ((cfg->mem.nwin == 1) && (cfg->mem.win[0].len >= 0x4000)); - p_dev->io.BasePort1 = io->win[i].base; - p_dev->io.NumPorts1 = io->win[i].len; - p_dev->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK; - if (p_dev->io.NumPorts1 + p_dev->io.NumPorts2 >= 32) + p_dev->resource[0]->start = io->win[i].base; + p_dev->resource[0]->end = io->win[i].len; + p_dev->io_lines = io->flags & CISTPL_IO_LINES_MASK; + if (p_dev->resource[0]->end + p_dev->resource[1]->end >= 32) return try_io_port(p_dev); return 0; diff --git a/drivers/net/pcmcia/smc91c92_cs.c b/drivers/net/pcmcia/smc91c92_cs.c index 1b0b3230dd71..a5e47796f6ae 100644 --- a/drivers/net/pcmcia/smc91c92_cs.c +++ b/drivers/net/pcmcia/smc91c92_cs.c @@ -324,9 +324,8 @@ static int smc91c92_probe(struct pcmcia_device *link) link->priv = dev; spin_lock_init(&smc->lock); - link->io.NumPorts1 = 16; - link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO; - link->io.IOAddrLines = 4; + link->resource[0]->end = 16; + link->resource[0]->flags |= IO_DATA_PATH_WIDTH_AUTO; link->conf.Attributes = CONF_ENABLE_IRQ; link->conf.IntType = INT_MEMORY_AND_IO; @@ -427,12 +426,13 @@ static int mhz_mfc_config_check(struct pcmcia_device *p_dev, void *priv_data) { int k; - p_dev->io.BasePort2 = cf->io.win[0].base; + p_dev->resource[1]->start = cf->io.win[0].base; for (k = 0; k < 0x400; k += 0x10) { if (k & 0x80) continue; - p_dev->io.BasePort1 = k ^ 0x300; - if (!pcmcia_request_io(p_dev, &p_dev->io)) + p_dev->resource[0]->start = k ^ 0x300; + p_dev->io_lines = 16; + if (!pcmcia_request_io(p_dev)) return 0; } return -ENODEV; @@ -448,9 +448,8 @@ static int mhz_mfc_config(struct pcmcia_device *link) link->conf.Attributes |= CONF_ENABLE_SPKR; link->conf.Status = CCSR_AUDIO_ENA; - link->io.IOAddrLines = 16; - link->io.Attributes2 = IO_DATA_PATH_WIDTH_8; - link->io.NumPorts2 = 8; + link->resource[1]->flags |= IO_DATA_PATH_WIDTH_8; + link->resource[1]->end = 8; /* The Megahertz combo cards have modem-like CIS entries, so we have to explicitly try a bunch of port combinations. */ @@ -601,9 +600,9 @@ static int smc_configcheck(struct pcmcia_device *p_dev, unsigned int vcc, void *priv_data) { - p_dev->io.BasePort1 = cf->io.win[0].base; - p_dev->io.IOAddrLines = cf->io.flags & CISTPL_IO_LINES_MASK; - return pcmcia_request_io(p_dev, &p_dev->io); + p_dev->resource[0]->start = cf->io.win[0].base; + p_dev->io_lines = cf->io.flags & CISTPL_IO_LINES_MASK; + return pcmcia_request_io(p_dev); } static int smc_config(struct pcmcia_device *link) @@ -611,7 +610,7 @@ static int smc_config(struct pcmcia_device *link) struct net_device *dev = link->priv; int i; - link->io.NumPorts1 = 16; + link->resource[0]->end = 16; i = pcmcia_loop_config(link, smc_configcheck, NULL); if (!i) dev->base_addr = link->resource[0]->start; @@ -646,25 +645,25 @@ static int osi_config(struct pcmcia_device *link) link->conf.Attributes |= CONF_ENABLE_SPKR; link->conf.Status = CCSR_AUDIO_ENA; - link->io.NumPorts1 = 64; - link->io.Attributes2 = IO_DATA_PATH_WIDTH_8; - link->io.NumPorts2 = 8; - link->io.IOAddrLines = 16; + link->resource[0]->end = 64; + link->resource[1]->flags |= IO_DATA_PATH_WIDTH_8; + link->resource[1]->end = 8; /* Enable Hard Decode, LAN, Modem */ link->conf.ConfigIndex = 0x23; + link->io_lines = 16; for (i = j = 0; j < 4; j++) { - link->io.BasePort2 = com[j]; - i = pcmcia_request_io(link, &link->io); + link->resource[1]->start = com[j]; + i = pcmcia_request_io(link); if (i == 0) break; } if (i != 0) { /* Fallback: turn off hard decode */ link->conf.ConfigIndex = 0x03; - link->io.NumPorts2 = 0; - i = pcmcia_request_io(link, &link->io); + link->resource[1]->end = 0; + i = pcmcia_request_io(link); } dev->base_addr = link->resource[0]->start + 0x10; return i; @@ -803,7 +802,7 @@ static int check_sig(struct pcmcia_device *link) } /* Try setting bus width */ - width = (link->io.Attributes1 == IO_DATA_PATH_WIDTH_AUTO); + width = (link->resource[0]->flags == IO_DATA_PATH_WIDTH_AUTO); s = inb(ioaddr + CONFIG); if (width) s |= CFG_16BIT; diff --git a/drivers/net/pcmcia/xirc2ps_cs.c b/drivers/net/pcmcia/xirc2ps_cs.c index 034920b459d1..8fb0eb1dc341 100644 --- a/drivers/net/pcmcia/xirc2ps_cs.c +++ b/drivers/net/pcmcia/xirc2ps_cs.c @@ -677,9 +677,9 @@ xirc2ps_config_modem(struct pcmcia_device *p_dev, if (cf->io.nwin > 0 && (cf->io.win[0].base & 0xf) == 8) { for (ioaddr = 0x300; ioaddr < 0x400; ioaddr += 0x10) { - p_dev->io.BasePort2 = cf->io.win[0].base; - p_dev->io.BasePort1 = ioaddr; - if (!pcmcia_request_io(p_dev, &p_dev->io)) + p_dev->resource[1]->start = cf->io.win[0].base; + p_dev->resource[0]->start = ioaddr; + if (!pcmcia_request_io(p_dev)) return 0; } } @@ -696,11 +696,11 @@ xirc2ps_config_check(struct pcmcia_device *p_dev, int *pass = priv_data; if (cf->io.nwin > 0 && (cf->io.win[0].base & 0xf) == 8) { - p_dev->io.BasePort2 = cf->io.win[0].base; - p_dev->io.BasePort1 = p_dev->io.BasePort2 + p_dev->resource[1]->start = cf->io.win[0].base; + p_dev->resource[0]->start = p_dev->resource[1]->start + (*pass ? (cf->index & 0x20 ? -24:8) : (cf->index & 0x20 ? 8:-24)); - if (!pcmcia_request_io(p_dev, &p_dev->io)) + if (!pcmcia_request_io(p_dev)) return 0; } return -ENODEV; @@ -807,8 +807,7 @@ xirc2ps_config(struct pcmcia_device * link) goto failure; } - link->io.IOAddrLines =10; - link->io.Attributes1 = IO_DATA_PATH_WIDTH_16; + link->resource[0]->flags |= IO_DATA_PATH_WIDTH_16; if (local->modem) { int pass; @@ -816,16 +815,16 @@ xirc2ps_config(struct pcmcia_device * link) link->conf.Attributes |= CONF_ENABLE_SPKR; link->conf.Status |= CCSR_AUDIO_ENA; } - link->io.NumPorts2 = 8; - link->io.Attributes2 = IO_DATA_PATH_WIDTH_8; + link->resource[1]->end = 8; + link->resource[1]->flags |= IO_DATA_PATH_WIDTH_8; if (local->dingo) { /* Take the Modem IO port from the CIS and scan for a free * Ethernet port */ - link->io.NumPorts1 = 16; /* no Mako stuff anymore */ + link->resource[0]->end = 16; /* no Mako stuff anymore */ if (!pcmcia_loop_config(link, xirc2ps_config_modem, NULL)) goto port_found; } else { - link->io.NumPorts1 = 18; + link->resource[0]->end = 18; /* We do 2 passes here: The first one uses the regular mapping and * the second tries again, thereby considering that the 32 ports are * mirrored every 32 bytes. Actually we use a mirrored port for @@ -840,14 +839,15 @@ xirc2ps_config(struct pcmcia_device * link) } printk(KNOT_XIRC "no ports available\n"); } else { - link->io.NumPorts1 = 16; + link->io_lines = 10; + link->resource[0]->end = 16; for (ioaddr = 0x300; ioaddr < 0x400; ioaddr += 0x10) { - link->io.BasePort1 = ioaddr; - if (!(err=pcmcia_request_io(link, &link->io))) + link->resource[0]->start = ioaddr; + if (!(err = pcmcia_request_io(link))) goto port_found; } - link->io.BasePort1 = 0; /* let CS decide */ - if ((err=pcmcia_request_io(link, &link->io))) + link->resource[0]->start = 0; /* let CS decide */ + if ((err = pcmcia_request_io(link))) goto config_error; } port_found: diff --git a/drivers/net/wireless/airo_cs.c b/drivers/net/wireless/airo_cs.c index b7e7f5054e44..d241b4aed71e 100644 --- a/drivers/net/wireless/airo_cs.c +++ b/drivers/net/wireless/airo_cs.c @@ -175,25 +175,23 @@ static int airo_cs_config_check(struct pcmcia_device *p_dev, p_dev->conf.Attributes |= CONF_ENABLE_IRQ; /* IO window settings */ - p_dev->io.NumPorts1 = p_dev->io.NumPorts2 = 0; + p_dev->resource[0]->end = p_dev->resource[1]->end = 0; if ((cfg->io.nwin > 0) || (dflt->io.nwin > 0)) { cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt->io; - p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO; - if (!(io->flags & CISTPL_IO_8BIT)) - p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_16; - if (!(io->flags & CISTPL_IO_16BIT)) - p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_8; - p_dev->io.BasePort1 = io->win[0].base; - p_dev->io.NumPorts1 = io->win[0].len; + p_dev->resource[0]->flags &= ~IO_DATA_PATH_WIDTH; + p_dev->resource[0]->flags |= + pcmcia_io_cfg_data_width(io->flags); + p_dev->resource[0]->start = io->win[0].base; + p_dev->resource[0]->end = io->win[0].len; if (io->nwin > 1) { - p_dev->io.Attributes2 = p_dev->io.Attributes1; - p_dev->io.BasePort2 = io->win[1].base; - p_dev->io.NumPorts2 = io->win[1].len; + p_dev->resource[1]->flags = p_dev->resource[0]->flags; + p_dev->resource[1]->start = io->win[1].base; + p_dev->resource[1]->end = io->win[1].len; } } /* This reserves IO space but doesn't actually enable it */ - if (pcmcia_request_io(p_dev, &p_dev->io) != 0) + if (pcmcia_request_io(p_dev) != 0) return -ENODEV; /* diff --git a/drivers/net/wireless/atmel_cs.c b/drivers/net/wireless/atmel_cs.c index 65b3aed49e58..3b632161c106 100644 --- a/drivers/net/wireless/atmel_cs.c +++ b/drivers/net/wireless/atmel_cs.c @@ -190,25 +190,23 @@ static int atmel_config_check(struct pcmcia_device *p_dev, p_dev->conf.Attributes |= CONF_ENABLE_IRQ; /* IO window settings */ - p_dev->io.NumPorts1 = p_dev->io.NumPorts2 = 0; + p_dev->resource[0]->end = p_dev->resource[1]->end = 0; if ((cfg->io.nwin > 0) || (dflt->io.nwin > 0)) { cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt->io; - p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO; - if (!(io->flags & CISTPL_IO_8BIT)) - p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_16; - if (!(io->flags & CISTPL_IO_16BIT)) - p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_8; - p_dev->io.BasePort1 = io->win[0].base; - p_dev->io.NumPorts1 = io->win[0].len; + p_dev->resource[0]->flags &= ~IO_DATA_PATH_WIDTH; + p_dev->resource[0]->flags |= + pcmcia_io_cfg_data_width(io->flags); + p_dev->resource[0]->start = io->win[0].base; + p_dev->resource[0]->end = io->win[0].len; if (io->nwin > 1) { - p_dev->io.Attributes2 = p_dev->io.Attributes1; - p_dev->io.BasePort2 = io->win[1].base; - p_dev->io.NumPorts2 = io->win[1].len; + p_dev->resource[1]->flags = p_dev->resource[0]->flags; + p_dev->resource[1]->start = io->win[1].base; + p_dev->resource[1]->end = io->win[1].len; } } /* This reserves IO space but doesn't actually enable it */ - return pcmcia_request_io(p_dev, &p_dev->io); + return pcmcia_request_io(p_dev); } static int atmel_config(struct pcmcia_device *link) diff --git a/drivers/net/wireless/b43/pcmcia.c b/drivers/net/wireless/b43/pcmcia.c index f71bc7821378..7c9af82fcf7e 100644 --- a/drivers/net/wireless/b43/pcmcia.c +++ b/drivers/net/wireless/b43/pcmcia.c @@ -77,10 +77,6 @@ static int __devinit b43_pcmcia_probe(struct pcmcia_device *dev) dev->conf.Attributes = CONF_ENABLE_IRQ; dev->conf.IntType = INT_MEMORY_AND_IO; - dev->io.BasePort2 = 0; - dev->io.NumPorts2 = 0; - dev->io.Attributes2 = 0; - win.Attributes = WIN_ADDR_SPACE_MEM | WIN_MEMORY_TYPE_CM | WIN_ENABLE | WIN_DATA_WIDTH_16 | WIN_USE_WAIT; diff --git a/drivers/net/wireless/hostap/hostap_cs.c b/drivers/net/wireless/hostap/hostap_cs.c index 4e13cedb8235..ba54d1b04d22 100644 --- a/drivers/net/wireless/hostap/hostap_cs.c +++ b/drivers/net/wireless/hostap/hostap_cs.c @@ -519,30 +519,24 @@ static int prism2_config_check(struct pcmcia_device *p_dev, PDEBUG(DEBUG_EXTRA, "IO window settings: cfg->io.nwin=%d " "dflt->io.nwin=%d\n", cfg->io.nwin, dflt->io.nwin); - p_dev->io.NumPorts1 = p_dev->io.NumPorts2 = 0; + p_dev->resource[0]->end = p_dev->resource[1]->end = 0; if ((cfg->io.nwin > 0) || (dflt->io.nwin > 0)) { cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt->io; - p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO; - PDEBUG(DEBUG_EXTRA, "io->flags = 0x%04X, " - "io.base=0x%04x, len=%d\n", io->flags, - io->win[0].base, io->win[0].len); - if (!(io->flags & CISTPL_IO_8BIT)) - p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_16; - if (!(io->flags & CISTPL_IO_16BIT)) - p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_8; - p_dev->io.IOAddrLines = io->flags & - CISTPL_IO_LINES_MASK; - p_dev->io.BasePort1 = io->win[0].base; - p_dev->io.NumPorts1 = io->win[0].len; + p_dev->resource[0]->flags &= ~IO_DATA_PATH_WIDTH; + p_dev->resource[0]->flags |= + pcmcia_io_cfg_data_width(io->flags); + p_dev->io_lines = io->flags & CISTPL_IO_LINES_MASK; + p_dev->resource[0]->start = io->win[0].base; + p_dev->resource[0]->end = io->win[0].len; if (io->nwin > 1) { - p_dev->io.Attributes2 = p_dev->io.Attributes1; - p_dev->io.BasePort2 = io->win[1].base; - p_dev->io.NumPorts2 = io->win[1].len; + p_dev->resource[1]->flags = p_dev->resource[0]->flags; + p_dev->resource[1]->start = io->win[1].base; + p_dev->resource[1]->end = io->win[1].len; } } /* This reserves IO space but doesn't actually enable it */ - return pcmcia_request_io(p_dev, &p_dev->io); + return pcmcia_request_io(p_dev); } static int prism2_config(struct pcmcia_device *link) diff --git a/drivers/net/wireless/libertas/if_cs.c b/drivers/net/wireless/libertas/if_cs.c index be4c47594b59..9c298396be50 100644 --- a/drivers/net/wireless/libertas/if_cs.c +++ b/drivers/net/wireless/libertas/if_cs.c @@ -801,9 +801,9 @@ static int if_cs_ioprobe(struct pcmcia_device *p_dev, unsigned int vcc, void *priv_data) { - p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO; - p_dev->io.BasePort1 = cfg->io.win[0].base; - p_dev->io.NumPorts1 = cfg->io.win[0].len; + p_dev->resource[0]->flags |= IO_DATA_PATH_WIDTH_AUTO; + p_dev->resource[0]->start = cfg->io.win[0].base; + p_dev->resource[0]->end = cfg->io.win[0].len; /* Do we need to allocate an interrupt? */ p_dev->conf.Attributes |= CONF_ENABLE_IRQ; @@ -815,7 +815,7 @@ static int if_cs_ioprobe(struct pcmcia_device *p_dev, } /* This reserves IO space but doesn't actually enable it */ - return pcmcia_request_io(p_dev, &p_dev->io); + return pcmcia_request_io(p_dev); } static int if_cs_probe(struct pcmcia_device *p_dev) diff --git a/drivers/net/wireless/orinoco/orinoco_cs.c b/drivers/net/wireless/orinoco/orinoco_cs.c index 6d514b5462fd..ef46a2d88539 100644 --- a/drivers/net/wireless/orinoco/orinoco_cs.c +++ b/drivers/net/wireless/orinoco/orinoco_cs.c @@ -191,25 +191,23 @@ static int orinoco_cs_config_check(struct pcmcia_device *p_dev, p_dev->conf.Attributes |= CONF_ENABLE_IRQ; /* IO window settings */ - p_dev->io.NumPorts1 = p_dev->io.NumPorts2 = 0; + p_dev->resource[0]->end = p_dev->resource[1]->end = 0; if ((cfg->io.nwin > 0) || (dflt->io.nwin > 0)) { cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt->io; - p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO; - if (!(io->flags & CISTPL_IO_8BIT)) - p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_16; - if (!(io->flags & CISTPL_IO_16BIT)) - p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_8; - p_dev->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK; - p_dev->io.BasePort1 = io->win[0].base; - p_dev->io.NumPorts1 = io->win[0].len; + p_dev->io_lines = io->flags & CISTPL_IO_LINES_MASK; + p_dev->resource[0]->flags &= ~IO_DATA_PATH_WIDTH; + p_dev->resource[0]->flags |= + pcmcia_io_cfg_data_width(io->flags); + p_dev->resource[0]->start = io->win[0].base; + p_dev->resource[0]->end = io->win[0].len; if (io->nwin > 1) { - p_dev->io.Attributes2 = p_dev->io.Attributes1; - p_dev->io.BasePort2 = io->win[1].base; - p_dev->io.NumPorts2 = io->win[1].len; + p_dev->resource[1]->flags = p_dev->resource[0]->flags; + p_dev->resource[1]->start = io->win[1].base; + p_dev->resource[1]->end = io->win[1].len; } /* This reserves IO space but doesn't actually enable it */ - if (pcmcia_request_io(p_dev, &p_dev->io) != 0) + if (pcmcia_request_io(p_dev) != 0) goto next_entry; } return 0; diff --git a/drivers/net/wireless/orinoco/spectrum_cs.c b/drivers/net/wireless/orinoco/spectrum_cs.c index 4f8f55eab955..873877e17e1b 100644 --- a/drivers/net/wireless/orinoco/spectrum_cs.c +++ b/drivers/net/wireless/orinoco/spectrum_cs.c @@ -253,25 +253,23 @@ static int spectrum_cs_config_check(struct pcmcia_device *p_dev, p_dev->conf.Attributes |= CONF_ENABLE_IRQ; /* IO window settings */ - p_dev->io.NumPorts1 = p_dev->io.NumPorts2 = 0; + p_dev->resource[0]->end = p_dev->resource[1]->end = 0; if ((cfg->io.nwin > 0) || (dflt->io.nwin > 0)) { cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt->io; - p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO; - if (!(io->flags & CISTPL_IO_8BIT)) - p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_16; - if (!(io->flags & CISTPL_IO_16BIT)) - p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_8; - p_dev->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK; - p_dev->io.BasePort1 = io->win[0].base; - p_dev->io.NumPorts1 = io->win[0].len; + p_dev->io_lines = io->flags & CISTPL_IO_LINES_MASK; + p_dev->resource[0]->flags &= ~IO_DATA_PATH_WIDTH; + p_dev->resource[0]->flags |= + pcmcia_io_cfg_data_width(io->flags); + p_dev->resource[0]->start = io->win[0].base; + p_dev->resource[0]->end = io->win[0].len; if (io->nwin > 1) { - p_dev->io.Attributes2 = p_dev->io.Attributes1; - p_dev->io.BasePort2 = io->win[1].base; - p_dev->io.NumPorts2 = io->win[1].len; + p_dev->resource[1]->flags = p_dev->resource[0]->flags; + p_dev->resource[1]->start = io->win[1].base; + p_dev->resource[1]->end = io->win[1].len; } /* This reserves IO space but doesn't actually enable it */ - if (pcmcia_request_io(p_dev, &p_dev->io) != 0) + if (pcmcia_request_io(p_dev) != 0) goto next_entry; } return 0; diff --git a/drivers/net/wireless/ray_cs.c b/drivers/net/wireless/ray_cs.c index 165beb6af849..b83d5ef1dffe 100644 --- a/drivers/net/wireless/ray_cs.c +++ b/drivers/net/wireless/ray_cs.c @@ -315,9 +315,8 @@ static int ray_probe(struct pcmcia_device *p_dev) local->finder = p_dev; /* The io structure describes IO port mapping. None used here */ - p_dev->io.NumPorts1 = 0; - p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_8; - p_dev->io.IOAddrLines = 5; + p_dev->resource[0]->end = 0; + p_dev->resource[0]->flags |= IO_DATA_PATH_WIDTH_8; /* General socket configuration */ p_dev->conf.Attributes = CONF_ENABLE_IRQ; diff --git a/drivers/net/wireless/wl3501_cs.c b/drivers/net/wireless/wl3501_cs.c index a32f220648c0..a1cc2d498a1c 100644 --- a/drivers/net/wireless/wl3501_cs.c +++ b/drivers/net/wireless/wl3501_cs.c @@ -1884,9 +1884,8 @@ static int wl3501_probe(struct pcmcia_device *p_dev) struct wl3501_card *this; /* The io structure describes IO port mapping */ - p_dev->io.NumPorts1 = 16; - p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_8; - p_dev->io.IOAddrLines = 5; + p_dev->resource[0]->end = 16; + p_dev->resource[0]->flags = IO_DATA_PATH_WIDTH_8; /* General socket configuration */ p_dev->conf.Attributes = CONF_ENABLE_IRQ; @@ -1932,13 +1931,14 @@ static int wl3501_config(struct pcmcia_device *link) /* Try allocating IO ports. This tries a few fixed addresses. If you * want, you can also read the card's config table to pick addresses -- * see the serial driver for an example. */ + link->io_lines = 5; for (j = 0x280; j < 0x400; j += 0x20) { /* The '^0x300' is so that we probe 0x300-0x3ff first, then * 0x200-0x2ff, and so on, because this seems safer */ - link->io.BasePort1 = j; - link->io.BasePort2 = link->io.BasePort1 + 0x10; - i = pcmcia_request_io(link, &link->io); + link->resource[0]->start = j; + link->resource[1]->start = link->resource[0]->start + 0x10; + i = pcmcia_request_io(link); if (i == 0) break; } diff --git a/drivers/parport/parport_cs.c b/drivers/parport/parport_cs.c index fc1639c5ada6..23e50f4a27c5 100644 --- a/drivers/parport/parport_cs.c +++ b/drivers/parport/parport_cs.c @@ -101,8 +101,8 @@ static int parport_probe(struct pcmcia_device *link) link->priv = info; info->p_dev = link; - link->io.Attributes1 = IO_DATA_PATH_WIDTH_8; - link->io.Attributes2 = IO_DATA_PATH_WIDTH_8; + link->resource[0]->flags |= IO_DATA_PATH_WIDTH_8; + link->resource[1]->flags |= IO_DATA_PATH_WIDTH_8; link->conf.Attributes = CONF_ENABLE_IRQ; link->conf.IntType = INT_MEMORY_AND_IO; @@ -143,16 +143,16 @@ static int parport_config_check(struct pcmcia_device *p_dev, { if ((cfg->io.nwin > 0) || (dflt->io.nwin > 0)) { cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt->io; + p_dev->io_lines = io->flags & CISTPL_IO_LINES_MASK; if (epp_mode) p_dev->conf.ConfigIndex |= FORCE_EPP_MODE; - p_dev->io.BasePort1 = io->win[0].base; - p_dev->io.NumPorts1 = io->win[0].len; - p_dev->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK; + p_dev->resource[0]->start = io->win[0].base; + p_dev->resource[0]->end = io->win[0].len; if (io->nwin == 2) { - p_dev->io.BasePort2 = io->win[1].base; - p_dev->io.NumPorts2 = io->win[1].len; + p_dev->resource[1]->start = io->win[1].base; + p_dev->resource[1]->end = io->win[1].len; } - if (pcmcia_request_io(p_dev, &p_dev->io) != 0) + if (pcmcia_request_io(p_dev) != 0) return -ENODEV; return 0; } diff --git a/drivers/pcmcia/pcmcia_resource.c b/drivers/pcmcia/pcmcia_resource.c index fcd48dae79bc..a48d4a91d440 100644 --- a/drivers/pcmcia/pcmcia_resource.c +++ b/drivers/pcmcia/pcmcia_resource.c @@ -70,7 +70,8 @@ static int alloc_io_space(struct pcmcia_socket *s, struct resource *res, res->flags |= IORESOURCE_IO; - dev_dbg(&s->dev, "alloc_io_space request for %pR\n", res); + dev_dbg(&s->dev, "alloc_io_space request for %pR, %d lines\n", + res, lines); align = base ? (lines ? 1<resource[0] and *p_dev->resource[1]. The + * &struct pcmcia_device @p_dev->resource[0] and @p_dev->resource[1]. The * "start" value is the requested start of the IO port resource; "end" - * relfects the number of ports requested. - * - * If io_req_t is passed, those values are converted automatically. + * reflects the number of ports requested. The number of IO lines requested + * is specified in &struct pcmcia_device @p_dev->io_lines. */ -int pcmcia_request_io(struct pcmcia_device *p_dev, io_req_t *req) +int pcmcia_request_io(struct pcmcia_device *p_dev) { struct pcmcia_socket *s = p_dev->socket; - config_t *c; + config_t *c = p_dev->function_config; int ret = -EINVAL; - unsigned int lines = req->IOAddrLines; mutex_lock(&s->ops_mutex); + dev_dbg(&s->dev, "pcmcia_request_io: %pR , %pR", &c->io[0], &c->io[1]); if (!(s->state & SOCKET_PRESENT)) { dev_dbg(&s->dev, "pcmcia_request_io: No card present\n"); goto out; } - c = p_dev->function_config; - if (req) { - c->io[0].start = req->BasePort1; - c->io[0].end = req->NumPorts1; - c->io[0].flags |= req->Attributes1; - c->io[1].start = req->BasePort2; - c->io[1].end = req->NumPorts2; - c->io[1].flags |= req->Attributes2; - } - - dev_dbg(&s->dev, "pcmcia_request_io: %pR , %pR", &c->io[0], &c->io[1]); - if (c->state & CONFIG_LOCKED) { dev_dbg(&s->dev, "Configuration is locked\n"); goto out; @@ -582,12 +570,12 @@ int pcmcia_request_io(struct pcmcia_device *p_dev, io_req_t *req) goto out; } - ret = alloc_io_space(s, &c->io[0], lines); + ret = alloc_io_space(s, &c->io[0], p_dev->io_lines); if (ret) goto out; if (c->io[1].end) { - ret = alloc_io_space(s, &c->io[1], lines); + ret = alloc_io_space(s, &c->io[1], p_dev->io_lines); if (ret) { release_io_space(s, &c->io[0]); goto out; @@ -598,11 +586,6 @@ int pcmcia_request_io(struct pcmcia_device *p_dev, io_req_t *req) c->state |= CONFIG_IO_REQ; p_dev->_io = 1; - if (!ret) { - req->BasePort1 = c->io[0].start; - req->BasePort2 = c->io[1].start; - } - dev_dbg(&s->dev, "pcmcia_request_io succeeded: %pR , %pR", &c->io[0], &c->io[1]); out: diff --git a/drivers/scsi/pcmcia/aha152x_stub.c b/drivers/scsi/pcmcia/aha152x_stub.c index 3e040f503afa..61f49bdcc0c2 100644 --- a/drivers/scsi/pcmcia/aha152x_stub.c +++ b/drivers/scsi/pcmcia/aha152x_stub.c @@ -100,9 +100,8 @@ static int aha152x_probe(struct pcmcia_device *link) info->p_dev = link; link->priv = info; - link->io.NumPorts1 = 0x20; - link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO; - link->io.IOAddrLines = 10; + link->resource[0]->end = 0x20; + link->resource[0]->flags |= IO_DATA_PATH_WIDTH_AUTO; link->conf.Attributes = CONF_ENABLE_IRQ; link->conf.IntType = INT_MEMORY_AND_IO; link->conf.Present = PRESENT_OPTION; @@ -130,15 +129,16 @@ static int aha152x_config_check(struct pcmcia_device *p_dev, unsigned int vcc, void *priv_data) { + p_dev->io_lines = 10; /* For New Media T&J, look for a SCSI window */ if (cfg->io.win[0].len >= 0x20) - p_dev->io.BasePort1 = cfg->io.win[0].base; + p_dev->resource[0]->start = cfg->io.win[0].base; else if ((cfg->io.nwin > 1) && (cfg->io.win[1].len >= 0x20)) - p_dev->io.BasePort1 = cfg->io.win[1].base; + p_dev->resource[0]->start = cfg->io.win[1].base; if ((cfg->io.nwin > 0) && - (p_dev->io.BasePort1 < 0xffff)) { - if (!pcmcia_request_io(p_dev, &p_dev->io)) + (p_dev->resource[0]->start < 0xffff)) { + if (!pcmcia_request_io(p_dev)) return 0; } return -EINVAL; diff --git a/drivers/scsi/pcmcia/fdomain_stub.c b/drivers/scsi/pcmcia/fdomain_stub.c index 49a9a0a60c82..13dbe5c48492 100644 --- a/drivers/scsi/pcmcia/fdomain_stub.c +++ b/drivers/scsi/pcmcia/fdomain_stub.c @@ -83,9 +83,8 @@ static int fdomain_probe(struct pcmcia_device *link) info->p_dev = link; link->priv = info; - link->io.NumPorts1 = 0x10; - link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO; - link->io.IOAddrLines = 10; + link->resource[0]->end = 0x10; + link->resource[0]->flags |= IO_DATA_PATH_WIDTH_AUTO; link->conf.Attributes = CONF_ENABLE_IRQ; link->conf.IntType = INT_MEMORY_AND_IO; link->conf.Present = PRESENT_OPTION; @@ -112,8 +111,9 @@ static int fdomain_config_check(struct pcmcia_device *p_dev, unsigned int vcc, void *priv_data) { - p_dev->io.BasePort1 = cfg->io.win[0].base; - return pcmcia_request_io(p_dev, &p_dev->io); + p_dev->io_lines = 10; + p_dev->resource[0]->start = cfg->io.win[0].base; + return pcmcia_request_io(p_dev); } diff --git a/drivers/scsi/pcmcia/nsp_cs.c b/drivers/scsi/pcmcia/nsp_cs.c index d929891809ab..8bb598bb440d 100644 --- a/drivers/scsi/pcmcia/nsp_cs.c +++ b/drivers/scsi/pcmcia/nsp_cs.c @@ -1558,9 +1558,8 @@ static int nsp_cs_probe(struct pcmcia_device *link) nsp_dbg(NSP_DEBUG_INIT, "info=0x%p", info); /* The io structure describes IO port mapping */ - link->io.NumPorts1 = 0x10; - link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO; - link->io.IOAddrLines = 10; /* not used */ + link->resource[0]->end = 0x10; + link->resource[0]->flags = IO_DATA_PATH_WIDTH_AUTO; /* General socket configuration */ link->conf.Attributes = CONF_ENABLE_IRQ; @@ -1641,24 +1640,23 @@ static int nsp_cs_config_check(struct pcmcia_device *p_dev, p_dev->conf.Attributes |= CONF_ENABLE_IRQ; /* IO window settings */ - p_dev->io.NumPorts1 = p_dev->io.NumPorts2 = 0; + p_dev->resource[0]->end = p_dev->resource[1]->end = 0; if ((cfg->io.nwin > 0) || (dflt->io.nwin > 0)) { cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt->io; - p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO; - if (!(io->flags & CISTPL_IO_8BIT)) - p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_16; - if (!(io->flags & CISTPL_IO_16BIT)) - p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_8; - p_dev->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK; - p_dev->io.BasePort1 = io->win[0].base; - p_dev->io.NumPorts1 = io->win[0].len; + p_dev->io_lines = io->flags & CISTPL_IO_LINES_MASK; + p_dev->resource[0]->flags &= ~IO_DATA_PATH_WIDTH; + p_dev->resource[0]->flags |= + pcmcia_io_cfg_data_width(io->flags); + p_dev->resource[0]->start = io->win[0].base; + p_dev->resource[0]->end = io->win[0].len; if (io->nwin > 1) { - p_dev->io.Attributes2 = p_dev->io.Attributes1; - p_dev->io.BasePort2 = io->win[1].base; - p_dev->io.NumPorts2 = io->win[1].len; + p_dev->resource[1]->flags = + p_dev->resource[0]->flags; + p_dev->resource[1]->start = io->win[1].base; + p_dev->resource[1]->end = io->win[1].len; } /* This reserves IO space but doesn't actually enable it */ - if (pcmcia_request_io(p_dev, &p_dev->io) != 0) + if (pcmcia_request_io(p_dev) != 0) goto next_entry; } diff --git a/drivers/scsi/pcmcia/qlogic_stub.c b/drivers/scsi/pcmcia/qlogic_stub.c index 4e2b83f26232..eb775f1a523c 100644 --- a/drivers/scsi/pcmcia/qlogic_stub.c +++ b/drivers/scsi/pcmcia/qlogic_stub.c @@ -156,9 +156,8 @@ static int qlogic_probe(struct pcmcia_device *link) return -ENOMEM; info->p_dev = link; link->priv = info; - link->io.NumPorts1 = 16; - link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO; - link->io.IOAddrLines = 10; + link->resource[0]->end = 16; + link->resource[0]->flags |= IO_DATA_PATH_WIDTH_AUTO; link->conf.Attributes = CONF_ENABLE_IRQ; link->conf.IntType = INT_MEMORY_AND_IO; link->conf.Present = PRESENT_OPTION; @@ -185,13 +184,14 @@ static int qlogic_config_check(struct pcmcia_device *p_dev, unsigned int vcc, void *priv_data) { - p_dev->io.BasePort1 = cfg->io.win[0].base; - p_dev->io.NumPorts1 = cfg->io.win[0].len; + p_dev->io_lines = 10; + p_dev->resource[0]->start = cfg->io.win[0].base; + p_dev->resource[0]->end = cfg->io.win[0].len; - if (p_dev->io.BasePort1 == 0) + if (p_dev->resource[0]->start == 0) return -ENODEV; - return pcmcia_request_io(p_dev, &p_dev->io); + return pcmcia_request_io(p_dev); } static int qlogic_config(struct pcmcia_device * link) diff --git a/drivers/scsi/pcmcia/sym53c500_cs.c b/drivers/scsi/pcmcia/sym53c500_cs.c index d99c0cbad2de..321e390c9120 100644 --- a/drivers/scsi/pcmcia/sym53c500_cs.c +++ b/drivers/scsi/pcmcia/sym53c500_cs.c @@ -690,13 +690,14 @@ static int SYM53C500_config_check(struct pcmcia_device *p_dev, unsigned int vcc, void *priv_data) { - p_dev->io.BasePort1 = cfg->io.win[0].base; - p_dev->io.NumPorts1 = cfg->io.win[0].len; + p_dev->io_lines = 10; + p_dev->resource[0]->start = cfg->io.win[0].base; + p_dev->resource[0]->end = cfg->io.win[0].len; - if (p_dev->io.BasePort1 == 0) + if (p_dev->resource[0]->start == 0) return -ENODEV; - return pcmcia_request_io(p_dev, &p_dev->io); + return pcmcia_request_io(p_dev); } static int @@ -858,9 +859,8 @@ SYM53C500_probe(struct pcmcia_device *link) return -ENOMEM; info->p_dev = link; link->priv = info; - link->io.NumPorts1 = 16; - link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO; - link->io.IOAddrLines = 10; + link->resource[0]->end = 16; + link->resource[0]->flags |= IO_DATA_PATH_WIDTH_AUTO; link->conf.Attributes = CONF_ENABLE_IRQ; link->conf.IntType = INT_MEMORY_AND_IO; diff --git a/drivers/serial/serial_cs.c b/drivers/serial/serial_cs.c index fe7adcdfde9e..141c69554bd4 100644 --- a/drivers/serial/serial_cs.c +++ b/drivers/serial/serial_cs.c @@ -335,8 +335,8 @@ static int serial_probe(struct pcmcia_device *link) info->p_dev = link; link->priv = info; - link->io.Attributes1 = IO_DATA_PATH_WIDTH_8; - link->io.NumPorts1 = 8; + link->resource[0]->flags |= IO_DATA_PATH_WIDTH_8; + link->resource[0]->end = 8; link->conf.Attributes = CONF_ENABLE_IRQ; if (do_sound) { link->conf.Attributes |= CONF_ENABLE_SPKR; @@ -424,12 +424,13 @@ static int simple_config_check(struct pcmcia_device *p_dev, p_dev->conf.Vpp = cf->vpp1.param[CISTPL_POWER_VNOM] / 10000; + p_dev->io_lines = ((*try & 0x1) == 0) ? + 16 : cf->io.flags & CISTPL_IO_LINES_MASK; + if ((cf->io.nwin > 0) && (cf->io.win[0].len == size_table[(*try >> 1)]) && (cf->io.win[0].base != 0)) { - p_dev->io.BasePort1 = cf->io.win[0].base; - p_dev->io.IOAddrLines = ((*try & 0x1) == 0) ? - 16 : cf->io.flags & CISTPL_IO_LINES_MASK; - if (!pcmcia_request_io(p_dev, &p_dev->io)) + p_dev->resource[0]->start = cf->io.win[0].base; + if (!pcmcia_request_io(p_dev)) return 0; } return -EINVAL; @@ -446,9 +447,9 @@ static int simple_config_check_notpicky(struct pcmcia_device *p_dev, if ((cf->io.nwin > 0) && ((cf->io.flags & CISTPL_IO_LINES_MASK) <= 3)) { for (j = 0; j < 5; j++) { - p_dev->io.BasePort1 = base[j]; - p_dev->io.IOAddrLines = base[j] ? 16 : 3; - if (!pcmcia_request_io(p_dev, &p_dev->io)) + p_dev->resource[0]->start = base[j]; + p_dev->io_lines = base[j] ? 16 : 3; + if (!pcmcia_request_io(p_dev)) return 0; } } @@ -521,9 +522,9 @@ static int multi_config_check(struct pcmcia_device *p_dev, /* The quad port cards have bad CIS's, so just look for a window larger than 8 ports and assume it will be right */ if ((cf->io.nwin == 1) && (cf->io.win[0].len > 8)) { - p_dev->io.BasePort1 = cf->io.win[0].base; - p_dev->io.IOAddrLines = cf->io.flags & CISTPL_IO_LINES_MASK; - if (!pcmcia_request_io(p_dev, &p_dev->io)) { + p_dev->resource[0]->start = cf->io.win[0].base; + p_dev->io_lines = cf->io.flags & CISTPL_IO_LINES_MASK; + if (!pcmcia_request_io(p_dev)) { *base2 = p_dev->resource[0]->start + 8; return 0; } @@ -540,10 +541,10 @@ static int multi_config_check_notpicky(struct pcmcia_device *p_dev, int *base2 = priv_data; if (cf->io.nwin == 2) { - p_dev->io.BasePort1 = cf->io.win[0].base; - p_dev->io.BasePort2 = cf->io.win[1].base; - p_dev->io.IOAddrLines = cf->io.flags & CISTPL_IO_LINES_MASK; - if (!pcmcia_request_io(p_dev, &p_dev->io)) { + p_dev->resource[0]->start = cf->io.win[0].base; + p_dev->resource[1]->start = cf->io.win[1].base; + p_dev->io_lines = cf->io.flags & CISTPL_IO_LINES_MASK; + if (!pcmcia_request_io(p_dev)) { *base2 = p_dev->resource[1]->start; return 0; } @@ -557,10 +558,10 @@ static int multi_config(struct pcmcia_device *link) int i, base2 = 0; /* First, look for a generic full-sized window */ - link->io.NumPorts1 = info->multi * 8; + link->resource[0]->end = info->multi * 8; if (pcmcia_loop_config(link, multi_config_check, &base2)) { /* If that didn't work, look for two windows */ - link->io.NumPorts1 = link->io.NumPorts2 = 8; + link->resource[0]->end = link->resource[1]->end = 8; info->multi = 2; if (pcmcia_loop_config(link, multi_config_check_notpicky, &base2)) { diff --git a/drivers/staging/comedi/drivers/cb_das16_cs.c b/drivers/staging/comedi/drivers/cb_das16_cs.c index 208f1b7a1312..7cf0ccb5adef 100644 --- a/drivers/staging/comedi/drivers/cb_das16_cs.c +++ b/drivers/staging/comedi/drivers/cb_das16_cs.c @@ -736,24 +736,22 @@ static int das16cs_pcmcia_config_loop(struct pcmcia_device *p_dev, p_dev->conf.Attributes |= CONF_ENABLE_IRQ; /* IO window settings */ - p_dev->io.NumPorts1 = p_dev->io.NumPorts2 = 0; + p_dev->resource[0]->end = p_dev->resource[1]->end = 0; if ((cfg->io.nwin > 0) || (dflt->io.nwin > 0)) { cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt->io; - p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO; - if (!(io->flags & CISTPL_IO_8BIT)) - p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_16; - if (!(io->flags & CISTPL_IO_16BIT)) - p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_8; - p_dev->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK; - p_dev->io.BasePort1 = io->win[0].base; - p_dev->io.NumPorts1 = io->win[0].len; + p_dev->io_lines = io->flags & CISTPL_IO_LINES_MASK; + p_dev->resource[0]->flags &= ~IO_DATA_PATH_WIDTH; + p_dev->resource[0]->flags |= + pcmcia_io_cfg_data_width(io->flags); + p_dev->resource[0]->start = io->win[0].base; + p_dev->resource[0]->end = io->win[0].len; if (io->nwin > 1) { - p_dev->io.Attributes2 = p_dev->io.Attributes1; - p_dev->io.BasePort2 = io->win[1].base; - p_dev->io.NumPorts2 = io->win[1].len; + p_dev->resource[1]->flags = p_dev->resource[0]->flags; + p_dev->resource[1]->start = io->win[1].base; + p_dev->resource[1]->end = io->win[1].len; } /* This reserves IO space but doesn't actually enable it */ - return pcmcia_request_io(p_dev, &p_dev->io); + return pcmcia_request_io(p_dev); } return 0; diff --git a/drivers/staging/comedi/drivers/das08_cs.c b/drivers/staging/comedi/drivers/das08_cs.c index c4cfcffc633e..9ee677f14b66 100644 --- a/drivers/staging/comedi/drivers/das08_cs.c +++ b/drivers/staging/comedi/drivers/das08_cs.c @@ -224,24 +224,23 @@ static int das08_pcmcia_config_loop(struct pcmcia_device *p_dev, p_dev->conf.Attributes |= CONF_ENABLE_IRQ; /* IO window settings */ - p_dev->io.NumPorts1 = p_dev->io.NumPorts2 = 0; + p_dev->resource[0]->end = p_dev->resource[1]->end = 0; if ((cfg->io.nwin > 0) || (dflt->io.nwin > 0)) { cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt->io; - p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO; - if (!(io->flags & CISTPL_IO_8BIT)) - p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_16; - if (!(io->flags & CISTPL_IO_16BIT)) - p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_8; + p_dev->io_lines = io->flags & CISTPL_IO_LINES_MASK; + p_dev->resource[0]->flags &= ~IO_DATA_PATH_WIDTH; + p_dev->resource[0]->flags |= + pcmcia_io_cfg_data_width(io->flags); p_dev->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK; - p_dev->io.BasePort1 = io->win[0].base; - p_dev->io.NumPorts1 = io->win[0].len; + p_dev->resource[0]->start = io->win[0].base; + p_dev->resource[0]->end = io->win[0].len; if (io->nwin > 1) { - p_dev->io.Attributes2 = p_dev->io.Attributes1; - p_dev->io.BasePort2 = io->win[1].base; - p_dev->io.NumPorts2 = io->win[1].len; + p_dev->resource[1]->flags = p_dev->resource[0]->flags; + p_dev->resource[1]->start = io->win[1].base; + p_dev->resource[1]->end = io->win[1].len; } /* This reserves IO space but doesn't actually enable it */ - return pcmcia_request_io(p_dev, &p_dev->io); + return pcmcia_request_io(p_dev); } return 0; } diff --git a/drivers/staging/comedi/drivers/ni_daq_700.c b/drivers/staging/comedi/drivers/ni_daq_700.c index 6d569579d677..7e41ad93703d 100644 --- a/drivers/staging/comedi/drivers/ni_daq_700.c +++ b/drivers/staging/comedi/drivers/ni_daq_700.c @@ -571,24 +571,22 @@ static int dio700_pcmcia_config_loop(struct pcmcia_device *p_dev, p_dev->conf.Attributes |= CONF_ENABLE_IRQ; /* IO window settings */ - p_dev->io.NumPorts1 = p_dev->io.NumPorts2 = 0; + p_dev->resource[0]->end = p_dev->resource[1]->end = 0; if ((cfg->io.nwin > 0) || (dflt->io.nwin > 0)) { cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt->io; - p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO; - if (!(io->flags & CISTPL_IO_8BIT)) - p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_16; - if (!(io->flags & CISTPL_IO_16BIT)) - p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_8; - p_dev->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK; - p_dev->io.BasePort1 = io->win[0].base; - p_dev->io.NumPorts1 = io->win[0].len; + p_dev->io_lines = io->flags & CISTPL_IO_LINES_MASK; + p_dev->resource[0]->flags &= ~IO_DATA_PATH_WIDTH; + p_dev->resource[0]->flags |= + pcmcia_io_cfg_data_width(io->flags); + p_dev->resource[0]->start = io->win[0].base; + p_dev->resource[0]->end = io->win[0].len; if (io->nwin > 1) { - p_dev->io.Attributes2 = p_dev->io.Attributes1; - p_dev->io.BasePort2 = io->win[1].base; - p_dev->io.NumPorts2 = io->win[1].len; + p_dev->resource[1]->flags = p_dev->resource[0]->flags; + p_dev->resource[1]->start = io->win[1].base; + p_dev->resource[1]->end = io->win[1].len; } /* This reserves IO space but doesn't actually enable it */ - if (pcmcia_request_io(p_dev, &p_dev->io) != 0) + if (pcmcia_request_io(p_dev) != 0) return -ENODEV; } diff --git a/drivers/staging/comedi/drivers/ni_daq_dio24.c b/drivers/staging/comedi/drivers/ni_daq_dio24.c index 29e1daf6a9e6..b2483f86c242 100644 --- a/drivers/staging/comedi/drivers/ni_daq_dio24.c +++ b/drivers/staging/comedi/drivers/ni_daq_dio24.c @@ -323,24 +323,22 @@ static int dio24_pcmcia_config_loop(struct pcmcia_device *p_dev, p_dev->conf.Attributes |= CONF_ENABLE_IRQ; /* IO window settings */ - p_dev->io.NumPorts1 = p_dev->io.NumPorts2 = 0; + p_dev->resource[0]->end = p_dev->resource[1]->end = 0; if ((cfg->io.nwin > 0) || (dflt->io.nwin > 0)) { cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt->io; - p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO; - if (!(io->flags & CISTPL_IO_8BIT)) - p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_16; - if (!(io->flags & CISTPL_IO_16BIT)) - p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_8; - p_dev->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK; - p_dev->io.BasePort1 = io->win[0].base; - p_dev->io.NumPorts1 = io->win[0].len; + p_dev->io_lines = io->flags & CISTPL_IO_LINES_MASK; + p_dev->resource[0]->flags &= ~IO_DATA_PATH_WIDTH; + p_dev->resource[0]->flags |= + pcmcia_io_cfg_data_width(io->flags); + p_dev->resource[0]->start = io->win[0].base; + p_dev->resource[0]->end = io->win[0].len; if (io->nwin > 1) { - p_dev->io.Attributes2 = p_dev->io.Attributes1; - p_dev->io.BasePort2 = io->win[1].base; - p_dev->io.NumPorts2 = io->win[1].len; + p_dev->resource[1]->flags = p_dev->resource[0]->flags; + p_dev->resource[1]->start = io->win[1].base; + p_dev->resource[1]->end = io->win[1].len; } /* This reserves IO space but doesn't actually enable it */ - if (pcmcia_request_io(p_dev, &p_dev->io) != 0) + if (pcmcia_request_io(p_dev) != 0) return -ENODEV; } diff --git a/drivers/staging/comedi/drivers/ni_labpc_cs.c b/drivers/staging/comedi/drivers/ni_labpc_cs.c index fb10987a97b2..c1444b4a5b4c 100644 --- a/drivers/staging/comedi/drivers/ni_labpc_cs.c +++ b/drivers/staging/comedi/drivers/ni_labpc_cs.c @@ -301,24 +301,22 @@ static int labpc_pcmcia_config_loop(struct pcmcia_device *p_dev, p_dev->conf.Attributes |= CONF_ENABLE_IRQ | CONF_ENABLE_PULSE_IRQ; /* IO window settings */ - p_dev->io.NumPorts1 = p_dev->io.NumPorts2 = 0; + p_dev->resource[0]->end = p_dev->resource[1]->end = 0; if ((cfg->io.nwin > 0) || (dflt->io.nwin > 0)) { cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt->io; - p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO; - if (!(io->flags & CISTPL_IO_8BIT)) - p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_16; - if (!(io->flags & CISTPL_IO_16BIT)) - p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_8; - p_dev->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK; - p_dev->io.BasePort1 = io->win[0].base; - p_dev->io.NumPorts1 = io->win[0].len; + p_dev->io_lines = io->flags & CISTPL_IO_LINES_MASK; + p_dev->resource[0]->flags &= ~IO_DATA_PATH_WIDTH; + p_dev->resource[0]->flags |= + pcmcia_io_cfg_data_width(io->flags); + p_dev->resource[0]->start = io->win[0].base; + p_dev->resource[0]->end = io->win[0].len; if (io->nwin > 1) { - p_dev->io.Attributes2 = p_dev->io.Attributes1; - p_dev->io.BasePort2 = io->win[1].base; - p_dev->io.NumPorts2 = io->win[1].len; + p_dev->resource[1]->flags = p_dev->resource[0]->flags; + p_dev->resource[1]->start = io->win[1].base; + p_dev->resource[1]->end = io->win[1].len; } /* This reserves IO space but doesn't actually enable it */ - if (pcmcia_request_io(p_dev, &p_dev->io) != 0) + if (pcmcia_request_io(p_dev) != 0) return -ENODEV; } diff --git a/drivers/staging/comedi/drivers/ni_mio_cs.c b/drivers/staging/comedi/drivers/ni_mio_cs.c index f37dc22b4dbc..d50b6c409fe7 100644 --- a/drivers/staging/comedi/drivers/ni_mio_cs.c +++ b/drivers/staging/comedi/drivers/ni_mio_cs.c @@ -264,8 +264,8 @@ static const dev_info_t dev_info = "ni_mio_cs"; static int cs_attach(struct pcmcia_device *link) { - link->io.Attributes1 = IO_DATA_PATH_WIDTH_16; - link->io.NumPorts1 = 16; + link->resource[0]->flags |= IO_DATA_PATH_WIDTH_16; + link->resource[0]->end = 16; link->conf.Attributes = CONF_ENABLE_IRQ; link->conf.IntType = INT_MEMORY_AND_IO; @@ -310,13 +310,12 @@ static int mio_pcmcia_config_loop(struct pcmcia_device *p_dev, { int base, ret; - p_dev->io.NumPorts1 = cfg->io.win[0].len; - p_dev->io.IOAddrLines = cfg->io.flags & CISTPL_IO_LINES_MASK; - p_dev->io.NumPorts2 = 0; + p_dev->resource[0]->end = cfg->io.win[0].len; + p_dev->io_lines = cfg->io.flags & CISTPL_IO_LINES_MASK; for (base = 0x000; base < 0x400; base += 0x20) { - p_dev->io.BasePort1 = base; - ret = pcmcia_request_io(p_dev, &p_dev->io); + p_dev->resource[0]->start = base; + ret = pcmcia_request_io(p_dev); if (!ret) return 0; } diff --git a/drivers/staging/comedi/drivers/quatech_daqp_cs.c b/drivers/staging/comedi/drivers/quatech_daqp_cs.c index 80b8d57c6842..25f4e67e3e89 100644 --- a/drivers/staging/comedi/drivers/quatech_daqp_cs.c +++ b/drivers/staging/comedi/drivers/quatech_daqp_cs.c @@ -1102,26 +1102,24 @@ static int daqp_pcmcia_config_loop(struct pcmcia_device *p_dev, p_dev->conf.Attributes |= CONF_ENABLE_IRQ; /* IO window settings */ - p_dev->io.NumPorts1 = p_dev->io.NumPorts2 = 0; + p_dev->resource[0]->end = p_dev->resource[1]->end = 0; if ((cfg->io.nwin > 0) || (dflt->io.nwin > 0)) { cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt->io; - p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO; - if (!(io->flags & CISTPL_IO_8BIT)) - p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_16; - if (!(io->flags & CISTPL_IO_16BIT)) - p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_8; - p_dev->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK; - p_dev->io.BasePort1 = io->win[0].base; - p_dev->io.NumPorts1 = io->win[0].len; + p_dev->io_lines = io->flags & CISTPL_IO_LINES_MASK; + p_dev->resource[0]->flags &= ~IO_DATA_PATH_WIDTH; + p_dev->resource[0]->flags |= + pcmcia_io_cfg_data_width(io->flags); + p_dev->resource[0]->start = io->win[0].base; + p_dev->resource[0]->end = io->win[0].len; if (io->nwin > 1) { - p_dev->io.Attributes2 = p_dev->io.Attributes1; - p_dev->io.BasePort2 = io->win[1].base; - p_dev->io.NumPorts2 = io->win[1].len; + p_dev->resource[1]->flags = p_dev->resource[0]->flags; + p_dev->resource[1]->start = io->win[1].base; + p_dev->resource[1]->end = io->win[1].len; } } /* This reserves IO space but doesn't actually enable it */ - return pcmcia_request_io(p_dev, &p_dev->io); + return pcmcia_request_io(p_dev); } static void daqp_cs_config(struct pcmcia_device *link) diff --git a/drivers/staging/wlags49_h2/wl_cs.c b/drivers/staging/wlags49_h2/wl_cs.c index 23615378acf1..f15afd2050be 100644 --- a/drivers/staging/wlags49_h2/wl_cs.c +++ b/drivers/staging/wlags49_h2/wl_cs.c @@ -145,9 +145,8 @@ static int wl_adapter_attach(struct pcmcia_device *link) return -ENOMEM; } - link->io.NumPorts1 = HCF_NUM_IO_PORTS; - link->io.Attributes1 = IO_DATA_PATH_WIDTH_16; - link->io.IOAddrLines = 6; + link->resource[0]->end = HCF_NUM_IO_PORTS; + link->resource[0]->flags = IO_DATA_PATH_WIDTH_16; link->conf.Attributes = CONF_ENABLE_IRQ; link->conf.IntType = INT_MEMORY_AND_IO; link->conf.ConfigIndex = 5; @@ -305,8 +304,9 @@ void wl_adapter_insert( struct pcmcia_device *link ) /* Do we need to allocate an interrupt? */ link->conf.Attributes |= CONF_ENABLE_IRQ; + link->io_lines = 6; - ret = pcmcia_request_io(link, &link->io); + ret = pcmcia_request_io(link); if (ret != 0) goto failed; diff --git a/drivers/telephony/ixj_pcmcia.c b/drivers/telephony/ixj_pcmcia.c index a801036392cd..a1900e502518 100644 --- a/drivers/telephony/ixj_pcmcia.c +++ b/drivers/telephony/ixj_pcmcia.c @@ -32,9 +32,8 @@ static int ixj_probe(struct pcmcia_device *p_dev) { dev_dbg(&p_dev->dev, "ixj_attach()\n"); /* Create new ixj device */ - p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_8; - p_dev->io.Attributes2 = IO_DATA_PATH_WIDTH_8; - p_dev->io.IOAddrLines = 3; + p_dev->resource[0]->flags |= IO_DATA_PATH_WIDTH_8; + p_dev->resource[1]->flags |= IO_DATA_PATH_WIDTH_8; p_dev->conf.IntType = INT_MEMORY_AND_IO; p_dev->priv = kzalloc(sizeof(struct ixj_info_t), GFP_KERNEL); if (!p_dev->priv) { @@ -120,13 +119,14 @@ static int ixj_config_check(struct pcmcia_device *p_dev, { if ((cfg->io.nwin > 0) || (dflt->io.nwin > 0)) { cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt->io; - p_dev->io.BasePort1 = io->win[0].base; - p_dev->io.NumPorts1 = io->win[0].len; + p_dev->resource[0]->start = io->win[0].base; + p_dev->resource[0]->end = io->win[0].len; + p_dev->io_lines = 3; if (io->nwin == 2) { - p_dev->io.BasePort2 = io->win[1].base; - p_dev->io.NumPorts2 = io->win[1].len; + p_dev->resource[1]->start = io->win[1].base; + p_dev->resource[1]->end = io->win[1].len; } - if (!pcmcia_request_io(p_dev, &p_dev->io)) + if (!pcmcia_request_io(p_dev)) return 0; } return -ENODEV; diff --git a/drivers/usb/host/sl811_cs.c b/drivers/usb/host/sl811_cs.c index 22e04f206304..0e13a00eb2ed 100644 --- a/drivers/usb/host/sl811_cs.c +++ b/drivers/usb/host/sl811_cs.c @@ -162,16 +162,16 @@ static int sl811_cs_config_check(struct pcmcia_device *p_dev, p_dev->conf.Attributes |= CONF_ENABLE_IRQ; /* IO window settings */ - p_dev->io.NumPorts1 = p_dev->io.NumPorts2 = 0; + p_dev->resource[0]->end = p_dev->resource[1]->end = 0; if ((cfg->io.nwin > 0) || (dflt->io.nwin > 0)) { cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt->io; + p_dev->io_lines = io->flags & CISTPL_IO_LINES_MASK; - p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_8; - p_dev->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK; - p_dev->io.BasePort1 = io->win[0].base; - p_dev->io.NumPorts1 = io->win[0].len; + p_dev->resource[0]->flags |= IO_DATA_PATH_WIDTH_8; + p_dev->resource[0]->start = io->win[0].base; + p_dev->resource[0]->end = io->win[0].len; - return pcmcia_request_io(p_dev, &p_dev->io); + return pcmcia_request_io(p_dev); } pcmcia_disable_device(p_dev); return -ENODEV; diff --git a/include/pcmcia/cs.h b/include/pcmcia/cs.h index 0cd8c70d8aaa..ad71bb5a8658 100644 --- a/include/pcmcia/cs.h +++ b/include/pcmcia/cs.h @@ -56,23 +56,6 @@ typedef struct config_req_t { #define INT_CARDBUS 0x04 #define INT_ZOOMED_VIDEO 0x08 -/* For RequestIO and ReleaseIO */ -typedef struct io_req_t { - u_int BasePort1; - u_int NumPorts1; - u_int Attributes1; - u_int BasePort2; - u_int NumPorts2; - u_int Attributes2; - u_int IOAddrLines; -} io_req_t; - -/* Attributes for RequestIO and ReleaseIO */ -#define IO_DATA_PATH_WIDTH 0x18 -#define IO_DATA_PATH_WIDTH_8 0x00 -#define IO_DATA_PATH_WIDTH_16 0x08 -#define IO_DATA_PATH_WIDTH_AUTO 0x10 - /* Bits in IRQInfo1 field */ #define IRQ_NMI_ID 0x01 #define IRQ_IOCK_ID 0x02 diff --git a/include/pcmcia/ds.h b/include/pcmcia/ds.h index 3dafd7db34df..0748bec0a87a 100644 --- a/include/pcmcia/ds.h +++ b/include/pcmcia/ds.h @@ -80,7 +80,6 @@ struct pcmcia_device { struct list_head socket_device_list; /* deprecated, will be cleaned up soon */ - io_req_t io; config_req_t conf; window_handle_t win; @@ -88,6 +87,8 @@ struct pcmcia_device { unsigned int irq; struct resource *resource[MAX_IO_WIN]; + unsigned int io_lines; /* number of I/O lines */ + /* Is the device suspended? */ u16 suspended:1; @@ -179,7 +180,7 @@ int pcmcia_read_config_byte(struct pcmcia_device *p_dev, off_t where, u8 *val); int pcmcia_write_config_byte(struct pcmcia_device *p_dev, off_t where, u8 val); /* device configuration */ -int pcmcia_request_io(struct pcmcia_device *p_dev, io_req_t *req); +int pcmcia_request_io(struct pcmcia_device *p_dev); int __must_check __pcmcia_request_exclusive_irq(struct pcmcia_device *p_dev, @@ -206,6 +207,22 @@ int pcmcia_map_mem_page(struct pcmcia_device *p_dev, window_handle_t win, int pcmcia_modify_configuration(struct pcmcia_device *p_dev, modconf_t *mod); void pcmcia_disable_device(struct pcmcia_device *p_dev); +/* IO ports */ +#define IO_DATA_PATH_WIDTH 0x18 +#define IO_DATA_PATH_WIDTH_8 0x00 +#define IO_DATA_PATH_WIDTH_16 0x08 +#define IO_DATA_PATH_WIDTH_AUTO 0x10 + +/* convert flag found in cfgtable to data path width parameter */ +static inline int pcmcia_io_cfg_data_width(unsigned int flags) +{ + if (!(flags & CISTPL_IO_8BIT)) + return IO_DATA_PATH_WIDTH_16; + if (!(flags & CISTPL_IO_16BIT)) + return IO_DATA_PATH_WIDTH_8; + return IO_DATA_PATH_WIDTH_AUTO; +} + #endif /* __KERNEL__ */ #endif /* _LINUX_DS_H */ diff --git a/sound/pcmcia/pdaudiocf/pdaudiocf.c b/sound/pcmcia/pdaudiocf/pdaudiocf.c index 9f897bca0615..7ab9174a8a84 100644 --- a/sound/pcmcia/pdaudiocf/pdaudiocf.c +++ b/sound/pcmcia/pdaudiocf/pdaudiocf.c @@ -139,8 +139,8 @@ static int snd_pdacf_probe(struct pcmcia_device *link) pdacf->p_dev = link; link->priv = pdacf; - link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO; - link->io.NumPorts1 = 16; + link->resource[0]->flags |= IO_DATA_PATH_WIDTH_AUTO; + link->resource[0]->end = 16; link->conf.Attributes = CONF_ENABLE_IRQ | CONF_ENABLE_PULSE_IRQ; link->conf.IntType = INT_MEMORY_AND_IO; @@ -219,7 +219,7 @@ static int pdacf_config(struct pcmcia_device *link) snd_printdd(KERN_DEBUG "pdacf_config called\n"); link->conf.ConfigIndex = 0x5; - ret = pcmcia_request_io(link, &link->io); + ret = pcmcia_request_io(link); if (ret) goto failed; diff --git a/sound/pcmcia/vx/vxpocket.c b/sound/pcmcia/vx/vxpocket.c index f23c235013a4..a6edfc3be29a 100644 --- a/sound/pcmcia/vx/vxpocket.c +++ b/sound/pcmcia/vx/vxpocket.c @@ -159,8 +159,8 @@ static int snd_vxpocket_new(struct snd_card *card, int ibl, vxp->p_dev = link; link->priv = chip; - link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO; - link->io.NumPorts1 = 16; + link->resource[0]->flags |= IO_DATA_PATH_WIDTH_AUTO; + link->resource[0]->end = 16; link->conf.Attributes = CONF_ENABLE_IRQ; link->conf.IntType = INT_MEMORY_AND_IO; @@ -226,7 +226,7 @@ static int vxpocket_config(struct pcmcia_device *link) strcpy(chip->card->driver, vxp440_hw.name); } - ret = pcmcia_request_io(link, &link->io); + ret = pcmcia_request_io(link); if (ret) goto failed; -- cgit v1.2.3