···4445Again, keep in mind that this list assumes you are already46functionally running a Linux 2.4 kernel. Also, not all tools are47-necessary on all systems; obviously, if you don't have any PCMCIA (PC48-Card) hardware, for example, you probably needn't concern yourself49-with pcmcia-cs.5051o Gnu C 2.95.3 # gcc --version52o Gnu make 3.79.1 # make --version···57o jfsutils 1.1.3 # fsck.jfs -V58o reiserfsprogs 3.6.3 # reiserfsck -V 2>&1|grep reiserfsprogs59o xfsprogs 2.6.0 # xfs_db -V060o pcmcia-cs 3.1.21 # cardmgr -V61o quota-tools 3.09 # quota -V62o PPP 2.4.0 # pppd --version···187work correctly with this version of the XFS kernel code (2.6.0 or188later is recommended, due to some significant improvements).1890000000190191Pcmcia-cs192---------193194PCMCIA (PC Card) support is now partially implemented in the main195-kernel source. Pay attention when you recompile your kernel ;-).196-Also, be sure to upgrade to the latest pcmcia-cs release.197198Quota-tools199-----------···357--------358o <ftp://oss.sgi.com/projects/xfs/download/>3590000360Pcmcia-cs361---------362-o <ftp://pcmcia-cs.sourceforge.net/pub/pcmcia-cs/pcmcia-cs-3.1.21.tar.gz>363364Quota-tools365----------
···4445Again, keep in mind that this list assumes you are already46functionally running a Linux 2.4 kernel. Also, not all tools are47+necessary on all systems; obviously, if you don't have any ISDN48+hardware, for example, you probably needn't concern yourself with49+isdn4k-utils.5051o Gnu C 2.95.3 # gcc --version52o Gnu make 3.79.1 # make --version···57o jfsutils 1.1.3 # fsck.jfs -V58o reiserfsprogs 3.6.3 # reiserfsck -V 2>&1|grep reiserfsprogs59o xfsprogs 2.6.0 # xfs_db -V60+o pcmciautils 00161o pcmcia-cs 3.1.21 # cardmgr -V62o quota-tools 3.09 # quota -V63o PPP 2.4.0 # pppd --version···186work correctly with this version of the XFS kernel code (2.6.0 or187later is recommended, due to some significant improvements).188189+PCMCIAutils190+-----------191+192+PCMCIAutils replaces pcmcia-cs (see below). It properly sets up193+PCMCIA sockets at system startup and loads the appropriate modules194+for 16-bit PCMCIA devices if the kernel is modularized and the hotplug195+subsystem is used.196197Pcmcia-cs198---------199200PCMCIA (PC Card) support is now partially implemented in the main201+kernel source. The "pcmciautils" package (see above) replaces pcmcia-cs202+for newest kernels.203204Quota-tools205-----------···349--------350o <ftp://oss.sgi.com/projects/xfs/download/>351352+Pcmciautils353+-----------354+o <ftp://ftp.kernel.org/pub/linux/utils/kernel/pcmcia/>355+356Pcmcia-cs357---------358+o <http://pcmcia-cs.sourceforge.net/>359360Quota-tools361----------
···1+Matching of PCMCIA devices to drivers is done using one or more of the2+following criteria:3+4+- manufactor ID5+- card ID6+- product ID strings _and_ hashes of these strings7+- function ID8+- device function (actual and pseudo)9+10+You should use the helpers in include/pcmcia/device_id.h for generating the11+struct pcmcia_device_id[] entries which match devices to drivers.12+13+If you want to match product ID strings, you also need to pass the crc3214+hashes of the string to the macro, e.g. if you want to match the product ID15+string 1, you need to use16+17+PCMCIA_DEVICE_PROD_ID1("some_string", 0x(hash_of_some_string)),18+19+If the hash is incorrect, the kernel will inform you about this in "dmesg"20+upon module initialization, and tell you of the correct hash.21+22+You can determine the hash of the product ID strings by running23+"pcmcia-modalias %n.%m" [%n being replaced with the socket number and %m being24+replaced with the device function] from pcmciautils. It generates a string25+in the following form:26+pcmcia:m0149cC1ABf06pfn00fn00pa725B842DpbF1EFEE84pc0877B627pd0000000027+28+The hex value after "pa" is the hash of product ID string 1, after "pb" for29+string 2 and so on.30+31+Alternatively, you can use this small tool to determine the crc32 hash.32+simply pass the string you want to evaluate as argument to this program,33+e.g.34+$ ./crc32hash "Dual Speed"35+36+-------------------------------------------------------------------------37+/* crc32hash.c - derived from linux/lib/crc32.c, GNU GPL v2 */38+#include <string.h>39+#include <stdio.h>40+#include <ctype.h>41+#include <stdlib.h>42+43+unsigned int crc32(unsigned char const *p, unsigned int len)44+{45+ int i;46+ unsigned int crc = 0;47+ while (len--) {48+ crc ^= *p++;49+ for (i = 0; i < 8; i++)50+ crc = (crc >> 1) ^ ((crc & 1) ? 0xedb88320 : 0);51+ }52+ return crc;53+}54+55+int main(int argc, char **argv) {56+ unsigned int result;57+ if (argc != 2) {58+ printf("no string passed as argument\n");59+ return -1;60+ }61+ result = crc32(argv[1], strlen(argv[1]));62+ printf("0x%x\n", result);63+ return 0;64+}
···1+This file details changes in 2.6 which affect PCMCIA card driver authors:2+3+* in-kernel device<->driver matching4+ PCMCIA devices and their correct drivers can now be matched in5+ kernelspace. See 'devicetable.txt' for details.6+7+* Device model integration (as of 2.6.11)8+ A struct pcmcia_device is registered with the device model core,9+ and can be used (e.g. for SET_NETDEV_DEV) by using10+ handle_to_dev(client_handle_t * handle).11+12+* Convert internal I/O port addresses to unsigned long (as of 2.6.11)13+ ioaddr_t should be replaced by kio_addr_t in PCMCIA card drivers.14+15+* irq_mask and irq_list parameters (as of 2.6.11)16+ The irq_mask and irq_list parameters should no longer be used in17+ PCMCIA card drivers. Instead, it is the job of the PCMCIA core to18+ determine which IRQ should be used. Therefore, link->irq.IRQInfo219+ is ignored.20+21+* client->PendingEvents is gone (as of 2.6.11)22+ client->PendingEvents is no longer available.23+24+* client->Attributes are gone (as of 2.6.11)25+ client->Attributes is unused, therefore it is removed from all26+ PCMCIA card drivers27+28+* core functions no longer available (as of 2.6.11)29+ The following functions have been removed from the kernel source30+ because they are unused by all in-kernel drivers, and no external31+ driver was reported to rely on them:32+ pcmcia_get_first_region()33+ pcmcia_get_next_region()34+ pcmcia_modify_window()35+ pcmcia_set_event_mask()36+ pcmcia_get_first_window()37+ pcmcia_get_next_window()38+39+* device list iteration upon module removal (as of 2.6.10)40+ It is no longer necessary to iterate on the driver's internal41+ client list and call the ->detach() function upon module removal.42+43+* Resource management. (as of 2.6.8)44+ Although the PCMCIA subsystem will allocate resources for cards,45+ it no longer marks these resources busy. This means that driver46+ authors are now responsible for claiming your resources as per47+ other drivers in Linux. You should use request_region() to mark48+ your IO regions in-use, and request_mem_region() to mark your49+ memory regions in-use. The name argument should be a pointer to50+ your driver name. Eg, for pcnet_cs, name should point to the51+ string "pcnet_cs".
+1-1
arch/sparc64/kernel/auxio.c
···16#include <asm/ebus.h>17#include <asm/auxio.h>1819-/* This cannot be static, as it is referenced in entry.S */20void __iomem *auxio_register = NULL;2122enum auxio_type {
···16#include <asm/ebus.h>17#include <asm/auxio.h>1819+/* This cannot be static, as it is referenced in irq.c */20void __iomem *auxio_register = NULL;2122enum auxio_type {
···606 <http://www.ite.com.tw/ia/brief_it8172bsp.htm>; picture of the607 board at <http://www.mvista.com/partners/semiconductor/ite.html>.608000000609config BLK_DEV_NS87415610 tristate "NS87415 chipset support"611 help
···606 <http://www.ite.com.tw/ia/brief_it8172bsp.htm>; picture of the607 board at <http://www.mvista.com/partners/semiconductor/ite.html>.608609+config BLK_DEV_IT821X610+ tristate "IT821X IDE support"611+ help612+ This driver adds support for the ITE 8211 IDE controller and the613+ IT 8212 IDE RAID controller in both RAID and pass-through mode.614+615config BLK_DEV_NS87415616 tristate "NS87415 chipset support"617 help
+4
drivers/ide/ide-disk.c
···119{120 unsigned long lba_sects, chs_sects, head, tail;1210000122 /*123 * The ATA spec tells large drives to return124 * C/H/S = 16383/16/63 independent of their size.
···119{120 unsigned long lba_sects, chs_sects, head, tail;121122+ /* No non-LBA info .. so valid! */123+ if (id->cyls == 0)124+ return 1;125+126 /*127 * The ATA spec tells large drives to return128 * C/H/S = 16383/16/63 independent of their size.
···1+2+/*3+ * linux/drivers/ide/pci/it821x.c Version 0.09 December 20044+ *5+ * Copyright (C) 2004 Red Hat <alan@redhat.com>6+ *7+ * May be copied or modified under the terms of the GNU General Public License8+ * Based in part on the ITE vendor provided SCSI driver.9+ *10+ * Documentation available from11+ * http://www.ite.com.tw/pc/IT8212F_V04.pdf12+ * Some other documents are NDA.13+ *14+ * The ITE8212 isn't exactly a standard IDE controller. It has two15+ * modes. In pass through mode then it is an IDE controller. In its smart16+ * mode its actually quite a capable hardware raid controller disguised17+ * as an IDE controller. Smart mode only understands DMA read/write and18+ * identify, none of the fancier commands apply. The IT8211 is identical19+ * in other respects but lacks the raid mode.20+ *21+ * Errata:22+ * o Rev 0x10 also requires master/slave hold the same DMA timings and23+ * cannot do ATAPI MWDMA.24+ * o The identify data for raid volumes lacks CHS info (technically ok)25+ * but also fails to set the LBA28 and other bits. We fix these in26+ * the IDE probe quirk code.27+ * o If you write LBA48 sized I/O's (ie > 256 sector) in smart mode28+ * raid then the controller firmware dies29+ * o Smart mode without RAID doesn't clear all the necessary identify30+ * bits to reduce the command set to the one used31+ *32+ * This has a few impacts on the driver33+ * - In pass through mode we do all the work you would expect34+ * - In smart mode the clocking set up is done by the controller generally35+ * but we must watch the other limits and filter.36+ * - There are a few extra vendor commands that actually talk to the37+ * controller but only work PIO with no IRQ.38+ *39+ * Vendor areas of the identify block in smart mode are used for the40+ * timing and policy set up. Each HDD in raid mode also has a serial41+ * block on the disk. The hardware extra commands are get/set chip status,42+ * rebuild, get rebuild status.43+ *44+ * In Linux the driver supports pass through mode as if the device was45+ * just another IDE controller. If the smart mode is running then46+ * volumes are managed by the controller firmware and each IDE "disk"47+ * is a raid volume. Even more cute - the controller can do automated48+ * hotplug and rebuild.49+ *50+ * The pass through controller itself is a little demented. It has a51+ * flaw that it has a single set of PIO/MWDMA timings per channel so52+ * non UDMA devices restrict each others performance. It also has a53+ * single clock source per channel so mixed UDMA100/133 performance54+ * isn't perfect and we have to pick a clock. Thankfully none of this55+ * matters in smart mode. ATAPI DMA is not currently supported.56+ *57+ * It seems the smart mode is a win for RAID1/RAID10 but otherwise not.58+ *59+ * TODO60+ * - ATAPI UDMA is ok but not MWDMA it seems61+ * - RAID configuration ioctls62+ * - Move to libata once it grows up63+ */64+65+#include <linux/config.h>66+#include <linux/types.h>67+#include <linux/module.h>68+#include <linux/pci.h>69+#include <linux/delay.h>70+#include <linux/hdreg.h>71+#include <linux/ide.h>72+#include <linux/init.h>73+74+#include <asm/io.h>75+76+struct it821x_dev77+{78+ unsigned int smart:1, /* Are we in smart raid mode */79+ timing10:1; /* Rev 0x10 */80+ u8 clock_mode; /* 0, ATA_50 or ATA_66 */81+ u8 want[2][2]; /* Mode/Pri log for master slave */82+ /* We need these for switching the clock when DMA goes on/off83+ The high byte is the 66Mhz timing */84+ u16 pio[2]; /* Cached PIO values */85+ u16 mwdma[2]; /* Cached MWDMA values */86+ u16 udma[2]; /* Cached UDMA values (per drive) */87+};88+89+#define ATA_66 090+#define ATA_50 191+#define ATA_ANY 292+93+#define UDMA_OFF 094+#define MWDMA_OFF 095+96+/*97+ * We allow users to force the card into non raid mode without98+ * flashing the alternative BIOS. This is also neccessary right now99+ * for embedded platforms that cannot run a PC BIOS but are using this100+ * device.101+ */102+103+static int it8212_noraid;104+105+/**106+ * it821x_program - program the PIO/MWDMA registers107+ * @drive: drive to tune108+ *109+ * Program the PIO/MWDMA timing for this channel according to the110+ * current clock.111+ */112+113+static void it821x_program(ide_drive_t *drive, u16 timing)114+{115+ ide_hwif_t *hwif = drive->hwif;116+ struct it821x_dev *itdev = ide_get_hwifdata(hwif);117+ int channel = hwif->channel;118+ u8 conf;119+120+ /* Program PIO/MWDMA timing bits */121+ if(itdev->clock_mode == ATA_66)122+ conf = timing >> 8;123+ else124+ conf = timing & 0xFF;125+ pci_write_config_byte(hwif->pci_dev, 0x54 + 4 * channel, conf);126+}127+128+/**129+ * it821x_program_udma - program the UDMA registers130+ * @drive: drive to tune131+ *132+ * Program the UDMA timing for this drive according to the133+ * current clock.134+ */135+136+static void it821x_program_udma(ide_drive_t *drive, u16 timing)137+{138+ ide_hwif_t *hwif = drive->hwif;139+ struct it821x_dev *itdev = ide_get_hwifdata(hwif);140+ int channel = hwif->channel;141+ int unit = drive->select.b.unit;142+ u8 conf;143+144+ /* Program UDMA timing bits */145+ if(itdev->clock_mode == ATA_66)146+ conf = timing >> 8;147+ else148+ conf = timing & 0xFF;149+ if(itdev->timing10 == 0)150+ pci_write_config_byte(hwif->pci_dev, 0x56 + 4 * channel + unit, conf);151+ else {152+ pci_write_config_byte(hwif->pci_dev, 0x56 + 4 * channel, conf);153+ pci_write_config_byte(hwif->pci_dev, 0x56 + 4 * channel + 1, conf);154+ }155+}156+157+158+/**159+ * it821x_clock_strategy160+ * @hwif: hardware interface161+ *162+ * Select between the 50 and 66Mhz base clocks to get the best163+ * results for this interface.164+ */165+166+static void it821x_clock_strategy(ide_drive_t *drive)167+{168+ ide_hwif_t *hwif = drive->hwif;169+ struct it821x_dev *itdev = ide_get_hwifdata(hwif);170+171+ u8 unit = drive->select.b.unit;172+ ide_drive_t *pair = &hwif->drives[1-unit];173+174+ int clock, altclock;175+ u8 v;176+ int sel = 0;177+178+ if(itdev->want[0][0] > itdev->want[1][0]) {179+ clock = itdev->want[0][1];180+ altclock = itdev->want[1][1];181+ } else {182+ clock = itdev->want[1][1];183+ altclock = itdev->want[0][1];184+ }185+186+ /* Master doesn't care does the slave ? */187+ if(clock == ATA_ANY)188+ clock = altclock;189+190+ /* Nobody cares - keep the same clock */191+ if(clock == ATA_ANY)192+ return;193+ /* No change */194+ if(clock == itdev->clock_mode)195+ return;196+197+ /* Load this into the controller ? */198+ if(clock == ATA_66)199+ itdev->clock_mode = ATA_66;200+ else {201+ itdev->clock_mode = ATA_50;202+ sel = 1;203+ }204+ pci_read_config_byte(hwif->pci_dev, 0x50, &v);205+ v &= ~(1 << (1 + hwif->channel));206+ v |= sel << (1 + hwif->channel);207+ pci_write_config_byte(hwif->pci_dev, 0x50, v);208+209+ /*210+ * Reprogram the UDMA/PIO of the pair drive for the switch211+ * MWDMA will be dealt with by the dma switcher212+ */213+ if(pair && itdev->udma[1-unit] != UDMA_OFF) {214+ it821x_program_udma(pair, itdev->udma[1-unit]);215+ it821x_program(pair, itdev->pio[1-unit]);216+ }217+ /*218+ * Reprogram the UDMA/PIO of our drive for the switch.219+ * MWDMA will be dealt with by the dma switcher220+ */221+ if(itdev->udma[unit] != UDMA_OFF) {222+ it821x_program_udma(drive, itdev->udma[unit]);223+ it821x_program(drive, itdev->pio[unit]);224+ }225+}226+227+/**228+ * it821x_ratemask - Compute available modes229+ * @drive: IDE drive230+ *231+ * Compute the available speeds for the devices on the interface. This232+ * is all modes to ATA133 clipped by drive cable setup.233+ */234+235+static u8 it821x_ratemask (ide_drive_t *drive)236+{237+ u8 mode = 4;238+ if (!eighty_ninty_three(drive))239+ mode = min(mode, (u8)1);240+ return mode;241+}242+243+/**244+ * it821x_tuneproc - tune a drive245+ * @drive: drive to tune246+ * @mode_wanted: the target operating mode247+ *248+ * Load the timing settings for this device mode into the249+ * controller. By the time we are called the mode has been250+ * modified as neccessary to handle the absence of seperate251+ * master/slave timers for MWDMA/PIO.252+ *253+ * This code is only used in pass through mode.254+ */255+256+static void it821x_tuneproc (ide_drive_t *drive, byte mode_wanted)257+{258+ ide_hwif_t *hwif = drive->hwif;259+ struct it821x_dev *itdev = ide_get_hwifdata(hwif);260+ int unit = drive->select.b.unit;261+262+ /* Spec says 89 ref driver uses 88 */263+ static u16 pio[] = { 0xAA88, 0xA382, 0xA181, 0x3332, 0x3121 };264+ static u8 pio_want[] = { ATA_66, ATA_66, ATA_66, ATA_66, ATA_ANY };265+266+ if(itdev->smart)267+ return;268+269+ /* We prefer 66Mhz clock for PIO 0-3, don't care for PIO4 */270+ itdev->want[unit][1] = pio_want[mode_wanted];271+ itdev->want[unit][0] = 1; /* PIO is lowest priority */272+ itdev->pio[unit] = pio[mode_wanted];273+ it821x_clock_strategy(drive);274+ it821x_program(drive, itdev->pio[unit]);275+}276+277+/**278+ * it821x_tune_mwdma - tune a channel for MWDMA279+ * @drive: drive to set up280+ * @mode_wanted: the target operating mode281+ *282+ * Load the timing settings for this device mode into the283+ * controller when doing MWDMA in pass through mode. The caller284+ * must manage the whole lack of per device MWDMA/PIO timings and285+ * the shared MWDMA/PIO timing register.286+ */287+288+static void it821x_tune_mwdma (ide_drive_t *drive, byte mode_wanted)289+{290+ ide_hwif_t *hwif = drive->hwif;291+ struct it821x_dev *itdev = (void *)ide_get_hwifdata(hwif);292+ int unit = drive->select.b.unit;293+ int channel = hwif->channel;294+ u8 conf;295+296+ static u16 dma[] = { 0x8866, 0x3222, 0x3121 };297+ static u8 mwdma_want[] = { ATA_ANY, ATA_66, ATA_ANY };298+299+ itdev->want[unit][1] = mwdma_want[mode_wanted];300+ itdev->want[unit][0] = 2; /* MWDMA is low priority */301+ itdev->mwdma[unit] = dma[mode_wanted];302+ itdev->udma[unit] = UDMA_OFF;303+304+ /* UDMA bits off - Revision 0x10 do them in pairs */305+ pci_read_config_byte(hwif->pci_dev, 0x50, &conf);306+ if(itdev->timing10)307+ conf |= channel ? 0x60: 0x18;308+ else309+ conf |= 1 << (3 + 2 * channel + unit);310+ pci_write_config_byte(hwif->pci_dev, 0x50, conf);311+312+ it821x_clock_strategy(drive);313+ /* FIXME: do we need to program this ? */314+ /* it821x_program(drive, itdev->mwdma[unit]); */315+}316+317+/**318+ * it821x_tune_udma - tune a channel for UDMA319+ * @drive: drive to set up320+ * @mode_wanted: the target operating mode321+ *322+ * Load the timing settings for this device mode into the323+ * controller when doing UDMA modes in pass through.324+ */325+326+static void it821x_tune_udma (ide_drive_t *drive, byte mode_wanted)327+{328+ ide_hwif_t *hwif = drive->hwif;329+ struct it821x_dev *itdev = ide_get_hwifdata(hwif);330+ int unit = drive->select.b.unit;331+ int channel = hwif->channel;332+ u8 conf;333+334+ static u16 udma[] = { 0x4433, 0x4231, 0x3121, 0x2121, 0x1111, 0x2211, 0x1111 };335+ static u8 udma_want[] = { ATA_ANY, ATA_50, ATA_ANY, ATA_66, ATA_66, ATA_50, ATA_66 };336+337+ itdev->want[unit][1] = udma_want[mode_wanted];338+ itdev->want[unit][0] = 3; /* UDMA is high priority */339+ itdev->mwdma[unit] = MWDMA_OFF;340+ itdev->udma[unit] = udma[mode_wanted];341+ if(mode_wanted >= 5)342+ itdev->udma[unit] |= 0x8080; /* UDMA 5/6 select on */343+344+ /* UDMA on. Again revision 0x10 must do the pair */345+ pci_read_config_byte(hwif->pci_dev, 0x50, &conf);346+ if(itdev->timing10)347+ conf &= channel ? 0x9F: 0xE7;348+ else349+ conf &= ~ (1 << (3 + 2 * channel + unit));350+ pci_write_config_byte(hwif->pci_dev, 0x50, conf);351+352+ it821x_clock_strategy(drive);353+ it821x_program_udma(drive, itdev->udma[unit]);354+355+}356+357+/**358+ * config_it821x_chipset_for_pio - set drive timings359+ * @drive: drive to tune360+ * @speed we want361+ *362+ * Compute the best pio mode we can for a given device. We must363+ * pick a speed that does not cause problems with the other device364+ * on the cable.365+ */366+367+static void config_it821x_chipset_for_pio (ide_drive_t *drive, byte set_speed)368+{369+ u8 unit = drive->select.b.unit;370+ ide_hwif_t *hwif = drive->hwif;371+ ide_drive_t *pair = &hwif->drives[1-unit];372+ u8 speed = 0, set_pio = ide_get_best_pio_mode(drive, 255, 5, NULL);373+ u8 pair_pio;374+375+ /* We have to deal with this mess in pairs */376+ if(pair != NULL) {377+ pair_pio = ide_get_best_pio_mode(pair, 255, 5, NULL);378+ /* Trim PIO to the slowest of the master/slave */379+ if(pair_pio < set_pio)380+ set_pio = pair_pio;381+ }382+ it821x_tuneproc(drive, set_pio);383+ speed = XFER_PIO_0 + set_pio;384+ /* XXX - We trim to the lowest of the pair so the other drive385+ will always be fine at this point until we do hotplug passthru */386+387+ if (set_speed)388+ (void) ide_config_drive_speed(drive, speed);389+}390+391+/**392+ * it821x_dma_read - DMA hook393+ * @drive: drive for DMA394+ *395+ * The IT821x has a single timing register for MWDMA and for PIO396+ * operations. As we flip back and forth we have to reload the397+ * clock. In addition the rev 0x10 device only works if the same398+ * timing value is loaded into the master and slave UDMA clock399+ * so we must also reload that.400+ *401+ * FIXME: we could figure out in advance if we need to do reloads402+ */403+404+static void it821x_dma_start(ide_drive_t *drive)405+{406+ ide_hwif_t *hwif = drive->hwif;407+ struct it821x_dev *itdev = ide_get_hwifdata(hwif);408+ int unit = drive->select.b.unit;409+ if(itdev->mwdma[unit] != MWDMA_OFF)410+ it821x_program(drive, itdev->mwdma[unit]);411+ else if(itdev->udma[unit] != UDMA_OFF && itdev->timing10)412+ it821x_program_udma(drive, itdev->udma[unit]);413+ ide_dma_start(drive);414+}415+416+/**417+ * it821x_dma_write - DMA hook418+ * @drive: drive for DMA stop419+ *420+ * The IT821x has a single timing register for MWDMA and for PIO421+ * operations. As we flip back and forth we have to reload the422+ * clock.423+ */424+425+static int it821x_dma_end(ide_drive_t *drive)426+{427+ ide_hwif_t *hwif = drive->hwif;428+ int unit = drive->select.b.unit;429+ struct it821x_dev *itdev = ide_get_hwifdata(hwif);430+ int ret = __ide_dma_end(drive);431+ if(itdev->mwdma[unit] != MWDMA_OFF)432+ it821x_program(drive, itdev->pio[unit]);433+ return ret;434+}435+436+437+/**438+ * it821x_tune_chipset - set controller timings439+ * @drive: Drive to set up440+ * @xferspeed: speed we want to achieve441+ *442+ * Tune the ITE chipset for the desired mode. If we can't achieve443+ * the desired mode then tune for a lower one, but ultimately444+ * make the thing work.445+ */446+447+static int it821x_tune_chipset (ide_drive_t *drive, byte xferspeed)448+{449+450+ ide_hwif_t *hwif = drive->hwif;451+ struct it821x_dev *itdev = ide_get_hwifdata(hwif);452+ u8 speed = ide_rate_filter(it821x_ratemask(drive), xferspeed);453+454+ if(!itdev->smart) {455+ switch(speed) {456+ case XFER_PIO_4:457+ case XFER_PIO_3:458+ case XFER_PIO_2:459+ case XFER_PIO_1:460+ case XFER_PIO_0:461+ it821x_tuneproc(drive, (speed - XFER_PIO_0));462+ break;463+ /* MWDMA tuning is really hard because our MWDMA and PIO464+ timings are kept in the same place. We can switch in the465+ host dma on/off callbacks */466+ case XFER_MW_DMA_2:467+ case XFER_MW_DMA_1:468+ case XFER_MW_DMA_0:469+ it821x_tune_mwdma(drive, (speed - XFER_MW_DMA_0));470+ break;471+ case XFER_UDMA_6:472+ case XFER_UDMA_5:473+ case XFER_UDMA_4:474+ case XFER_UDMA_3:475+ case XFER_UDMA_2:476+ case XFER_UDMA_1:477+ case XFER_UDMA_0:478+ it821x_tune_udma(drive, (speed - XFER_UDMA_0));479+ break;480+ default:481+ return 1;482+ }483+ }484+ /*485+ * In smart mode the clocking is done by the host controller486+ * snooping the mode we picked. The rest of it is not our problem487+ */488+ return ide_config_drive_speed(drive, speed);489+}490+491+/**492+ * config_chipset_for_dma - configure for DMA493+ * @drive: drive to configure494+ *495+ * Called by the IDE layer when it wants the timings set up.496+ */497+498+static int config_chipset_for_dma (ide_drive_t *drive)499+{500+ u8 speed = ide_dma_speed(drive, it821x_ratemask(drive));501+502+ config_it821x_chipset_for_pio(drive, !speed);503+ it821x_tune_chipset(drive, speed);504+ return ide_dma_enable(drive);505+}506+507+/**508+ * it821x_configure_drive_for_dma - set up for DMA transfers509+ * @drive: drive we are going to set up510+ *511+ * Set up the drive for DMA, tune the controller and drive as512+ * required. If the drive isn't suitable for DMA or we hit513+ * other problems then we will drop down to PIO and set up514+ * PIO appropriately515+ */516+517+static int it821x_config_drive_for_dma (ide_drive_t *drive)518+{519+ ide_hwif_t *hwif = drive->hwif;520+521+ if (ide_use_dma(drive)) {522+ if (config_chipset_for_dma(drive))523+ return hwif->ide_dma_on(drive);524+ }525+ config_it821x_chipset_for_pio(drive, 1);526+ return hwif->ide_dma_off_quietly(drive);527+}528+529+/**530+ * ata66_it821x - check for 80 pin cable531+ * @hwif: interface to check532+ *533+ * Check for the presence of an ATA66 capable cable on the534+ * interface. Problematic as it seems some cards don't have535+ * the needed logic onboard.536+ */537+538+static unsigned int __devinit ata66_it821x(ide_hwif_t *hwif)539+{540+ /* The reference driver also only does disk side */541+ return 1;542+}543+544+/**545+ * it821x_fixup - post init callback546+ * @hwif: interface547+ *548+ * This callback is run after the drives have been probed but549+ * before anything gets attached. It allows drivers to do any550+ * final tuning that is needed, or fixups to work around bugs.551+ */552+553+static void __devinit it821x_fixups(ide_hwif_t *hwif)554+{555+ struct it821x_dev *itdev = ide_get_hwifdata(hwif);556+ int i;557+558+ if(!itdev->smart) {559+ /*560+ * If we are in pass through mode then not much561+ * needs to be done, but we do bother to clear the562+ * IRQ mask as we may well be in PIO (eg rev 0x10)563+ * for now and we know unmasking is safe on this chipset.564+ */565+ for (i = 0; i < 2; i++) {566+ ide_drive_t *drive = &hwif->drives[i];567+ if(drive->present)568+ drive->unmask = 1;569+ }570+ return;571+ }572+ /*573+ * Perform fixups on smart mode. We need to "lose" some574+ * capabilities the firmware lacks but does not filter, and575+ * also patch up some capability bits that it forgets to set576+ * in RAID mode.577+ */578+579+ for(i = 0; i < 2; i++) {580+ ide_drive_t *drive = &hwif->drives[i];581+ struct hd_driveid *id;582+ u16 *idbits;583+584+ if(!drive->present)585+ continue;586+ id = drive->id;587+ idbits = (u16 *)drive->id;588+589+ /* Check for RAID v native */590+ if(strstr(id->model, "Integrated Technology Express")) {591+ /* In raid mode the ident block is slightly buggy592+ We need to set the bits so that the IDE layer knows593+ LBA28. LBA48 and DMA ar valid */594+ id->capability |= 3; /* LBA28, DMA */595+ id->command_set_2 |= 0x0400; /* LBA48 valid */596+ id->cfs_enable_2 |= 0x0400; /* LBA48 on */597+ /* Reporting logic */598+ printk(KERN_INFO "%s: IT8212 %sRAID %d volume",599+ drive->name,600+ idbits[147] ? "Bootable ":"",601+ idbits[129]);602+ if(idbits[129] != 1)603+ printk("(%dK stripe)", idbits[146]);604+ printk(".\n");605+ /* Now the core code will have wrongly decided no DMA606+ so we need to fix this */607+ hwif->ide_dma_off_quietly(drive);608+#ifdef CONFIG_IDEDMA_ONLYDISK609+ if (drive->media == ide_disk)610+#endif611+ hwif->ide_dma_check(drive);612+ } else {613+ /* Non RAID volume. Fixups to stop the core code614+ doing unsupported things */615+ id->field_valid &= 1;616+ id->queue_depth = 0;617+ id->command_set_1 = 0;618+ id->command_set_2 &= 0xC400;619+ id->cfsse &= 0xC000;620+ id->cfs_enable_1 = 0;621+ id->cfs_enable_2 &= 0xC400;622+ id->csf_default &= 0xC000;623+ id->word127 = 0;624+ id->dlf = 0;625+ id->csfo = 0;626+ id->cfa_power = 0;627+ printk(KERN_INFO "%s: Performing identify fixups.\n",628+ drive->name);629+ }630+ }631+632+}633+634+/**635+ * init_hwif_it821x - set up hwif structs636+ * @hwif: interface to set up637+ *638+ * We do the basic set up of the interface structure. The IT8212639+ * requires several custom handlers so we override the default640+ * ide DMA handlers appropriately641+ */642+643+static void __devinit init_hwif_it821x(ide_hwif_t *hwif)644+{645+ struct it821x_dev *idev = kmalloc(sizeof(struct it821x_dev), GFP_KERNEL);646+ u8 conf;647+648+ if(idev == NULL) {649+ printk(KERN_ERR "it821x: out of memory, falling back to legacy behaviour.\n");650+ goto fallback;651+ }652+ memset(idev, 0, sizeof(struct it821x_dev));653+ ide_set_hwifdata(hwif, idev);654+655+ pci_read_config_byte(hwif->pci_dev, 0x50, &conf);656+ if(conf & 1) {657+ idev->smart = 1;658+ hwif->atapi_dma = 0;659+ /* Long I/O's although allowed in LBA48 space cause the660+ onboard firmware to enter the twighlight zone */661+ hwif->rqsize = 256;662+ }663+664+ /* Pull the current clocks from 0x50 also */665+ if (conf & (1 << (1 + hwif->channel)))666+ idev->clock_mode = ATA_50;667+ else668+ idev->clock_mode = ATA_66;669+670+ idev->want[0][1] = ATA_ANY;671+ idev->want[1][1] = ATA_ANY;672+673+ /*674+ * Not in the docs but according to the reference driver675+ * this is neccessary.676+ */677+678+ pci_read_config_byte(hwif->pci_dev, 0x08, &conf);679+ if(conf == 0x10) {680+ idev->timing10 = 1;681+ hwif->atapi_dma = 0;682+ if(!idev->smart)683+ printk(KERN_WARNING "it821x: Revision 0x10, workarounds activated.\n");684+ }685+686+ hwif->speedproc = &it821x_tune_chipset;687+ hwif->tuneproc = &it821x_tuneproc;688+689+ /* MWDMA/PIO clock switching for pass through mode */690+ if(!idev->smart) {691+ hwif->dma_start = &it821x_dma_start;692+ hwif->ide_dma_end = &it821x_dma_end;693+ }694+695+ hwif->drives[0].autotune = 1;696+ hwif->drives[1].autotune = 1;697+698+ if (!hwif->dma_base)699+ goto fallback;700+701+ hwif->ultra_mask = 0x7f;702+ hwif->mwdma_mask = 0x07;703+ hwif->swdma_mask = 0x07;704+705+ hwif->ide_dma_check = &it821x_config_drive_for_dma;706+ if (!(hwif->udma_four))707+ hwif->udma_four = ata66_it821x(hwif);708+709+ /*710+ * The BIOS often doesn't set up DMA on this controller711+ * so we always do it.712+ */713+714+ hwif->autodma = 1;715+ hwif->drives[0].autodma = hwif->autodma;716+ hwif->drives[1].autodma = hwif->autodma;717+ return;718+fallback:719+ hwif->autodma = 0;720+ return;721+}722+723+static void __devinit it8212_disable_raid(struct pci_dev *dev)724+{725+ /* Reset local CPU, and set BIOS not ready */726+ pci_write_config_byte(dev, 0x5E, 0x01);727+728+ /* Set to bypass mode, and reset PCI bus */729+ pci_write_config_byte(dev, 0x50, 0x00);730+ pci_write_config_word(dev, PCI_COMMAND,731+ PCI_COMMAND_PARITY | PCI_COMMAND_IO |732+ PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER);733+ pci_write_config_word(dev, 0x40, 0xA0F3);734+735+ pci_write_config_dword(dev,0x4C, 0x02040204);736+ pci_write_config_byte(dev, 0x42, 0x36);737+ pci_write_config_byte(dev, PCI_LATENCY_TIMER, 0);738+}739+740+static unsigned int __devinit init_chipset_it821x(struct pci_dev *dev, const char *name)741+{742+ u8 conf;743+ static char *mode[2] = { "pass through", "smart" };744+745+ /* Force the card into bypass mode if so requested */746+ if (it8212_noraid) {747+ printk(KERN_INFO "it8212: forcing bypass mode.\n");748+ it8212_disable_raid(dev);749+ }750+ pci_read_config_byte(dev, 0x50, &conf);751+ printk(KERN_INFO "it821x: controller in %s mode.\n", mode[conf & 1]);752+ return 0;753+}754+755+756+#define DECLARE_ITE_DEV(name_str) \757+ { \758+ .name = name_str, \759+ .init_chipset = init_chipset_it821x, \760+ .init_hwif = init_hwif_it821x, \761+ .channels = 2, \762+ .autodma = AUTODMA, \763+ .bootable = ON_BOARD, \764+ .fixup = it821x_fixups \765+ }766+767+static ide_pci_device_t it821x_chipsets[] __devinitdata = {768+ /* 0 */ DECLARE_ITE_DEV("IT8212"),769+};770+771+/**772+ * it821x_init_one - pci layer discovery entry773+ * @dev: PCI device774+ * @id: ident table entry775+ *776+ * Called by the PCI code when it finds an ITE821x controller.777+ * We then use the IDE PCI generic helper to do most of the work.778+ */779+780+static int __devinit it821x_init_one(struct pci_dev *dev, const struct pci_device_id *id)781+{782+ ide_setup_pci_device(dev, &it821x_chipsets[id->driver_data]);783+ return 0;784+}785+786+static struct pci_device_id it821x_pci_tbl[] = {787+ { PCI_VENDOR_ID_ITE, PCI_DEVICE_ID_ITE_8211, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},788+ { PCI_VENDOR_ID_ITE, PCI_DEVICE_ID_ITE_8212, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},789+ { 0, },790+};791+792+MODULE_DEVICE_TABLE(pci, it821x_pci_tbl);793+794+static struct pci_driver driver = {795+ .name = "ITE821x IDE",796+ .id_table = it821x_pci_tbl,797+ .probe = it821x_init_one,798+};799+800+static int __init it821x_ide_init(void)801+{802+ return ide_pci_register_driver(&driver);803+}804+805+module_init(it821x_ide_init);806+807+module_param_named(noraid, it8212_noraid, int, S_IRUGO);808+MODULE_PARM_DESC(it8212_noraid, "Force card into bypass mode");809+810+MODULE_AUTHOR("Alan Cox");811+MODULE_DESCRIPTION("PCI driver module for the ITE 821x");812+MODULE_LICENSE("GPL");
+5-5
drivers/ide/pci/serverworks.c
···442 return (dev->irq) ? dev->irq : 0;443}444445-static unsigned int __init ata66_svwks_svwks (ide_hwif_t *hwif)446{447 return 1;448}···454 * Bit 14 clear = primary IDE channel does not have 80-pin cable.455 * Bit 14 set = primary IDE channel has 80-pin cable.456 */457-static unsigned int __init ata66_svwks_dell (ide_hwif_t *hwif)458{459 struct pci_dev *dev = hwif->pci_dev;460 if (dev->subsystem_vendor == PCI_VENDOR_ID_DELL &&···472 *473 * WARNING: this only works on Alpine hardware!474 */475-static unsigned int __init ata66_svwks_cobalt (ide_hwif_t *hwif)476{477 struct pci_dev *dev = hwif->pci_dev;478 if (dev->subsystem_vendor == PCI_VENDOR_ID_SUN &&···483 return 0;484}485486-static unsigned int __init ata66_svwks (ide_hwif_t *hwif)487{488 struct pci_dev *dev = hwif->pci_dev;489···573 return ide_setup_pci_device(dev, d);574}575576-static int __init init_setup_csb6 (struct pci_dev *dev, ide_pci_device_t *d)577{578 if (!(PCI_FUNC(dev->devfn) & 1)) {579 d->bootable = NEVER_BOARD;
···442 return (dev->irq) ? dev->irq : 0;443}444445+static unsigned int __devinit ata66_svwks_svwks (ide_hwif_t *hwif)446{447 return 1;448}···454 * Bit 14 clear = primary IDE channel does not have 80-pin cable.455 * Bit 14 set = primary IDE channel has 80-pin cable.456 */457+static unsigned int __devinit ata66_svwks_dell (ide_hwif_t *hwif)458{459 struct pci_dev *dev = hwif->pci_dev;460 if (dev->subsystem_vendor == PCI_VENDOR_ID_DELL &&···472 *473 * WARNING: this only works on Alpine hardware!474 */475+static unsigned int __devinit ata66_svwks_cobalt (ide_hwif_t *hwif)476{477 struct pci_dev *dev = hwif->pci_dev;478 if (dev->subsystem_vendor == PCI_VENDOR_ID_SUN &&···483 return 0;484}485486+static unsigned int __devinit ata66_svwks (ide_hwif_t *hwif)487{488 struct pci_dev *dev = hwif->pci_dev;489···573 return ide_setup_pci_device(dev, d);574}575576+static int __devinit init_setup_csb6 (struct pci_dev *dev, ide_pci_device_t *d)577{578 if (!(PCI_FUNC(dev->devfn) & 1)) {579 d->bootable = NEVER_BOARD;
+12-19
drivers/input/gameport/gameport.c
···17#include <linux/init.h>18#include <linux/gameport.h>19#include <linux/wait.h>20-#include <linux/completion.h>21#include <linux/sched.h>22-#include <linux/smp_lock.h>23#include <linux/slab.h>24#include <linux/delay.h>02526/*#include <asm/io.h>*/27···237static DEFINE_SPINLOCK(gameport_event_lock); /* protects gameport_event_list */238static LIST_HEAD(gameport_event_list);239static DECLARE_WAIT_QUEUE_HEAD(gameport_wait);240-static DECLARE_COMPLETION(gameport_exited);241-static int gameport_pid;242243static void gameport_queue_event(void *object, struct module *owner,244 enum gameport_event_type event_type)···248 spin_lock_irqsave(&gameport_event_lock, flags);249250 /*251- * Scan event list for the other events for the same gameport port,252 * starting with the most recent one. If event is the same we253 * do not need add new one. If event is of different type we254 * need to add this event and should not look further because255 * we need to preseve sequence of distinct events.256- */257 list_for_each_entry_reverse(event, &gameport_event_list, node) {258 if (event->object == object) {259 if (event->type == event_type)···430431static int gameport_thread(void *nothing)432{433- lock_kernel();434- daemonize("kgameportd");435- allow_signal(SIGTERM);436-437 do {438 gameport_handle_events();439- wait_event_interruptible(gameport_wait, !list_empty(&gameport_event_list));0440 try_to_freeze();441- } while (!signal_pending(current));442443 printk(KERN_DEBUG "gameport: kgameportd exiting\n");444-445- unlock_kernel();446- complete_and_exit(&gameport_exited, 0);447}448449···766767static int __init gameport_init(void)768{769- if (!(gameport_pid = kernel_thread(gameport_thread, NULL, CLONE_KERNEL))) {0770 printk(KERN_ERR "gameport: Failed to start kgameportd\n");771- return -1;772 }773774 gameport_bus.dev_attrs = gameport_device_attrs;···783static void __exit gameport_exit(void)784{785 bus_unregister(&gameport_bus);786- kill_proc(gameport_pid, SIGTERM, 1);787- wait_for_completion(&gameport_exited);788}789790module_init(gameport_init);
···17#include <linux/init.h>18#include <linux/gameport.h>19#include <linux/wait.h>020#include <linux/sched.h>021#include <linux/slab.h>22#include <linux/delay.h>23+#include <linux/kthread.h>2425/*#include <asm/io.h>*/26···238static DEFINE_SPINLOCK(gameport_event_lock); /* protects gameport_event_list */239static LIST_HEAD(gameport_event_list);240static DECLARE_WAIT_QUEUE_HEAD(gameport_wait);241+static struct task_struct *gameport_task;0242243static void gameport_queue_event(void *object, struct module *owner,244 enum gameport_event_type event_type)···250 spin_lock_irqsave(&gameport_event_lock, flags);251252 /*253+ * Scan event list for the other events for the same gameport port,254 * starting with the most recent one. If event is the same we255 * do not need add new one. If event is of different type we256 * need to add this event and should not look further because257 * we need to preseve sequence of distinct events.258+ */259 list_for_each_entry_reverse(event, &gameport_event_list, node) {260 if (event->object == object) {261 if (event->type == event_type)···432433static int gameport_thread(void *nothing)434{0000435 do {436 gameport_handle_events();437+ wait_event_interruptible(gameport_wait,438+ kthread_should_stop() || !list_empty(&gameport_event_list));439 try_to_freeze();440+ } while (!kthread_should_stop());441442 printk(KERN_DEBUG "gameport: kgameportd exiting\n");443+ return 0;00444}445446···773774static int __init gameport_init(void)775{776+ gameport_task = kthread_run(gameport_thread, NULL, "kgameportd");777+ if (IS_ERR(gameport_task)) {778 printk(KERN_ERR "gameport: Failed to start kgameportd\n");779+ return PTR_ERR(gameport_task);780 }781782 gameport_bus.dev_attrs = gameport_device_attrs;···789static void __exit gameport_exit(void)790{791 bus_unregister(&gameport_bus);792+ kthread_stop(gameport_task);0793}794795module_init(gameport_init);
+62-27
drivers/input/serio/serio.c
···31#include <linux/serio.h>32#include <linux/errno.h>33#include <linux/wait.h>34-#include <linux/completion.h>35#include <linux/sched.h>36-#include <linux/smp_lock.h>37#include <linux/slab.h>03839MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>");40MODULE_DESCRIPTION("Serio abstraction core");···42EXPORT_SYMBOL(serio_interrupt);43EXPORT_SYMBOL(__serio_register_port);44EXPORT_SYMBOL(serio_unregister_port);045EXPORT_SYMBOL(__serio_unregister_port_delayed);46EXPORT_SYMBOL(__serio_register_driver);47EXPORT_SYMBOL(serio_unregister_driver);···68static void serio_reconnect_port(struct serio *serio);69static void serio_disconnect_port(struct serio *serio);70000000000000000000000000000000071static int serio_match_port(const struct serio_device_id *ids, struct serio *serio)72{73 while (ids->type || ids->proto) {···122123 if (serio_match_port(drv->id_table, serio)) {124 serio->dev.driver = &drv->driver;125- if (drv->connect(serio, drv)) {126 serio->dev.driver = NULL;127 goto out;128 }···169static DEFINE_SPINLOCK(serio_event_lock); /* protects serio_event_list */170static LIST_HEAD(serio_event_list);171static DECLARE_WAIT_QUEUE_HEAD(serio_wait);172-static DECLARE_COMPLETION(serio_exited);173-static int serio_pid;174175static void serio_queue_event(void *object, struct module *owner,176 enum serio_event_type event_type)···180 spin_lock_irqsave(&serio_event_lock, flags);181182 /*183- * Scan event list for the other events for the same serio port,184 * starting with the most recent one. If event is the same we185 * do not need add new one. If event is of different type we186 * need to add this event and should not look further because187 * we need to preseve sequence of distinct events.188- */189 list_for_each_entry_reverse(event, &serio_event_list, node) {190 if (event->object == object) {191 if (event->type == event_type)···367368static int serio_thread(void *nothing)369{370- lock_kernel();371- daemonize("kseriod");372- allow_signal(SIGTERM);373-374 do {375 serio_handle_events();376- wait_event_interruptible(serio_wait, !list_empty(&serio_event_list));0377 try_to_freeze();378- } while (!signal_pending(current));379380 printk(KERN_DEBUG "serio: kseriod exiting\n");381-382- unlock_kernel();383- complete_and_exit(&serio_exited, 0);384}385386···582static void serio_reconnect_port(struct serio *serio)583{584 do {585- if (!serio->drv || !serio->drv->reconnect || serio->drv->reconnect(serio)) {586 serio_disconnect_port(serio);587 serio_find_driver(serio);588 /* Ok, old children are now gone, we are done */···655}656657/*0000000000000658 * Submits register request to kseriod for subsequent execution.659 * Can be used when it is not obvious whether the serio_sem is660 * taken or not and when delayed execution is feasible.···724 struct serio *serio = to_serio_port(dev);725 struct serio_driver *drv = to_serio_driver(dev->driver);726727- return drv->connect(serio, drv);728}729730static int serio_driver_remove(struct device *dev)731{732 struct serio *serio = to_serio_port(dev);733- struct serio_driver *drv = to_serio_driver(dev->driver);734735- drv->disconnect(serio);736 return 0;737}738···767768static void serio_set_drv(struct serio *serio, struct serio_driver *drv)769{770- down(&serio->drv_sem);771 serio_pause_rx(serio);772 serio->drv = drv;773 serio_continue_rx(serio);774- up(&serio->drv_sem);775}776777static int serio_bus_match(struct device *dev, struct device_driver *drv)···829{830 struct serio *serio = to_serio_port(dev);831832- if (!serio->drv || !serio->drv->reconnect || serio->drv->reconnect(serio)) {833 /*834 * Driver re-probing can take a while, so better let kseriod835 * deal with it.···883884static int __init serio_init(void)885{886- if (!(serio_pid = kernel_thread(serio_thread, NULL, CLONE_KERNEL))) {0887 printk(KERN_ERR "serio: Failed to start kseriod\n");888- return -1;889 }890891 serio_bus.dev_attrs = serio_device_attrs;···902static void __exit serio_exit(void)903{904 bus_unregister(&serio_bus);905- kill_proc(serio_pid, SIGTERM, 1);906- wait_for_completion(&serio_exited);907}908909module_init(serio_init);
···31#include <linux/serio.h>32#include <linux/errno.h>33#include <linux/wait.h>034#include <linux/sched.h>035#include <linux/slab.h>36+#include <linux/kthread.h>3738MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>");39MODULE_DESCRIPTION("Serio abstraction core");···43EXPORT_SYMBOL(serio_interrupt);44EXPORT_SYMBOL(__serio_register_port);45EXPORT_SYMBOL(serio_unregister_port);46+EXPORT_SYMBOL(serio_unregister_child_port);47EXPORT_SYMBOL(__serio_unregister_port_delayed);48EXPORT_SYMBOL(__serio_register_driver);49EXPORT_SYMBOL(serio_unregister_driver);···68static void serio_reconnect_port(struct serio *serio);69static void serio_disconnect_port(struct serio *serio);7071+static int serio_connect_driver(struct serio *serio, struct serio_driver *drv)72+{73+ int retval;74+75+ down(&serio->drv_sem);76+ retval = drv->connect(serio, drv);77+ up(&serio->drv_sem);78+79+ return retval;80+}81+82+static int serio_reconnect_driver(struct serio *serio)83+{84+ int retval = -1;85+86+ down(&serio->drv_sem);87+ if (serio->drv && serio->drv->reconnect)88+ retval = serio->drv->reconnect(serio);89+ up(&serio->drv_sem);90+91+ return retval;92+}93+94+static void serio_disconnect_driver(struct serio *serio)95+{96+ down(&serio->drv_sem);97+ if (serio->drv)98+ serio->drv->disconnect(serio);99+ up(&serio->drv_sem);100+}101+102static int serio_match_port(const struct serio_device_id *ids, struct serio *serio)103{104 while (ids->type || ids->proto) {···9192 if (serio_match_port(drv->id_table, serio)) {93 serio->dev.driver = &drv->driver;94+ if (serio_connect_driver(serio, drv)) {95 serio->dev.driver = NULL;96 goto out;97 }···138static DEFINE_SPINLOCK(serio_event_lock); /* protects serio_event_list */139static LIST_HEAD(serio_event_list);140static DECLARE_WAIT_QUEUE_HEAD(serio_wait);141+static struct task_struct *serio_task;0142143static void serio_queue_event(void *object, struct module *owner,144 enum serio_event_type event_type)···150 spin_lock_irqsave(&serio_event_lock, flags);151152 /*153+ * Scan event list for the other events for the same serio port,154 * starting with the most recent one. If event is the same we155 * do not need add new one. If event is of different type we156 * need to add this event and should not look further because157 * we need to preseve sequence of distinct events.158+ */159 list_for_each_entry_reverse(event, &serio_event_list, node) {160 if (event->object == object) {161 if (event->type == event_type)···337338static int serio_thread(void *nothing)339{0000340 do {341 serio_handle_events();342+ wait_event_interruptible(serio_wait,343+ kthread_should_stop() || !list_empty(&serio_event_list));344 try_to_freeze();345+ } while (!kthread_should_stop());346347 printk(KERN_DEBUG "serio: kseriod exiting\n");348+ return 0;00349}350351···557static void serio_reconnect_port(struct serio *serio)558{559 do {560+ if (serio_reconnect_driver(serio)) {561 serio_disconnect_port(serio);562 serio_find_driver(serio);563 /* Ok, old children are now gone, we are done */···630}631632/*633+ * Safely unregisters child port if one is present.634+ */635+void serio_unregister_child_port(struct serio *serio)636+{637+ down(&serio_sem);638+ if (serio->child) {639+ serio_disconnect_port(serio->child);640+ serio_destroy_port(serio->child);641+ }642+ up(&serio_sem);643+}644+645+/*646 * Submits register request to kseriod for subsequent execution.647 * Can be used when it is not obvious whether the serio_sem is648 * taken or not and when delayed execution is feasible.···686 struct serio *serio = to_serio_port(dev);687 struct serio_driver *drv = to_serio_driver(dev->driver);688689+ return serio_connect_driver(serio, drv);690}691692static int serio_driver_remove(struct device *dev)693{694 struct serio *serio = to_serio_port(dev);0695696+ serio_disconnect_driver(serio);697 return 0;698}699···730731static void serio_set_drv(struct serio *serio, struct serio_driver *drv)732{0733 serio_pause_rx(serio);734 serio->drv = drv;735 serio_continue_rx(serio);0736}737738static int serio_bus_match(struct device *dev, struct device_driver *drv)···794{795 struct serio *serio = to_serio_port(dev);796797+ if (serio_reconnect_driver(serio)) {798 /*799 * Driver re-probing can take a while, so better let kseriod800 * deal with it.···848849static int __init serio_init(void)850{851+ serio_task = kthread_run(serio_thread, NULL, "kseriod");852+ if (IS_ERR(serio_task)) {853 printk(KERN_ERR "serio: Failed to start kseriod\n");854+ return PTR_ERR(serio_task);855 }856857 serio_bus.dev_attrs = serio_device_attrs;···866static void __exit serio_exit(void)867{868 bus_unregister(&serio_bus);869+ kthread_stop(serio_task);0870}871872module_init(serio_init);
···607 cards are usually around 4-16MiB in size. This does not include608 Compact Flash cards which are treated as IDE devices.6090000000000610config MTD_UCLINUX611 tristate "Generic uClinux RAM/ROM filesystem support"612 depends on MTD_PARTITIONS && !MMU
···607 cards are usually around 4-16MiB in size. This does not include608 Compact Flash cards which are treated as IDE devices.609610+config MTD_PCMCIA_ANONYMOUS611+ bool "Use PCMCIA MTD drivers for anonymous PCMCIA cards"612+ depends on MTD_PCMCIA613+ default N614+ help615+ If this option is enabled, PCMCIA cards which do not report616+ anything about themselves are assumed to be MTD cards.617+618+ If unsure, say N.619+620config MTD_UCLINUX621 tristate "Generic uClinux RAM/ROM filesystem support"622 depends on MTD_PARTITIONS && !MMU
···14 Say Y here if you want to attach PCMCIA- or PC-cards to your Linux15 computer. These are credit-card size devices such as network cards,16 modems or hard drives often used with laptops computers. There are17- actually two varieties of these cards: the older 16 bit PCMCIA cards18- and the newer 32 bit CardBus cards.1920 To compile this driver as modules, choose M here: the21 module will be called pcmcia_core.···4243config PCMCIA44 tristate "16-bit PCMCIA support"045 default y46 ---help---47 This option enables support for 16-bit PCMCIA cards. Most older48 PC-cards are such 16-bit PCMCIA cards, so unless you know you're49 only using 32-bit CardBus cards, say Y or M here.5051- To use 16-bit PCMCIA cards, you will need supporting software from 52- David Hinds' pcmcia-cs package (see the file <file:Documentation/Changes>53- for location). Please also read the PCMCIA-HOWTO, available from54- <http://www.tldp.org/docs.html#howto>.5556 To compile this driver as modules, choose M here: the57 module will be called pcmcia.5859 If unsure, say Y.000000000000000000000000000006061config CARDBUS62 bool "32-bit CardBus support" ···106107config YENTA108 tristate "CardBus yenta-compatible bridge support"109- depends on PCI110-#fixme: remove dependendcy on CARDBUS111 depends on CARDBUS112 select PCCARD_NONSTATIC113 ---help---
···14 Say Y here if you want to attach PCMCIA- or PC-cards to your Linux15 computer. These are credit-card size devices such as network cards,16 modems or hard drives often used with laptops computers. There are17+ actually two varieties of these cards: 16 bit PCMCIA and 32 bit18+ CardBus cards.1920 To compile this driver as modules, choose M here: the21 module will be called pcmcia_core.···4243config PCMCIA44 tristate "16-bit PCMCIA support"45+ select CRC3246 default y47 ---help---48 This option enables support for 16-bit PCMCIA cards. Most older49 PC-cards are such 16-bit PCMCIA cards, so unless you know you're50 only using 32-bit CardBus cards, say Y or M here.5152+ To use 16-bit PCMCIA cards, you will need supporting software in53+ most cases. (see the file <file:Documentation/Changes> for54+ location and details).05556 To compile this driver as modules, choose M here: the57 module will be called pcmcia.5859 If unsure, say Y.60+61+config PCMCIA_LOAD_CIS62+ bool "Load CIS updates from userspace (EXPERIMENTAL)"63+ depends on PCMCIA && EXPERIMENTAL64+ select FW_LOADER65+ default y66+ help67+ Some PCMCIA cards require an updated Card Information Structure (CIS)68+ to be loaded from userspace to work correctly. If you say Y here,69+ and your userspace is arranged correctly, this will be loaded70+ automatically using the in-kernel firmware loader and the hotplug71+ subsystem, instead of relying on cardmgr from pcmcia-cs to do so.72+73+ If unsure, say Y.74+75+config PCMCIA_IOCTL76+ bool77+ depends on PCMCIA78+ default y79+ help80+ If you say Y here, the deprecated ioctl interface to the PCMCIA81+ subsystem will be built. It is needed by cardmgr and cardctl82+ (pcmcia-cs) to function properly.83+84+ If you do not use the new pcmciautils package, and have a85+ yenta, Cirrus PD6729, i82092, i82365 or tcic compatible bridge,86+ you need to say Y here to be able to use 16-bit PCMCIA cards.87+88+ If unsure, say Y.8990config CARDBUS91 bool "32-bit CardBus support" ···7778config YENTA79 tristate "CardBus yenta-compatible bridge support"0080 depends on CARDBUS81 select PCCARD_NONSTATIC82 ---help---
···89set_cis_map(struct pcmcia_socket *s, unsigned int card_offset, unsigned int flags)90{91 pccard_mem_map *mem = &s->cis_mem;0092 if (!(s->features & SS_CAP_STATIC_MAP) && mem->res == NULL) {93- mem->res = find_mem_region(0, s->map_size, s->map_size, 0, s);94 if (mem->res == NULL) {95 printk(KERN_NOTICE "cs: unable to map card memory!\n");96 return NULL;···101 }102 mem->card_start = card_offset;103 mem->flags = flags;104- s->ops->set_mem_map(s, mem);00000105 if (s->features & SS_CAP_STATIC_MAP) {106 if (s->cis_virt)107 iounmap(s->cis_virt);···126#define IS_ATTR 1127#define IS_INDIRECT 8128129-int read_cis_mem(struct pcmcia_socket *s, int attr, u_int addr,130 u_int len, void *ptr)131{132 void __iomem *sys, *end;133 unsigned char *buf = ptr;134135- cs_dbg(s, 3, "read_cis_mem(%d, %#x, %u)\n", attr, addr, len);136137 if (attr & IS_INDIRECT) {138 /* Indirect accesses use a bunch of special registers at fixed···189 *(u_char *)(ptr+2), *(u_char *)(ptr+3));190 return 0;191}0192193-void write_cis_mem(struct pcmcia_socket *s, int attr, u_int addr,0194 u_int len, void *ptr)195{196 void __iomem *sys, *end;197 unsigned char *buf = ptr;198199- cs_dbg(s, 3, "write_cis_mem(%d, %#x, %u)\n", attr, addr, len);200201 if (attr & IS_INDIRECT) {202 /* Indirect accesses use a bunch of special registers at fixed···248 }249 }250}00251252/*======================================================================253···285 ret = read_cb_mem(s, attr, addr, len, ptr);286 else287#endif288- ret = read_cis_mem(s, attr, addr, len, ptr);289290 if (ret == 0) {291 /* Copy data into the cache */···359 read_cb_mem(s, cis->attr, cis->addr, len, buf);360 else361#endif362- read_cis_mem(s, cis->attr, cis->addr, len, buf);363364 if (memcmp(buf, cis->cache, len) != 0) {365 kfree(buf);···392 memcpy(s->fake_cis, cis->Data, cis->Length);393 return CS_SUCCESS;394}0395396/*======================================================================397
···89set_cis_map(struct pcmcia_socket *s, unsigned int card_offset, unsigned int flags)90{91 pccard_mem_map *mem = &s->cis_mem;92+ int ret;93+94 if (!(s->features & SS_CAP_STATIC_MAP) && mem->res == NULL) {95+ mem->res = pcmcia_find_mem_region(0, s->map_size, s->map_size, 0, s);96 if (mem->res == NULL) {97 printk(KERN_NOTICE "cs: unable to map card memory!\n");98 return NULL;···99 }100 mem->card_start = card_offset;101 mem->flags = flags;102+ ret = s->ops->set_mem_map(s, mem);103+ if (ret) {104+ iounmap(s->cis_virt);105+ return NULL;106+ }107+108 if (s->features & SS_CAP_STATIC_MAP) {109 if (s->cis_virt)110 iounmap(s->cis_virt);···119#define IS_ATTR 1120#define IS_INDIRECT 8121122+int pcmcia_read_cis_mem(struct pcmcia_socket *s, int attr, u_int addr,123 u_int len, void *ptr)124{125 void __iomem *sys, *end;126 unsigned char *buf = ptr;127128+ cs_dbg(s, 3, "pcmcia_read_cis_mem(%d, %#x, %u)\n", attr, addr, len);129130 if (attr & IS_INDIRECT) {131 /* Indirect accesses use a bunch of special registers at fixed···182 *(u_char *)(ptr+2), *(u_char *)(ptr+3));183 return 0;184}185+EXPORT_SYMBOL(pcmcia_read_cis_mem);186187+188+void pcmcia_write_cis_mem(struct pcmcia_socket *s, int attr, u_int addr,189 u_int len, void *ptr)190{191 void __iomem *sys, *end;192 unsigned char *buf = ptr;193194+ cs_dbg(s, 3, "pcmcia_write_cis_mem(%d, %#x, %u)\n", attr, addr, len);195196 if (attr & IS_INDIRECT) {197 /* Indirect accesses use a bunch of special registers at fixed···239 }240 }241}242+EXPORT_SYMBOL(pcmcia_write_cis_mem);243+244245/*======================================================================246···274 ret = read_cb_mem(s, attr, addr, len, ptr);275 else276#endif277+ ret = pcmcia_read_cis_mem(s, attr, addr, len, ptr);278279 if (ret == 0) {280 /* Copy data into the cache */···348 read_cb_mem(s, cis->attr, cis->addr, len, buf);349 else350#endif351+ pcmcia_read_cis_mem(s, cis->attr, cis->addr, len, buf);352353 if (memcmp(buf, cis->cache, len) != 0) {354 kfree(buf);···381 memcpy(s->fake_cis, cis->Data, cis->Length);382 return CS_SUCCESS;383}384+EXPORT_SYMBOL(pcmcia_replace_cis);385386/*======================================================================387
+91-1073
drivers/pcmcia/cs.c
···43#include <pcmcia/ds.h>44#include "cs_internal.h"4546-#ifdef CONFIG_PCI47-#define PCI_OPT " [pci]"48-#else49-#define PCI_OPT ""50-#endif51-#ifdef CONFIG_CARDBUS52-#define CB_OPT " [cardbus]"53-#else54-#define CB_OPT ""55-#endif56-#ifdef CONFIG_PM57-#define PM_OPT " [pm]"58-#else59-#define PM_OPT ""60-#endif61-#if !defined(CONFIG_CARDBUS) && !defined(CONFIG_PCI) && !defined(CONFIG_PM)62-#define OPTIONS " none"63-#else64-#define OPTIONS PCI_OPT CB_OPT PM_OPT65-#endif66-67-static const char *release = "Linux Kernel Card Services";68-static const char *options = "options: " OPTIONS;69-70-/*====================================================================*/7172/* Module parameters */7374MODULE_AUTHOR("David Hinds <dahinds@users.sourceforge.net>");75-MODULE_DESCRIPTION("Linux Kernel Card Services\noptions:" OPTIONS);76MODULE_LICENSE("GPL");7778#define INT_MODULE_PARM(n, v) static int n = v; module_param(n, int, 0444)···64/* Access speed for attribute memory windows */65INT_MODULE_PARM(cis_speed, 300); /* ns */6667-/* Access speed for IO windows */68-INT_MODULE_PARM(io_speed, 0); /* ns */69-70#ifdef DEBUG71static int pc_debug;72···75}76#endif7778-/*====================================================================*/7980socket_state_t dead_socket = {81 .csc_mask = SS_DETECT,82};0838485/* List of all sockets, protected by a rwsem */86LIST_HEAD(pcmcia_socket_list);87-DECLARE_RWSEM(pcmcia_socket_list_rwsem);88EXPORT_SYMBOL(pcmcia_socket_list);0089EXPORT_SYMBOL(pcmcia_socket_list_rwsem);909192-#ifdef CONFIG_PCMCIA_PROBE93-/* mask ofIRQs already reserved by other cards, we should avoid using them */94-static u8 pcmcia_used_irq[NR_IRQS];95-#endif96-97-/*====================================================================98-99- Low-level PC Card interface drivers need to register with Card100- Services using these calls.101-102-======================================================================*/103-104/**105- * socket drivers are expected to use the following callbacks in their 000106 * .drv struct:107 * - pcmcia_socket_dev_suspend108 * - pcmcia_socket_dev_resume···194 }195196 /* try to obtain a socket number [yes, it gets ugly if we197- * register more than 2^sizeof(unsigned int) pcmcia 198- * sockets... but the socket number is deprecated 199 * anyways, so I don't care] */200 down_write(&pcmcia_socket_list_rwsem);201 if (list_empty(&pcmcia_socket_list))···304EXPORT_SYMBOL(pcmcia_get_socket_by_nr);305306307-/*======================================================================308-309- socket_setup() and shutdown_socket() are called by the main event310- handler when card insertion and removal events are received.311- socket_setup() turns on socket power and resets the socket, in two stages.312- shutdown_socket() unconfigures a socket and turns off socket power.313-314-======================================================================*/315-316static void shutdown_socket(struct pcmcia_socket *s)317{318- cs_dbg(s, 1, "shutdown_socket\n");319320- /* Blank out the socket state */321- s->socket = dead_socket;322- s->ops->init(s);323- s->ops->set_socket(s, &s->socket);324- s->irq.AssignedIRQ = s->irq.Config = 0;325- s->lock_count = 0;326- destroy_cis_cache(s);327#ifdef CONFIG_CARDBUS328- cb_free(s);329#endif330- s->functions = 0;331- if (s->config) {332- kfree(s->config);333- s->config = NULL;334- }335-336- {337- int status;338- s->ops->get_status(s, &status);339- if (status & SS_POWERON) {340- printk(KERN_ERR "PCMCIA: socket %p: *** DANGER *** unable to remove socket power\n", s);341 }342- }0000000343} /* shutdown_socket */344345-/*======================================================================346347- The central event handler. Send_event() sends an event to the348- 16-bit subsystem, which then calls the relevant device drivers.349- Parse_events() interprets the event bits from350- a card status change report. Do_shutdown() handles the high351- priority stuff associated with a card removal.352-353-======================================================================*/354-355356/* NOTE: send_event needs to be called with skt->sem held. */357···705 wake_up(&s->thread_wait);706 }707} /* pcmcia_parse_events */0708709-710-/*======================================================================711-712- Special stuff for managing IO windows, because they are scarce.713-714-======================================================================*/715-716-static int alloc_io_space(struct pcmcia_socket *s, u_int attr, ioaddr_t *base,717- ioaddr_t num, u_int lines)718-{719- int i;720- kio_addr_t try, align;721-722- align = (*base) ? (lines ? 1<<lines : 0) : 1;723- if (align && (align < num)) {724- if (*base) {725- cs_dbg(s, 0, "odd IO request: num %#x align %#lx\n",726- num, align);727- align = 0;728- } else729- while (align && (align < num)) align <<= 1;730- }731- if (*base & ~(align-1)) {732- cs_dbg(s, 0, "odd IO request: base %#x align %#lx\n",733- *base, align);734- align = 0;735- }736- if ((s->features & SS_CAP_STATIC_MAP) && s->io_offset) {737- *base = s->io_offset | (*base & 0x0fff);738- return 0;739- }740- /* Check for an already-allocated window that must conflict with741- what was asked for. It is a hack because it does not catch all742- potential conflicts, just the most obvious ones. */743- for (i = 0; i < MAX_IO_WIN; i++)744- if ((s->io[i].NumPorts != 0) &&745- ((s->io[i].BasePort & (align-1)) == *base))746- return 1;747- for (i = 0; i < MAX_IO_WIN; i++) {748- if (s->io[i].NumPorts == 0) {749- s->io[i].res = find_io_region(*base, num, align, s);750- if (s->io[i].res) {751- s->io[i].Attributes = attr;752- s->io[i].BasePort = *base = s->io[i].res->start;753- s->io[i].NumPorts = s->io[i].InUse = num;754- break;755- } else756- return 1;757- } else if (s->io[i].Attributes != attr)758- continue;759- /* Try to extend top of window */760- try = s->io[i].BasePort + s->io[i].NumPorts;761- if ((*base == 0) || (*base == try))762- if (adjust_io_region(s->io[i].res, s->io[i].res->start,763- s->io[i].res->end + num, s) == 0) {764- *base = try;765- s->io[i].NumPorts += num;766- s->io[i].InUse += num;767- break;768- }769- /* Try to extend bottom of window */770- try = s->io[i].BasePort - num;771- if ((*base == 0) || (*base == try))772- if (adjust_io_region(s->io[i].res, s->io[i].res->start - num,773- s->io[i].res->end, s) == 0) {774- s->io[i].BasePort = *base = try;775- s->io[i].NumPorts += num;776- s->io[i].InUse += num;777- break;778- }779- }780- return (i == MAX_IO_WIN);781-} /* alloc_io_space */782-783-static void release_io_space(struct pcmcia_socket *s, ioaddr_t base,784- ioaddr_t num)785-{786- int i;787-788- for (i = 0; i < MAX_IO_WIN; i++) {789- if ((s->io[i].BasePort <= base) &&790- (s->io[i].BasePort+s->io[i].NumPorts >= base+num)) {791- s->io[i].InUse -= num;792- /* Free the window if no one else is using it */793- if (s->io[i].InUse == 0) {794- s->io[i].NumPorts = 0;795- release_resource(s->io[i].res);796- kfree(s->io[i].res);797- s->io[i].res = NULL;798- }799- }800- }801-}802-803-/*======================================================================804-805- Access_configuration_register() reads and writes configuration806- registers in attribute memory. Memory window 0 is reserved for807- this and the tuple reading services.808-809-======================================================================*/810-811-int pccard_access_configuration_register(struct pcmcia_socket *s,812- unsigned int function,813- conf_reg_t *reg)814-{815- config_t *c;816- int addr;817- u_char val;818-819- if (!s || !s->config)820- return CS_NO_CARD; 821-822- c = &s->config[function];823-824- if (c == NULL)825- return CS_NO_CARD;826-827- if (!(c->state & CONFIG_LOCKED))828- return CS_CONFIGURATION_LOCKED;829-830- addr = (c->ConfigBase + reg->Offset) >> 1;831-832- switch (reg->Action) {833- case CS_READ:834- read_cis_mem(s, 1, addr, 1, &val);835- reg->Value = val;836- break;837- case CS_WRITE:838- val = reg->Value;839- write_cis_mem(s, 1, addr, 1, &val);840- break;841- default:842- return CS_BAD_ARGS;843- break;844- }845- return CS_SUCCESS;846-} /* access_configuration_register */847-EXPORT_SYMBOL(pccard_access_configuration_register);848-849-850-/*====================================================================*/851-852-int pccard_get_configuration_info(struct pcmcia_socket *s,853- unsigned int function,854- config_info_t *config)855-{856- config_t *c;857-858- if (!(s->state & SOCKET_PRESENT))859- return CS_NO_CARD;860-861- config->Function = function;862-863-#ifdef CONFIG_CARDBUS864- if (s->state & SOCKET_CARDBUS) {865- memset(config, 0, sizeof(config_info_t));866- config->Vcc = s->socket.Vcc;867- config->Vpp1 = config->Vpp2 = s->socket.Vpp;868- config->Option = s->cb_dev->subordinate->number;869- if (s->state & SOCKET_CARDBUS_CONFIG) {870- config->Attributes = CONF_VALID_CLIENT;871- config->IntType = INT_CARDBUS;872- config->AssignedIRQ = s->irq.AssignedIRQ;873- if (config->AssignedIRQ)874- config->Attributes |= CONF_ENABLE_IRQ;875- config->BasePort1 = s->io[0].BasePort;876- config->NumPorts1 = s->io[0].NumPorts;877- }878- return CS_SUCCESS;879- }880-#endif881-882- c = (s->config != NULL) ? &s->config[function] : NULL;883-884- if ((c == NULL) || !(c->state & CONFIG_LOCKED)) {885- config->Attributes = 0;886- config->Vcc = s->socket.Vcc;887- config->Vpp1 = config->Vpp2 = s->socket.Vpp;888- return CS_SUCCESS;889- }890-891- /* !!! This is a hack !!! */892- memcpy(&config->Attributes, &c->Attributes, sizeof(config_t));893- config->Attributes |= CONF_VALID_CLIENT;894- config->CardValues = c->CardValues;895- config->IRQAttributes = c->irq.Attributes;896- config->AssignedIRQ = s->irq.AssignedIRQ;897- config->BasePort1 = c->io.BasePort1;898- config->NumPorts1 = c->io.NumPorts1;899- config->Attributes1 = c->io.Attributes1;900- config->BasePort2 = c->io.BasePort2;901- config->NumPorts2 = c->io.NumPorts2;902- config->Attributes2 = c->io.Attributes2;903- config->IOAddrLines = c->io.IOAddrLines;904-905- return CS_SUCCESS;906-} /* get_configuration_info */907-EXPORT_SYMBOL(pccard_get_configuration_info);908-909-/*======================================================================910-911- Return information about this version of Card Services.912-913-======================================================================*/914-915-int pcmcia_get_card_services_info(servinfo_t *info)916-{917- unsigned int socket_count = 0;918- struct list_head *tmp;919- info->Signature[0] = 'C';920- info->Signature[1] = 'S';921- down_read(&pcmcia_socket_list_rwsem);922- list_for_each(tmp, &pcmcia_socket_list)923- socket_count++;924- up_read(&pcmcia_socket_list_rwsem);925- info->Count = socket_count;926- info->Revision = CS_RELEASE_CODE;927- info->CSLevel = 0x0210;928- info->VendorString = (char *)release;929- return CS_SUCCESS;930-} /* get_card_services_info */931-932-933-/*====================================================================*/934-935-int pcmcia_get_window(struct pcmcia_socket *s, window_handle_t *handle, int idx, win_req_t *req)936-{937- window_t *win;938- int w;939-940- if (!s || !(s->state & SOCKET_PRESENT))941- return CS_NO_CARD;942- for (w = idx; w < MAX_WIN; w++)943- if (s->state & SOCKET_WIN_REQ(w)) break;944- if (w == MAX_WIN)945- return CS_NO_MORE_ITEMS;946- win = &s->win[w];947- req->Base = win->ctl.res->start;948- req->Size = win->ctl.res->end - win->ctl.res->start + 1;949- req->AccessSpeed = win->ctl.speed;950- req->Attributes = 0;951- if (win->ctl.flags & MAP_ATTRIB)952- req->Attributes |= WIN_MEMORY_TYPE_AM;953- if (win->ctl.flags & MAP_ACTIVE)954- req->Attributes |= WIN_ENABLE;955- if (win->ctl.flags & MAP_16BIT)956- req->Attributes |= WIN_DATA_WIDTH_16;957- if (win->ctl.flags & MAP_USE_WAIT)958- req->Attributes |= WIN_USE_WAIT;959- *handle = win;960- return CS_SUCCESS;961-} /* get_window */962-EXPORT_SYMBOL(pcmcia_get_window);963-964-/*=====================================================================965-966- Return the PCI device associated with a card..967-968-======================================================================*/969-970-#ifdef CONFIG_CARDBUS971-972-struct pci_bus *pcmcia_lookup_bus(struct pcmcia_socket *s)973-{974- if (!s || !(s->state & SOCKET_CARDBUS))975- return NULL;976-977- return s->cb_dev->subordinate;978-}979-980-EXPORT_SYMBOL(pcmcia_lookup_bus);981-982-#endif983-984-/*======================================================================985-986- Get the current socket state bits. We don't support the latched987- SocketState yet: I haven't seen any point for it.988-989-======================================================================*/990-991-int pccard_get_status(struct pcmcia_socket *s, unsigned int function, cs_status_t *status)992-{993- config_t *c;994- int val;995-996- s->ops->get_status(s, &val);997- status->CardState = status->SocketState = 0;998- status->CardState |= (val & SS_DETECT) ? CS_EVENT_CARD_DETECT : 0;999- status->CardState |= (val & SS_CARDBUS) ? CS_EVENT_CB_DETECT : 0;1000- status->CardState |= (val & SS_3VCARD) ? CS_EVENT_3VCARD : 0;1001- status->CardState |= (val & SS_XVCARD) ? CS_EVENT_XVCARD : 0;1002- if (s->state & SOCKET_SUSPEND)1003- status->CardState |= CS_EVENT_PM_SUSPEND;1004- if (!(s->state & SOCKET_PRESENT))1005- return CS_NO_CARD;1006-1007- c = (s->config != NULL) ? &s->config[function] : NULL;1008- if ((c != NULL) && (c->state & CONFIG_LOCKED) &&1009- (c->IntType & (INT_MEMORY_AND_IO | INT_ZOOMED_VIDEO))) {1010- u_char reg;1011- if (c->Present & PRESENT_PIN_REPLACE) {1012- read_cis_mem(s, 1, (c->ConfigBase+CISREG_PRR)>>1, 1, ®);1013- status->CardState |=1014- (reg & PRR_WP_STATUS) ? CS_EVENT_WRITE_PROTECT : 0;1015- status->CardState |=1016- (reg & PRR_READY_STATUS) ? CS_EVENT_READY_CHANGE : 0;1017- status->CardState |=1018- (reg & PRR_BVD2_STATUS) ? CS_EVENT_BATTERY_LOW : 0;1019- status->CardState |=1020- (reg & PRR_BVD1_STATUS) ? CS_EVENT_BATTERY_DEAD : 0;1021- } else {1022- /* No PRR? Then assume we're always ready */1023- status->CardState |= CS_EVENT_READY_CHANGE;1024- }1025- if (c->Present & PRESENT_EXT_STATUS) {1026- read_cis_mem(s, 1, (c->ConfigBase+CISREG_ESR)>>1, 1, ®);1027- status->CardState |=1028- (reg & ESR_REQ_ATTN) ? CS_EVENT_REQUEST_ATTENTION : 0;1029- }1030- return CS_SUCCESS;1031- }1032- status->CardState |=1033- (val & SS_WRPROT) ? CS_EVENT_WRITE_PROTECT : 0;1034- status->CardState |=1035- (val & SS_BATDEAD) ? CS_EVENT_BATTERY_DEAD : 0;1036- status->CardState |=1037- (val & SS_BATWARN) ? CS_EVENT_BATTERY_LOW : 0;1038- status->CardState |=1039- (val & SS_READY) ? CS_EVENT_READY_CHANGE : 0;1040- return CS_SUCCESS;1041-} /* get_status */1042-EXPORT_SYMBOL(pccard_get_status);1043-1044-/*======================================================================1045-1046- Change the card address of an already open memory window.1047-1048-======================================================================*/1049-1050-int pcmcia_get_mem_page(window_handle_t win, memreq_t *req)1051-{1052- if ((win == NULL) || (win->magic != WINDOW_MAGIC))1053- return CS_BAD_HANDLE;1054- req->Page = 0;1055- req->CardOffset = win->ctl.card_start;1056- return CS_SUCCESS;1057-} /* get_mem_page */1058-1059-int pcmcia_map_mem_page(window_handle_t win, memreq_t *req)1060-{1061- struct pcmcia_socket *s;1062- if ((win == NULL) || (win->magic != WINDOW_MAGIC))1063- return CS_BAD_HANDLE;1064- if (req->Page != 0)1065- return CS_BAD_PAGE;1066- s = win->sock;1067- win->ctl.card_start = req->CardOffset;1068- if (s->ops->set_mem_map(s, &win->ctl) != 0)1069- return CS_BAD_OFFSET;1070- return CS_SUCCESS;1071-} /* map_mem_page */1072-1073-/*======================================================================1074-1075- Modify a locked socket configuration1076-1077-======================================================================*/1078-1079-int pcmcia_modify_configuration(client_handle_t handle,1080- modconf_t *mod)1081-{1082- struct pcmcia_socket *s;1083- config_t *c;1084-1085- if (CHECK_HANDLE(handle))1086- return CS_BAD_HANDLE;1087- s = SOCKET(handle); c = CONFIG(handle);1088- if (!(s->state & SOCKET_PRESENT))1089- return CS_NO_CARD;1090- if (!(c->state & CONFIG_LOCKED))1091- return CS_CONFIGURATION_LOCKED;1092-1093- if (mod->Attributes & CONF_IRQ_CHANGE_VALID) {1094- if (mod->Attributes & CONF_ENABLE_IRQ) {1095- c->Attributes |= CONF_ENABLE_IRQ;1096- s->socket.io_irq = s->irq.AssignedIRQ;1097- } else {1098- c->Attributes &= ~CONF_ENABLE_IRQ;1099- s->socket.io_irq = 0;1100- }1101- s->ops->set_socket(s, &s->socket);1102- }1103-1104- if (mod->Attributes & CONF_VCC_CHANGE_VALID)1105- return CS_BAD_VCC;1106-1107- /* We only allow changing Vpp1 and Vpp2 to the same value */1108- if ((mod->Attributes & CONF_VPP1_CHANGE_VALID) &&1109- (mod->Attributes & CONF_VPP2_CHANGE_VALID)) {1110- if (mod->Vpp1 != mod->Vpp2)1111- return CS_BAD_VPP;1112- c->Vpp1 = c->Vpp2 = s->socket.Vpp = mod->Vpp1;1113- if (s->ops->set_socket(s, &s->socket))1114- return CS_BAD_VPP;1115- } else if ((mod->Attributes & CONF_VPP1_CHANGE_VALID) ||1116- (mod->Attributes & CONF_VPP2_CHANGE_VALID))1117- return CS_BAD_VPP;1118-1119- return CS_SUCCESS;1120-} /* modify_configuration */11211122/* register pcmcia_callback */1123int pccard_register_pcmcia(struct pcmcia_socket *s, struct pcmcia_callback *c)···736}737EXPORT_SYMBOL(pccard_register_pcmcia);738739-/*====================================================================*/740741-int pcmcia_release_configuration(client_handle_t handle)742-{743- pccard_io_map io = { 0, 0, 0, 0, 1 };744- struct pcmcia_socket *s;745- int i;746-747- if (CHECK_HANDLE(handle) ||748- !(handle->state & CLIENT_CONFIG_LOCKED))749- return CS_BAD_HANDLE;750- handle->state &= ~CLIENT_CONFIG_LOCKED;751- s = SOCKET(handle);752-753-#ifdef CONFIG_CARDBUS754- if (handle->state & CLIENT_CARDBUS)755- return CS_SUCCESS;756-#endif757-758- if (!(handle->state & CLIENT_STALE)) {759- config_t *c = CONFIG(handle);760- if (--(s->lock_count) == 0) {761- s->socket.flags = SS_OUTPUT_ENA; /* Is this correct? */762- s->socket.Vpp = 0;763- s->socket.io_irq = 0;764- s->ops->set_socket(s, &s->socket);765- }766- if (c->state & CONFIG_IO_REQ)767- for (i = 0; i < MAX_IO_WIN; i++) {768- if (s->io[i].NumPorts == 0)769- continue;770- s->io[i].Config--;771- if (s->io[i].Config != 0)772- continue;773- io.map = i;774- s->ops->set_io_map(s, &io);775- }776- c->state &= ~CONFIG_LOCKED;777- }778-779- return CS_SUCCESS;780-} /* release_configuration */781-782-/*======================================================================783-784- Release_io() releases the I/O ranges allocated by a client. This785- may be invoked some time after a card ejection has already dumped786- the actual socket configuration, so if the client is "stale", we787- don't bother checking the port ranges against the current socket788- values.789-790-======================================================================*/791-792-int pcmcia_release_io(client_handle_t handle, io_req_t *req)793-{794- struct pcmcia_socket *s;795-796- if (CHECK_HANDLE(handle) || !(handle->state & CLIENT_IO_REQ))797- return CS_BAD_HANDLE;798- handle->state &= ~CLIENT_IO_REQ;799- s = SOCKET(handle);800-801-#ifdef CONFIG_CARDBUS802- if (handle->state & CLIENT_CARDBUS)803- return CS_SUCCESS;804-#endif805-806- if (!(handle->state & CLIENT_STALE)) {807- config_t *c = CONFIG(handle);808- if (c->state & CONFIG_LOCKED)809- return CS_CONFIGURATION_LOCKED;810- if ((c->io.BasePort1 != req->BasePort1) ||811- (c->io.NumPorts1 != req->NumPorts1) ||812- (c->io.BasePort2 != req->BasePort2) ||813- (c->io.NumPorts2 != req->NumPorts2))814- return CS_BAD_ARGS;815- c->state &= ~CONFIG_IO_REQ;816- }817-818- release_io_space(s, req->BasePort1, req->NumPorts1);819- if (req->NumPorts2)820- release_io_space(s, req->BasePort2, req->NumPorts2);821-822- return CS_SUCCESS;823-} /* release_io */824-825-/*====================================================================*/826-827-int pcmcia_release_irq(client_handle_t handle, irq_req_t *req)828-{829- struct pcmcia_socket *s;830- if (CHECK_HANDLE(handle) || !(handle->state & CLIENT_IRQ_REQ))831- return CS_BAD_HANDLE;832- handle->state &= ~CLIENT_IRQ_REQ;833- s = SOCKET(handle);834-835- if (!(handle->state & CLIENT_STALE)) {836- config_t *c = CONFIG(handle);837- if (c->state & CONFIG_LOCKED)838- return CS_CONFIGURATION_LOCKED;839- if (c->irq.Attributes != req->Attributes)840- return CS_BAD_ATTRIBUTE;841- if (s->irq.AssignedIRQ != req->AssignedIRQ)842- return CS_BAD_IRQ;843- if (--s->irq.Config == 0) {844- c->state &= ~CONFIG_IRQ_REQ;845- s->irq.AssignedIRQ = 0;846- }847- }848-849- if (req->Attributes & IRQ_HANDLE_PRESENT) {850- free_irq(req->AssignedIRQ, req->Instance);851- }852-853-#ifdef CONFIG_PCMCIA_PROBE854- pcmcia_used_irq[req->AssignedIRQ]--;855-#endif856-857- return CS_SUCCESS;858-} /* cs_release_irq */859-860-/*====================================================================*/861-862-int pcmcia_release_window(window_handle_t win)863-{864- struct pcmcia_socket *s;865-866- if ((win == NULL) || (win->magic != WINDOW_MAGIC))867- return CS_BAD_HANDLE;868- s = win->sock;869- if (!(win->handle->state & CLIENT_WIN_REQ(win->index)))870- return CS_BAD_HANDLE;871-872- /* Shut down memory window */873- win->ctl.flags &= ~MAP_ACTIVE;874- s->ops->set_mem_map(s, &win->ctl);875- s->state &= ~SOCKET_WIN_REQ(win->index);876-877- /* Release system memory */878- if (win->ctl.res) {879- release_resource(win->ctl.res);880- kfree(win->ctl.res);881- win->ctl.res = NULL;882- }883- win->handle->state &= ~CLIENT_WIN_REQ(win->index);884-885- win->magic = 0;886-887- return CS_SUCCESS;888-} /* release_window */889-890-/*====================================================================*/891-892-int pcmcia_request_configuration(client_handle_t handle,893- config_req_t *req)894-{895- int i;896- u_int base;897- struct pcmcia_socket *s;898- config_t *c;899- pccard_io_map iomap;900-901- if (CHECK_HANDLE(handle))902- return CS_BAD_HANDLE;903- s = SOCKET(handle);904- if (!(s->state & SOCKET_PRESENT))905- return CS_NO_CARD;906-907-#ifdef CONFIG_CARDBUS908- if (handle->state & CLIENT_CARDBUS)909- return CS_UNSUPPORTED_MODE;910-#endif911-912- if (req->IntType & INT_CARDBUS)913- return CS_UNSUPPORTED_MODE;914- c = CONFIG(handle);915- if (c->state & CONFIG_LOCKED)916- return CS_CONFIGURATION_LOCKED;917-918- /* Do power control. We don't allow changes in Vcc. */919- if (s->socket.Vcc != req->Vcc)920- return CS_BAD_VCC;921- if (req->Vpp1 != req->Vpp2)922- return CS_BAD_VPP;923- s->socket.Vpp = req->Vpp1;924- if (s->ops->set_socket(s, &s->socket))925- return CS_BAD_VPP;926-927- c->Vcc = req->Vcc; c->Vpp1 = c->Vpp2 = req->Vpp1;928-929- /* Pick memory or I/O card, DMA mode, interrupt */930- c->IntType = req->IntType;931- c->Attributes = req->Attributes;932- if (req->IntType & INT_MEMORY_AND_IO)933- s->socket.flags |= SS_IOCARD;934- if (req->IntType & INT_ZOOMED_VIDEO)935- s->socket.flags |= SS_ZVCARD | SS_IOCARD;936- if (req->Attributes & CONF_ENABLE_DMA)937- s->socket.flags |= SS_DMA_MODE;938- if (req->Attributes & CONF_ENABLE_SPKR)939- s->socket.flags |= SS_SPKR_ENA;940- if (req->Attributes & CONF_ENABLE_IRQ)941- s->socket.io_irq = s->irq.AssignedIRQ;942- else943- s->socket.io_irq = 0;944- s->ops->set_socket(s, &s->socket);945- s->lock_count++;946-947- /* Set up CIS configuration registers */948- base = c->ConfigBase = req->ConfigBase;949- c->Present = c->CardValues = req->Present;950- if (req->Present & PRESENT_COPY) {951- c->Copy = req->Copy;952- write_cis_mem(s, 1, (base + CISREG_SCR)>>1, 1, &c->Copy);953- }954- if (req->Present & PRESENT_OPTION) {955- if (s->functions == 1) {956- c->Option = req->ConfigIndex & COR_CONFIG_MASK;957- } else {958- c->Option = req->ConfigIndex & COR_MFC_CONFIG_MASK;959- c->Option |= COR_FUNC_ENA|COR_IREQ_ENA;960- if (req->Present & PRESENT_IOBASE_0)961- c->Option |= COR_ADDR_DECODE;962- }963- if (c->state & CONFIG_IRQ_REQ)964- if (!(c->irq.Attributes & IRQ_FORCED_PULSE))965- c->Option |= COR_LEVEL_REQ;966- write_cis_mem(s, 1, (base + CISREG_COR)>>1, 1, &c->Option);967- mdelay(40);968- }969- if (req->Present & PRESENT_STATUS) {970- c->Status = req->Status;971- write_cis_mem(s, 1, (base + CISREG_CCSR)>>1, 1, &c->Status);972- }973- if (req->Present & PRESENT_PIN_REPLACE) {974- c->Pin = req->Pin;975- write_cis_mem(s, 1, (base + CISREG_PRR)>>1, 1, &c->Pin);976- }977- if (req->Present & PRESENT_EXT_STATUS) {978- c->ExtStatus = req->ExtStatus;979- write_cis_mem(s, 1, (base + CISREG_ESR)>>1, 1, &c->ExtStatus);980- }981- if (req->Present & PRESENT_IOBASE_0) {982- u_char b = c->io.BasePort1 & 0xff;983- write_cis_mem(s, 1, (base + CISREG_IOBASE_0)>>1, 1, &b);984- b = (c->io.BasePort1 >> 8) & 0xff;985- write_cis_mem(s, 1, (base + CISREG_IOBASE_1)>>1, 1, &b);986- }987- if (req->Present & PRESENT_IOSIZE) {988- u_char b = c->io.NumPorts1 + c->io.NumPorts2 - 1;989- write_cis_mem(s, 1, (base + CISREG_IOSIZE)>>1, 1, &b);990- }991-992- /* Configure I/O windows */993- if (c->state & CONFIG_IO_REQ) {994- iomap.speed = io_speed;995- for (i = 0; i < MAX_IO_WIN; i++)996- if (s->io[i].NumPorts != 0) {997- iomap.map = i;998- iomap.flags = MAP_ACTIVE;999- switch (s->io[i].Attributes & IO_DATA_PATH_WIDTH) {1000- case IO_DATA_PATH_WIDTH_16:1001- iomap.flags |= MAP_16BIT; break;1002- case IO_DATA_PATH_WIDTH_AUTO:1003- iomap.flags |= MAP_AUTOSZ; break;1004- default:1005- break;1006- }1007- iomap.start = s->io[i].BasePort;1008- iomap.stop = iomap.start + s->io[i].NumPorts - 1;1009- s->ops->set_io_map(s, &iomap);1010- s->io[i].Config++;1011- }1012- }1013-1014- c->state |= CONFIG_LOCKED;1015- handle->state |= CLIENT_CONFIG_LOCKED;1016- return CS_SUCCESS;1017-} /* request_configuration */1018-1019-/*======================================================================1020-1021- Request_io() reserves ranges of port addresses for a socket.1022- I have not implemented range sharing or alias addressing.1023-1024-======================================================================*/1025-1026-int pcmcia_request_io(client_handle_t handle, io_req_t *req)1027-{1028- struct pcmcia_socket *s;1029- config_t *c;1030-1031- if (CHECK_HANDLE(handle))1032- return CS_BAD_HANDLE;1033- s = SOCKET(handle);1034- if (!(s->state & SOCKET_PRESENT))1035- return CS_NO_CARD;1036-1037- if (handle->state & CLIENT_CARDBUS) {1038-#ifdef CONFIG_CARDBUS1039- handle->state |= CLIENT_IO_REQ;1040- return CS_SUCCESS;1041-#else1042- return CS_UNSUPPORTED_FUNCTION;1043-#endif1044- }1045-1046- if (!req)1047- return CS_UNSUPPORTED_MODE;1048- c = CONFIG(handle);1049- if (c->state & CONFIG_LOCKED)1050- return CS_CONFIGURATION_LOCKED;1051- if (c->state & CONFIG_IO_REQ)1052- return CS_IN_USE;1053- if (req->Attributes1 & (IO_SHARED | IO_FORCE_ALIAS_ACCESS))1054- return CS_BAD_ATTRIBUTE;1055- if ((req->NumPorts2 > 0) &&1056- (req->Attributes2 & (IO_SHARED | IO_FORCE_ALIAS_ACCESS)))1057- return CS_BAD_ATTRIBUTE;1058-1059- if (alloc_io_space(s, req->Attributes1, &req->BasePort1,1060- req->NumPorts1, req->IOAddrLines))1061- return CS_IN_USE;1062-1063- if (req->NumPorts2) {1064- if (alloc_io_space(s, req->Attributes2, &req->BasePort2,1065- req->NumPorts2, req->IOAddrLines)) {1066- release_io_space(s, req->BasePort1, req->NumPorts1);1067- return CS_IN_USE;1068- }1069- }1070-1071- c->io = *req;1072- c->state |= CONFIG_IO_REQ;1073- handle->state |= CLIENT_IO_REQ;1074- return CS_SUCCESS;1075-} /* request_io */1076-1077-/*======================================================================1078-1079- Request_irq() reserves an irq for this client.1080-1081- Also, since Linux only reserves irq's when they are actually1082- hooked, we don't guarantee that an irq will still be available1083- when the configuration is locked. Now that I think about it,1084- there might be a way to fix this using a dummy handler.1085-1086-======================================================================*/1087-1088-#ifdef CONFIG_PCMCIA_PROBE1089-static irqreturn_t test_action(int cpl, void *dev_id, struct pt_regs *regs)1090-{1091- return IRQ_NONE;1092-}1093-#endif1094-1095-int pcmcia_request_irq(client_handle_t handle, irq_req_t *req)1096-{1097- struct pcmcia_socket *s;1098- config_t *c;1099- int ret = CS_IN_USE, irq = 0;1100- struct pcmcia_device *p_dev = handle_to_pdev(handle);1101-1102- if (CHECK_HANDLE(handle))1103- return CS_BAD_HANDLE;1104- s = SOCKET(handle);1105- if (!(s->state & SOCKET_PRESENT))1106- return CS_NO_CARD;1107- c = CONFIG(handle);1108- if (c->state & CONFIG_LOCKED)1109- return CS_CONFIGURATION_LOCKED;1110- if (c->state & CONFIG_IRQ_REQ)1111- return CS_IN_USE;1112-1113-#ifdef CONFIG_PCMCIA_PROBE1114- if (s->irq.AssignedIRQ != 0) {1115- /* If the interrupt is already assigned, it must be the same */1116- irq = s->irq.AssignedIRQ;1117- } else {1118- int try;1119- u32 mask = s->irq_mask;1120- void *data = NULL;1121-1122- for (try = 0; try < 64; try++) {1123- irq = try % 32;1124-1125- /* marked as available by driver, and not blocked by userspace? */1126- if (!((mask >> irq) & 1))1127- continue;1128-1129- /* avoid an IRQ which is already used by a PCMCIA card */1130- if ((try < 32) && pcmcia_used_irq[irq])1131- continue;1132-1133- /* register the correct driver, if possible, of check whether1134- * registering a dummy handle works, i.e. if the IRQ isn't1135- * marked as used by the kernel resource management core */1136- ret = request_irq(irq,1137- (req->Attributes & IRQ_HANDLE_PRESENT) ? req->Handler : test_action,1138- ((req->Attributes & IRQ_TYPE_DYNAMIC_SHARING) ||1139- (s->functions > 1) ||1140- (irq == s->pci_irq)) ? SA_SHIRQ : 0,1141- p_dev->dev.bus_id,1142- (req->Attributes & IRQ_HANDLE_PRESENT) ? req->Instance : data);1143- if (!ret) {1144- if (!(req->Attributes & IRQ_HANDLE_PRESENT))1145- free_irq(irq, data);1146- break;1147- }1148- }1149- }1150-#endif1151- if (ret) {1152- if (!s->pci_irq)1153- return ret;1154- irq = s->pci_irq;1155- }1156-1157- if (ret && req->Attributes & IRQ_HANDLE_PRESENT) {1158- if (request_irq(irq, req->Handler,1159- ((req->Attributes & IRQ_TYPE_DYNAMIC_SHARING) ||1160- (s->functions > 1) ||1161- (irq == s->pci_irq)) ? SA_SHIRQ : 0,1162- p_dev->dev.bus_id, req->Instance))1163- return CS_IN_USE;1164- }1165-1166- c->irq.Attributes = req->Attributes;1167- s->irq.AssignedIRQ = req->AssignedIRQ = irq;1168- s->irq.Config++;1169-1170- c->state |= CONFIG_IRQ_REQ;1171- handle->state |= CLIENT_IRQ_REQ;1172-1173-#ifdef CONFIG_PCMCIA_PROBE1174- pcmcia_used_irq[irq]++;1175-#endif1176-1177- return CS_SUCCESS;1178-} /* pcmcia_request_irq */1179-1180-/*======================================================================1181-1182- Request_window() establishes a mapping between card memory space1183- and system memory space.1184-1185-======================================================================*/1186-1187-int pcmcia_request_window(client_handle_t *handle, win_req_t *req, window_handle_t *wh)1188-{1189- struct pcmcia_socket *s;1190- window_t *win;1191- u_long align;1192- int w;1193-1194- if (CHECK_HANDLE(*handle))1195- return CS_BAD_HANDLE;1196- s = (*handle)->Socket;1197- if (!(s->state & SOCKET_PRESENT))1198- return CS_NO_CARD;1199- if (req->Attributes & (WIN_PAGED | WIN_SHARED))1200- return CS_BAD_ATTRIBUTE;1201-1202- /* Window size defaults to smallest available */1203- if (req->Size == 0)1204- req->Size = s->map_size;1205- align = (((s->features & SS_CAP_MEM_ALIGN) ||1206- (req->Attributes & WIN_STRICT_ALIGN)) ?1207- req->Size : s->map_size);1208- if (req->Size & (s->map_size-1))1209- return CS_BAD_SIZE;1210- if ((req->Base && (s->features & SS_CAP_STATIC_MAP)) ||1211- (req->Base & (align-1)))1212- return CS_BAD_BASE;1213- if (req->Base)1214- align = 0;1215-1216- /* Allocate system memory window */1217- for (w = 0; w < MAX_WIN; w++)1218- if (!(s->state & SOCKET_WIN_REQ(w))) break;1219- if (w == MAX_WIN)1220- return CS_OUT_OF_RESOURCE;1221-1222- win = &s->win[w];1223- win->magic = WINDOW_MAGIC;1224- win->index = w;1225- win->handle = *handle;1226- win->sock = s;1227-1228- if (!(s->features & SS_CAP_STATIC_MAP)) {1229- win->ctl.res = find_mem_region(req->Base, req->Size, align,1230- (req->Attributes & WIN_MAP_BELOW_1MB), s);1231- if (!win->ctl.res)1232- return CS_IN_USE;1233- }1234- (*handle)->state |= CLIENT_WIN_REQ(w);1235-1236- /* Configure the socket controller */1237- win->ctl.map = w+1;1238- win->ctl.flags = 0;1239- win->ctl.speed = req->AccessSpeed;1240- if (req->Attributes & WIN_MEMORY_TYPE)1241- win->ctl.flags |= MAP_ATTRIB;1242- if (req->Attributes & WIN_ENABLE)1243- win->ctl.flags |= MAP_ACTIVE;1244- if (req->Attributes & WIN_DATA_WIDTH_16)1245- win->ctl.flags |= MAP_16BIT;1246- if (req->Attributes & WIN_USE_WAIT)1247- win->ctl.flags |= MAP_USE_WAIT;1248- win->ctl.card_start = 0;1249- if (s->ops->set_mem_map(s, &win->ctl) != 0)1250- return CS_BAD_ARGS;1251- s->state |= SOCKET_WIN_REQ(w);1252-1253- /* Return window handle */1254- if (s->features & SS_CAP_STATIC_MAP) {1255- req->Base = win->ctl.static_start;1256- } else {1257- req->Base = win->ctl.res->start;1258- }1259- *wh = win;1260-1261- return CS_SUCCESS;1262-} /* request_window */1263-1264-/*======================================================================1265-1266- I'm not sure which "reset" function this is supposed to use,1267- but for now, it uses the low-level interface's reset, not the1268- CIS register.1269-1270-======================================================================*/12711272int pccard_reset_card(struct pcmcia_socket *skt)1273{1274 int ret;1275-1276 cs_dbg(skt, 1, "resetting socket\n");12771278 down(&skt->skt_sem);···778} /* reset_card */779EXPORT_SYMBOL(pccard_reset_card);780781-/*======================================================================782783- These shut down or wake up a socket. They are sort of user784- initiated versions of the APM suspend and resume actions.785-786-======================================================================*/787-788int pcmcia_suspend_card(struct pcmcia_socket *skt)789{790 int ret;791-792 cs_dbg(skt, 1, "suspending socket\n");793794 down(&skt->skt_sem);···804805 return ret;806} /* suspend_card */00807808int pcmcia_resume_card(struct pcmcia_socket *skt)809{···829830 return ret;831} /* resume_card */0832833-/*======================================================================834835- These handle user requests to eject or insert a card.836-837-======================================================================*/838-839int pcmcia_eject_card(struct pcmcia_socket *skt)840{841 int ret;···859860 return ret;861} /* eject_card */00862863int pcmcia_insert_card(struct pcmcia_socket *skt)864{···884885 return ret;886} /* insert_card */887-888-/*======================================================================889-890- OS-specific module glue goes here891-892-======================================================================*/893-/* in alpha order */894-EXPORT_SYMBOL(pcmcia_eject_card);895-EXPORT_SYMBOL(pcmcia_get_card_services_info);896-EXPORT_SYMBOL(pcmcia_get_mem_page);897EXPORT_SYMBOL(pcmcia_insert_card);898-EXPORT_SYMBOL(pcmcia_map_mem_page);899-EXPORT_SYMBOL(pcmcia_modify_configuration);900-EXPORT_SYMBOL(pcmcia_release_configuration);901-EXPORT_SYMBOL(pcmcia_release_io);902-EXPORT_SYMBOL(pcmcia_release_irq);903-EXPORT_SYMBOL(pcmcia_release_window);904-EXPORT_SYMBOL(pcmcia_replace_cis);905-EXPORT_SYMBOL(pcmcia_request_configuration);906-EXPORT_SYMBOL(pcmcia_request_io);907-EXPORT_SYMBOL(pcmcia_request_irq);908-EXPORT_SYMBOL(pcmcia_request_window);909-EXPORT_SYMBOL(pcmcia_resume_card);910-EXPORT_SYMBOL(pcmcia_suspend_card);911912-EXPORT_SYMBOL(dead_socket);913-EXPORT_SYMBOL(pcmcia_parse_events);0000000000000000000000914915struct class pcmcia_socket_class = {916 .name = "pcmcia_socket",0917 .release = pcmcia_release_socket,0918};919EXPORT_SYMBOL(pcmcia_socket_class);920···923static int __init init_pcmcia_cs(void)924{925 int ret;926- printk(KERN_INFO "%s\n", release);927- printk(KERN_INFO " %s\n", options);9280929 ret = class_register(&pcmcia_socket_class);930 if (ret)931 return (ret);···933934static void __exit exit_pcmcia_cs(void)935{936- printk(KERN_INFO "unloading Kernel Card Services\n");937- class_interface_unregister(&pccard_sysfs_interface);938- class_unregister(&pcmcia_socket_class);0939}940941subsys_initcall(init_pcmcia_cs);942module_exit(exit_pcmcia_cs);943-944-/*====================================================================*/945
···43#include <pcmcia/ds.h>44#include "cs_internal.h"4500000000000000000000000004647/* Module parameters */4849MODULE_AUTHOR("David Hinds <dahinds@users.sourceforge.net>");50+MODULE_DESCRIPTION("Linux Kernel Card Services");51MODULE_LICENSE("GPL");5253#define INT_MODULE_PARM(n, v) static int n = v; module_param(n, int, 0444)···89/* Access speed for attribute memory windows */90INT_MODULE_PARM(cis_speed, 300); /* ns */9100092#ifdef DEBUG93static int pc_debug;94···103}104#endif1050106107socket_state_t dead_socket = {108 .csc_mask = SS_DETECT,109};110+EXPORT_SYMBOL(dead_socket);111112113/* List of all sockets, protected by a rwsem */114LIST_HEAD(pcmcia_socket_list);0115EXPORT_SYMBOL(pcmcia_socket_list);116+117+DECLARE_RWSEM(pcmcia_socket_list_rwsem);118EXPORT_SYMBOL(pcmcia_socket_list_rwsem);119120000000000000121/**122+ * Low-level PCMCIA socket drivers need to register with the PCCard123+ * core using pcmcia_register_socket.124+ *125+ * socket drivers are expected to use the following callbacks in their126 * .drv struct:127 * - pcmcia_socket_dev_suspend128 * - pcmcia_socket_dev_resume···230 }231232 /* try to obtain a socket number [yes, it gets ugly if we233+ * register more than 2^sizeof(unsigned int) pcmcia234+ * sockets... but the socket number is deprecated235 * anyways, so I don't care] */236 down_write(&pcmcia_socket_list_rwsem);237 if (list_empty(&pcmcia_socket_list))···340EXPORT_SYMBOL(pcmcia_get_socket_by_nr);341342343+/**344+ * socket_setup() and shutdown_socket() are called by the main event345+ * handler when card insertion and removal events are received.346+ * socket_setup() turns on socket power and resets the socket, in two stages.347+ * shutdown_socket() unconfigures a socket and turns off socket power.348+ */000349static void shutdown_socket(struct pcmcia_socket *s)350{351+ cs_dbg(s, 1, "shutdown_socket\n");352353+ /* Blank out the socket state */354+ s->socket = dead_socket;355+ s->ops->init(s);356+ s->ops->set_socket(s, &s->socket);357+ s->irq.AssignedIRQ = s->irq.Config = 0;358+ s->lock_count = 0;359+ destroy_cis_cache(s);360#ifdef CONFIG_CARDBUS361+ cb_free(s);362#endif363+ s->functions = 0;364+ if (s->config) {365+ kfree(s->config);366+ s->config = NULL;0000000367 }368+369+ {370+ int status;371+ s->ops->get_status(s, &status);372+ if (status & SS_POWERON) {373+ printk(KERN_ERR "PCMCIA: socket %p: *** DANGER *** unable to remove socket power\n", s);374+ }375+ }376} /* shutdown_socket */3770378379+/**380+ * The central event handler. Send_event() sends an event to the381+ * 16-bit subsystem, which then calls the relevant device drivers.382+ * Parse_events() interprets the event bits from383+ * a card status change report. Do_shutdown() handles the high384+ * priority stuff associated with a card removal.385+ */0386387/* NOTE: send_event needs to be called with skt->sem held. */388···746 wake_up(&s->thread_wait);747 }748} /* pcmcia_parse_events */749+EXPORT_SYMBOL(pcmcia_parse_events);7500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000751752/* register pcmcia_callback */753int pccard_register_pcmcia(struct pcmcia_socket *s, struct pcmcia_callback *c)···1188}1189EXPORT_SYMBOL(pccard_register_pcmcia);1190011911192+/* I'm not sure which "reset" function this is supposed to use,1193+ * but for now, it uses the low-level interface's reset, not the1194+ * CIS register.1195+ */000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011961197int pccard_reset_card(struct pcmcia_socket *skt)1198{1199 int ret;1200+1201 cs_dbg(skt, 1, "resetting socket\n");12021203 down(&skt->skt_sem);···1757} /* reset_card */1758EXPORT_SYMBOL(pccard_reset_card);1759017601761+/* These shut down or wake up a socket. They are sort of user1762+ * initiated versions of the APM suspend and resume actions.1763+ */001764int pcmcia_suspend_card(struct pcmcia_socket *skt)1765{1766 int ret;1767+1768 cs_dbg(skt, 1, "suspending socket\n");17691770 down(&skt->skt_sem);···17861787 return ret;1788} /* suspend_card */1789+EXPORT_SYMBOL(pcmcia_suspend_card);1790+17911792int pcmcia_resume_card(struct pcmcia_socket *skt)1793{···18091810 return ret;1811} /* resume_card */1812+EXPORT_SYMBOL(pcmcia_resume_card);1813018141815+/* These handle user requests to eject or insert a card. */0001816int pcmcia_eject_card(struct pcmcia_socket *skt)1817{1818 int ret;···18421843 return ret;1844} /* eject_card */1845+EXPORT_SYMBOL(pcmcia_eject_card);1846+18471848int pcmcia_insert_card(struct pcmcia_socket *skt)1849{···18651866 return ret;1867} /* insert_card */00000000001868EXPORT_SYMBOL(pcmcia_insert_card);000000000000018691870+1871+static int pcmcia_socket_hotplug(struct class_device *dev, char **envp,1872+ int num_envp, char *buffer, int buffer_size)1873+{1874+ struct pcmcia_socket *s = container_of(dev, struct pcmcia_socket, dev);1875+ int i = 0, length = 0;1876+1877+ if (add_hotplug_env_var(envp, num_envp, &i, buffer, buffer_size,1878+ &length, "SOCKET_NO=%u", s->sock))1879+ return -ENOMEM;1880+1881+ envp[i] = NULL;1882+1883+ return 0;1884+}1885+1886+1887+static struct completion pcmcia_unload;1888+1889+static void pcmcia_release_socket_class(struct class *data)1890+{1891+ complete(&pcmcia_unload);1892+}1893+18941895struct class pcmcia_socket_class = {1896 .name = "pcmcia_socket",1897+ .hotplug = pcmcia_socket_hotplug,1898 .release = pcmcia_release_socket,1899+ .class_release = pcmcia_release_socket_class,1900};1901EXPORT_SYMBOL(pcmcia_socket_class);1902···1903static int __init init_pcmcia_cs(void)1904{1905 int ret;0019061907+ init_completion(&pcmcia_unload);1908 ret = class_register(&pcmcia_socket_class);1909 if (ret)1910 return (ret);···19141915static void __exit exit_pcmcia_cs(void)1916{1917+ class_interface_unregister(&pccard_sysfs_interface);1918+ class_unregister(&pcmcia_socket_class);1919+1920+ wait_for_completion(&pcmcia_unload);1921}19221923subsys_initcall(init_pcmcia_cs);1924module_exit(exit_pcmcia_cs);001925
+6-7
drivers/pcmcia/cs_internal.h
···123int read_cb_mem(struct pcmcia_socket *s, int space, u_int addr, u_int len, void *ptr);124125/* In cistpl.c */126-int read_cis_mem(struct pcmcia_socket *s, int attr,127 u_int addr, u_int len, void *ptr);128-void write_cis_mem(struct pcmcia_socket *s, int attr,129 u_int addr, u_int len, void *ptr);130void release_cis_mem(struct pcmcia_socket *s);131void destroy_cis_cache(struct pcmcia_socket *s);···134135/* In rsrc_mgr */136void pcmcia_validate_mem(struct pcmcia_socket *s);137-struct resource *find_io_region(unsigned long base, int num, unsigned long align,138 struct pcmcia_socket *s);139-int adjust_io_region(struct resource *res, unsigned long r_start,140 unsigned long r_end, struct pcmcia_socket *s);141-struct resource *find_mem_region(u_long base, u_long num, u_long align,142 int low, struct pcmcia_socket *s);143-int adjust_resource_info(client_handle_t handle, adjust_t *adj);144void release_resource_db(struct pcmcia_socket *s);145146/* In socket_sysfs.c */···158struct pcmcia_callback{159 struct module *owner;160 int (*event) (struct pcmcia_socket *s, event_t event, int priority);161- int (*resources_done) (struct pcmcia_socket *s);162};163164int pccard_register_pcmcia(struct pcmcia_socket *s, struct pcmcia_callback *c);
···123int read_cb_mem(struct pcmcia_socket *s, int space, u_int addr, u_int len, void *ptr);124125/* In cistpl.c */126+int pcmcia_read_cis_mem(struct pcmcia_socket *s, int attr,127 u_int addr, u_int len, void *ptr);128+void pcmcia_write_cis_mem(struct pcmcia_socket *s, int attr,129 u_int addr, u_int len, void *ptr);130void release_cis_mem(struct pcmcia_socket *s);131void destroy_cis_cache(struct pcmcia_socket *s);···134135/* In rsrc_mgr */136void pcmcia_validate_mem(struct pcmcia_socket *s);137+struct resource *pcmcia_find_io_region(unsigned long base, int num, unsigned long align,138 struct pcmcia_socket *s);139+int pcmcia_adjust_io_region(struct resource *res, unsigned long r_start,140 unsigned long r_end, struct pcmcia_socket *s);141+struct resource *pcmcia_find_mem_region(u_long base, u_long num, u_long align,142 int low, struct pcmcia_socket *s);0143void release_resource_db(struct pcmcia_socket *s);144145/* In socket_sysfs.c */···159struct pcmcia_callback{160 struct module *owner;161 int (*event) (struct pcmcia_socket *s, event_t event, int priority);162+ void (*requery) (struct pcmcia_socket *s);163};164165int pccard_register_pcmcia(struct pcmcia_socket *s, struct pcmcia_callback *c);
+428-843
drivers/pcmcia/ds.c
···10 * are Copyright (C) 1999 David A. Hinds. All Rights Reserved.11 *12 * (C) 1999 David A. Hinds13- * (C) 2003 - 2004 Dominik Brodowski14 */1516#include <linux/config.h>17-#include <linux/module.h>18-#include <linux/moduleparam.h>19-#include <linux/init.h>20#include <linux/kernel.h>21-#include <linux/major.h>22-#include <linux/string.h>23#include <linux/errno.h>24-#include <linux/slab.h>25-#include <linux/mm.h>26-#include <linux/fcntl.h>27-#include <linux/sched.h>28-#include <linux/smp_lock.h>29-#include <linux/timer.h>30-#include <linux/ioctl.h>31-#include <linux/proc_fs.h>32-#include <linux/poll.h>33-#include <linux/pci.h>34#include <linux/list.h>35#include <linux/delay.h>36-#include <linux/kref.h>37#include <linux/workqueue.h>38-39-#include <asm/atomic.h>4041#define IN_CARD_SERVICES42-#include <pcmcia/version.h>43#include <pcmcia/cs_types.h>44#include <pcmcia/cs.h>45-#include <pcmcia/bulkmem.h>46#include <pcmcia/cistpl.h>47#include <pcmcia/ds.h>48#include <pcmcia/ss.h>4950#include "cs_internal.h"05152/*====================================================================*/53···55#define ds_dbg(lvl, fmt, arg...) do { } while (0)56#endif5758-/*====================================================================*/5960-/* Device user information */61-#define MAX_EVENTS 3262-#define USER_MAGIC 0x7ea463-#define CHECK_USER(u) \64- (((u) == NULL) || ((u)->user_magic != USER_MAGIC))65-typedef struct user_info_t {66- u_int user_magic;67- int event_head, event_tail;68- event_t event[MAX_EVENTS];69- struct user_info_t *next;70- struct pcmcia_bus_socket *socket;71-} user_info_t;72-73-/* Socket state information */74-struct pcmcia_bus_socket {75- struct kref refcount;76- struct pcmcia_callback callback;77- int state;78- user_info_t *user;79- wait_queue_head_t queue;80- struct pcmcia_socket *parent;81-82- /* the PCMCIA devices connected to this socket (normally one, more83- * for multifunction devices: */84- struct list_head devices_list;85- u8 device_count; /* the number of devices, used86- * only internally and subject87- * to incorrectness and change */88-};89-static spinlock_t pcmcia_dev_list_lock;90-91-#define DS_SOCKET_PRESENT 0x0192-#define DS_SOCKET_BUSY 0x0293-#define DS_SOCKET_REMOVAL_PENDING 0x1094-#define DS_SOCKET_DEAD 0x8095-96-/*====================================================================*/97-98-static int major_dev = -1;99-100-static int unbind_request(struct pcmcia_bus_socket *s);101102/*====================================================================*/103···158};159160161-int pcmcia_report_error(client_handle_t handle, error_info_t *err)162{163 int i;164 char *serv;···188189 return CS_SUCCESS;190} /* report_error */191-EXPORT_SYMBOL(pcmcia_report_error);192193/* end of code which was in cs.c before */194···200}201EXPORT_SYMBOL(cs_error);20200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000203/*======================================================================*/204205-static struct pcmcia_driver * get_pcmcia_driver (dev_info_t *dev_info);206-static struct pcmcia_bus_socket * get_socket_info_by_nr(unsigned int nr);207-208-static void pcmcia_release_bus_socket(struct kref *refcount)209-{210- struct pcmcia_bus_socket *s = container_of(refcount, struct pcmcia_bus_socket, refcount);211- pcmcia_put_socket(s->parent);212- kfree(s);213-}214-215-static void pcmcia_put_bus_socket(struct pcmcia_bus_socket *s)216-{217- kref_put(&s->refcount, pcmcia_release_bus_socket);218-}219-220-static struct pcmcia_bus_socket *pcmcia_get_bus_socket(struct pcmcia_bus_socket *s)221-{222- kref_get(&s->refcount);223- return (s);224-}225226/**227 * pcmcia_register_driver - register a PCMCIA driver with the bus core···307{308 if (!driver)309 return -EINVAL;00310311 /* initialize common fields */312 driver->drv.bus = &pcmcia_bus_type;···329}330EXPORT_SYMBOL(pcmcia_unregister_driver);331332-#ifdef CONFIG_PROC_FS333-static struct proc_dir_entry *proc_pccard = NULL;334-335-static int proc_read_drivers_callback(struct device_driver *driver, void *d)336-{337- char **p = d;338- struct pcmcia_driver *p_drv = container_of(driver,339- struct pcmcia_driver, drv);340-341- *p += sprintf(*p, "%-24.24s 1 %d\n", p_drv->drv.name,342-#ifdef CONFIG_MODULE_UNLOAD343- (p_drv->owner) ? module_refcount(p_drv->owner) : 1344-#else345- 1346-#endif347- );348- d = (void *) p;349-350- return 0;351-}352-353-static int proc_read_drivers(char *buf, char **start, off_t pos,354- int count, int *eof, void *data)355-{356- char *p = buf;357-358- bus_for_each_drv(&pcmcia_bus_type, NULL, 359- (void *) &p, proc_read_drivers_callback);360-361- return (p - buf);362-}363-#endif364365/* pcmcia_device handling */366367-static struct pcmcia_device * pcmcia_get_dev(struct pcmcia_device *p_dev)368{369 struct device *tmp_dev;370 tmp_dev = get_device(&p_dev->dev);···341 return to_pcmcia_dev(tmp_dev);342}343344-static void pcmcia_put_dev(struct pcmcia_device *p_dev)345{346 if (p_dev)347 put_device(&p_dev->dev);···351{352 struct pcmcia_device *p_dev = to_pcmcia_dev(dev);353 ds_dbg(1, "releasing dev %p\n", p_dev);354- pcmcia_put_bus_socket(p_dev->socket->pcmcia);355 kfree(p_dev);356}357···486 */487static DECLARE_MUTEX(device_add_lock);488489-static struct pcmcia_device * pcmcia_device_add(struct pcmcia_bus_socket *s, unsigned int function)490{491 struct pcmcia_device *p_dev;492 unsigned long flags;493494- s = pcmcia_get_bus_socket(s);495 if (!s)496 return NULL;497498 down(&device_add_lock);0000499500 p_dev = kmalloc(sizeof(struct pcmcia_device), GFP_KERNEL);501 if (!p_dev)502 goto err_put;503 memset(p_dev, 0, sizeof(struct pcmcia_device));504505- p_dev->socket = s->parent;506 p_dev->device_no = (s->device_count++);507 p_dev->func = function;508509 p_dev->dev.bus = &pcmcia_bus_type;510- p_dev->dev.parent = s->parent->dev.dev;511 p_dev->dev.release = pcmcia_release_dev;512 sprintf (p_dev->dev.bus_id, "%d.%d", p_dev->socket->sock, p_dev->device_no);513514 /* compat */515 p_dev->client.client_magic = CLIENT_MAGIC;516- p_dev->client.Socket = s->parent;517 p_dev->client.Function = function;518 p_dev->client.state = CLIENT_UNBOUND;519···525 spin_lock_irqsave(&pcmcia_dev_list_lock, flags);526 list_add_tail(&p_dev->socket_device_list, &s->devices_list);527 spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags);00528529 if (device_register(&p_dev->dev)) {530 spin_lock_irqsave(&pcmcia_dev_list_lock, flags);···545 s->device_count--;546 err_put:547 up(&device_add_lock);548- pcmcia_put_bus_socket(s);549550 return NULL;551}···576 /* this doesn't handle multifunction devices on one pcmcia function577 * yet. */578 for (i=0; i < no_funcs; i++)579- pcmcia_device_add(s->pcmcia, i);580581 return (ret);0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000582}583584585static int pcmcia_bus_match(struct device * dev, struct device_driver * drv) {586 struct pcmcia_device * p_dev = to_pcmcia_dev(dev);587 struct pcmcia_driver * p_drv = to_pcmcia_drv(drv);0588589 /* matching by cardmgr */590 if (p_dev->cardmgr == p_drv)591 return 1;592000000593 return 0;594}00000000000000000000000000000000000000000000000000000000000000000595596/************************ per-device sysfs output ***************************/597···847pcmcia_device_stringattr(prod_id3, prod_id[2]);848pcmcia_device_stringattr(prod_id4, prod_id[3]);8490000000000000000000000000000000000000850static struct device_attribute pcmcia_dev_attrs[] = {851 __ATTR(function, 0444, func_show, NULL),852 __ATTR_RO(func_id),···893 __ATTR_RO(prod_id2),894 __ATTR_RO(prod_id3),895 __ATTR_RO(prod_id4),00896 __ATTR_NULL,897};898-899-900-/*======================================================================901-902- These manage a ring buffer of events pending for one user process903-904-======================================================================*/905-906-static int queue_empty(user_info_t *user)907-{908- return (user->event_head == user->event_tail);909-}910-911-static event_t get_queued_event(user_info_t *user)912-{913- user->event_tail = (user->event_tail+1) % MAX_EVENTS;914- return user->event[user->event_tail];915-}916-917-static void queue_event(user_info_t *user, event_t event)918-{919- user->event_head = (user->event_head+1) % MAX_EVENTS;920- if (user->event_head == user->event_tail)921- user->event_tail = (user->event_tail+1) % MAX_EVENTS;922- user->event[user->event_head] = event;923-}924-925-static void handle_event(struct pcmcia_bus_socket *s, event_t event)926-{927- user_info_t *user;928- for (user = s->user; user; user = user->next)929- queue_event(user, event);930- wake_up_interruptible(&s->queue);931-}932933934/*======================================================================···932933static int send_event(struct pcmcia_socket *s, event_t event, int priority)934{935- int ret = 0;936 struct send_event_data private;937- struct pcmcia_bus_socket *skt = pcmcia_get_bus_socket(s->pcmcia);938-939- if (!skt)940- return 0;941942 private.skt = s;943 private.event = event;944 private.priority = priority;945946- ret = bus_for_each_dev(&pcmcia_bus_type, NULL, &private, send_event_callback);947-948- pcmcia_put_bus_socket(skt);949- return ret;950} /* send_event */951952···949950static int ds_event(struct pcmcia_socket *skt, event_t event, int priority)951{952- struct pcmcia_bus_socket *s = skt->pcmcia;953 int ret = 0;954955 ds_dbg(1, "ds_event(0x%06x, %d, 0x%p)\n",956- event, priority, s);957958 switch (event) {959960 case CS_EVENT_CARD_REMOVAL:961- s->state &= ~DS_SOCKET_PRESENT;962 send_event(skt, event, priority);963- unbind_request(s);964- handle_event(s, event);965 break;966967 case CS_EVENT_CARD_INSERTION:968- s->state |= DS_SOCKET_PRESENT;969 pcmcia_card_add(skt);970- handle_event(s, event);971 break;972973 case CS_EVENT_EJECTION_REQUEST:···975 break;976977 default:978- handle_event(s, event);979 send_event(skt, event, priority);980 break;981 }00982983 return 0;984} /* ds_event */985986987-/*======================================================================988-989- bind_request() and bind_device() are merged by now. Register_client()990- is called right at the end of bind_request(), during the driver's991- ->attach() call. Individual descriptions:992-993- bind_request() connects a socket to a particular client driver.994- It looks up the specified device ID in the list of registered995- drivers, binds it to the socket, and tries to create an instance996- of the device. unbind_request() deletes a driver instance.997-998- Bind_device() associates a device driver with a particular socket.999- It is normally called by Driver Services after it has identified1000- a newly inserted card. An instance of that driver will then be1001- eligible to register as a client of this socket.1002-1003- Register_client() uses the dev_info_t handle to match the1004- caller with a socket. The driver must have already been bound1005- to a socket with bind_device() -- in fact, bind_device()1006- allocates the client structure that will be used.1007-1008-======================================================================*/1009-1010-static int bind_request(struct pcmcia_bus_socket *s, bind_info_t *bind_info)1011-{1012- struct pcmcia_driver *p_drv;1013- struct pcmcia_device *p_dev;1014- int ret = 0;1015- unsigned long flags;1016-1017- s = pcmcia_get_bus_socket(s);1018- if (!s)1019- return -EINVAL;1020-1021- ds_dbg(2, "bind_request(%d, '%s')\n", s->parent->sock,1022- (char *)bind_info->dev_info);1023-1024- p_drv = get_pcmcia_driver(&bind_info->dev_info);1025- if (!p_drv) {1026- ret = -EINVAL;1027- goto err_put;1028- }1029-1030- if (!try_module_get(p_drv->owner)) {1031- ret = -EINVAL;1032- goto err_put_driver;1033- }1034-1035- spin_lock_irqsave(&pcmcia_dev_list_lock, flags);1036- list_for_each_entry(p_dev, &s->devices_list, socket_device_list) {1037- if (p_dev->func == bind_info->function) {1038- if ((p_dev->dev.driver == &p_drv->drv)) {1039- if (p_dev->cardmgr) {1040- /* if there's already a device1041- * registered, and it was registered1042- * by userspace before, we need to1043- * return the "instance". */1044- spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags);1045- bind_info->instance = p_dev->instance;1046- ret = -EBUSY;1047- goto err_put_module;1048- } else {1049- /* the correct driver managed to bind1050- * itself magically to the correct1051- * device. */1052- spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags);1053- p_dev->cardmgr = p_drv;1054- ret = 0;1055- goto err_put_module;1056- }1057- } else if (!p_dev->dev.driver) {1058- /* there's already a device available where1059- * no device has been bound to yet. So we don't1060- * need to register a device! */1061- spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags);1062- goto rescan;1063- }1064- }1065- }1066- spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags);1067-1068- p_dev = pcmcia_device_add(s, bind_info->function);1069- if (!p_dev) {1070- ret = -EIO;1071- goto err_put_module;1072- }1073-1074-rescan:1075- p_dev->cardmgr = p_drv;1076-1077- pcmcia_device_query(p_dev);1078-1079- /*1080- * Prevent this racing with a card insertion.1081- */1082- down(&s->parent->skt_sem);1083- bus_rescan_devices(&pcmcia_bus_type);1084- up(&s->parent->skt_sem);1085-1086- /* check whether the driver indeed matched. I don't care if this1087- * is racy or not, because it can only happen on cardmgr access1088- * paths...1089- */1090- if (!(p_dev->dev.driver == &p_drv->drv))1091- p_dev->cardmgr = NULL;1092-1093- err_put_module:1094- module_put(p_drv->owner);1095- err_put_driver:1096- put_driver(&p_drv->drv);1097- err_put:1098- pcmcia_put_bus_socket(s);1099-1100- return (ret);1101-} /* bind_request */1102-11031104int pcmcia_register_client(client_handle_t *handle, client_reg_t *req)1105{1106 client_t *client = NULL;1107- struct pcmcia_socket *s;1108- struct pcmcia_bus_socket *skt = NULL;1109 struct pcmcia_device *p_dev = NULL;11101111 /* Look for unbound client with matching dev_info */···1001 if (s->state & SOCKET_CARDBUS)1002 continue;10031004- skt = s->pcmcia;1005- if (!skt)1006- continue;1007- skt = pcmcia_get_bus_socket(skt);1008- if (!skt)1009 continue;1010 spin_lock_irqsave(&pcmcia_dev_list_lock, flags);1011- list_for_each_entry(p_dev, &skt->devices_list, socket_device_list) {1012 struct pcmcia_driver *p_drv;1013 p_dev = pcmcia_get_dev(p_dev);1014 if (!p_dev)···1024 pcmcia_put_dev(p_dev);1025 }1026 spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags);1027- pcmcia_put_bus_socket(skt);1028 }1029 found:1030 up_read(&pcmcia_socket_list_rwsem);1031 if (!p_dev || !client)1032 return -ENODEV;10331034- pcmcia_put_bus_socket(skt); /* safe, as we already hold a reference from bind_device */10351036 *handle = client;1037 client->state &= ~CLIENT_UNBOUND;···1078EXPORT_SYMBOL(pcmcia_register_client);107910801081-/*====================================================================*/1082-1083-extern struct pci_bus *pcmcia_lookup_bus(struct pcmcia_socket *s);1084-1085-static int get_device_info(struct pcmcia_bus_socket *s, bind_info_t *bind_info, int first)1086-{1087- dev_node_t *node;1088- struct pcmcia_device *p_dev;1089- unsigned long flags;1090- int ret = 0;1091-1092-#ifdef CONFIG_CARDBUS1093- /*1094- * Some unbelievably ugly code to associate the PCI cardbus1095- * device and its driver with the PCMCIA "bind" information.1096- */1097- {1098- struct pci_bus *bus;1099-1100- bus = pcmcia_lookup_bus(s->parent);1101- if (bus) {1102- struct list_head *list;1103- struct pci_dev *dev = NULL;1104-1105- list = bus->devices.next;1106- while (list != &bus->devices) {1107- struct pci_dev *pdev = pci_dev_b(list);1108- list = list->next;1109-1110- if (first) {1111- dev = pdev;1112- break;1113- }1114-1115- /* Try to handle "next" here some way? */1116- }1117- if (dev && dev->driver) {1118- strlcpy(bind_info->name, dev->driver->name, DEV_NAME_LEN);1119- bind_info->major = 0;1120- bind_info->minor = 0;1121- bind_info->next = NULL;1122- return 0;1123- }1124- }1125- }1126-#endif1127-1128- spin_lock_irqsave(&pcmcia_dev_list_lock, flags);1129- list_for_each_entry(p_dev, &s->devices_list, socket_device_list) {1130- if (p_dev->func == bind_info->function) {1131- p_dev = pcmcia_get_dev(p_dev);1132- if (!p_dev)1133- continue;1134- goto found;1135- }1136- }1137- spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags);1138- return -ENODEV;1139-1140- found:1141- spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags);1142-1143- if ((!p_dev->instance) ||1144- (p_dev->instance->state & DEV_CONFIG_PENDING)) {1145- ret = -EAGAIN;1146- goto err_put;1147- }1148-1149- if (first)1150- node = p_dev->instance->dev;1151- else1152- for (node = p_dev->instance->dev; node; node = node->next)1153- if (node == bind_info->next)1154- break;1155- if (!node) {1156- ret = -ENODEV;1157- goto err_put;1158- }1159-1160- strlcpy(bind_info->name, node->dev_name, DEV_NAME_LEN);1161- bind_info->major = node->major;1162- bind_info->minor = node->minor;1163- bind_info->next = node->next;1164-1165- err_put:1166- pcmcia_put_dev(p_dev);1167- return (ret);1168-} /* get_device_info */1169-1170-/*====================================================================*/1171-1172/* unbind _all_ devices attached to a given pcmcia_bus_socket. The1173 * drivers have been called with EVENT_CARD_REMOVAL before.1174 */1175-static int unbind_request(struct pcmcia_bus_socket *s)1176{1177 struct pcmcia_device *p_dev;1178 unsigned long flags;11791180- ds_dbg(2, "unbind_request(%d)\n", s->parent->sock);11811182 s->device_count = 0;1183···1142} /* deregister_client */1143EXPORT_SYMBOL(pcmcia_deregister_client);11441145-1146-/*======================================================================1147-1148- The user-mode PC Card device interface1149-1150-======================================================================*/1151-1152-static int ds_open(struct inode *inode, struct file *file)1153-{1154- socket_t i = iminor(inode);1155- struct pcmcia_bus_socket *s;1156- user_info_t *user;1157-1158- ds_dbg(0, "ds_open(socket %d)\n", i);1159-1160- s = get_socket_info_by_nr(i);1161- if (!s)1162- return -ENODEV;1163- s = pcmcia_get_bus_socket(s);1164- if (!s)1165- return -ENODEV;1166-1167- if ((file->f_flags & O_ACCMODE) != O_RDONLY) {1168- if (s->state & DS_SOCKET_BUSY) {1169- pcmcia_put_bus_socket(s);1170- return -EBUSY;1171- }1172- else1173- s->state |= DS_SOCKET_BUSY;1174- }1175-1176- user = kmalloc(sizeof(user_info_t), GFP_KERNEL);1177- if (!user) {1178- pcmcia_put_bus_socket(s);1179- return -ENOMEM;1180- }1181- user->event_tail = user->event_head = 0;1182- user->next = s->user;1183- user->user_magic = USER_MAGIC;1184- user->socket = s;1185- s->user = user;1186- file->private_data = user;1187-1188- if (s->state & DS_SOCKET_PRESENT)1189- queue_event(user, CS_EVENT_CARD_INSERTION);1190- return 0;1191-} /* ds_open */1192-1193-/*====================================================================*/1194-1195-static int ds_release(struct inode *inode, struct file *file)1196-{1197- struct pcmcia_bus_socket *s;1198- user_info_t *user, **link;1199-1200- ds_dbg(0, "ds_release(socket %d)\n", iminor(inode));1201-1202- user = file->private_data;1203- if (CHECK_USER(user))1204- goto out;1205-1206- s = user->socket;1207-1208- /* Unlink user data structure */1209- if ((file->f_flags & O_ACCMODE) != O_RDONLY) {1210- s->state &= ~DS_SOCKET_BUSY;1211- }1212- file->private_data = NULL;1213- for (link = &s->user; *link; link = &(*link)->next)1214- if (*link == user) break;1215- if (link == NULL)1216- goto out;1217- *link = user->next;1218- user->user_magic = 0;1219- kfree(user);1220- pcmcia_put_bus_socket(s);1221-out:1222- return 0;1223-} /* ds_release */1224-1225-/*====================================================================*/1226-1227-static ssize_t ds_read(struct file *file, char __user *buf,1228- size_t count, loff_t *ppos)1229-{1230- struct pcmcia_bus_socket *s;1231- user_info_t *user;1232- int ret;1233-1234- ds_dbg(2, "ds_read(socket %d)\n", iminor(file->f_dentry->d_inode));1235-1236- if (count < 4)1237- return -EINVAL;1238-1239- user = file->private_data;1240- if (CHECK_USER(user))1241- return -EIO;1242-1243- s = user->socket;1244- if (s->state & DS_SOCKET_DEAD)1245- return -EIO;1246-1247- ret = wait_event_interruptible(s->queue, !queue_empty(user));1248- if (ret == 0)1249- ret = put_user(get_queued_event(user), (int __user *)buf) ? -EFAULT : 4;1250-1251- return ret;1252-} /* ds_read */1253-1254-/*====================================================================*/1255-1256-static ssize_t ds_write(struct file *file, const char __user *buf,1257- size_t count, loff_t *ppos)1258-{1259- ds_dbg(2, "ds_write(socket %d)\n", iminor(file->f_dentry->d_inode));1260-1261- if (count != 4)1262- return -EINVAL;1263- if ((file->f_flags & O_ACCMODE) == O_RDONLY)1264- return -EBADF;1265-1266- return -EIO;1267-} /* ds_write */1268-1269-/*====================================================================*/1270-1271-/* No kernel lock - fine */1272-static u_int ds_poll(struct file *file, poll_table *wait)1273-{1274- struct pcmcia_bus_socket *s;1275- user_info_t *user;1276-1277- ds_dbg(2, "ds_poll(socket %d)\n", iminor(file->f_dentry->d_inode));1278-1279- user = file->private_data;1280- if (CHECK_USER(user))1281- return POLLERR;1282- s = user->socket;1283- /*1284- * We don't check for a dead socket here since that1285- * will send cardmgr into an endless spin.1286- */1287- poll_wait(file, &s->queue, wait);1288- if (!queue_empty(user))1289- return POLLIN | POLLRDNORM;1290- return 0;1291-} /* ds_poll */1292-1293-/*====================================================================*/1294-1295-extern int pcmcia_adjust_resource_info(adjust_t *adj);1296-1297-static int ds_ioctl(struct inode * inode, struct file * file,1298- u_int cmd, u_long arg)1299-{1300- struct pcmcia_bus_socket *s;1301- void __user *uarg = (char __user *)arg;1302- u_int size;1303- int ret, err;1304- ds_ioctl_arg_t *buf;1305- user_info_t *user;1306-1307- ds_dbg(2, "ds_ioctl(socket %d, %#x, %#lx)\n", iminor(inode), cmd, arg);1308-1309- user = file->private_data;1310- if (CHECK_USER(user))1311- return -EIO;1312-1313- s = user->socket;1314- if (s->state & DS_SOCKET_DEAD)1315- return -EIO;1316-1317- size = (cmd & IOCSIZE_MASK) >> IOCSIZE_SHIFT;1318- if (size > sizeof(ds_ioctl_arg_t)) return -EINVAL;1319-1320- /* Permission check */1321- if (!(cmd & IOC_OUT) && !capable(CAP_SYS_ADMIN))1322- return -EPERM;1323-1324- if (cmd & IOC_IN) {1325- if (!access_ok(VERIFY_READ, uarg, size)) {1326- ds_dbg(3, "ds_ioctl(): verify_read = %d\n", -EFAULT);1327- return -EFAULT;1328- }1329- }1330- if (cmd & IOC_OUT) {1331- if (!access_ok(VERIFY_WRITE, uarg, size)) {1332- ds_dbg(3, "ds_ioctl(): verify_write = %d\n", -EFAULT);1333- return -EFAULT;1334- }1335- }1336- buf = kmalloc(sizeof(ds_ioctl_arg_t), GFP_KERNEL);1337- if (!buf)1338- return -ENOMEM;1339-1340- err = ret = 0;1341-1342- if (cmd & IOC_IN) __copy_from_user((char *)buf, uarg, size);1343-1344- switch (cmd) {1345- case DS_ADJUST_RESOURCE_INFO:1346- ret = pcmcia_adjust_resource_info(&buf->adjust);1347- break;1348- case DS_GET_CARD_SERVICES_INFO:1349- ret = pcmcia_get_card_services_info(&buf->servinfo);1350- break;1351- case DS_GET_CONFIGURATION_INFO:1352- if (buf->config.Function &&1353- (buf->config.Function >= s->parent->functions))1354- ret = CS_BAD_ARGS;1355- else1356- ret = pccard_get_configuration_info(s->parent,1357- buf->config.Function, &buf->config);1358- break;1359- case DS_GET_FIRST_TUPLE:1360- down(&s->parent->skt_sem);1361- pcmcia_validate_mem(s->parent);1362- up(&s->parent->skt_sem);1363- ret = pccard_get_first_tuple(s->parent, BIND_FN_ALL, &buf->tuple);1364- break;1365- case DS_GET_NEXT_TUPLE:1366- ret = pccard_get_next_tuple(s->parent, BIND_FN_ALL, &buf->tuple);1367- break;1368- case DS_GET_TUPLE_DATA:1369- buf->tuple.TupleData = buf->tuple_parse.data;1370- buf->tuple.TupleDataMax = sizeof(buf->tuple_parse.data);1371- ret = pccard_get_tuple_data(s->parent, &buf->tuple);1372- break;1373- case DS_PARSE_TUPLE:1374- buf->tuple.TupleData = buf->tuple_parse.data;1375- ret = pccard_parse_tuple(&buf->tuple, &buf->tuple_parse.parse);1376- break;1377- case DS_RESET_CARD:1378- ret = pccard_reset_card(s->parent);1379- break;1380- case DS_GET_STATUS:1381- if (buf->status.Function &&1382- (buf->status.Function >= s->parent->functions))1383- ret = CS_BAD_ARGS;1384- else1385- ret = pccard_get_status(s->parent, buf->status.Function, &buf->status);1386- break;1387- case DS_VALIDATE_CIS:1388- down(&s->parent->skt_sem);1389- pcmcia_validate_mem(s->parent);1390- up(&s->parent->skt_sem);1391- ret = pccard_validate_cis(s->parent, BIND_FN_ALL, &buf->cisinfo);1392- break;1393- case DS_SUSPEND_CARD:1394- ret = pcmcia_suspend_card(s->parent);1395- break;1396- case DS_RESUME_CARD:1397- ret = pcmcia_resume_card(s->parent);1398- break;1399- case DS_EJECT_CARD:1400- err = pcmcia_eject_card(s->parent);1401- break;1402- case DS_INSERT_CARD:1403- err = pcmcia_insert_card(s->parent);1404- break;1405- case DS_ACCESS_CONFIGURATION_REGISTER:1406- if ((buf->conf_reg.Action == CS_WRITE) && !capable(CAP_SYS_ADMIN)) {1407- err = -EPERM;1408- goto free_out;1409- }1410- if (buf->conf_reg.Function &&1411- (buf->conf_reg.Function >= s->parent->functions))1412- ret = CS_BAD_ARGS;1413- else1414- ret = pccard_access_configuration_register(s->parent,1415- buf->conf_reg.Function, &buf->conf_reg);1416- break;1417- case DS_GET_FIRST_REGION:1418- case DS_GET_NEXT_REGION:1419- case DS_BIND_MTD:1420- if (!capable(CAP_SYS_ADMIN)) {1421- err = -EPERM;1422- goto free_out;1423- } else {1424- static int printed = 0;1425- if (!printed) {1426- printk(KERN_WARNING "2.6. kernels use pcmciamtd instead of memory_cs.c and do not require special\n");1427- printk(KERN_WARNING "MTD handling any more.\n");1428- printed++;1429- }1430- }1431- err = -EINVAL;1432- goto free_out;1433- break;1434- case DS_GET_FIRST_WINDOW:1435- ret = pcmcia_get_window(s->parent, &buf->win_info.handle, 0,1436- &buf->win_info.window);1437- break;1438- case DS_GET_NEXT_WINDOW:1439- ret = pcmcia_get_window(s->parent, &buf->win_info.handle,1440- buf->win_info.handle->index + 1, &buf->win_info.window);1441- break;1442- case DS_GET_MEM_PAGE:1443- ret = pcmcia_get_mem_page(buf->win_info.handle,1444- &buf->win_info.map);1445- break;1446- case DS_REPLACE_CIS:1447- ret = pcmcia_replace_cis(s->parent, &buf->cisdump);1448- break;1449- case DS_BIND_REQUEST:1450- if (!capable(CAP_SYS_ADMIN)) {1451- err = -EPERM;1452- goto free_out;1453- }1454- err = bind_request(s, &buf->bind_info);1455- break;1456- case DS_GET_DEVICE_INFO:1457- err = get_device_info(s, &buf->bind_info, 1);1458- break;1459- case DS_GET_NEXT_DEVICE:1460- err = get_device_info(s, &buf->bind_info, 0);1461- break;1462- case DS_UNBIND_REQUEST:1463- err = 0;1464- break;1465- default:1466- err = -EINVAL;1467- }1468-1469- if ((err == 0) && (ret != CS_SUCCESS)) {1470- ds_dbg(2, "ds_ioctl: ret = %d\n", ret);1471- switch (ret) {1472- case CS_BAD_SOCKET: case CS_NO_CARD:1473- err = -ENODEV; break;1474- case CS_BAD_ARGS: case CS_BAD_ATTRIBUTE: case CS_BAD_IRQ:1475- case CS_BAD_TUPLE:1476- err = -EINVAL; break;1477- case CS_IN_USE:1478- err = -EBUSY; break;1479- case CS_OUT_OF_RESOURCE:1480- err = -ENOSPC; break;1481- case CS_NO_MORE_ITEMS:1482- err = -ENODATA; break;1483- case CS_UNSUPPORTED_FUNCTION:1484- err = -ENOSYS; break;1485- default:1486- err = -EIO; break;1487- }1488- }1489-1490- if (cmd & IOC_OUT) {1491- if (__copy_to_user(uarg, (char *)buf, size))1492- err = -EFAULT;1493- }1494-1495-free_out:1496- kfree(buf);1497- return err;1498-} /* ds_ioctl */1499-1500-/*====================================================================*/1501-1502-static struct file_operations ds_fops = {1503- .owner = THIS_MODULE,1504- .open = ds_open,1505- .release = ds_release,1506- .ioctl = ds_ioctl,1507- .read = ds_read,1508- .write = ds_write,1509- .poll = ds_poll,1510};15111512static int __devinit pcmcia_bus_add_socket(struct class_device *class_dev)1513{1514 struct pcmcia_socket *socket = class_get_devdata(class_dev);1515- struct pcmcia_bus_socket *s;1516 int ret;15171518- s = kmalloc(sizeof(struct pcmcia_bus_socket), GFP_KERNEL);1519- if(!s)1520- return -ENOMEM;1521- memset(s, 0, sizeof(struct pcmcia_bus_socket));1522-1523- /* get reference to parent socket */1524- s->parent = pcmcia_get_socket(socket);1525- if (!s->parent) {1526 printk(KERN_ERR "PCMCIA obtaining reference to socket %p failed\n", socket);1527- kfree (s);1528 return -ENODEV;1529 }15301531- kref_init(&s->refcount);1532-1533 /*1534 * Ugly. But we want to wait for the socket threads to have started up.1535 * We really should let the drivers themselves drive some of this..1536 */1537 msleep(250);15381539- init_waitqueue_head(&s->queue);1540- INIT_LIST_HEAD(&s->devices_list);0000015411542- /* Set up hotline to Card Services */1543- s->callback.owner = THIS_MODULE;1544- s->callback.event = &ds_event;1545- s->callback.resources_done = &pcmcia_card_add;1546- socket->pcmcia = s;1547-1548- ret = pccard_register_pcmcia(socket, &s->callback);1549 if (ret) {1550 printk(KERN_ERR "PCMCIA registration PCCard core failed for socket %p\n", socket);1551- pcmcia_put_bus_socket(s);1552- socket->pcmcia = NULL;1553 return (ret);1554 }15551556 return 0;1557}15581559-1560static void pcmcia_bus_remove_socket(struct class_device *class_dev)1561{1562 struct pcmcia_socket *socket = class_get_devdata(class_dev);15631564- if (!socket || !socket->pcmcia)1565 return;156601567 pccard_register_pcmcia(socket, NULL);15681569- socket->pcmcia->state |= DS_SOCKET_DEAD;1570- pcmcia_put_bus_socket(socket->pcmcia);1571- socket->pcmcia = NULL;15721573 return;1574}···12091210struct bus_type pcmcia_bus_type = {1211 .name = "pcmcia",01212 .match = pcmcia_bus_match,1213 .dev_attrs = pcmcia_dev_attrs,1214};1215-EXPORT_SYMBOL(pcmcia_bus_type);121612171218static int __init init_pcmcia_bus(void)1219{1220- int i;1221-1222 spin_lock_init(&pcmcia_dev_list_lock);12231224 bus_register(&pcmcia_bus_type);1225 class_interface_register(&pcmcia_bus_interface);12261227- /* Set up character device for user mode clients */1228- i = register_chrdev(0, "pcmcia", &ds_fops);1229- if (i < 0)1230- printk(KERN_NOTICE "unable to find a free device # for "1231- "Driver Services (error=%d)\n", i);1232- else1233- major_dev = i;1234-1235-#ifdef CONFIG_PROC_FS1236- proc_pccard = proc_mkdir("pccard", proc_bus);1237- if (proc_pccard)1238- create_proc_read_entry("drivers",0,proc_pccard,proc_read_drivers,NULL);1239-#endif12401241 return 0;1242}···12321233static void __exit exit_pcmcia_bus(void)1234{1235- class_interface_unregister(&pcmcia_bus_interface);12361237-#ifdef CONFIG_PROC_FS1238- if (proc_pccard) {1239- remove_proc_entry("drivers", proc_pccard);1240- remove_proc_entry("pccard", proc_bus);1241- }1242-#endif1243- if (major_dev != -1)1244- unregister_chrdev(major_dev, "pcmcia");12451246 bus_unregister(&pcmcia_bus_type);1247}1248module_exit(exit_pcmcia_bus);12491250-1251-1252-/* helpers for backwards-compatible functions */1253-1254-static struct pcmcia_bus_socket * get_socket_info_by_nr(unsigned int nr)1255-{1256- struct pcmcia_socket * s = pcmcia_get_socket_by_nr(nr);1257- if (s && s->pcmcia)1258- return s->pcmcia;1259- else1260- return NULL;1261-}1262-1263-/* backwards-compatible accessing of driver --- by name! */1264-1265-static struct pcmcia_driver * get_pcmcia_driver (dev_info_t *dev_info)1266-{1267- struct device_driver *drv;1268- struct pcmcia_driver *p_drv;1269-1270- drv = driver_find((char *) dev_info, &pcmcia_bus_type);1271- if (!drv)1272- return NULL;1273-1274- p_drv = container_of(drv, struct pcmcia_driver, drv);1275-1276- return (p_drv);1277-}12781279MODULE_ALIAS("ds");
···10 * are Copyright (C) 1999 David A. Hinds. All Rights Reserved.11 *12 * (C) 1999 David A. Hinds13+ * (C) 2003 - 2005 Dominik Brodowski14 */1516#include <linux/config.h>00017#include <linux/kernel.h>18+#include <linux/module.h>19+#include <linux/init.h>20#include <linux/errno.h>000000000021#include <linux/list.h>22#include <linux/delay.h>023#include <linux/workqueue.h>24+#include <linux/crc32.h>25+#include <linux/firmware.h>2627#define IN_CARD_SERVICES028#include <pcmcia/cs_types.h>29#include <pcmcia/cs.h>030#include <pcmcia/cistpl.h>31#include <pcmcia/ds.h>32#include <pcmcia/ss.h>3334#include "cs_internal.h"35+#include "ds_internal.h"3637/*====================================================================*/38···70#define ds_dbg(lvl, fmt, arg...) do { } while (0)71#endif7273+spinlock_t pcmcia_dev_list_lock;7475+static int unbind_request(struct pcmcia_socket *s);00000000000000000000000000000000000000007677/*====================================================================*/78···213};214215216+static int pcmcia_report_error(client_handle_t handle, error_info_t *err)217{218 int i;219 char *serv;···243244 return CS_SUCCESS;245} /* report_error */0246247/* end of code which was in cs.c before */248···256}257EXPORT_SYMBOL(cs_error);258259+260+static void pcmcia_check_driver(struct pcmcia_driver *p_drv)261+{262+ struct pcmcia_device_id *did = p_drv->id_table;263+ unsigned int i;264+ u32 hash;265+266+ while (did && did->match_flags) {267+ for (i=0; i<4; i++) {268+ if (!did->prod_id[i])269+ continue;270+271+ hash = crc32(0, did->prod_id[i], strlen(did->prod_id[i]));272+ if (hash == did->prod_id_hash[i])273+ continue;274+275+ printk(KERN_DEBUG "pcmcia: %s: invalid hash for "276+ "product string \"%s\": is 0x%x, should "277+ "be 0x%x\n", p_drv->drv.name, did->prod_id[i],278+ did->prod_id_hash[i], hash);279+ printk(KERN_DEBUG "pcmcia: see "280+ "Documentation/pcmcia/devicetable.txt for "281+ "details\n");282+ }283+ did++;284+ }285+286+ return;287+}288+289+290+#ifdef CONFIG_PCMCIA_LOAD_CIS291+292+/**293+ * pcmcia_load_firmware - load CIS from userspace if device-provided is broken294+ * @dev - the pcmcia device which needs a CIS override295+ * @filename - requested filename in /lib/firmware/cis/296+ *297+ * This uses the in-kernel firmware loading mechanism to use a "fake CIS" if298+ * the one provided by the card is broken. The firmware files reside in299+ * /lib/firmware/cis/ in userspace.300+ */301+static int pcmcia_load_firmware(struct pcmcia_device *dev, char * filename)302+{303+ struct pcmcia_socket *s = dev->socket;304+ const struct firmware *fw;305+ char path[20];306+ int ret=-ENOMEM;307+ cisdump_t *cis;308+309+ if (!filename)310+ return -EINVAL;311+312+ ds_dbg(1, "trying to load firmware %s\n", filename);313+314+ if (strlen(filename) > 14)315+ return -EINVAL;316+317+ snprintf(path, 20, "%s", filename);318+319+ if (request_firmware(&fw, path, &dev->dev) == 0) {320+ if (fw->size >= CISTPL_MAX_CIS_SIZE)321+ goto release;322+323+ cis = kmalloc(sizeof(cisdump_t), GFP_KERNEL);324+ if (!cis)325+ goto release;326+327+ memset(cis, 0, sizeof(cisdump_t));328+329+ cis->Length = fw->size + 1;330+ memcpy(cis->Data, fw->data, fw->size);331+332+ if (!pcmcia_replace_cis(s, cis))333+ ret = 0;334+ }335+ release:336+ release_firmware(fw);337+338+ return (ret);339+}340+341+#else /* !CONFIG_PCMCIA_LOAD_CIS */342+343+static inline int pcmcia_load_firmware(struct pcmcia_device *dev, char * filename)344+{345+ return -ENODEV;346+}347+348+#endif349+350+351/*======================================================================*/35200000000000000000000353354/**355 * pcmcia_register_driver - register a PCMCIA driver with the bus core···291{292 if (!driver)293 return -EINVAL;294+295+ pcmcia_check_driver(driver);296297 /* initialize common fields */298 driver->drv.bus = &pcmcia_bus_type;···311}312EXPORT_SYMBOL(pcmcia_unregister_driver);31300000000000000000000000000000000314315/* pcmcia_device handling */316317+struct pcmcia_device * pcmcia_get_dev(struct pcmcia_device *p_dev)318{319 struct device *tmp_dev;320 tmp_dev = get_device(&p_dev->dev);···355 return to_pcmcia_dev(tmp_dev);356}357358+void pcmcia_put_dev(struct pcmcia_device *p_dev)359{360 if (p_dev)361 put_device(&p_dev->dev);···365{366 struct pcmcia_device *p_dev = to_pcmcia_dev(dev);367 ds_dbg(1, "releasing dev %p\n", p_dev);368+ pcmcia_put_socket(p_dev->socket);369 kfree(p_dev);370}371···500 */501static DECLARE_MUTEX(device_add_lock);502503+struct pcmcia_device * pcmcia_device_add(struct pcmcia_socket *s, unsigned int function)504{505 struct pcmcia_device *p_dev;506 unsigned long flags;507508+ s = pcmcia_get_socket(s);509 if (!s)510 return NULL;511512 down(&device_add_lock);513+514+ /* max of 2 devices per card */515+ if (s->device_count == 2)516+ goto err_put;517518 p_dev = kmalloc(sizeof(struct pcmcia_device), GFP_KERNEL);519 if (!p_dev)520 goto err_put;521 memset(p_dev, 0, sizeof(struct pcmcia_device));522523+ p_dev->socket = s;524 p_dev->device_no = (s->device_count++);525 p_dev->func = function;526527 p_dev->dev.bus = &pcmcia_bus_type;528+ p_dev->dev.parent = s->dev.dev;529 p_dev->dev.release = pcmcia_release_dev;530 sprintf (p_dev->dev.bus_id, "%d.%d", p_dev->socket->sock, p_dev->device_no);531532 /* compat */533 p_dev->client.client_magic = CLIENT_MAGIC;534+ p_dev->client.Socket = s;535 p_dev->client.Function = function;536 p_dev->client.state = CLIENT_UNBOUND;537···535 spin_lock_irqsave(&pcmcia_dev_list_lock, flags);536 list_add_tail(&p_dev->socket_device_list, &s->devices_list);537 spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags);538+539+ pcmcia_device_query(p_dev);540541 if (device_register(&p_dev->dev)) {542 spin_lock_irqsave(&pcmcia_dev_list_lock, flags);···553 s->device_count--;554 err_put:555 up(&device_add_lock);556+ pcmcia_put_socket(s);557558 return NULL;559}···584 /* this doesn't handle multifunction devices on one pcmcia function585 * yet. */586 for (i=0; i < no_funcs; i++)587+ pcmcia_device_add(s, i);588589 return (ret);590+}591+592+593+static void pcmcia_delayed_add_pseudo_device(void *data)594+{595+ struct pcmcia_socket *s = data;596+ pcmcia_device_add(s, 0);597+ s->pcmcia_state.device_add_pending = 0;598+}599+600+static inline void pcmcia_add_pseudo_device(struct pcmcia_socket *s)601+{602+ if (!s->pcmcia_state.device_add_pending) {603+ schedule_work(&s->device_add);604+ s->pcmcia_state.device_add_pending = 1;605+ }606+ return;607+}608+609+static int pcmcia_requery(struct device *dev, void * _data)610+{611+ struct pcmcia_device *p_dev = to_pcmcia_dev(dev);612+ if (!p_dev->dev.driver)613+ pcmcia_device_query(p_dev);614+615+ return 0;616+}617+618+static void pcmcia_bus_rescan(struct pcmcia_socket *skt)619+{620+ int no_devices=0;621+ unsigned long flags;622+623+ /* must be called with skt_sem held */624+ spin_lock_irqsave(&pcmcia_dev_list_lock, flags);625+ if (list_empty(&skt->devices_list))626+ no_devices=1;627+ spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags);628+629+ /* if no devices were added for this socket yet because of630+ * missing resource information or other trouble, we need to631+ * do this now. */632+ if (no_devices) {633+ int ret = pcmcia_card_add(skt);634+ if (ret)635+ return;636+ }637+638+ /* some device information might have changed because of a CIS639+ * update or because we can finally read it correctly... so640+ * determine it again, overwriting old values if necessary. */641+ bus_for_each_dev(&pcmcia_bus_type, NULL, NULL, pcmcia_requery);642+643+ /* we re-scan all devices, not just the ones connected to this644+ * socket. This does not matter, though. */645+ bus_rescan_devices(&pcmcia_bus_type);646+}647+648+static inline int pcmcia_devmatch(struct pcmcia_device *dev,649+ struct pcmcia_device_id *did)650+{651+ if (did->match_flags & PCMCIA_DEV_ID_MATCH_MANF_ID) {652+ if ((!dev->has_manf_id) || (dev->manf_id != did->manf_id))653+ return 0;654+ }655+656+ if (did->match_flags & PCMCIA_DEV_ID_MATCH_CARD_ID) {657+ if ((!dev->has_card_id) || (dev->card_id != did->card_id))658+ return 0;659+ }660+661+ if (did->match_flags & PCMCIA_DEV_ID_MATCH_FUNCTION) {662+ if (dev->func != did->function)663+ return 0;664+ }665+666+ if (did->match_flags & PCMCIA_DEV_ID_MATCH_PROD_ID1) {667+ if (!dev->prod_id[0])668+ return 0;669+ if (strcmp(did->prod_id[0], dev->prod_id[0]))670+ return 0;671+ }672+673+ if (did->match_flags & PCMCIA_DEV_ID_MATCH_PROD_ID2) {674+ if (!dev->prod_id[1])675+ return 0;676+ if (strcmp(did->prod_id[1], dev->prod_id[1]))677+ return 0;678+ }679+680+ if (did->match_flags & PCMCIA_DEV_ID_MATCH_PROD_ID3) {681+ if (!dev->prod_id[2])682+ return 0;683+ if (strcmp(did->prod_id[2], dev->prod_id[2]))684+ return 0;685+ }686+687+ if (did->match_flags & PCMCIA_DEV_ID_MATCH_PROD_ID4) {688+ if (!dev->prod_id[3])689+ return 0;690+ if (strcmp(did->prod_id[3], dev->prod_id[3]))691+ return 0;692+ }693+694+ if (did->match_flags & PCMCIA_DEV_ID_MATCH_DEVICE_NO) {695+ /* handle pseudo multifunction devices:696+ * there are at most two pseudo multifunction devices.697+ * if we're matching against the first, schedule a698+ * call which will then check whether there are two699+ * pseudo devices, and if not, add the second one.700+ */701+ if (dev->device_no == 0)702+ pcmcia_add_pseudo_device(dev->socket);703+704+ if (dev->device_no != did->device_no)705+ return 0;706+ }707+708+ if (did->match_flags & PCMCIA_DEV_ID_MATCH_FUNC_ID) {709+ if ((!dev->has_func_id) || (dev->func_id != did->func_id))710+ return 0;711+712+ /* if this is a pseudo-multi-function device,713+ * we need explicit matches */714+ if (did->match_flags & PCMCIA_DEV_ID_MATCH_DEVICE_NO)715+ return 0;716+ if (dev->device_no)717+ return 0;718+719+ /* also, FUNC_ID matching needs to be activated by userspace720+ * after it has re-checked that there is no possible module721+ * with a prod_id/manf_id/card_id match.722+ */723+ if (!dev->allow_func_id_match)724+ return 0;725+ }726+727+ if (did->match_flags & PCMCIA_DEV_ID_MATCH_FAKE_CIS) {728+ if (!dev->socket->fake_cis)729+ pcmcia_load_firmware(dev, did->cisfile);730+731+ if (!dev->socket->fake_cis)732+ return 0;733+ }734+735+ if (did->match_flags & PCMCIA_DEV_ID_MATCH_ANONYMOUS) {736+ int i;737+ for (i=0; i<4; i++)738+ if (dev->prod_id[i])739+ return 0;740+ if (dev->has_manf_id || dev->has_card_id || dev->has_func_id)741+ return 0;742+ }743+744+ dev->dev.driver_data = (void *) did;745+746+ return 1;747}748749750static int pcmcia_bus_match(struct device * dev, struct device_driver * drv) {751 struct pcmcia_device * p_dev = to_pcmcia_dev(dev);752 struct pcmcia_driver * p_drv = to_pcmcia_drv(drv);753+ struct pcmcia_device_id *did = p_drv->id_table;754755 /* matching by cardmgr */756 if (p_dev->cardmgr == p_drv)757 return 1;758759+ while (did && did->match_flags) {760+ if (pcmcia_devmatch(p_dev, did))761+ return 1;762+ did++;763+ }764+765 return 0;766}767+768+#ifdef CONFIG_HOTPLUG769+770+static int pcmcia_bus_hotplug(struct device *dev, char **envp, int num_envp,771+ char *buffer, int buffer_size)772+{773+ struct pcmcia_device *p_dev;774+ int i, length = 0;775+ u32 hash[4] = { 0, 0, 0, 0};776+777+ if (!dev)778+ return -ENODEV;779+780+ p_dev = to_pcmcia_dev(dev);781+782+ /* calculate hashes */783+ for (i=0; i<4; i++) {784+ if (!p_dev->prod_id[i])785+ continue;786+ hash[i] = crc32(0, p_dev->prod_id[i], strlen(p_dev->prod_id[i]));787+ }788+789+ i = 0;790+791+ if (add_hotplug_env_var(envp, num_envp, &i,792+ buffer, buffer_size, &length,793+ "SOCKET_NO=%u",794+ p_dev->socket->sock))795+ return -ENOMEM;796+797+ if (add_hotplug_env_var(envp, num_envp, &i,798+ buffer, buffer_size, &length,799+ "DEVICE_NO=%02X",800+ p_dev->device_no))801+ return -ENOMEM;802+803+ if (add_hotplug_env_var(envp, num_envp, &i,804+ buffer, buffer_size, &length,805+ "MODALIAS=pcmcia:m%04Xc%04Xf%02Xfn%02Xpfn%02X"806+ "pa%08Xpb%08Xpc%08Xpd%08X",807+ p_dev->has_manf_id ? p_dev->manf_id : 0,808+ p_dev->has_card_id ? p_dev->card_id : 0,809+ p_dev->has_func_id ? p_dev->func_id : 0,810+ p_dev->func,811+ p_dev->device_no,812+ hash[0],813+ hash[1],814+ hash[2],815+ hash[3]))816+ return -ENOMEM;817+818+ envp[i] = NULL;819+820+ return 0;821+}822+823+#else824+825+static int pcmcia_bus_hotplug(struct device *dev, char **envp, int num_envp,826+ char *buffer, int buffer_size)827+{828+ return -ENODEV;829+}830+831+#endif832833/************************ per-device sysfs output ***************************/834···626pcmcia_device_stringattr(prod_id3, prod_id[2]);627pcmcia_device_stringattr(prod_id4, prod_id[3]);628629+static ssize_t modalias_show(struct device *dev, char *buf)630+{631+ struct pcmcia_device *p_dev = to_pcmcia_dev(dev);632+ int i;633+ u32 hash[4] = { 0, 0, 0, 0};634+635+ /* calculate hashes */636+ for (i=0; i<4; i++) {637+ if (!p_dev->prod_id[i])638+ continue;639+ hash[i] = crc32(0,p_dev->prod_id[i],strlen(p_dev->prod_id[i]));640+ }641+ return sprintf(buf, "pcmcia:m%04Xc%04Xf%02Xfn%02Xpfn%02X"642+ "pa%08Xpb%08Xpc%08Xpd%08X\n",643+ p_dev->has_manf_id ? p_dev->manf_id : 0,644+ p_dev->has_card_id ? p_dev->card_id : 0,645+ p_dev->has_func_id ? p_dev->func_id : 0,646+ p_dev->func, p_dev->device_no,647+ hash[0], hash[1], hash[2], hash[3]);648+}649+650+static ssize_t pcmcia_store_allow_func_id_match(struct device *dev,651+ struct device_attribute *attr, const char *buf, size_t count)652+{653+ struct pcmcia_device *p_dev = to_pcmcia_dev(dev);654+ if (!count)655+ return -EINVAL;656+657+ down(&p_dev->socket->skt_sem);658+ p_dev->allow_func_id_match = 1;659+ up(&p_dev->socket->skt_sem);660+661+ bus_rescan_devices(&pcmcia_bus_type);662+663+ return count;664+}665+666static struct device_attribute pcmcia_dev_attrs[] = {667 __ATTR(function, 0444, func_show, NULL),668 __ATTR_RO(func_id),···635 __ATTR_RO(prod_id2),636 __ATTR_RO(prod_id3),637 __ATTR_RO(prod_id4),638+ __ATTR_RO(modalias),639+ __ATTR(allow_func_id_match, 0200, NULL, pcmcia_store_allow_func_id_match),640 __ATTR_NULL,641};0000000000000000000000000000000000642643644/*======================================================================···706707static int send_event(struct pcmcia_socket *s, event_t event, int priority)708{0709 struct send_event_data private;0000710711 private.skt = s;712 private.event = event;713 private.priority = priority;714715+ return bus_for_each_dev(&pcmcia_bus_type, NULL, &private, send_event_callback);000716} /* send_event */717718···731732static int ds_event(struct pcmcia_socket *skt, event_t event, int priority)733{734+ struct pcmcia_socket *s = pcmcia_get_socket(skt);735 int ret = 0;736737 ds_dbg(1, "ds_event(0x%06x, %d, 0x%p)\n",738+ event, priority, skt);739740 switch (event) {741742 case CS_EVENT_CARD_REMOVAL:743+ s->pcmcia_state.present = 0;744 send_event(skt, event, priority);745+ unbind_request(skt);746+ handle_event(skt, event);747 break;748749 case CS_EVENT_CARD_INSERTION:750+ s->pcmcia_state.present = 1;751 pcmcia_card_add(skt);752+ handle_event(skt, event);753 break;754755 case CS_EVENT_EJECTION_REQUEST:···757 break;758759 default:760+ handle_event(skt, event);761 send_event(skt, event, priority);762 break;763 }764+765+ pcmcia_put_socket(s);766767 return 0;768} /* ds_event */76977000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000771772int pcmcia_register_client(client_handle_t *handle, client_reg_t *req)773{774 client_t *client = NULL;775+ struct pcmcia_socket *s = NULL;0776 struct pcmcia_device *p_dev = NULL;777778 /* Look for unbound client with matching dev_info */···898 if (s->state & SOCKET_CARDBUS)899 continue;900901+ s = pcmcia_get_socket(s);902+ if (!s)000903 continue;904 spin_lock_irqsave(&pcmcia_dev_list_lock, flags);905+ list_for_each_entry(p_dev, &s->devices_list, socket_device_list) {906 struct pcmcia_driver *p_drv;907 p_dev = pcmcia_get_dev(p_dev);908 if (!p_dev)···924 pcmcia_put_dev(p_dev);925 }926 spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags);927+ pcmcia_put_socket(s);928 }929 found:930 up_read(&pcmcia_socket_list_rwsem);931 if (!p_dev || !client)932 return -ENODEV;933934+ pcmcia_put_socket(s); /* safe, as we already hold a reference from bind_device */935936 *handle = client;937 client->state &= ~CLIENT_UNBOUND;···978EXPORT_SYMBOL(pcmcia_register_client);9799800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000981/* unbind _all_ devices attached to a given pcmcia_bus_socket. The982 * drivers have been called with EVENT_CARD_REMOVAL before.983 */984+static int unbind_request(struct pcmcia_socket *s)985{986 struct pcmcia_device *p_dev;987 unsigned long flags;988989+ ds_dbg(2, "unbind_request(%d)\n", s->sock);990991 s->device_count = 0;992···1133} /* deregister_client */1134EXPORT_SYMBOL(pcmcia_deregister_client);11351136+static struct pcmcia_callback pcmcia_bus_callback = {1137+ .owner = THIS_MODULE,1138+ .event = ds_event,1139+ .requery = pcmcia_bus_rescan,00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001140};11411142static int __devinit pcmcia_bus_add_socket(struct class_device *class_dev)1143{1144 struct pcmcia_socket *socket = class_get_devdata(class_dev);01145 int ret;11461147+ socket = pcmcia_get_socket(socket);1148+ if (!socket) {0000001149 printk(KERN_ERR "PCMCIA obtaining reference to socket %p failed\n", socket);01150 return -ENODEV;1151 }1152001153 /*1154 * Ugly. But we want to wait for the socket threads to have started up.1155 * We really should let the drivers themselves drive some of this..1156 */1157 msleep(250);11581159+#ifdef CONFIG_PCMCIA_IOCTL1160+ init_waitqueue_head(&socket->queue);1161+#endif1162+ INIT_LIST_HEAD(&socket->devices_list);1163+ INIT_WORK(&socket->device_add, pcmcia_delayed_add_pseudo_device, socket);1164+ memset(&socket->pcmcia_state, 0, sizeof(u8));1165+ socket->device_count = 0;11661167+ ret = pccard_register_pcmcia(socket, &pcmcia_bus_callback);0000001168 if (ret) {1169 printk(KERN_ERR "PCMCIA registration PCCard core failed for socket %p\n", socket);1170+ pcmcia_put_socket(socket);01171 return (ret);1172 }11731174 return 0;1175}117601177static void pcmcia_bus_remove_socket(struct class_device *class_dev)1178{1179 struct pcmcia_socket *socket = class_get_devdata(class_dev);11801181+ if (!socket)1182 return;11831184+ socket->pcmcia_state.dead = 1;1185 pccard_register_pcmcia(socket, NULL);11861187+ pcmcia_put_socket(socket);0011881189 return;1190}···15751576struct bus_type pcmcia_bus_type = {1577 .name = "pcmcia",1578+ .hotplug = pcmcia_bus_hotplug,1579 .match = pcmcia_bus_match,1580 .dev_attrs = pcmcia_dev_attrs,1581};0158215831584static int __init init_pcmcia_bus(void)1585{001586 spin_lock_init(&pcmcia_dev_list_lock);15871588 bus_register(&pcmcia_bus_type);1589 class_interface_register(&pcmcia_bus_interface);15901591+ pcmcia_setup_ioctl();00000000000015921593 return 0;1594}···16121613static void __exit exit_pcmcia_bus(void)1614{1615+ pcmcia_cleanup_ioctl();16161617+ class_interface_unregister(&pcmcia_bus_interface);000000016181619 bus_unregister(&pcmcia_bus_type);1620}1621module_exit(exit_pcmcia_bus);1622000000000000000000000000000016231624MODULE_ALIAS("ds");
···1+/*2+ * PCMCIA 16-bit resource management functions3+ *4+ * The initial developer of the original code is David A. Hinds5+ * <dahinds@users.sourceforge.net>. Portions created by David A. Hinds6+ * are Copyright (C) 1999 David A. Hinds. All Rights Reserved.7+ *8+ * Copyright (C) 1999 David A. Hinds9+ * Copyright (C) 2004-2005 Dominik Brodowski10+ *11+ * This program is free software; you can redistribute it and/or modify12+ * it under the terms of the GNU General Public License version 2 as13+ * published by the Free Software Foundation.14+ *15+ */16+17+#include <linux/config.h>18+#include <linux/module.h>19+#include <linux/kernel.h>20+#include <linux/interrupt.h>21+#include <linux/delay.h>22+#include <linux/pci.h>23+#include <linux/device.h>24+25+#define IN_CARD_SERVICES26+#include <pcmcia/version.h>27+#include <pcmcia/cs_types.h>28+#include <pcmcia/ss.h>29+#include <pcmcia/cs.h>30+#include <pcmcia/bulkmem.h>31+#include <pcmcia/cistpl.h>32+#include <pcmcia/cisreg.h>33+#include <pcmcia/ds.h>34+35+#include "cs_internal.h"36+#include "ds_internal.h"37+38+39+/* Access speed for IO windows */40+static int io_speed = 0;41+module_param(io_speed, int, 0444);42+43+44+#ifdef CONFIG_PCMCIA_PROBE45+/* mask of IRQs already reserved by other cards, we should avoid using them */46+static u8 pcmcia_used_irq[NR_IRQS];47+#endif48+49+50+#ifdef DEBUG51+extern int ds_pc_debug;52+#define cs_socket_name(skt) ((skt)->dev.class_id)53+54+#define ds_dbg(skt, lvl, fmt, arg...) do { \55+ if (ds_pc_debug >= lvl) \56+ printk(KERN_DEBUG "pcmcia_resource: %s: " fmt, \57+ cs_socket_name(skt) , ## arg); \58+} while (0)59+#else60+#define ds_dbg(lvl, fmt, arg...) do { } while (0)61+#endif62+63+64+65+/** alloc_io_space66+ *67+ * Special stuff for managing IO windows, because they are scarce68+ */69+70+static int alloc_io_space(struct pcmcia_socket *s, u_int attr, ioaddr_t *base,71+ ioaddr_t num, u_int lines)72+{73+ int i;74+ kio_addr_t try, align;75+76+ align = (*base) ? (lines ? 1<<lines : 0) : 1;77+ if (align && (align < num)) {78+ if (*base) {79+ ds_dbg(s, 0, "odd IO request: num %#x align %#lx\n",80+ num, align);81+ align = 0;82+ } else83+ while (align && (align < num)) align <<= 1;84+ }85+ if (*base & ~(align-1)) {86+ ds_dbg(s, 0, "odd IO request: base %#x align %#lx\n",87+ *base, align);88+ align = 0;89+ }90+ if ((s->features & SS_CAP_STATIC_MAP) && s->io_offset) {91+ *base = s->io_offset | (*base & 0x0fff);92+ s->io[0].Attributes = attr;93+ return 0;94+ }95+ /* Check for an already-allocated window that must conflict with96+ * what was asked for. It is a hack because it does not catch all97+ * potential conflicts, just the most obvious ones.98+ */99+ for (i = 0; i < MAX_IO_WIN; i++)100+ if ((s->io[i].NumPorts != 0) &&101+ ((s->io[i].BasePort & (align-1)) == *base))102+ return 1;103+ for (i = 0; i < MAX_IO_WIN; i++) {104+ if (s->io[i].NumPorts == 0) {105+ s->io[i].res = pcmcia_find_io_region(*base, num, align, s);106+ if (s->io[i].res) {107+ s->io[i].Attributes = attr;108+ s->io[i].BasePort = *base = s->io[i].res->start;109+ s->io[i].NumPorts = s->io[i].InUse = num;110+ break;111+ } else112+ return 1;113+ } else if (s->io[i].Attributes != attr)114+ continue;115+ /* Try to extend top of window */116+ try = s->io[i].BasePort + s->io[i].NumPorts;117+ if ((*base == 0) || (*base == try))118+ if (pcmcia_adjust_io_region(s->io[i].res, s->io[i].res->start,119+ s->io[i].res->end + num, s) == 0) {120+ *base = try;121+ s->io[i].NumPorts += num;122+ s->io[i].InUse += num;123+ break;124+ }125+ /* Try to extend bottom of window */126+ try = s->io[i].BasePort - num;127+ if ((*base == 0) || (*base == try))128+ if (pcmcia_adjust_io_region(s->io[i].res, s->io[i].res->start - num,129+ s->io[i].res->end, s) == 0) {130+ s->io[i].BasePort = *base = try;131+ s->io[i].NumPorts += num;132+ s->io[i].InUse += num;133+ break;134+ }135+ }136+ return (i == MAX_IO_WIN);137+} /* alloc_io_space */138+139+140+static void release_io_space(struct pcmcia_socket *s, ioaddr_t base,141+ ioaddr_t num)142+{143+ int i;144+145+ for (i = 0; i < MAX_IO_WIN; i++) {146+ if ((s->io[i].BasePort <= base) &&147+ (s->io[i].BasePort+s->io[i].NumPorts >= base+num)) {148+ s->io[i].InUse -= num;149+ /* Free the window if no one else is using it */150+ if (s->io[i].InUse == 0) {151+ s->io[i].NumPorts = 0;152+ release_resource(s->io[i].res);153+ kfree(s->io[i].res);154+ s->io[i].res = NULL;155+ }156+ }157+ }158+} /* release_io_space */159+160+161+/** pccard_access_configuration_register162+ *163+ * Access_configuration_register() reads and writes configuration164+ * registers in attribute memory. Memory window 0 is reserved for165+ * this and the tuple reading services.166+ */167+168+int pccard_access_configuration_register(struct pcmcia_socket *s,169+ unsigned int function,170+ conf_reg_t *reg)171+{172+ config_t *c;173+ int addr;174+ u_char val;175+176+ if (!s || !s->config)177+ return CS_NO_CARD;178+179+ c = &s->config[function];180+181+ if (c == NULL)182+ return CS_NO_CARD;183+184+ if (!(c->state & CONFIG_LOCKED))185+ return CS_CONFIGURATION_LOCKED;186+187+ addr = (c->ConfigBase + reg->Offset) >> 1;188+189+ switch (reg->Action) {190+ case CS_READ:191+ pcmcia_read_cis_mem(s, 1, addr, 1, &val);192+ reg->Value = val;193+ break;194+ case CS_WRITE:195+ val = reg->Value;196+ pcmcia_write_cis_mem(s, 1, addr, 1, &val);197+ break;198+ default:199+ return CS_BAD_ARGS;200+ break;201+ }202+ return CS_SUCCESS;203+} /* pccard_access_configuration_register */204+205+int pcmcia_access_configuration_register(client_handle_t handle,206+ conf_reg_t *reg)207+{208+ struct pcmcia_socket *s;209+ if (CHECK_HANDLE(handle))210+ return CS_BAD_HANDLE;211+ s = SOCKET(handle);212+ return pccard_access_configuration_register(s, handle->Function, reg);213+}214+EXPORT_SYMBOL(pcmcia_access_configuration_register);215+216+217+218+int pccard_get_configuration_info(struct pcmcia_socket *s,219+ unsigned int function,220+ config_info_t *config)221+{222+ config_t *c;223+224+ if (!(s->state & SOCKET_PRESENT))225+ return CS_NO_CARD;226+227+ config->Function = function;228+229+#ifdef CONFIG_CARDBUS230+ if (s->state & SOCKET_CARDBUS) {231+ memset(config, 0, sizeof(config_info_t));232+ config->Vcc = s->socket.Vcc;233+ config->Vpp1 = config->Vpp2 = s->socket.Vpp;234+ config->Option = s->cb_dev->subordinate->number;235+ if (s->state & SOCKET_CARDBUS_CONFIG) {236+ config->Attributes = CONF_VALID_CLIENT;237+ config->IntType = INT_CARDBUS;238+ config->AssignedIRQ = s->irq.AssignedIRQ;239+ if (config->AssignedIRQ)240+ config->Attributes |= CONF_ENABLE_IRQ;241+ config->BasePort1 = s->io[0].BasePort;242+ config->NumPorts1 = s->io[0].NumPorts;243+ }244+ return CS_SUCCESS;245+ }246+#endif247+248+ c = (s->config != NULL) ? &s->config[function] : NULL;249+250+ if ((c == NULL) || !(c->state & CONFIG_LOCKED)) {251+ config->Attributes = 0;252+ config->Vcc = s->socket.Vcc;253+ config->Vpp1 = config->Vpp2 = s->socket.Vpp;254+ return CS_SUCCESS;255+ }256+257+ /* !!! This is a hack !!! */258+ memcpy(&config->Attributes, &c->Attributes, sizeof(config_t));259+ config->Attributes |= CONF_VALID_CLIENT;260+ config->CardValues = c->CardValues;261+ config->IRQAttributes = c->irq.Attributes;262+ config->AssignedIRQ = s->irq.AssignedIRQ;263+ config->BasePort1 = c->io.BasePort1;264+ config->NumPorts1 = c->io.NumPorts1;265+ config->Attributes1 = c->io.Attributes1;266+ config->BasePort2 = c->io.BasePort2;267+ config->NumPorts2 = c->io.NumPorts2;268+ config->Attributes2 = c->io.Attributes2;269+ config->IOAddrLines = c->io.IOAddrLines;270+271+ return CS_SUCCESS;272+} /* pccard_get_configuration_info */273+274+int pcmcia_get_configuration_info(client_handle_t handle,275+ config_info_t *config)276+{277+ struct pcmcia_socket *s;278+279+ if ((CHECK_HANDLE(handle)) || !config)280+ return CS_BAD_HANDLE;281+ s = SOCKET(handle);282+ if (!s)283+ return CS_BAD_HANDLE;284+ return pccard_get_configuration_info(s, handle->Function, config);285+}286+EXPORT_SYMBOL(pcmcia_get_configuration_info);287+288+289+/** pcmcia_get_window290+ */291+int pcmcia_get_window(struct pcmcia_socket *s, window_handle_t *handle,292+ int idx, win_req_t *req)293+{294+ window_t *win;295+ int w;296+297+ if (!s || !(s->state & SOCKET_PRESENT))298+ return CS_NO_CARD;299+ for (w = idx; w < MAX_WIN; w++)300+ if (s->state & SOCKET_WIN_REQ(w))301+ break;302+ if (w == MAX_WIN)303+ return CS_NO_MORE_ITEMS;304+ win = &s->win[w];305+ req->Base = win->ctl.res->start;306+ req->Size = win->ctl.res->end - win->ctl.res->start + 1;307+ req->AccessSpeed = win->ctl.speed;308+ req->Attributes = 0;309+ if (win->ctl.flags & MAP_ATTRIB)310+ req->Attributes |= WIN_MEMORY_TYPE_AM;311+ if (win->ctl.flags & MAP_ACTIVE)312+ req->Attributes |= WIN_ENABLE;313+ if (win->ctl.flags & MAP_16BIT)314+ req->Attributes |= WIN_DATA_WIDTH_16;315+ if (win->ctl.flags & MAP_USE_WAIT)316+ req->Attributes |= WIN_USE_WAIT;317+ *handle = win;318+ return CS_SUCCESS;319+} /* pcmcia_get_window */320+EXPORT_SYMBOL(pcmcia_get_window);321+322+323+/** pccard_get_status324+ *325+ * Get the current socket state bits. We don't support the latched326+ * SocketState yet: I haven't seen any point for it.327+ */328+329+int pccard_get_status(struct pcmcia_socket *s, unsigned int function,330+ cs_status_t *status)331+{332+ config_t *c;333+ int val;334+335+ s->ops->get_status(s, &val);336+ status->CardState = status->SocketState = 0;337+ status->CardState |= (val & SS_DETECT) ? CS_EVENT_CARD_DETECT : 0;338+ status->CardState |= (val & SS_CARDBUS) ? CS_EVENT_CB_DETECT : 0;339+ status->CardState |= (val & SS_3VCARD) ? CS_EVENT_3VCARD : 0;340+ status->CardState |= (val & SS_XVCARD) ? CS_EVENT_XVCARD : 0;341+ if (s->state & SOCKET_SUSPEND)342+ status->CardState |= CS_EVENT_PM_SUSPEND;343+ if (!(s->state & SOCKET_PRESENT))344+ return CS_NO_CARD;345+346+ c = (s->config != NULL) ? &s->config[function] : NULL;347+ if ((c != NULL) && (c->state & CONFIG_LOCKED) &&348+ (c->IntType & (INT_MEMORY_AND_IO | INT_ZOOMED_VIDEO))) {349+ u_char reg;350+ if (c->Present & PRESENT_PIN_REPLACE) {351+ pcmcia_read_cis_mem(s, 1, (c->ConfigBase+CISREG_PRR)>>1, 1, ®);352+ status->CardState |=353+ (reg & PRR_WP_STATUS) ? CS_EVENT_WRITE_PROTECT : 0;354+ status->CardState |=355+ (reg & PRR_READY_STATUS) ? CS_EVENT_READY_CHANGE : 0;356+ status->CardState |=357+ (reg & PRR_BVD2_STATUS) ? CS_EVENT_BATTERY_LOW : 0;358+ status->CardState |=359+ (reg & PRR_BVD1_STATUS) ? CS_EVENT_BATTERY_DEAD : 0;360+ } else {361+ /* No PRR? Then assume we're always ready */362+ status->CardState |= CS_EVENT_READY_CHANGE;363+ }364+ if (c->Present & PRESENT_EXT_STATUS) {365+ pcmcia_read_cis_mem(s, 1, (c->ConfigBase+CISREG_ESR)>>1, 1, ®);366+ status->CardState |=367+ (reg & ESR_REQ_ATTN) ? CS_EVENT_REQUEST_ATTENTION : 0;368+ }369+ return CS_SUCCESS;370+ }371+ status->CardState |=372+ (val & SS_WRPROT) ? CS_EVENT_WRITE_PROTECT : 0;373+ status->CardState |=374+ (val & SS_BATDEAD) ? CS_EVENT_BATTERY_DEAD : 0;375+ status->CardState |=376+ (val & SS_BATWARN) ? CS_EVENT_BATTERY_LOW : 0;377+ status->CardState |=378+ (val & SS_READY) ? CS_EVENT_READY_CHANGE : 0;379+ return CS_SUCCESS;380+} /* pccard_get_status */381+382+int pcmcia_get_status(client_handle_t handle, cs_status_t *status)383+{384+ struct pcmcia_socket *s;385+ if (CHECK_HANDLE(handle))386+ return CS_BAD_HANDLE;387+ s = SOCKET(handle);388+ return pccard_get_status(s, handle->Function, status);389+}390+EXPORT_SYMBOL(pcmcia_get_status);391+392+393+394+/** pcmcia_get_mem_page395+ *396+ * Change the card address of an already open memory window.397+ */398+int pcmcia_get_mem_page(window_handle_t win, memreq_t *req)399+{400+ if ((win == NULL) || (win->magic != WINDOW_MAGIC))401+ return CS_BAD_HANDLE;402+ req->Page = 0;403+ req->CardOffset = win->ctl.card_start;404+ return CS_SUCCESS;405+} /* pcmcia_get_mem_page */406+EXPORT_SYMBOL(pcmcia_get_mem_page);407+408+409+int pcmcia_map_mem_page(window_handle_t win, memreq_t *req)410+{411+ struct pcmcia_socket *s;412+ if ((win == NULL) || (win->magic != WINDOW_MAGIC))413+ return CS_BAD_HANDLE;414+ if (req->Page != 0)415+ return CS_BAD_PAGE;416+ s = win->sock;417+ win->ctl.card_start = req->CardOffset;418+ if (s->ops->set_mem_map(s, &win->ctl) != 0)419+ return CS_BAD_OFFSET;420+ return CS_SUCCESS;421+} /* pcmcia_map_mem_page */422+EXPORT_SYMBOL(pcmcia_map_mem_page);423+424+425+/** pcmcia_modify_configuration426+ *427+ * Modify a locked socket configuration428+ */429+int pcmcia_modify_configuration(client_handle_t handle,430+ modconf_t *mod)431+{432+ struct pcmcia_socket *s;433+ config_t *c;434+435+ if (CHECK_HANDLE(handle))436+ return CS_BAD_HANDLE;437+ s = SOCKET(handle);438+ c = CONFIG(handle);439+ if (!(s->state & SOCKET_PRESENT))440+ return CS_NO_CARD;441+ if (!(c->state & CONFIG_LOCKED))442+ return CS_CONFIGURATION_LOCKED;443+444+ if (mod->Attributes & CONF_IRQ_CHANGE_VALID) {445+ if (mod->Attributes & CONF_ENABLE_IRQ) {446+ c->Attributes |= CONF_ENABLE_IRQ;447+ s->socket.io_irq = s->irq.AssignedIRQ;448+ } else {449+ c->Attributes &= ~CONF_ENABLE_IRQ;450+ s->socket.io_irq = 0;451+ }452+ s->ops->set_socket(s, &s->socket);453+ }454+455+ if (mod->Attributes & CONF_VCC_CHANGE_VALID)456+ return CS_BAD_VCC;457+458+ /* We only allow changing Vpp1 and Vpp2 to the same value */459+ if ((mod->Attributes & CONF_VPP1_CHANGE_VALID) &&460+ (mod->Attributes & CONF_VPP2_CHANGE_VALID)) {461+ if (mod->Vpp1 != mod->Vpp2)462+ return CS_BAD_VPP;463+ c->Vpp1 = c->Vpp2 = s->socket.Vpp = mod->Vpp1;464+ if (s->ops->set_socket(s, &s->socket))465+ return CS_BAD_VPP;466+ } else if ((mod->Attributes & CONF_VPP1_CHANGE_VALID) ||467+ (mod->Attributes & CONF_VPP2_CHANGE_VALID))468+ return CS_BAD_VPP;469+470+ return CS_SUCCESS;471+} /* modify_configuration */472+EXPORT_SYMBOL(pcmcia_modify_configuration);473+474+475+int pcmcia_release_configuration(client_handle_t handle)476+{477+ pccard_io_map io = { 0, 0, 0, 0, 1 };478+ struct pcmcia_socket *s;479+ int i;480+481+ if (CHECK_HANDLE(handle) ||482+ !(handle->state & CLIENT_CONFIG_LOCKED))483+ return CS_BAD_HANDLE;484+ handle->state &= ~CLIENT_CONFIG_LOCKED;485+ s = SOCKET(handle);486+487+#ifdef CONFIG_CARDBUS488+ if (handle->state & CLIENT_CARDBUS)489+ return CS_SUCCESS;490+#endif491+492+ if (!(handle->state & CLIENT_STALE)) {493+ config_t *c = CONFIG(handle);494+ if (--(s->lock_count) == 0) {495+ s->socket.flags = SS_OUTPUT_ENA; /* Is this correct? */496+ s->socket.Vpp = 0;497+ s->socket.io_irq = 0;498+ s->ops->set_socket(s, &s->socket);499+ }500+ if (c->state & CONFIG_IO_REQ)501+ for (i = 0; i < MAX_IO_WIN; i++) {502+ if (s->io[i].NumPorts == 0)503+ continue;504+ s->io[i].Config--;505+ if (s->io[i].Config != 0)506+ continue;507+ io.map = i;508+ s->ops->set_io_map(s, &io);509+ }510+ c->state &= ~CONFIG_LOCKED;511+ }512+513+ return CS_SUCCESS;514+} /* pcmcia_release_configuration */515+EXPORT_SYMBOL(pcmcia_release_configuration);516+517+518+/** pcmcia_release_io519+ *520+ * Release_io() releases the I/O ranges allocated by a client. This521+ * may be invoked some time after a card ejection has already dumped522+ * the actual socket configuration, so if the client is "stale", we523+ * don't bother checking the port ranges against the current socket524+ * values.525+ */526+int pcmcia_release_io(client_handle_t handle, io_req_t *req)527+{528+ struct pcmcia_socket *s;529+530+ if (CHECK_HANDLE(handle) || !(handle->state & CLIENT_IO_REQ))531+ return CS_BAD_HANDLE;532+ handle->state &= ~CLIENT_IO_REQ;533+ s = SOCKET(handle);534+535+#ifdef CONFIG_CARDBUS536+ if (handle->state & CLIENT_CARDBUS)537+ return CS_SUCCESS;538+#endif539+540+ if (!(handle->state & CLIENT_STALE)) {541+ config_t *c = CONFIG(handle);542+ if (c->state & CONFIG_LOCKED)543+ return CS_CONFIGURATION_LOCKED;544+ if ((c->io.BasePort1 != req->BasePort1) ||545+ (c->io.NumPorts1 != req->NumPorts1) ||546+ (c->io.BasePort2 != req->BasePort2) ||547+ (c->io.NumPorts2 != req->NumPorts2))548+ return CS_BAD_ARGS;549+ c->state &= ~CONFIG_IO_REQ;550+ }551+552+ release_io_space(s, req->BasePort1, req->NumPorts1);553+ if (req->NumPorts2)554+ release_io_space(s, req->BasePort2, req->NumPorts2);555+556+ return CS_SUCCESS;557+} /* pcmcia_release_io */558+EXPORT_SYMBOL(pcmcia_release_io);559+560+561+int pcmcia_release_irq(client_handle_t handle, irq_req_t *req)562+{563+ struct pcmcia_socket *s;564+ if (CHECK_HANDLE(handle) || !(handle->state & CLIENT_IRQ_REQ))565+ return CS_BAD_HANDLE;566+ handle->state &= ~CLIENT_IRQ_REQ;567+ s = SOCKET(handle);568+569+ if (!(handle->state & CLIENT_STALE)) {570+ config_t *c = CONFIG(handle);571+ if (c->state & CONFIG_LOCKED)572+ return CS_CONFIGURATION_LOCKED;573+ if (c->irq.Attributes != req->Attributes)574+ return CS_BAD_ATTRIBUTE;575+ if (s->irq.AssignedIRQ != req->AssignedIRQ)576+ return CS_BAD_IRQ;577+ if (--s->irq.Config == 0) {578+ c->state &= ~CONFIG_IRQ_REQ;579+ s->irq.AssignedIRQ = 0;580+ }581+ }582+583+ if (req->Attributes & IRQ_HANDLE_PRESENT) {584+ free_irq(req->AssignedIRQ, req->Instance);585+ }586+587+#ifdef CONFIG_PCMCIA_PROBE588+ pcmcia_used_irq[req->AssignedIRQ]--;589+#endif590+591+ return CS_SUCCESS;592+} /* pcmcia_release_irq */593+EXPORT_SYMBOL(pcmcia_release_irq);594+595+596+int pcmcia_release_window(window_handle_t win)597+{598+ struct pcmcia_socket *s;599+600+ if ((win == NULL) || (win->magic != WINDOW_MAGIC))601+ return CS_BAD_HANDLE;602+ s = win->sock;603+ if (!(win->handle->state & CLIENT_WIN_REQ(win->index)))604+ return CS_BAD_HANDLE;605+606+ /* Shut down memory window */607+ win->ctl.flags &= ~MAP_ACTIVE;608+ s->ops->set_mem_map(s, &win->ctl);609+ s->state &= ~SOCKET_WIN_REQ(win->index);610+611+ /* Release system memory */612+ if (win->ctl.res) {613+ release_resource(win->ctl.res);614+ kfree(win->ctl.res);615+ win->ctl.res = NULL;616+ }617+ win->handle->state &= ~CLIENT_WIN_REQ(win->index);618+619+ win->magic = 0;620+621+ return CS_SUCCESS;622+} /* pcmcia_release_window */623+EXPORT_SYMBOL(pcmcia_release_window);624+625+626+int pcmcia_request_configuration(client_handle_t handle,627+ config_req_t *req)628+{629+ int i;630+ u_int base;631+ struct pcmcia_socket *s;632+ config_t *c;633+ pccard_io_map iomap;634+635+ if (CHECK_HANDLE(handle))636+ return CS_BAD_HANDLE;637+ s = SOCKET(handle);638+ if (!(s->state & SOCKET_PRESENT))639+ return CS_NO_CARD;640+641+#ifdef CONFIG_CARDBUS642+ if (handle->state & CLIENT_CARDBUS)643+ return CS_UNSUPPORTED_MODE;644+#endif645+646+ if (req->IntType & INT_CARDBUS)647+ return CS_UNSUPPORTED_MODE;648+ c = CONFIG(handle);649+ if (c->state & CONFIG_LOCKED)650+ return CS_CONFIGURATION_LOCKED;651+652+ /* Do power control. We don't allow changes in Vcc. */653+ if (s->socket.Vcc != req->Vcc)654+ return CS_BAD_VCC;655+ if (req->Vpp1 != req->Vpp2)656+ return CS_BAD_VPP;657+ s->socket.Vpp = req->Vpp1;658+ if (s->ops->set_socket(s, &s->socket))659+ return CS_BAD_VPP;660+661+ c->Vcc = req->Vcc; c->Vpp1 = c->Vpp2 = req->Vpp1;662+663+ /* Pick memory or I/O card, DMA mode, interrupt */664+ c->IntType = req->IntType;665+ c->Attributes = req->Attributes;666+ if (req->IntType & INT_MEMORY_AND_IO)667+ s->socket.flags |= SS_IOCARD;668+ if (req->IntType & INT_ZOOMED_VIDEO)669+ s->socket.flags |= SS_ZVCARD | SS_IOCARD;670+ if (req->Attributes & CONF_ENABLE_DMA)671+ s->socket.flags |= SS_DMA_MODE;672+ if (req->Attributes & CONF_ENABLE_SPKR)673+ s->socket.flags |= SS_SPKR_ENA;674+ if (req->Attributes & CONF_ENABLE_IRQ)675+ s->socket.io_irq = s->irq.AssignedIRQ;676+ else677+ s->socket.io_irq = 0;678+ s->ops->set_socket(s, &s->socket);679+ s->lock_count++;680+681+ /* Set up CIS configuration registers */682+ base = c->ConfigBase = req->ConfigBase;683+ c->Present = c->CardValues = req->Present;684+ if (req->Present & PRESENT_COPY) {685+ c->Copy = req->Copy;686+ pcmcia_write_cis_mem(s, 1, (base + CISREG_SCR)>>1, 1, &c->Copy);687+ }688+ if (req->Present & PRESENT_OPTION) {689+ if (s->functions == 1) {690+ c->Option = req->ConfigIndex & COR_CONFIG_MASK;691+ } else {692+ c->Option = req->ConfigIndex & COR_MFC_CONFIG_MASK;693+ c->Option |= COR_FUNC_ENA|COR_IREQ_ENA;694+ if (req->Present & PRESENT_IOBASE_0)695+ c->Option |= COR_ADDR_DECODE;696+ }697+ if (c->state & CONFIG_IRQ_REQ)698+ if (!(c->irq.Attributes & IRQ_FORCED_PULSE))699+ c->Option |= COR_LEVEL_REQ;700+ pcmcia_write_cis_mem(s, 1, (base + CISREG_COR)>>1, 1, &c->Option);701+ mdelay(40);702+ }703+ if (req->Present & PRESENT_STATUS) {704+ c->Status = req->Status;705+ pcmcia_write_cis_mem(s, 1, (base + CISREG_CCSR)>>1, 1, &c->Status);706+ }707+ if (req->Present & PRESENT_PIN_REPLACE) {708+ c->Pin = req->Pin;709+ pcmcia_write_cis_mem(s, 1, (base + CISREG_PRR)>>1, 1, &c->Pin);710+ }711+ if (req->Present & PRESENT_EXT_STATUS) {712+ c->ExtStatus = req->ExtStatus;713+ pcmcia_write_cis_mem(s, 1, (base + CISREG_ESR)>>1, 1, &c->ExtStatus);714+ }715+ if (req->Present & PRESENT_IOBASE_0) {716+ u_char b = c->io.BasePort1 & 0xff;717+ pcmcia_write_cis_mem(s, 1, (base + CISREG_IOBASE_0)>>1, 1, &b);718+ b = (c->io.BasePort1 >> 8) & 0xff;719+ pcmcia_write_cis_mem(s, 1, (base + CISREG_IOBASE_1)>>1, 1, &b);720+ }721+ if (req->Present & PRESENT_IOSIZE) {722+ u_char b = c->io.NumPorts1 + c->io.NumPorts2 - 1;723+ pcmcia_write_cis_mem(s, 1, (base + CISREG_IOSIZE)>>1, 1, &b);724+ }725+726+ /* Configure I/O windows */727+ if (c->state & CONFIG_IO_REQ) {728+ iomap.speed = io_speed;729+ for (i = 0; i < MAX_IO_WIN; i++)730+ if (s->io[i].NumPorts != 0) {731+ iomap.map = i;732+ iomap.flags = MAP_ACTIVE;733+ switch (s->io[i].Attributes & IO_DATA_PATH_WIDTH) {734+ case IO_DATA_PATH_WIDTH_16:735+ iomap.flags |= MAP_16BIT; break;736+ case IO_DATA_PATH_WIDTH_AUTO:737+ iomap.flags |= MAP_AUTOSZ; break;738+ default:739+ break;740+ }741+ iomap.start = s->io[i].BasePort;742+ iomap.stop = iomap.start + s->io[i].NumPorts - 1;743+ s->ops->set_io_map(s, &iomap);744+ s->io[i].Config++;745+ }746+ }747+748+ c->state |= CONFIG_LOCKED;749+ handle->state |= CLIENT_CONFIG_LOCKED;750+ return CS_SUCCESS;751+} /* pcmcia_request_configuration */752+EXPORT_SYMBOL(pcmcia_request_configuration);753+754+755+/** pcmcia_request_io756+ *757+ * Request_io() reserves ranges of port addresses for a socket.758+ * I have not implemented range sharing or alias addressing.759+ */760+int pcmcia_request_io(client_handle_t handle, io_req_t *req)761+{762+ struct pcmcia_socket *s;763+ config_t *c;764+765+ if (CHECK_HANDLE(handle))766+ return CS_BAD_HANDLE;767+ s = SOCKET(handle);768+ if (!(s->state & SOCKET_PRESENT))769+ return CS_NO_CARD;770+771+ if (handle->state & CLIENT_CARDBUS) {772+#ifdef CONFIG_CARDBUS773+ handle->state |= CLIENT_IO_REQ;774+ return CS_SUCCESS;775+#else776+ return CS_UNSUPPORTED_FUNCTION;777+#endif778+ }779+780+ if (!req)781+ return CS_UNSUPPORTED_MODE;782+ c = CONFIG(handle);783+ if (c->state & CONFIG_LOCKED)784+ return CS_CONFIGURATION_LOCKED;785+ if (c->state & CONFIG_IO_REQ)786+ return CS_IN_USE;787+ if (req->Attributes1 & (IO_SHARED | IO_FORCE_ALIAS_ACCESS))788+ return CS_BAD_ATTRIBUTE;789+ if ((req->NumPorts2 > 0) &&790+ (req->Attributes2 & (IO_SHARED | IO_FORCE_ALIAS_ACCESS)))791+ return CS_BAD_ATTRIBUTE;792+793+ if (alloc_io_space(s, req->Attributes1, &req->BasePort1,794+ req->NumPorts1, req->IOAddrLines))795+ return CS_IN_USE;796+797+ if (req->NumPorts2) {798+ if (alloc_io_space(s, req->Attributes2, &req->BasePort2,799+ req->NumPorts2, req->IOAddrLines)) {800+ release_io_space(s, req->BasePort1, req->NumPorts1);801+ return CS_IN_USE;802+ }803+ }804+805+ c->io = *req;806+ c->state |= CONFIG_IO_REQ;807+ handle->state |= CLIENT_IO_REQ;808+ return CS_SUCCESS;809+} /* pcmcia_request_io */810+EXPORT_SYMBOL(pcmcia_request_io);811+812+813+/** pcmcia_request_irq814+ *815+ * Request_irq() reserves an irq for this client.816+ *817+ * Also, since Linux only reserves irq's when they are actually818+ * hooked, we don't guarantee that an irq will still be available819+ * when the configuration is locked. Now that I think about it,820+ * there might be a way to fix this using a dummy handler.821+ */822+823+#ifdef CONFIG_PCMCIA_PROBE824+static irqreturn_t test_action(int cpl, void *dev_id, struct pt_regs *regs)825+{826+ return IRQ_NONE;827+}828+#endif829+830+int pcmcia_request_irq(client_handle_t handle, irq_req_t *req)831+{832+ struct pcmcia_socket *s;833+ config_t *c;834+ int ret = CS_IN_USE, irq = 0;835+ struct pcmcia_device *p_dev = handle_to_pdev(handle);836+837+ if (CHECK_HANDLE(handle))838+ return CS_BAD_HANDLE;839+ s = SOCKET(handle);840+ if (!(s->state & SOCKET_PRESENT))841+ return CS_NO_CARD;842+ c = CONFIG(handle);843+ if (c->state & CONFIG_LOCKED)844+ return CS_CONFIGURATION_LOCKED;845+ if (c->state & CONFIG_IRQ_REQ)846+ return CS_IN_USE;847+848+#ifdef CONFIG_PCMCIA_PROBE849+ if (s->irq.AssignedIRQ != 0) {850+ /* If the interrupt is already assigned, it must be the same */851+ irq = s->irq.AssignedIRQ;852+ } else {853+ int try;854+ u32 mask = s->irq_mask;855+ void *data = NULL;856+857+ for (try = 0; try < 64; try++) {858+ irq = try % 32;859+860+ /* marked as available by driver, and not blocked by userspace? */861+ if (!((mask >> irq) & 1))862+ continue;863+864+ /* avoid an IRQ which is already used by a PCMCIA card */865+ if ((try < 32) && pcmcia_used_irq[irq])866+ continue;867+868+ /* register the correct driver, if possible, of check whether869+ * registering a dummy handle works, i.e. if the IRQ isn't870+ * marked as used by the kernel resource management core */871+ ret = request_irq(irq,872+ (req->Attributes & IRQ_HANDLE_PRESENT) ? req->Handler : test_action,873+ ((req->Attributes & IRQ_TYPE_DYNAMIC_SHARING) ||874+ (s->functions > 1) ||875+ (irq == s->pci_irq)) ? SA_SHIRQ : 0,876+ p_dev->dev.bus_id,877+ (req->Attributes & IRQ_HANDLE_PRESENT) ? req->Instance : data);878+ if (!ret) {879+ if (!(req->Attributes & IRQ_HANDLE_PRESENT))880+ free_irq(irq, data);881+ break;882+ }883+ }884+ }885+#endif886+ if (ret) {887+ if (!s->pci_irq)888+ return ret;889+ irq = s->pci_irq;890+ }891+892+ if (ret && req->Attributes & IRQ_HANDLE_PRESENT) {893+ if (request_irq(irq, req->Handler,894+ ((req->Attributes & IRQ_TYPE_DYNAMIC_SHARING) ||895+ (s->functions > 1) ||896+ (irq == s->pci_irq)) ? SA_SHIRQ : 0,897+ p_dev->dev.bus_id, req->Instance))898+ return CS_IN_USE;899+ }900+901+ c->irq.Attributes = req->Attributes;902+ s->irq.AssignedIRQ = req->AssignedIRQ = irq;903+ s->irq.Config++;904+905+ c->state |= CONFIG_IRQ_REQ;906+ handle->state |= CLIENT_IRQ_REQ;907+908+#ifdef CONFIG_PCMCIA_PROBE909+ pcmcia_used_irq[irq]++;910+#endif911+912+ return CS_SUCCESS;913+} /* pcmcia_request_irq */914+EXPORT_SYMBOL(pcmcia_request_irq);915+916+917+/** pcmcia_request_window918+ *919+ * Request_window() establishes a mapping between card memory space920+ * and system memory space.921+ */922+int pcmcia_request_window(client_handle_t *handle, win_req_t *req, window_handle_t *wh)923+{924+ struct pcmcia_socket *s;925+ window_t *win;926+ u_long align;927+ int w;928+929+ if (CHECK_HANDLE(*handle))930+ return CS_BAD_HANDLE;931+ s = (*handle)->Socket;932+ if (!(s->state & SOCKET_PRESENT))933+ return CS_NO_CARD;934+ if (req->Attributes & (WIN_PAGED | WIN_SHARED))935+ return CS_BAD_ATTRIBUTE;936+937+ /* Window size defaults to smallest available */938+ if (req->Size == 0)939+ req->Size = s->map_size;940+ align = (((s->features & SS_CAP_MEM_ALIGN) ||941+ (req->Attributes & WIN_STRICT_ALIGN)) ?942+ req->Size : s->map_size);943+ if (req->Size & (s->map_size-1))944+ return CS_BAD_SIZE;945+ if ((req->Base && (s->features & SS_CAP_STATIC_MAP)) ||946+ (req->Base & (align-1)))947+ return CS_BAD_BASE;948+ if (req->Base)949+ align = 0;950+951+ /* Allocate system memory window */952+ for (w = 0; w < MAX_WIN; w++)953+ if (!(s->state & SOCKET_WIN_REQ(w))) break;954+ if (w == MAX_WIN)955+ return CS_OUT_OF_RESOURCE;956+957+ win = &s->win[w];958+ win->magic = WINDOW_MAGIC;959+ win->index = w;960+ win->handle = *handle;961+ win->sock = s;962+963+ if (!(s->features & SS_CAP_STATIC_MAP)) {964+ win->ctl.res = pcmcia_find_mem_region(req->Base, req->Size, align,965+ (req->Attributes & WIN_MAP_BELOW_1MB), s);966+ if (!win->ctl.res)967+ return CS_IN_USE;968+ }969+ (*handle)->state |= CLIENT_WIN_REQ(w);970+971+ /* Configure the socket controller */972+ win->ctl.map = w+1;973+ win->ctl.flags = 0;974+ win->ctl.speed = req->AccessSpeed;975+ if (req->Attributes & WIN_MEMORY_TYPE)976+ win->ctl.flags |= MAP_ATTRIB;977+ if (req->Attributes & WIN_ENABLE)978+ win->ctl.flags |= MAP_ACTIVE;979+ if (req->Attributes & WIN_DATA_WIDTH_16)980+ win->ctl.flags |= MAP_16BIT;981+ if (req->Attributes & WIN_USE_WAIT)982+ win->ctl.flags |= MAP_USE_WAIT;983+ win->ctl.card_start = 0;984+ if (s->ops->set_mem_map(s, &win->ctl) != 0)985+ return CS_BAD_ARGS;986+ s->state |= SOCKET_WIN_REQ(w);987+988+ /* Return window handle */989+ if (s->features & SS_CAP_STATIC_MAP) {990+ req->Base = win->ctl.static_start;991+ } else {992+ req->Base = win->ctl.res->start;993+ }994+ *wh = win;995+996+ return CS_SUCCESS;997+} /* pcmcia_request_window */998+EXPORT_SYMBOL(pcmcia_request_window);
+7-4
drivers/pcmcia/rsrc_mgr.c
···72 /* you can't use the old interface if the new73 * one was used before */74 spin_lock_irqsave(&s->lock, flags);75- if ((s->resource_setup_done) &&76 !(s->resource_setup_old)) {77 spin_unlock_irqrestore(&s->lock, flags);78 continue;···105}106EXPORT_SYMBOL(pcmcia_validate_mem);107108-int adjust_io_region(struct resource *res, unsigned long r_start,109 unsigned long r_end, struct pcmcia_socket *s)110{111 if (s->resource_ops->adjust_io_region)112 return s->resource_ops->adjust_io_region(res, r_start, r_end, s);113 return -ENOMEM;114}0115116-struct resource *find_io_region(unsigned long base, int num,117 unsigned long align, struct pcmcia_socket *s)118{119 if (s->resource_ops->find_io)120 return s->resource_ops->find_io(base, num, align, s);121 return NULL;122}0123124-struct resource *find_mem_region(u_long base, u_long num, u_long align,125 int low, struct pcmcia_socket *s)126{127 if (s->resource_ops->find_mem)128 return s->resource_ops->find_mem(base, num, align, low, s);129 return NULL;130}0131132void release_resource_db(struct pcmcia_socket *s)133{
···72 /* you can't use the old interface if the new73 * one was used before */74 spin_lock_irqsave(&s->lock, flags);75+ if ((s->resource_setup_new) &&76 !(s->resource_setup_old)) {77 spin_unlock_irqrestore(&s->lock, flags);78 continue;···105}106EXPORT_SYMBOL(pcmcia_validate_mem);107108+int pcmcia_adjust_io_region(struct resource *res, unsigned long r_start,109 unsigned long r_end, struct pcmcia_socket *s)110{111 if (s->resource_ops->adjust_io_region)112 return s->resource_ops->adjust_io_region(res, r_start, r_end, s);113 return -ENOMEM;114}115+EXPORT_SYMBOL(pcmcia_adjust_io_region);116117+struct resource *pcmcia_find_io_region(unsigned long base, int num,118 unsigned long align, struct pcmcia_socket *s)119{120 if (s->resource_ops->find_io)121 return s->resource_ops->find_io(base, num, align, s);122 return NULL;123}124+EXPORT_SYMBOL(pcmcia_find_io_region);125126+struct resource *pcmcia_find_mem_region(u_long base, u_long num, u_long align,127 int low, struct pcmcia_socket *s)128{129 if (s->resource_ops->find_mem)130 return s->resource_ops->find_mem(base, num, align, low, s);131 return NULL;132}133+EXPORT_SYMBOL(pcmcia_find_mem_region);134135void release_resource_db(struct pcmcia_socket *s)136{
+114-56
drivers/pcmcia/rsrc_nonstatic.c
···372 base, base+num-1);373 bad = fail = 0;374 step = (num < 0x20000) ? 0x2000 : ((num>>4) & ~0x1fff);000375 /* cis_readable wants to map 2x map_size */376 if (step < 2 * s->map_size)377 step = 2 * s->map_size;···468469 for (m = s_data->mem_db.next; m != &s_data->mem_db; m = mm.next) {470 mm = *m;471- if (do_mem_probe(mm.base, mm.num, s))472- break;473 }474}475···603604======================================================================*/605606-struct resource *nonstatic_find_io_region(unsigned long base, int num,607 unsigned long align, struct pcmcia_socket *s)608{609 struct resource *res = make_resource(0, num, IORESOURCE_IO, s->dev.class_id);···637 return res;638}639640-struct resource * nonstatic_find_mem_region(u_long base, u_long num, u_long align,641- int low, struct pcmcia_socket *s)642{643 struct resource *res = make_resource(0, num, IORESOURCE_MEM, s->dev.class_id);644 struct socket_data *s_data = s->resource_data;···685}686687688-static int adjust_memory(struct pcmcia_socket *s, adjust_t *adj)689{690- u_long base, num;691 struct socket_data *data = s->resource_data;692- int ret;0693694- base = adj->resource.memory.Base;695- num = adj->resource.memory.Size;696- if ((num == 0) || (base+num-1 < base))697- return CS_BAD_SIZE;698-699- ret = CS_SUCCESS;700701 down(&rsrc_sem);702- switch (adj->Action) {703 case ADD_MANAGED_RESOURCE:704- ret = add_interval(&data->mem_db, base, num);705 break;706 case REMOVE_MANAGED_RESOURCE:707- ret = sub_interval(&data->mem_db, base, num);708- if (ret == CS_SUCCESS) {709 struct pcmcia_socket *socket;710 down_read(&pcmcia_socket_list_rwsem);711 list_for_each_entry(socket, &pcmcia_socket_list, socket_list)···710 }711 break;712 default:713- ret = CS_UNSUPPORTED_FUNCTION;714 }715 up(&rsrc_sem);716···718}719720721-static int adjust_io(struct pcmcia_socket *s, adjust_t *adj)722{723 struct socket_data *data = s->resource_data;724- kio_addr_t base, num;725- int ret = CS_SUCCESS;726727- base = adj->resource.io.BasePort;728- num = adj->resource.io.NumPorts;729- if ((base < 0) || (base > 0xffff))730- return CS_BAD_BASE;731- if ((num <= 0) || (base+num > 0x10000) || (base+num <= base))732- return CS_BAD_SIZE;733734 down(&rsrc_sem);735- switch (adj->Action) {736 case ADD_MANAGED_RESOURCE:737- if (add_interval(&data->io_db, base, num) != 0) {738- ret = CS_IN_USE;739 break;740 }741#ifdef CONFIG_PCMCIA_PROBE742 if (probe_io)743- do_io_probe(s, base, num);744#endif745 break;746 case REMOVE_MANAGED_RESOURCE:747- sub_interval(&data->io_db, base, num);748 break;749 default:750- ret = CS_UNSUPPORTED_FUNCTION;751 break;752 }753 up(&rsrc_sem);···757758static int nonstatic_adjust_resource_info(struct pcmcia_socket *s, adjust_t *adj)759{00760 switch (adj->Resource) {761 case RES_MEMORY_RANGE:762- return adjust_memory(s, adj);0763 case RES_IO_RANGE:764- return adjust_io(s, adj);0765 }766 return CS_UNSUPPORTED_FUNCTION;767}000000000000000000000000000000000000000000000000000000000000000768769static int nonstatic_init(struct pcmcia_socket *s)770{···846 data->io_db.next = &data->io_db;847848 s->resource_data = (void *) data;00849850 return 0;851}···911{912 struct pcmcia_socket *s = class_get_devdata(class_dev);913 unsigned long start_addr, end_addr;914- unsigned int add = 1;915- adjust_t adj;916 ssize_t ret = 0;917918 ret = sscanf (buf, "+ 0x%lx - 0x%lx", &start_addr, &end_addr);919 if (ret != 2) {920 ret = sscanf (buf, "- 0x%lx - 0x%lx", &start_addr, &end_addr);921- add = 0;922 if (ret != 2) {923 ret = sscanf (buf, "0x%lx - 0x%lx", &start_addr, &end_addr);924- add = 1;925 if (ret != 2)926 return -EINVAL;927 }···928 if (end_addr <= start_addr)929 return -EINVAL;930931- adj.Action = add ? ADD_MANAGED_RESOURCE : REMOVE_MANAGED_RESOURCE;932- adj.Resource = RES_IO_RANGE;933- adj.resource.io.BasePort = start_addr;934- adj.resource.io.NumPorts = end_addr - start_addr + 1;935-936- ret = adjust_io(s, &adj);937938 return ret ? ret : count;939}···963{964 struct pcmcia_socket *s = class_get_devdata(class_dev);965 unsigned long start_addr, end_addr;966- unsigned int add = 1;967- adjust_t adj;968 ssize_t ret = 0;969970 ret = sscanf (buf, "+ 0x%lx - 0x%lx", &start_addr, &end_addr);971 if (ret != 2) {972 ret = sscanf (buf, "- 0x%lx - 0x%lx", &start_addr, &end_addr);973- add = 0;974 if (ret != 2) {975 ret = sscanf (buf, "0x%lx - 0x%lx", &start_addr, &end_addr);976- add = 1;977 if (ret != 2)978 return -EINVAL;979 }···980 if (end_addr <= start_addr)981 return -EINVAL;982983- adj.Action = add ? ADD_MANAGED_RESOURCE : REMOVE_MANAGED_RESOURCE;984- adj.Resource = RES_MEMORY_RANGE;985- adj.resource.memory.Base = start_addr;986- adj.resource.memory.Size = end_addr - start_addr + 1;987-988- ret = adjust_memory(s, &adj);989990 return ret ? ret : count;991}
···372 base, base+num-1);373 bad = fail = 0;374 step = (num < 0x20000) ? 0x2000 : ((num>>4) & ~0x1fff);375+ /* don't allow too large steps */376+ if (step > 0x800000)377+ step = 0x800000;378 /* cis_readable wants to map 2x map_size */379 if (step < 2 * s->map_size)380 step = 2 * s->map_size;···465466 for (m = s_data->mem_db.next; m != &s_data->mem_db; m = mm.next) {467 mm = *m;468+ do_mem_probe(mm.base, mm.num, s);0469 }470}471···601602======================================================================*/603604+static struct resource *nonstatic_find_io_region(unsigned long base, int num,605 unsigned long align, struct pcmcia_socket *s)606{607 struct resource *res = make_resource(0, num, IORESOURCE_IO, s->dev.class_id);···635 return res;636}637638+static struct resource * nonstatic_find_mem_region(u_long base, u_long num,639+ u_long align, int low, struct pcmcia_socket *s)640{641 struct resource *res = make_resource(0, num, IORESOURCE_MEM, s->dev.class_id);642 struct socket_data *s_data = s->resource_data;···683}684685686+static int adjust_memory(struct pcmcia_socket *s, unsigned int action, unsigned long start, unsigned long end)687{0688 struct socket_data *data = s->resource_data;689+ unsigned long size = end - start + 1;690+ int ret = 0;691692+ if (end <= start)693+ return -EINVAL;0000694695 down(&rsrc_sem);696+ switch (action) {697 case ADD_MANAGED_RESOURCE:698+ ret = add_interval(&data->mem_db, start, size);699 break;700 case REMOVE_MANAGED_RESOURCE:701+ ret = sub_interval(&data->mem_db, start, size);702+ if (!ret) {703 struct pcmcia_socket *socket;704 down_read(&pcmcia_socket_list_rwsem);705 list_for_each_entry(socket, &pcmcia_socket_list, socket_list)···712 }713 break;714 default:715+ ret = -EINVAL;716 }717 up(&rsrc_sem);718···720}721722723+static int adjust_io(struct pcmcia_socket *s, unsigned int action, unsigned long start, unsigned long end)724{725 struct socket_data *data = s->resource_data;726+ unsigned long size = end - start + 1;727+ int ret = 0;728729+ if (end <= start)730+ return -EINVAL;731+732+ if (end > IO_SPACE_LIMIT)733+ return -EINVAL;0734735 down(&rsrc_sem);736+ switch (action) {737 case ADD_MANAGED_RESOURCE:738+ if (add_interval(&data->io_db, start, size) != 0) {739+ ret = -EBUSY;740 break;741 }742#ifdef CONFIG_PCMCIA_PROBE743 if (probe_io)744+ do_io_probe(s, start, size);745#endif746 break;747 case REMOVE_MANAGED_RESOURCE:748+ sub_interval(&data->io_db, start, size);749 break;750 default:751+ ret = -EINVAL;752 break;753 }754 up(&rsrc_sem);···760761static int nonstatic_adjust_resource_info(struct pcmcia_socket *s, adjust_t *adj)762{763+ unsigned long end;764+765 switch (adj->Resource) {766 case RES_MEMORY_RANGE:767+ end = adj->resource.memory.Base + adj->resource.memory.Size - 1;768+ return adjust_memory(s, adj->Action, adj->resource.memory.Base, end);769 case RES_IO_RANGE:770+ end = adj->resource.io.BasePort + adj->resource.io.NumPorts - 1;771+ return adjust_io(s, adj->Action, adj->resource.io.BasePort, end);772 }773 return CS_UNSUPPORTED_FUNCTION;774}775+776+#ifdef CONFIG_PCI777+static int nonstatic_autoadd_resources(struct pcmcia_socket *s)778+{779+ struct resource *res;780+ int i, done = 0;781+782+ if (!s->cb_dev || !s->cb_dev->bus)783+ return -ENODEV;784+785+#if defined(CONFIG_X86) || defined(CONFIG_X86_64)786+ /* If this is the root bus, the risk of hitting787+ * some strange system devices which aren't protected788+ * by either ACPI resource tables or properly requested789+ * resources is too big. Therefore, don't do auto-adding790+ * of resources at the moment.791+ */792+ if (s->cb_dev->bus->number == 0)793+ return -EINVAL;794+#endif795+796+ for (i=0; i < PCI_BUS_NUM_RESOURCES; i++) {797+ res = s->cb_dev->bus->resource[i];798+ if (!res)799+ continue;800+801+ if (res->flags & IORESOURCE_IO) {802+ if (res == &ioport_resource)803+ continue;804+ printk(KERN_INFO "pcmcia: parent PCI bridge I/O window: 0x%lx - 0x%lx\n",805+ res->start, res->end);806+ if (!adjust_io(s, ADD_MANAGED_RESOURCE, res->start, res->end))807+ done |= IORESOURCE_IO;808+809+ }810+811+ if (res->flags & IORESOURCE_MEM) {812+ if (res == &iomem_resource)813+ continue;814+ printk(KERN_INFO "pcmcia: parent PCI bridge Memory window: 0x%lx - 0x%lx\n",815+ res->start, res->end);816+ if (!adjust_memory(s, ADD_MANAGED_RESOURCE, res->start, res->end))817+ done |= IORESOURCE_MEM;818+ }819+ }820+821+ /* if we got at least one of IO, and one of MEM, we can be glad and822+ * activate the PCMCIA subsystem */823+ if (done & (IORESOURCE_MEM | IORESOURCE_IO))824+ s->resource_setup_done = 1;825+826+ return 0;827+}828+829+#else830+831+static inline int nonstatic_autoadd_resources(struct pcmcia_socket *s)832+{833+ return -ENODEV;834+}835+836+#endif837+838839static int nonstatic_init(struct pcmcia_socket *s)840{···782 data->io_db.next = &data->io_db;783784 s->resource_data = (void *) data;785+786+ nonstatic_autoadd_resources(s);787788 return 0;789}···845{846 struct pcmcia_socket *s = class_get_devdata(class_dev);847 unsigned long start_addr, end_addr;848+ unsigned int add = ADD_MANAGED_RESOURCE;0849 ssize_t ret = 0;850851 ret = sscanf (buf, "+ 0x%lx - 0x%lx", &start_addr, &end_addr);852 if (ret != 2) {853 ret = sscanf (buf, "- 0x%lx - 0x%lx", &start_addr, &end_addr);854+ add = REMOVE_MANAGED_RESOURCE;855 if (ret != 2) {856 ret = sscanf (buf, "0x%lx - 0x%lx", &start_addr, &end_addr);857+ add = ADD_MANAGED_RESOURCE;858 if (ret != 2)859 return -EINVAL;860 }···863 if (end_addr <= start_addr)864 return -EINVAL;865866+ ret = adjust_io(s, add, start_addr, end_addr);867+ if (!ret)868+ s->resource_setup_new = 1;000869870 return ret ? ret : count;871}···901{902 struct pcmcia_socket *s = class_get_devdata(class_dev);903 unsigned long start_addr, end_addr;904+ unsigned int add = ADD_MANAGED_RESOURCE;0905 ssize_t ret = 0;906907 ret = sscanf (buf, "+ 0x%lx - 0x%lx", &start_addr, &end_addr);908 if (ret != 2) {909 ret = sscanf (buf, "- 0x%lx - 0x%lx", &start_addr, &end_addr);910+ add = REMOVE_MANAGED_RESOURCE;911 if (ret != 2) {912 ret = sscanf (buf, "0x%lx - 0x%lx", &start_addr, &end_addr);913+ add = ADD_MANAGED_RESOURCE;914 if (ret != 2)915 return -EINVAL;916 }···919 if (end_addr <= start_addr)920 return -EINVAL;921922+ ret = adjust_memory(s, add, start_addr, end_addr);923+ if (!ret)924+ s->resource_setup_new = 1;000925926 return ret ? ret : count;927}
···159 * underruns. If non-zero, doing_pdma encodes the direction of160 * the transfer for debugging. 1=read 2=write161 */162-char *pdma_vaddr;163unsigned long pdma_size;164volatile int doing_pdma = 0;165···209 pdma_areasize = pdma_size;210}211212-/* Our low-level entry point in arch/sparc/kernel/entry.S */213-extern irqreturn_t floppy_hardint(int irq, void *unused, struct pt_regs *regs);214215static int sun_fd_request_irq(void)216{···219 if(!once) {220 once = 1;221222- error = request_fast_irq(FLOPPY_IRQ, floppy_hardint, 223- SA_INTERRUPT, "floppy", NULL);224225 return ((error == 0) ? 0 : -1);226 }···614 struct linux_ebus *ebus;615 struct linux_ebus_device *edev = NULL;616 unsigned long config = 0;617- unsigned long auxio_reg;618619 for_each_ebus(ebus) {620 for_each_ebusdev(edev, ebus) {···641 /* Make sure the high density bit is set, some systems642 * (most notably Ultra5/Ultra10) come up with it clear.643 */644- auxio_reg = edev->resource[2].start;645 writel(readl(auxio_reg)|0x2, auxio_reg);646647 sun_pci_ebus_dev = ebus->self;···649 spin_lock_init(&sun_pci_fd_ebus_dma.lock);650651 /* XXX ioremap */652- sun_pci_fd_ebus_dma.regs = edev->resource[1].start;0653 if (!sun_pci_fd_ebus_dma.regs)654 return 0;655
···159 * underruns. If non-zero, doing_pdma encodes the direction of160 * the transfer for debugging. 1=read 2=write161 */162+unsigned char *pdma_vaddr;163unsigned long pdma_size;164volatile int doing_pdma = 0;165···209 pdma_areasize = pdma_size;210}211212+extern irqreturn_t sparc_floppy_irq(int, void *, struct pt_regs *);0213214static int sun_fd_request_irq(void)215{···220 if(!once) {221 once = 1;222223+ error = request_irq(FLOPPY_IRQ, sparc_floppy_irq, 224+ SA_INTERRUPT, "floppy", NULL);225226 return ((error == 0) ? 0 : -1);227 }···615 struct linux_ebus *ebus;616 struct linux_ebus_device *edev = NULL;617 unsigned long config = 0;618+ void __iomem *auxio_reg;619620 for_each_ebus(ebus) {621 for_each_ebusdev(edev, ebus) {···642 /* Make sure the high density bit is set, some systems643 * (most notably Ultra5/Ultra10) come up with it clear.644 */645+ auxio_reg = (void __iomem *) edev->resource[2].start;646 writel(readl(auxio_reg)|0x2, auxio_reg);647648 sun_pci_ebus_dev = ebus->self;···650 spin_lock_init(&sun_pci_fd_ebus_dma.lock);651652 /* XXX ioremap */653+ sun_pci_fd_ebus_dma.regs = (void __iomem *)654+ edev->resource[1].start;655 if (!sun_pci_fd_ebus_dma.regs)656 return 0;657
+1-6
include/asm-sparc64/irq.h
···19/* You should not mess with this directly. That's the job of irq.c.20 *21 * If you make changes here, please update hand coded assembler of22- * SBUS/floppy interrupt handler in entry.S -DaveM23 *24 * This is currently one DCACHE line, two buckets per L2 cache25 * line. Keep this in mind please.···121extern void enable_irq(unsigned int);122extern unsigned int build_irq(int pil, int inofixup, unsigned long iclr, unsigned long imap);123extern unsigned int sbus_build_irq(void *sbus, unsigned int ino);124-125-extern int request_fast_irq(unsigned int irq,126- irqreturn_t (*handler)(int, void *, struct pt_regs *),127- unsigned long flags, __const__ char *devname,128- void *dev_id);129130static __inline__ void set_softint(unsigned long bits)131{
···19/* You should not mess with this directly. That's the job of irq.c.20 *21 * If you make changes here, please update hand coded assembler of22+ * the vectored interrupt trap handler in entry.S -DaveM23 *24 * This is currently one DCACHE line, two buckets per L2 cache25 * line. Keep this in mind please.···121extern void enable_irq(unsigned int);122extern unsigned int build_irq(int pil, int inofixup, unsigned long iclr, unsigned long imap);123extern unsigned int sbus_build_irq(void *sbus, unsigned int ino);00000124125static __inline__ void set_softint(unsigned long bits)126{
···111 "membar #Sync"112 : /* No outputs */113 : "r" (tag), "r" (addr), "i" (ASI_DCACHE_TAG));114- __asm__ __volatile__ ("membar #Sync" : : : "memory");115}116117/* The instruction cache lines are flushed with this, but note that
···111 "membar #Sync"112 : /* No outputs */113 : "r" (tag), "r" (addr), "i" (ASI_DCACHE_TAG));0114}115116/* The instruction cache lines are flushed with this, but note that
···15#ifndef _LINUX_SS_H16#define _LINUX_SS_H1700018#include <pcmcia/cs_types.h>19#include <pcmcia/cs.h>20#include <pcmcia/bulkmem.h>21-#include <linux/device.h>2223/* Definitions for card status flags for GetStatus */24#define SS_WRPROT 0x0001···173174struct config_t;175struct pcmcia_callback;176-177178struct pcmcia_socket {179 struct module *owner;···218219 /* is set to one if resource setup is done using adjust_resource_info() */220 u8 resource_setup_old:1;0221222- u8 reserved:6;223224 /* socket operations */225 struct pccard_operations * ops;···244 unsigned int thread_events;245246 /* pcmcia (16-bit) */247- struct pcmcia_bus_socket *pcmcia;248 struct pcmcia_callback *callback;000000000000000000000000249250 /* cardbus (32-bit) */251#ifdef CONFIG_CARDBUS
···15#ifndef _LINUX_SS_H16#define _LINUX_SS_H1718+#include <linux/config.h>19+#include <linux/device.h>20+21#include <pcmcia/cs_types.h>22#include <pcmcia/cs.h>23#include <pcmcia/bulkmem.h>02425/* Definitions for card status flags for GetStatus */26#define SS_WRPROT 0x0001···171172struct config_t;173struct pcmcia_callback;174+struct user_info_t;175176struct pcmcia_socket {177 struct module *owner;···216217 /* is set to one if resource setup is done using adjust_resource_info() */218 u8 resource_setup_old:1;219+ u8 resource_setup_new:1;220221+ u8 reserved:5;222223 /* socket operations */224 struct pccard_operations * ops;···241 unsigned int thread_events;242243 /* pcmcia (16-bit) */0244 struct pcmcia_callback *callback;245+246+#if defined(CONFIG_PCMCIA) || defined(CONFIG_PCMCIA_MODULE)247+ struct list_head devices_list; /* PCMCIA devices */248+ u8 device_count; /* the number of devices, used249+ * only internally and subject250+ * to incorrectness and change */251+252+ struct {253+ u8 present:1, /* PCMCIA card is present in socket */254+ busy:1, /* "master" ioctl is used */255+ dead:1, /* pcmcia module is being unloaded */256+ device_add_pending:1, /* a pseudo-multifunction-device257+ * add event is pending */258+ reserved:4;259+ } pcmcia_state;260+261+ struct work_struct device_add; /* for adding further pseudo-multifunction262+ * devices */263+264+#ifdef CONFIG_PCMCIA_IOCTL265+ struct user_info_t *user;266+ wait_queue_head_t queue;267+#endif268+#endif269270 /* cardbus (32-bit) */271#ifdef CONFIG_CARDBUS
+39
scripts/mod/file2alias.c
···287 return 1;288}289000000000000000000000000000000000000290/* Ignore any prefix, eg. v850 prepends _ */291static inline int sym_is(const char *symbol, const char *name)292{···398 else if (sym_is(symname, "__mod_pnp_card_device_table"))399 do_table(symval, sym->st_size, sizeof(struct pnp_card_device_id),400 do_pnp_card_entry, mod);000401}402403/* Now add out buffered information to the generated C source */