···44444545Again, keep in mind that this list assumes you are already4646functionally running a Linux 2.4 kernel. Also, not all tools are4747-necessary on all systems; obviously, if you don't have any PCMCIA (PC4848-Card) hardware, for example, you probably needn't concern yourself4949-with pcmcia-cs.4747+necessary on all systems; obviously, if you don't have any ISDN4848+hardware, for example, you probably needn't concern yourself with4949+isdn4k-utils.50505151o Gnu C 2.95.3 # gcc --version5252o Gnu make 3.79.1 # make --version···5757o jfsutils 1.1.3 # fsck.jfs -V5858o reiserfsprogs 3.6.3 # reiserfsck -V 2>&1|grep reiserfsprogs5959o xfsprogs 2.6.0 # xfs_db -V6060+o pcmciautils 0016061o pcmcia-cs 3.1.21 # cardmgr -V6162o quota-tools 3.09 # quota -V6263o PPP 2.4.0 # pppd --version···187186work correctly with this version of the XFS kernel code (2.6.0 or188187later is recommended, due to some significant improvements).189188189189+PCMCIAutils190190+-----------191191+192192+PCMCIAutils replaces pcmcia-cs (see below). It properly sets up193193+PCMCIA sockets at system startup and loads the appropriate modules194194+for 16-bit PCMCIA devices if the kernel is modularized and the hotplug195195+subsystem is used.190196191197Pcmcia-cs192198---------193199194200PCMCIA (PC Card) support is now partially implemented in the main195195-kernel source. Pay attention when you recompile your kernel ;-).196196-Also, be sure to upgrade to the latest pcmcia-cs release.201201+kernel source. The "pcmciautils" package (see above) replaces pcmcia-cs202202+for newest kernels.197203198204Quota-tools199205-----------···357349--------358350o <ftp://oss.sgi.com/projects/xfs/download/>359351352352+Pcmciautils353353+-----------354354+o <ftp://ftp.kernel.org/pub/linux/utils/kernel/pcmcia/>355355+360356Pcmcia-cs361357---------362362-o <ftp://pcmcia-cs.sourceforge.net/pub/pcmcia-cs/pcmcia-cs-3.1.21.tar.gz>358358+o <http://pcmcia-cs.sourceforge.net/>363359364360Quota-tools365361----------
+64
Documentation/pcmcia/devicetable.txt
···11+Matching of PCMCIA devices to drivers is done using one or more of the22+following criteria:33+44+- manufactor ID55+- card ID66+- product ID strings _and_ hashes of these strings77+- function ID88+- device function (actual and pseudo)99+1010+You should use the helpers in include/pcmcia/device_id.h for generating the1111+struct pcmcia_device_id[] entries which match devices to drivers.1212+1313+If you want to match product ID strings, you also need to pass the crc321414+hashes of the string to the macro, e.g. if you want to match the product ID1515+string 1, you need to use1616+1717+PCMCIA_DEVICE_PROD_ID1("some_string", 0x(hash_of_some_string)),1818+1919+If the hash is incorrect, the kernel will inform you about this in "dmesg"2020+upon module initialization, and tell you of the correct hash.2121+2222+You can determine the hash of the product ID strings by running2323+"pcmcia-modalias %n.%m" [%n being replaced with the socket number and %m being2424+replaced with the device function] from pcmciautils. It generates a string2525+in the following form:2626+pcmcia:m0149cC1ABf06pfn00fn00pa725B842DpbF1EFEE84pc0877B627pd000000002727+2828+The hex value after "pa" is the hash of product ID string 1, after "pb" for2929+string 2 and so on.3030+3131+Alternatively, you can use this small tool to determine the crc32 hash.3232+simply pass the string you want to evaluate as argument to this program,3333+e.g.3434+$ ./crc32hash "Dual Speed"3535+3636+-------------------------------------------------------------------------3737+/* crc32hash.c - derived from linux/lib/crc32.c, GNU GPL v2 */3838+#include <string.h>3939+#include <stdio.h>4040+#include <ctype.h>4141+#include <stdlib.h>4242+4343+unsigned int crc32(unsigned char const *p, unsigned int len)4444+{4545+ int i;4646+ unsigned int crc = 0;4747+ while (len--) {4848+ crc ^= *p++;4949+ for (i = 0; i < 8; i++)5050+ crc = (crc >> 1) ^ ((crc & 1) ? 0xedb88320 : 0);5151+ }5252+ return crc;5353+}5454+5555+int main(int argc, char **argv) {5656+ unsigned int result;5757+ if (argc != 2) {5858+ printf("no string passed as argument\n");5959+ return -1;6060+ }6161+ result = crc32(argv[1], strlen(argv[1]));6262+ printf("0x%x\n", result);6363+ return 0;6464+}
+51
Documentation/pcmcia/driver-changes.txt
···11+This file details changes in 2.6 which affect PCMCIA card driver authors:22+33+* in-kernel device<->driver matching44+ PCMCIA devices and their correct drivers can now be matched in55+ kernelspace. See 'devicetable.txt' for details.66+77+* Device model integration (as of 2.6.11)88+ A struct pcmcia_device is registered with the device model core,99+ and can be used (e.g. for SET_NETDEV_DEV) by using1010+ handle_to_dev(client_handle_t * handle).1111+1212+* Convert internal I/O port addresses to unsigned long (as of 2.6.11)1313+ ioaddr_t should be replaced by kio_addr_t in PCMCIA card drivers.1414+1515+* irq_mask and irq_list parameters (as of 2.6.11)1616+ The irq_mask and irq_list parameters should no longer be used in1717+ PCMCIA card drivers. Instead, it is the job of the PCMCIA core to1818+ determine which IRQ should be used. Therefore, link->irq.IRQInfo21919+ is ignored.2020+2121+* client->PendingEvents is gone (as of 2.6.11)2222+ client->PendingEvents is no longer available.2323+2424+* client->Attributes are gone (as of 2.6.11)2525+ client->Attributes is unused, therefore it is removed from all2626+ PCMCIA card drivers2727+2828+* core functions no longer available (as of 2.6.11)2929+ The following functions have been removed from the kernel source3030+ because they are unused by all in-kernel drivers, and no external3131+ driver was reported to rely on them:3232+ pcmcia_get_first_region()3333+ pcmcia_get_next_region()3434+ pcmcia_modify_window()3535+ pcmcia_set_event_mask()3636+ pcmcia_get_first_window()3737+ pcmcia_get_next_window()3838+3939+* device list iteration upon module removal (as of 2.6.10)4040+ It is no longer necessary to iterate on the driver's internal4141+ client list and call the ->detach() function upon module removal.4242+4343+* Resource management. (as of 2.6.8)4444+ Although the PCMCIA subsystem will allocate resources for cards,4545+ it no longer marks these resources busy. This means that driver4646+ authors are now responsible for claiming your resources as per4747+ other drivers in Linux. You should use request_region() to mark4848+ your IO regions in-use, and request_mem_region() to mark your4949+ memory regions in-use. The name argument should be a pointer to5050+ your driver name. Eg, for pcnet_cs, name should point to the5151+ string "pcnet_cs".
+1-1
arch/sparc64/kernel/auxio.c
···1616#include <asm/ebus.h>1717#include <asm/auxio.h>18181919-/* This cannot be static, as it is referenced in entry.S */1919+/* This cannot be static, as it is referenced in irq.c */2020void __iomem *auxio_register = NULL;21212222enum auxio_type {
···606606 <http://www.ite.com.tw/ia/brief_it8172bsp.htm>; picture of the607607 board at <http://www.mvista.com/partners/semiconductor/ite.html>.608608609609+config BLK_DEV_IT821X610610+ tristate "IT821X IDE support"611611+ help612612+ This driver adds support for the ITE 8211 IDE controller and the613613+ IT 8212 IDE RAID controller in both RAID and pass-through mode.614614+609615config BLK_DEV_NS87415610616 tristate "NS87415 chipset support"611617 help
+4
drivers/ide/ide-disk.c
···119119{120120 unsigned long lba_sects, chs_sects, head, tail;121121122122+ /* No non-LBA info .. so valid! */123123+ if (id->cyls == 0)124124+ return 1;125125+122126 /*123127 * The ATA spec tells large drives to return124128 * C/H/S = 16383/16/63 independent of their size.
···1010 * donation of an ABit BP6 mainboard, processor, and memory acellerated1111 * development and support.1212 *1313+ *1414+ * Highpoint have their own driver (source except for the raid part)1515+ * available from http://www.highpoint-tech.com/hpt3xx-opensource-v131.tgz1616+ * This may be useful to anyone wanting to work on the mainstream hpt IDE.1717+ *1318 * Note that final HPT370 support was done by force extraction of GPL.1419 *1520 * - add function for getting/setting power status of drive···451446#define F_LOW_PCI_50 0x2d452447#define F_LOW_PCI_66 0x42453448454454-/* FIXME: compare with driver's code before removing */455455-#if 0456456- if (hpt_minimum_revision(dev, 3)) {457457- u8 cbl;458458- cbl = inb(iobase + 0x7b);459459- outb(cbl | 1, iobase + 0x7b);460460- outb(cbl & ~1, iobase + 0x7b);461461- cbl = inb(iobase + 0x7a);462462- p += sprintf(p, "Cable: ATA-%d"463463- " ATA-%d\n",464464- (cbl & 0x02) ? 33 : 66,465465- (cbl & 0x01) ? 33 : 66);466466- p += sprintf(p, "\n");467467- }468468- {469469- u8 c2, c3;470470- /* older revs don't have these registers mapped 471471- * into io space */472472- pci_read_config_byte(dev, 0x43, &c0);473473- pci_read_config_byte(dev, 0x47, &c1);474474- pci_read_config_byte(dev, 0x4b, &c2);475475- pci_read_config_byte(dev, 0x4f, &c3);449449+/*450450+ * Hold all the highpoint quirks and revision information in one451451+ * place.452452+ */476453477477- p += sprintf(p, "Mode: %s %s"478478- " %s %s\n",479479- (c0 & 0x10) ? "UDMA" : (c0 & 0x20) ? "DMA " : 480480- (c0 & 0x80) ? "PIO " : "off ",481481- (c1 & 0x10) ? "UDMA" : (c1 & 0x20) ? "DMA " :482482- (c1 & 0x80) ? "PIO " : "off ",483483- (c2 & 0x10) ? "UDMA" : (c2 & 0x20) ? "DMA " :484484- (c2 & 0x80) ? "PIO " : "off ",485485- (c3 & 0x10) ? "UDMA" : (c3 & 0x20) ? "DMA " :486486- (c3 & 0x80) ? "PIO " : "off ");487487- }488488- }489489-#endif454454+struct hpt_info455455+{456456+ u8 max_mode; /* Speeds allowed */457457+ int revision; /* Chipset revision */458458+ int flags; /* Chipset properties */459459+#define PLL_MODE 1460460+#define IS_372N 2461461+ /* Speed table */462462+ struct chipset_bus_clock_list_entry *speed;463463+};490464491491-static u32 hpt_revision (struct pci_dev *dev)465465+/*466466+ * This wants fixing so that we do everything not by classrev467467+ * (which breaks on the newest chips) but by creating an468468+ * enumeration of chip variants and using that469469+ */470470+471471+static __devinit u32 hpt_revision (struct pci_dev *dev)492472{493473 u32 class_rev;494474 pci_read_config_dword(dev, PCI_CLASS_REVISION, &class_rev);···497507 return class_rev;498508}499509500500-static u32 hpt_minimum_revision (struct pci_dev *dev, int revision)501501-{502502- unsigned int class_rev = hpt_revision(dev);503503- revision--;504504- return ((int) (class_rev > revision) ? 1 : 0);505505-}506506-507510static int check_in_drive_lists(ide_drive_t *drive, const char **list);508511509512static u8 hpt3xx_ratemask (ide_drive_t *drive)510513{511511- struct pci_dev *dev = HWIF(drive)->pci_dev;514514+ ide_hwif_t *hwif = drive->hwif;515515+ struct hpt_info *info = ide_get_hwifdata(hwif);512516 u8 mode = 0;513517514514- if (hpt_minimum_revision(dev, 8)) { /* HPT374 */518518+ /* FIXME: TODO - move this to set info->mode once at boot */519519+520520+ if (info->revision >= 8) { /* HPT374 */515521 mode = (HPT374_ALLOW_ATA133_6) ? 4 : 3;516516- } else if (hpt_minimum_revision(dev, 7)) { /* HPT371 */522522+ } else if (info->revision >= 7) { /* HPT371 */517523 mode = (HPT371_ALLOW_ATA133_6) ? 4 : 3;518518- } else if (hpt_minimum_revision(dev, 6)) { /* HPT302 */524524+ } else if (info->revision >= 6) { /* HPT302 */519525 mode = (HPT302_ALLOW_ATA133_6) ? 4 : 3;520520- } else if (hpt_minimum_revision(dev, 5)) { /* HPT372 */526526+ } else if (info->revision >= 5) { /* HPT372 */521527 mode = (HPT372_ALLOW_ATA133_6) ? 4 : 3;522522- } else if (hpt_minimum_revision(dev, 4)) { /* HPT370A */528528+ } else if (info->revision >= 4) { /* HPT370A */523529 mode = (HPT370_ALLOW_ATA100_5) ? 3 : 2;524524- } else if (hpt_minimum_revision(dev, 3)) { /* HPT370 */530530+ } else if (info->revision >= 3) { /* HPT370 */525531 mode = (HPT370_ALLOW_ATA100_5) ? 3 : 2;526532 mode = (check_in_drive_lists(drive, bad_ata33)) ? 0 : mode;527533 } else { /* HPT366 and HPT368 */528534 mode = (check_in_drive_lists(drive, bad_ata33)) ? 0 : 2;529535 }530530- if (!eighty_ninty_three(drive) && (mode))536536+ if (!eighty_ninty_three(drive) && mode)531537 mode = min(mode, (u8)1);532538 return mode;533539}···535549536550static u8 hpt3xx_ratefilter (ide_drive_t *drive, u8 speed)537551{538538- struct pci_dev *dev = HWIF(drive)->pci_dev;552552+ ide_hwif_t *hwif = drive->hwif;553553+ struct hpt_info *info = ide_get_hwifdata(hwif);539554 u8 mode = hpt3xx_ratemask(drive);540555541556 if (drive->media != ide_disk)···548561 break;549562 case 0x03:550563 speed = min(speed, (u8)XFER_UDMA_5);551551- if (hpt_minimum_revision(dev, 5))564564+ if (info->revision >= 5)552565 break;553566 if (check_in_drive_lists(drive, bad_ata100_5))554567 speed = min(speed, (u8)XFER_UDMA_4);···558571 /*559572 * CHECK ME, Does this need to be set to 5 ??560573 */561561- if (hpt_minimum_revision(dev, 3))574574+ if (info->revision >= 3)562575 break;563576 if ((check_in_drive_lists(drive, bad_ata66_4)) ||564577 (!(HPT366_ALLOW_ATA66_4)))···572585 /*573586 * CHECK ME, Does this need to be set to 5 ??574587 */575575- if (hpt_minimum_revision(dev, 3))588588+ if (info->revision >= 3)576589 break;577590 if (check_in_drive_lists(drive, bad_ata33))578591 speed = min(speed, (u8)XFER_MW_DMA_2);···611624612625static int hpt36x_tune_chipset(ide_drive_t *drive, u8 xferspeed)613626{614614- struct pci_dev *dev = HWIF(drive)->pci_dev;627627+ ide_hwif_t *hwif = drive->hwif;628628+ struct pci_dev *dev = hwif->pci_dev;629629+ struct hpt_info *info = ide_get_hwifdata(hwif);615630 u8 speed = hpt3xx_ratefilter(drive, xferspeed);616616-// u8 speed = ide_rate_filter(hpt3xx_ratemask(drive), xferspeed);617631 u8 regtime = (drive->select.b.unit & 0x01) ? 0x44 : 0x40;618618- u8 regfast = (HWIF(drive)->channel) ? 0x55 : 0x51;632632+ u8 regfast = (hwif->channel) ? 0x55 : 0x51;619633 u8 drive_fast = 0;620634 u32 reg1 = 0, reg2 = 0;621635···624636 * Disable the "fast interrupt" prediction.625637 */626638 pci_read_config_byte(dev, regfast, &drive_fast);627627-#if 0628628- if (drive_fast & 0x02)629629- pci_write_config_byte(dev, regfast, drive_fast & ~0x20);630630-#else631639 if (drive_fast & 0x80)632640 pci_write_config_byte(dev, regfast, drive_fast & ~0x80);633633-#endif634641635635- reg2 = pci_bus_clock_list(speed,636636- (struct chipset_bus_clock_list_entry *) pci_get_drvdata(dev));642642+ reg2 = pci_bus_clock_list(speed, info->speed);643643+637644 /*638645 * Disable on-chip PIO FIFO/buffer639646 * (to avoid problems handling I/O errors later)···648665649666static int hpt370_tune_chipset(ide_drive_t *drive, u8 xferspeed)650667{651651- struct pci_dev *dev = HWIF(drive)->pci_dev;668668+ ide_hwif_t *hwif = drive->hwif;669669+ struct pci_dev *dev = hwif->pci_dev;670670+ struct hpt_info *info = ide_get_hwifdata(hwif);652671 u8 speed = hpt3xx_ratefilter(drive, xferspeed);653653-// u8 speed = ide_rate_filter(hpt3xx_ratemask(drive), xferspeed);654654- u8 regfast = (HWIF(drive)->channel) ? 0x55 : 0x51;672672+ u8 regfast = (drive->hwif->channel) ? 0x55 : 0x51;655673 u8 drive_pci = 0x40 + (drive->dn * 4);656674 u8 new_fast = 0, drive_fast = 0;657675 u32 list_conf = 0, drive_conf = 0;···677693 if (new_fast != drive_fast)678694 pci_write_config_byte(dev, regfast, new_fast);679695680680- list_conf = pci_bus_clock_list(speed, 681681- (struct chipset_bus_clock_list_entry *)682682- pci_get_drvdata(dev));696696+ list_conf = pci_bus_clock_list(speed, info->speed);683697684698 pci_read_config_dword(dev, drive_pci, &drive_conf);685699 list_conf = (list_conf & ~conf_mask) | (drive_conf & conf_mask);686700687687- if (speed < XFER_MW_DMA_0) {701701+ if (speed < XFER_MW_DMA_0)688702 list_conf &= ~0x80000000; /* Disable on-chip PIO FIFO/buffer */689689- }690690-691703 pci_write_config_dword(dev, drive_pci, list_conf);692704693705 return ide_config_drive_speed(drive, speed);···691711692712static int hpt372_tune_chipset(ide_drive_t *drive, u8 xferspeed)693713{694694- struct pci_dev *dev = HWIF(drive)->pci_dev;714714+ ide_hwif_t *hwif = drive->hwif;715715+ struct pci_dev *dev = hwif->pci_dev;716716+ struct hpt_info *info = ide_get_hwifdata(hwif);695717 u8 speed = hpt3xx_ratefilter(drive, xferspeed);696696-// u8 speed = ide_rate_filter(hpt3xx_ratemask(drive), xferspeed);697697- u8 regfast = (HWIF(drive)->channel) ? 0x55 : 0x51;718718+ u8 regfast = (drive->hwif->channel) ? 0x55 : 0x51;698719 u8 drive_fast = 0, drive_pci = 0x40 + (drive->dn * 4);699720 u32 list_conf = 0, drive_conf = 0;700721 u32 conf_mask = (speed >= XFER_MW_DMA_0) ? 0xc0000000 : 0x30070000;···707726 pci_read_config_byte(dev, regfast, &drive_fast);708727 drive_fast &= ~0x07;709728 pci_write_config_byte(dev, regfast, drive_fast);710710-711711- list_conf = pci_bus_clock_list(speed,712712- (struct chipset_bus_clock_list_entry *)713713- pci_get_drvdata(dev));729729+730730+ list_conf = pci_bus_clock_list(speed, info->speed);714731 pci_read_config_dword(dev, drive_pci, &drive_conf);715732 list_conf = (list_conf & ~conf_mask) | (drive_conf & conf_mask);716733 if (speed < XFER_MW_DMA_0)···720741721742static int hpt3xx_tune_chipset (ide_drive_t *drive, u8 speed)722743{723723- struct pci_dev *dev = HWIF(drive)->pci_dev;744744+ ide_hwif_t *hwif = drive->hwif;745745+ struct hpt_info *info = ide_get_hwifdata(hwif);724746725725- if (hpt_minimum_revision(dev, 8))747747+ if (info->revision >= 8)726748 return hpt372_tune_chipset(drive, speed); /* not a typo */727727-#if 0728728- else if (hpt_minimum_revision(dev, 7))729729- hpt371_tune_chipset(drive, speed);730730- else if (hpt_minimum_revision(dev, 6))731731- hpt302_tune_chipset(drive, speed);732732-#endif733733- else if (hpt_minimum_revision(dev, 5))749749+ else if (info->revision >= 5)734750 return hpt372_tune_chipset(drive, speed);735735- else if (hpt_minimum_revision(dev, 3))751751+ else if (info->revision >= 3)736752 return hpt370_tune_chipset(drive, speed);737753 else /* hpt368: hpt_minimum_revision(dev, 2) */738754 return hpt36x_tune_chipset(drive, speed);···753779static int config_chipset_for_dma (ide_drive_t *drive)754780{755781 u8 speed = ide_dma_speed(drive, hpt3xx_ratemask(drive));782782+ ide_hwif_t *hwif = drive->hwif;783783+ struct hpt_info *info = ide_get_hwifdata(hwif);756784757757- if (!(speed))785785+ if (!speed)786786+ return 0;787787+788788+ /* If we don't have any timings we can't do a lot */789789+ if (info->speed == NULL)758790 return 0;759791760792 (void) hpt3xx_tune_chipset(drive, speed);···774794775795static void hpt3xx_intrproc (ide_drive_t *drive)776796{777777- ide_hwif_t *hwif = HWIF(drive);797797+ ide_hwif_t *hwif = drive->hwif;778798779799 if (drive->quirk_list)780800 return;···784804785805static void hpt3xx_maskproc (ide_drive_t *drive, int mask)786806{787787- struct pci_dev *dev = HWIF(drive)->pci_dev;807807+ ide_hwif_t *hwif = drive->hwif;808808+ struct hpt_info *info = ide_get_hwifdata(hwif);809809+ struct pci_dev *dev = hwif->pci_dev;788810789811 if (drive->quirk_list) {790790- if (hpt_minimum_revision(dev,3)) {812812+ if (info->revision >= 3) {791813 u8 reg5a = 0;792814 pci_read_config_byte(dev, 0x5a, ®5a);793815 if (((reg5a & 0x10) >> 4) != mask)794816 pci_write_config_byte(dev, 0x5a, mask ? (reg5a | 0x10) : (reg5a & ~0x10));795817 } else {796818 if (mask) {797797- disable_irq(HWIF(drive)->irq);819819+ disable_irq(hwif->irq);798820 } else {799799- enable_irq(HWIF(drive)->irq);821821+ enable_irq(hwif->irq);800822 }801823 }802824 } else {803825 if (IDE_CONTROL_REG)804804- HWIF(drive)->OUTB(mask ? (drive->ctl | 2) :826826+ hwif->OUTB(mask ? (drive->ctl | 2) :805827 (drive->ctl & ~2),806828 IDE_CONTROL_REG);807829 }···811829812830static int hpt366_config_drive_xfer_rate (ide_drive_t *drive)813831{814814- ide_hwif_t *hwif = HWIF(drive);832832+ ide_hwif_t *hwif = drive->hwif;815833 struct hd_driveid *id = drive->id;816834817835 drive->init_speed = 0;818836819819- if (id && (id->capability & 1) && drive->autodma) {837837+ if ((id->capability & 1) && drive->autodma) {820838821839 if (ide_use_dma(drive)) {822840 if (config_chipset_for_dma(drive))···850868 drive->name, __FUNCTION__, reg50h, reg52h, reg5ah);851869 if (reg5ah & 0x10)852870 pci_write_config_byte(dev, 0x5a, reg5ah & ~0x10);853853-#if 0854854- /* how about we flush and reset, mmmkay? */855855- pci_write_config_byte(dev, 0x51, 0x1F);856856- /* fall through to a reset */857857- case dma_start:858858- case ide_dma_end:859859- /* reset the chips state over and over.. */860860- pci_write_config_byte(dev, 0x51, 0x13);861861-#endif862871 return __ide_dma_lostirq(drive);863872}864873···892919 u8 dma_stat = 0, dma_cmd = 0;893920894921 pci_read_config_byte(HWIF(drive)->pci_dev, reginfo, &bfifo);895895- printk("%s: %d bytes in FIFO\n", drive->name, bfifo);922922+ printk(KERN_DEBUG "%s: %d bytes in FIFO\n", drive->name, bfifo);896923 hpt370_clear_engine(drive);897924 /* get dma command mode */898925 dma_cmd = hwif->INB(hwif->dma_command);···1020104710211048static void hpt3xx_reset (ide_drive_t *drive)10221049{10231023-#if 010241024- unsigned long high_16 = pci_resource_start(HWIF(drive)->pci_dev, 4);10251025- u8 reset = (HWIF(drive)->channel) ? 0x80 : 0x40;10261026- u8 reg59h = 0;10271027-10281028- pci_read_config_byte(HWIF(drive)->pci_dev, 0x59, ®59h);10291029- pci_write_config_byte(HWIF(drive)->pci_dev, 0x59, reg59h|reset);10301030- pci_write_config_byte(HWIF(drive)->pci_dev, 0x59, reg59h);10311031-#endif10321050}1033105110341052static int hpt3xx_tristate (ide_drive_t * drive, int state)···10281064 struct pci_dev *dev = hwif->pci_dev;10291065 u8 reg59h = 0, reset = (hwif->channel) ? 0x80 : 0x40;10301066 u8 regXXh = 0, state_reg= (hwif->channel) ? 0x57 : 0x53;10311031-10321032-// hwif->bus_state = state;1033106710341068 pci_read_config_byte(dev, 0x59, ®59h);10351069 pci_read_config_byte(dev, state_reg, ®XXh);···10551093#define TRISTATE_BIT 0x800010561094static int hpt370_busproc(ide_drive_t * drive, int state)10571095{10581058- ide_hwif_t *hwif = HWIF(drive);10961096+ ide_hwif_t *hwif = drive->hwif;10591097 struct pci_dev *dev = hwif->pci_dev;10601098 u8 tristate = 0, resetmask = 0, bus_reg = 0;10611099 u16 tri_reg;···11101148 return 0;11111149}1112115011131113-static int __devinit init_hpt37x(struct pci_dev *dev)11511151+static void __devinit hpt366_clocking(ide_hwif_t *hwif)11141152{11531153+ u32 reg1 = 0;11541154+ struct hpt_info *info = ide_get_hwifdata(hwif);11551155+11561156+ pci_read_config_dword(hwif->pci_dev, 0x40, ®1);11571157+11581158+ /* detect bus speed by looking at control reg timing: */11591159+ switch((reg1 >> 8) & 7) {11601160+ case 5:11611161+ info->speed = forty_base_hpt366;11621162+ break;11631163+ case 9:11641164+ info->speed = twenty_five_base_hpt366;11651165+ break;11661166+ case 7:11671167+ default:11681168+ info->speed = thirty_three_base_hpt366;11691169+ break;11701170+ }11711171+}11721172+11731173+static void __devinit hpt37x_clocking(ide_hwif_t *hwif)11741174+{11751175+ struct hpt_info *info = ide_get_hwifdata(hwif);11761176+ struct pci_dev *dev = hwif->pci_dev;11151177 int adjust, i;11161178 u16 freq;11171179 u32 pll;11181180 u8 reg5bh;11191119- u8 reg5ah = 0;11201120- unsigned long dmabase = pci_resource_start(dev, 4);11211121- u8 did, rid; 11221122- int is_372n = 0;1123118111241124- pci_read_config_byte(dev, 0x5a, ®5ah);11251125- /* interrupt force enable */11261126- pci_write_config_byte(dev, 0x5a, (reg5ah & ~0x10));11271127-11281128- if(dmabase)11291129- {11301130- did = inb(dmabase + 0x22);11311131- rid = inb(dmabase + 0x28);11321132-11331133- if((did == 4 && rid == 6) || (did == 5 && rid > 1))11341134- is_372n = 1;11351135- }11361136-11371182 /*11381183 * default to pci clock. make sure MA15/16 are set to output11391139- * to prevent drives having problems with 40-pin cables.11841184+ * to prevent drives having problems with 40-pin cables. Needed11851185+ * for some drives such as IBM-DTLA which will not enter ready11861186+ * state on reset when PDIAG is a input.11871187+ *11881188+ * ToDo: should we set 0x21 when using PLL mode ?11401189 */11411190 pci_write_config_byte(dev, 0x5b, 0x23);11421191···11701197 * Currently we always set up the PLL for the 372N11711198 */1172119911731173- pci_set_drvdata(dev, NULL);11741174-11751175- if(is_372n)12001200+ if(info->flags & IS_372N)11761201 {11771202 printk(KERN_INFO "hpt: HPT372N detected, using 372N timing.\n");11781203 if(freq < 0x55)···11981227 pll = F_LOW_PCI_66;1199122812001229 if (pll == F_LOW_PCI_33) {12011201- if (hpt_minimum_revision(dev,8))12021202- pci_set_drvdata(dev, (void *) thirty_three_base_hpt374);12031203- else if (hpt_minimum_revision(dev,5))12041204- pci_set_drvdata(dev, (void *) thirty_three_base_hpt372);12051205- else if (hpt_minimum_revision(dev,4))12061206- pci_set_drvdata(dev, (void *) thirty_three_base_hpt370a);12301230+ if (info->revision >= 8)12311231+ info->speed = thirty_three_base_hpt374;12321232+ else if (info->revision >= 5)12331233+ info->speed = thirty_three_base_hpt372;12341234+ else if (info->revision >= 4)12351235+ info->speed = thirty_three_base_hpt370a;12071236 else12081208- pci_set_drvdata(dev, (void *) thirty_three_base_hpt370);12091209- printk("HPT37X: using 33MHz PCI clock\n");12371237+ info->speed = thirty_three_base_hpt370;12381238+ printk(KERN_DEBUG "HPT37X: using 33MHz PCI clock\n");12101239 } else if (pll == F_LOW_PCI_40) {12111240 /* Unsupported */12121241 } else if (pll == F_LOW_PCI_50) {12131213- if (hpt_minimum_revision(dev,8))12141214- pci_set_drvdata(dev, (void *) fifty_base_hpt370a);12151215- else if (hpt_minimum_revision(dev,5))12161216- pci_set_drvdata(dev, (void *) fifty_base_hpt372);12171217- else if (hpt_minimum_revision(dev,4))12181218- pci_set_drvdata(dev, (void *) fifty_base_hpt370a);12421242+ if (info->revision >= 8)12431243+ info->speed = fifty_base_hpt370a;12441244+ else if (info->revision >= 5)12451245+ info->speed = fifty_base_hpt372;12461246+ else if (info->revision >= 4)12471247+ info->speed = fifty_base_hpt370a;12191248 else12201220- pci_set_drvdata(dev, (void *) fifty_base_hpt370a);12211221- printk("HPT37X: using 50MHz PCI clock\n");12491249+ info->speed = fifty_base_hpt370a;12501250+ printk(KERN_DEBUG "HPT37X: using 50MHz PCI clock\n");12221251 } else {12231223- if (hpt_minimum_revision(dev,8))12241224- {12521252+ if (info->revision >= 8) {12251253 printk(KERN_ERR "HPT37x: 66MHz timings are not supported.\n");12261254 }12271227- else if (hpt_minimum_revision(dev,5))12281228- pci_set_drvdata(dev, (void *) sixty_six_base_hpt372);12291229- else if (hpt_minimum_revision(dev,4))12301230- pci_set_drvdata(dev, (void *) sixty_six_base_hpt370a);12551255+ else if (info->revision >= 5)12561256+ info->speed = sixty_six_base_hpt372;12571257+ else if (info->revision >= 4)12581258+ info->speed = sixty_six_base_hpt370a;12311259 else12321232- pci_set_drvdata(dev, (void *) sixty_six_base_hpt370);12331233- printk("HPT37X: using 66MHz PCI clock\n");12601260+ info->speed = sixty_six_base_hpt370;12611261+ printk(KERN_DEBUG "HPT37X: using 66MHz PCI clock\n");12341262 }12351263 }12361264···12391269 * result in slow reads when using a 33MHz PCI clock. we also12401270 * don't like to use the PLL because it will cause glitches12411271 * on PRST/SRST when the HPT state engine gets reset.12721272+ *12731273+ * ToDo: Use 66MHz PLL when ATA133 devices are present on a12741274+ * 372 device so we can get ATA133 support12421275 */12431243- if (pci_get_drvdata(dev)) 12761276+ if (info->speed)12441277 goto init_hpt37X_done;12781278+12791279+ info->flags |= PLL_MODE;1245128012461281 /*12821282+ * FIXME: make this work correctly, esp with 372N as per12831283+ * reference driver code.12841284+ *12471285 * adjust PLL based upon PCI clock, enable it, and wait for12481286 * stabilization.12491287 */···12761298 pci_write_config_dword(dev, 0x5c, 12771299 pll & ~0x100);12781300 pci_write_config_byte(dev, 0x5b, 0x21);12791279- if (hpt_minimum_revision(dev,8))12801280- pci_set_drvdata(dev, (void *) fifty_base_hpt370a);12811281- else if (hpt_minimum_revision(dev,5))12821282- pci_set_drvdata(dev, (void *) fifty_base_hpt372);12831283- else if (hpt_minimum_revision(dev,4))12841284- pci_set_drvdata(dev, (void *) fifty_base_hpt370a);13011301+ if (info->revision >= 8)13021302+ info->speed = fifty_base_hpt370a;13031303+ else if (info->revision >= 5)13041304+ info->speed = fifty_base_hpt372;13051305+ else if (info->revision >= 4)13061306+ info->speed = fifty_base_hpt370a;12851307 else12861286- pci_set_drvdata(dev, (void *) fifty_base_hpt370a);13081308+ info->speed = fifty_base_hpt370a;12871309 printk("HPT37X: using 50MHz internal PLL\n");12881310 goto init_hpt37X_done;12891311 }···12961318 } 1297131912981320init_hpt37X_done:13211321+ if (!info->speed)13221322+ printk(KERN_ERR "HPT37X%s: unknown bus timing [%d %d].\n",13231323+ (info->flags & IS_372N)?"N":"", pll, freq);12991324 /* reset state engine */13001325 pci_write_config_byte(dev, 0x50, 0x37); 13011326 pci_write_config_byte(dev, 0x54, 0x37); 13021327 udelay(100);13281328+}13291329+13301330+static int __devinit init_hpt37x(struct pci_dev *dev)13311331+{13321332+ u8 reg5ah;13331333+13341334+ pci_read_config_byte(dev, 0x5a, ®5ah);13351335+ /* interrupt force enable */13361336+ pci_write_config_byte(dev, 0x5a, (reg5ah & ~0x10));13031337 return 0;13041338}13051339···13281338 pci_write_config_byte(dev, 0x51, drive_fast & ~0x80);13291339 pci_read_config_dword(dev, 0x40, ®1);1330134013311331- /* detect bus speed by looking at control reg timing: */13321332- switch((reg1 >> 8) & 7) {13331333- case 5:13341334- pci_set_drvdata(dev, (void *) forty_base_hpt366);13351335- break;13361336- case 9:13371337- pci_set_drvdata(dev, (void *) twenty_five_base_hpt366);13381338- break;13391339- case 7:13401340- default:13411341- pci_set_drvdata(dev, (void *) thirty_three_base_hpt366);13421342- break;13431343- }13441344-13451345- if (!pci_get_drvdata(dev))13461346- {13471347- printk(KERN_ERR "hpt366: unknown bus timing.\n");13481348- pci_set_drvdata(dev, NULL);13491349- }13501341 return 0;13511342}1352134313531344static unsigned int __devinit init_chipset_hpt366(struct pci_dev *dev, const char *name)13541345{13551346 int ret = 0;13561356- u8 test = 0;13571357-13471347+ /* FIXME: Not portable */13581348 if (dev->resource[PCI_ROM_RESOURCE].start)13591349 pci_write_config_byte(dev, PCI_ROM_ADDRESS,13601350 dev->resource[PCI_ROM_RESOURCE].start | PCI_ROM_ADDRESS_ENABLE);1361135113621362- pci_read_config_byte(dev, PCI_CACHE_LINE_SIZE, &test);13631363- if (test != (L1_CACHE_BYTES / 4))13641364- pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE,13651365- (L1_CACHE_BYTES / 4));13521352+ pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, (L1_CACHE_BYTES / 4));13531353+ pci_write_config_byte(dev, PCI_LATENCY_TIMER, 0x78);13541354+ pci_write_config_byte(dev, PCI_MIN_GNT, 0x08);13551355+ pci_write_config_byte(dev, PCI_MAX_LAT, 0x08);1366135613671367- pci_read_config_byte(dev, PCI_LATENCY_TIMER, &test);13681368- if (test != 0x78)13691369- pci_write_config_byte(dev, PCI_LATENCY_TIMER, 0x78);13701370-13711371- pci_read_config_byte(dev, PCI_MIN_GNT, &test);13721372- if (test != 0x08)13731373- pci_write_config_byte(dev, PCI_MIN_GNT, 0x08);13741374-13751375- pci_read_config_byte(dev, PCI_MAX_LAT, &test);13761376- if (test != 0x08)13771377- pci_write_config_byte(dev, PCI_MAX_LAT, 0x08);13781378-13791379- if (hpt_minimum_revision(dev, 3)) {13571357+ if (hpt_revision(dev) >= 3)13801358 ret = init_hpt37x(dev);13811381- } else {13821382- ret =init_hpt366(dev);13831383- }13591359+ else13601360+ ret = init_hpt366(dev);13611361+13841362 if (ret)13851363 return ret;13861364···13581400static void __devinit init_hwif_hpt366(ide_hwif_t *hwif)13591401{13601402 struct pci_dev *dev = hwif->pci_dev;14031403+ struct hpt_info *info = ide_get_hwifdata(hwif);13611404 u8 ata66 = 0, regmask = (hwif->channel) ? 0x01 : 0x02;13621362- u8 did, rid;13631363- unsigned long dmabase = hwif->dma_base;13641364- int is_372n = 0;1365140513661366- if(dmabase)13671367- {13681368- did = inb(dmabase + 0x22);13691369- rid = inb(dmabase + 0x28);13701370-13711371- if((did == 4 && rid == 6) || (did == 5 && rid > 1))13721372- is_372n = 1;13731373- }13741374-13751406 hwif->tuneproc = &hpt3xx_tune_drive;13761407 hwif->speedproc = &hpt3xx_tune_chipset;13771408 hwif->quirkproc = &hpt3xx_quirkproc;13781409 hwif->intrproc = &hpt3xx_intrproc;13791410 hwif->maskproc = &hpt3xx_maskproc;1380141113811381- if(is_372n)14121412+ if(info->flags & IS_372N)13821413 hwif->rw_disk = &hpt372n_rw_disk;1383141413841415 /*···13751428 * address lines to access an external eeprom. To read valid13761429 * cable detect state the pins must be enabled as inputs.13771430 */13781378- if (hpt_minimum_revision(dev, 8) && PCI_FUNC(dev->devfn) & 1) {14311431+ if (info->revision >= 8 && (PCI_FUNC(dev->devfn) & 1)) {13791432 /*13801433 * HPT374 PCI function 113811434 * - set bit 15 of reg 0x52 to enable TCBLID as input···13901443 pci_read_config_byte(dev, 0x5a, &ata66);13911444 pci_write_config_word(dev, 0x52, mcr3);13921445 pci_write_config_word(dev, 0x56, mcr6);13931393- } else if (hpt_minimum_revision(dev, 3)) {14461446+ } else if (info->revision >= 3) {13941447 /*13951448 * HPT370/372 and 374 pcifn 013961449 * - clear bit 0 of 0x5b to enable P/SCBLID as inputs···14171470 hwif->serialized = hwif->mate->serialized = 1;14181471#endif1419147214201420- if (hpt_minimum_revision(dev,3)) {14731473+ if (info->revision >= 3) {14211474 u8 reg5ah = 0;14221475 pci_write_config_byte(dev, 0x5a, reg5ah & ~0x10);14231476 /*···14271480 */14281481 hwif->resetproc = &hpt3xx_reset;14291482 hwif->busproc = &hpt370_busproc;14301430-// hwif->drives[0].autotune = hwif->drives[1].autotune = 1;14311431- } else if (hpt_minimum_revision(dev,2)) {14831483+ } else if (info->revision >= 2) {14321484 hwif->resetproc = &hpt3xx_reset;14331485 hwif->busproc = &hpt3xx_tristate;14341486 } else {···14481502 hwif->udma_four = ((ata66 & regmask) ? 0 : 1);14491503 hwif->ide_dma_check = &hpt366_config_drive_xfer_rate;1450150414511451- if (hpt_minimum_revision(dev,8)) {15051505+ if (info->revision >= 8) {14521506 hwif->ide_dma_test_irq = &hpt374_ide_dma_test_irq;14531507 hwif->ide_dma_end = &hpt374_ide_dma_end;14541454- } else if (hpt_minimum_revision(dev,5)) {15081508+ } else if (info->revision >= 5) {14551509 hwif->ide_dma_test_irq = &hpt374_ide_dma_test_irq;14561510 hwif->ide_dma_end = &hpt374_ide_dma_end;14571457- } else if (hpt_minimum_revision(dev,3)) {15111511+ } else if (info->revision >= 3) {14581512 hwif->dma_start = &hpt370_ide_dma_start;14591513 hwif->ide_dma_end = &hpt370_ide_dma_end;14601514 hwif->ide_dma_timeout = &hpt370_ide_dma_timeout;14611515 hwif->ide_dma_lostirq = &hpt370_ide_dma_lostirq;14621462- } else if (hpt_minimum_revision(dev,2))15161516+ } else if (info->revision >= 2)14631517 hwif->ide_dma_lostirq = &hpt366_ide_dma_lostirq;14641518 else14651519 hwif->ide_dma_lostirq = &hpt366_ide_dma_lostirq;···1472152614731527static void __devinit init_dma_hpt366(ide_hwif_t *hwif, unsigned long dmabase)14741528{15291529+ struct hpt_info *info = ide_get_hwifdata(hwif);14751530 u8 masterdma = 0, slavedma = 0;14761531 u8 dma_new = 0, dma_old = 0;14771532 u8 primary = hwif->channel ? 0x4b : 0x43;···14821535 if (!dmabase)14831536 return;1484153714851485- if(pci_get_drvdata(hwif->pci_dev) == NULL)14861486- {15381538+ if(info->speed == NULL) {14871539 printk(KERN_WARNING "hpt: no known IDE timings, disabling DMA.\n");14881540 return;14891541 }···15031557 local_irq_restore(flags);1504155815051559 ide_setup_dma(hwif, dmabase, 8);15601560+}15611561+15621562+/*15631563+ * We "borrow" this hook in order to set the data structures15641564+ * up early enough before dma or init_hwif calls are made.15651565+ */15661566+15671567+static void __devinit init_iops_hpt366(ide_hwif_t *hwif)15681568+{15691569+ struct hpt_info *info = kmalloc(sizeof(struct hpt_info), GFP_KERNEL);15701570+ unsigned long dmabase = pci_resource_start(hwif->pci_dev, 4);15711571+ u8 did, rid;15721572+15731573+ if(info == NULL) {15741574+ printk(KERN_WARNING "hpt366: out of memory.\n");15751575+ return;15761576+ }15771577+ memset(info, 0, sizeof(struct hpt_info));15781578+ ide_set_hwifdata(hwif, info);15791579+15801580+ if(dmabase) {15811581+ did = inb(dmabase + 0x22);15821582+ rid = inb(dmabase + 0x28);15831583+15841584+ if((did == 4 && rid == 6) || (did == 5 && rid > 1))15851585+ info->flags |= IS_372N;15861586+ }15871587+15881588+ info->revision = hpt_revision(hwif->pci_dev);15891589+15901590+ if (info->revision >= 3)15911591+ hpt37x_clocking(hwif);15921592+ else15931593+ hpt366_clocking(hwif);15061594}1507159515081596static int __devinit init_setup_hpt374(struct pci_dev *dev, ide_pci_device_t *d)···16261646 .name = "HPT366",16271647 .init_setup = init_setup_hpt366,16281648 .init_chipset = init_chipset_hpt366,16491649+ .init_iops = init_iops_hpt366,16291650 .init_hwif = init_hwif_hpt366,16301651 .init_dma = init_dma_hpt366,16311652 .channels = 2,···16371656 .name = "HPT372A",16381657 .init_setup = init_setup_hpt37x,16391658 .init_chipset = init_chipset_hpt366,16591659+ .init_iops = init_iops_hpt366,16401660 .init_hwif = init_hwif_hpt366,16411661 .init_dma = init_dma_hpt366,16421662 .channels = 2,···16471665 .name = "HPT302",16481666 .init_setup = init_setup_hpt37x,16491667 .init_chipset = init_chipset_hpt366,16681668+ .init_iops = init_iops_hpt366,16501669 .init_hwif = init_hwif_hpt366,16511670 .init_dma = init_dma_hpt366,16521671 .channels = 2,···16571674 .name = "HPT371",16581675 .init_setup = init_setup_hpt37x,16591676 .init_chipset = init_chipset_hpt366,16771677+ .init_iops = init_iops_hpt366,16601678 .init_hwif = init_hwif_hpt366,16611679 .init_dma = init_dma_hpt366,16621680 .channels = 2,···16671683 .name = "HPT374",16681684 .init_setup = init_setup_hpt374,16691685 .init_chipset = init_chipset_hpt366,16861686+ .init_iops = init_iops_hpt366,16701687 .init_hwif = init_hwif_hpt366,16711688 .init_dma = init_dma_hpt366,16721689 .channels = 2, /* 4 */···16771692 .name = "HPT372N",16781693 .init_setup = init_setup_hpt37x,16791694 .init_chipset = init_chipset_hpt366,16951695+ .init_iops = init_iops_hpt366,16801696 .init_hwif = init_hwif_hpt366,16811697 .init_dma = init_dma_hpt366,16821698 .channels = 2, /* 4 */
+812
drivers/ide/pci/it821x.c
···11+22+/*33+ * linux/drivers/ide/pci/it821x.c Version 0.09 December 200444+ *55+ * Copyright (C) 2004 Red Hat <alan@redhat.com>66+ *77+ * May be copied or modified under the terms of the GNU General Public License88+ * Based in part on the ITE vendor provided SCSI driver.99+ *1010+ * Documentation available from1111+ * http://www.ite.com.tw/pc/IT8212F_V04.pdf1212+ * Some other documents are NDA.1313+ *1414+ * The ITE8212 isn't exactly a standard IDE controller. It has two1515+ * modes. In pass through mode then it is an IDE controller. In its smart1616+ * mode its actually quite a capable hardware raid controller disguised1717+ * as an IDE controller. Smart mode only understands DMA read/write and1818+ * identify, none of the fancier commands apply. The IT8211 is identical1919+ * in other respects but lacks the raid mode.2020+ *2121+ * Errata:2222+ * o Rev 0x10 also requires master/slave hold the same DMA timings and2323+ * cannot do ATAPI MWDMA.2424+ * o The identify data for raid volumes lacks CHS info (technically ok)2525+ * but also fails to set the LBA28 and other bits. We fix these in2626+ * the IDE probe quirk code.2727+ * o If you write LBA48 sized I/O's (ie > 256 sector) in smart mode2828+ * raid then the controller firmware dies2929+ * o Smart mode without RAID doesn't clear all the necessary identify3030+ * bits to reduce the command set to the one used3131+ *3232+ * This has a few impacts on the driver3333+ * - In pass through mode we do all the work you would expect3434+ * - In smart mode the clocking set up is done by the controller generally3535+ * but we must watch the other limits and filter.3636+ * - There are a few extra vendor commands that actually talk to the3737+ * controller but only work PIO with no IRQ.3838+ *3939+ * Vendor areas of the identify block in smart mode are used for the4040+ * timing and policy set up. Each HDD in raid mode also has a serial4141+ * block on the disk. The hardware extra commands are get/set chip status,4242+ * rebuild, get rebuild status.4343+ *4444+ * In Linux the driver supports pass through mode as if the device was4545+ * just another IDE controller. If the smart mode is running then4646+ * volumes are managed by the controller firmware and each IDE "disk"4747+ * is a raid volume. Even more cute - the controller can do automated4848+ * hotplug and rebuild.4949+ *5050+ * The pass through controller itself is a little demented. It has a5151+ * flaw that it has a single set of PIO/MWDMA timings per channel so5252+ * non UDMA devices restrict each others performance. It also has a5353+ * single clock source per channel so mixed UDMA100/133 performance5454+ * isn't perfect and we have to pick a clock. Thankfully none of this5555+ * matters in smart mode. ATAPI DMA is not currently supported.5656+ *5757+ * It seems the smart mode is a win for RAID1/RAID10 but otherwise not.5858+ *5959+ * TODO6060+ * - ATAPI UDMA is ok but not MWDMA it seems6161+ * - RAID configuration ioctls6262+ * - Move to libata once it grows up6363+ */6464+6565+#include <linux/config.h>6666+#include <linux/types.h>6767+#include <linux/module.h>6868+#include <linux/pci.h>6969+#include <linux/delay.h>7070+#include <linux/hdreg.h>7171+#include <linux/ide.h>7272+#include <linux/init.h>7373+7474+#include <asm/io.h>7575+7676+struct it821x_dev7777+{7878+ unsigned int smart:1, /* Are we in smart raid mode */7979+ timing10:1; /* Rev 0x10 */8080+ u8 clock_mode; /* 0, ATA_50 or ATA_66 */8181+ u8 want[2][2]; /* Mode/Pri log for master slave */8282+ /* We need these for switching the clock when DMA goes on/off8383+ The high byte is the 66Mhz timing */8484+ u16 pio[2]; /* Cached PIO values */8585+ u16 mwdma[2]; /* Cached MWDMA values */8686+ u16 udma[2]; /* Cached UDMA values (per drive) */8787+};8888+8989+#define ATA_66 09090+#define ATA_50 19191+#define ATA_ANY 29292+9393+#define UDMA_OFF 09494+#define MWDMA_OFF 09595+9696+/*9797+ * We allow users to force the card into non raid mode without9898+ * flashing the alternative BIOS. This is also neccessary right now9999+ * for embedded platforms that cannot run a PC BIOS but are using this100100+ * device.101101+ */102102+103103+static int it8212_noraid;104104+105105+/**106106+ * it821x_program - program the PIO/MWDMA registers107107+ * @drive: drive to tune108108+ *109109+ * Program the PIO/MWDMA timing for this channel according to the110110+ * current clock.111111+ */112112+113113+static void it821x_program(ide_drive_t *drive, u16 timing)114114+{115115+ ide_hwif_t *hwif = drive->hwif;116116+ struct it821x_dev *itdev = ide_get_hwifdata(hwif);117117+ int channel = hwif->channel;118118+ u8 conf;119119+120120+ /* Program PIO/MWDMA timing bits */121121+ if(itdev->clock_mode == ATA_66)122122+ conf = timing >> 8;123123+ else124124+ conf = timing & 0xFF;125125+ pci_write_config_byte(hwif->pci_dev, 0x54 + 4 * channel, conf);126126+}127127+128128+/**129129+ * it821x_program_udma - program the UDMA registers130130+ * @drive: drive to tune131131+ *132132+ * Program the UDMA timing for this drive according to the133133+ * current clock.134134+ */135135+136136+static void it821x_program_udma(ide_drive_t *drive, u16 timing)137137+{138138+ ide_hwif_t *hwif = drive->hwif;139139+ struct it821x_dev *itdev = ide_get_hwifdata(hwif);140140+ int channel = hwif->channel;141141+ int unit = drive->select.b.unit;142142+ u8 conf;143143+144144+ /* Program UDMA timing bits */145145+ if(itdev->clock_mode == ATA_66)146146+ conf = timing >> 8;147147+ else148148+ conf = timing & 0xFF;149149+ if(itdev->timing10 == 0)150150+ pci_write_config_byte(hwif->pci_dev, 0x56 + 4 * channel + unit, conf);151151+ else {152152+ pci_write_config_byte(hwif->pci_dev, 0x56 + 4 * channel, conf);153153+ pci_write_config_byte(hwif->pci_dev, 0x56 + 4 * channel + 1, conf);154154+ }155155+}156156+157157+158158+/**159159+ * it821x_clock_strategy160160+ * @hwif: hardware interface161161+ *162162+ * Select between the 50 and 66Mhz base clocks to get the best163163+ * results for this interface.164164+ */165165+166166+static void it821x_clock_strategy(ide_drive_t *drive)167167+{168168+ ide_hwif_t *hwif = drive->hwif;169169+ struct it821x_dev *itdev = ide_get_hwifdata(hwif);170170+171171+ u8 unit = drive->select.b.unit;172172+ ide_drive_t *pair = &hwif->drives[1-unit];173173+174174+ int clock, altclock;175175+ u8 v;176176+ int sel = 0;177177+178178+ if(itdev->want[0][0] > itdev->want[1][0]) {179179+ clock = itdev->want[0][1];180180+ altclock = itdev->want[1][1];181181+ } else {182182+ clock = itdev->want[1][1];183183+ altclock = itdev->want[0][1];184184+ }185185+186186+ /* Master doesn't care does the slave ? */187187+ if(clock == ATA_ANY)188188+ clock = altclock;189189+190190+ /* Nobody cares - keep the same clock */191191+ if(clock == ATA_ANY)192192+ return;193193+ /* No change */194194+ if(clock == itdev->clock_mode)195195+ return;196196+197197+ /* Load this into the controller ? */198198+ if(clock == ATA_66)199199+ itdev->clock_mode = ATA_66;200200+ else {201201+ itdev->clock_mode = ATA_50;202202+ sel = 1;203203+ }204204+ pci_read_config_byte(hwif->pci_dev, 0x50, &v);205205+ v &= ~(1 << (1 + hwif->channel));206206+ v |= sel << (1 + hwif->channel);207207+ pci_write_config_byte(hwif->pci_dev, 0x50, v);208208+209209+ /*210210+ * Reprogram the UDMA/PIO of the pair drive for the switch211211+ * MWDMA will be dealt with by the dma switcher212212+ */213213+ if(pair && itdev->udma[1-unit] != UDMA_OFF) {214214+ it821x_program_udma(pair, itdev->udma[1-unit]);215215+ it821x_program(pair, itdev->pio[1-unit]);216216+ }217217+ /*218218+ * Reprogram the UDMA/PIO of our drive for the switch.219219+ * MWDMA will be dealt with by the dma switcher220220+ */221221+ if(itdev->udma[unit] != UDMA_OFF) {222222+ it821x_program_udma(drive, itdev->udma[unit]);223223+ it821x_program(drive, itdev->pio[unit]);224224+ }225225+}226226+227227+/**228228+ * it821x_ratemask - Compute available modes229229+ * @drive: IDE drive230230+ *231231+ * Compute the available speeds for the devices on the interface. This232232+ * is all modes to ATA133 clipped by drive cable setup.233233+ */234234+235235+static u8 it821x_ratemask (ide_drive_t *drive)236236+{237237+ u8 mode = 4;238238+ if (!eighty_ninty_three(drive))239239+ mode = min(mode, (u8)1);240240+ return mode;241241+}242242+243243+/**244244+ * it821x_tuneproc - tune a drive245245+ * @drive: drive to tune246246+ * @mode_wanted: the target operating mode247247+ *248248+ * Load the timing settings for this device mode into the249249+ * controller. By the time we are called the mode has been250250+ * modified as neccessary to handle the absence of seperate251251+ * master/slave timers for MWDMA/PIO.252252+ *253253+ * This code is only used in pass through mode.254254+ */255255+256256+static void it821x_tuneproc (ide_drive_t *drive, byte mode_wanted)257257+{258258+ ide_hwif_t *hwif = drive->hwif;259259+ struct it821x_dev *itdev = ide_get_hwifdata(hwif);260260+ int unit = drive->select.b.unit;261261+262262+ /* Spec says 89 ref driver uses 88 */263263+ static u16 pio[] = { 0xAA88, 0xA382, 0xA181, 0x3332, 0x3121 };264264+ static u8 pio_want[] = { ATA_66, ATA_66, ATA_66, ATA_66, ATA_ANY };265265+266266+ if(itdev->smart)267267+ return;268268+269269+ /* We prefer 66Mhz clock for PIO 0-3, don't care for PIO4 */270270+ itdev->want[unit][1] = pio_want[mode_wanted];271271+ itdev->want[unit][0] = 1; /* PIO is lowest priority */272272+ itdev->pio[unit] = pio[mode_wanted];273273+ it821x_clock_strategy(drive);274274+ it821x_program(drive, itdev->pio[unit]);275275+}276276+277277+/**278278+ * it821x_tune_mwdma - tune a channel for MWDMA279279+ * @drive: drive to set up280280+ * @mode_wanted: the target operating mode281281+ *282282+ * Load the timing settings for this device mode into the283283+ * controller when doing MWDMA in pass through mode. The caller284284+ * must manage the whole lack of per device MWDMA/PIO timings and285285+ * the shared MWDMA/PIO timing register.286286+ */287287+288288+static void it821x_tune_mwdma (ide_drive_t *drive, byte mode_wanted)289289+{290290+ ide_hwif_t *hwif = drive->hwif;291291+ struct it821x_dev *itdev = (void *)ide_get_hwifdata(hwif);292292+ int unit = drive->select.b.unit;293293+ int channel = hwif->channel;294294+ u8 conf;295295+296296+ static u16 dma[] = { 0x8866, 0x3222, 0x3121 };297297+ static u8 mwdma_want[] = { ATA_ANY, ATA_66, ATA_ANY };298298+299299+ itdev->want[unit][1] = mwdma_want[mode_wanted];300300+ itdev->want[unit][0] = 2; /* MWDMA is low priority */301301+ itdev->mwdma[unit] = dma[mode_wanted];302302+ itdev->udma[unit] = UDMA_OFF;303303+304304+ /* UDMA bits off - Revision 0x10 do them in pairs */305305+ pci_read_config_byte(hwif->pci_dev, 0x50, &conf);306306+ if(itdev->timing10)307307+ conf |= channel ? 0x60: 0x18;308308+ else309309+ conf |= 1 << (3 + 2 * channel + unit);310310+ pci_write_config_byte(hwif->pci_dev, 0x50, conf);311311+312312+ it821x_clock_strategy(drive);313313+ /* FIXME: do we need to program this ? */314314+ /* it821x_program(drive, itdev->mwdma[unit]); */315315+}316316+317317+/**318318+ * it821x_tune_udma - tune a channel for UDMA319319+ * @drive: drive to set up320320+ * @mode_wanted: the target operating mode321321+ *322322+ * Load the timing settings for this device mode into the323323+ * controller when doing UDMA modes in pass through.324324+ */325325+326326+static void it821x_tune_udma (ide_drive_t *drive, byte mode_wanted)327327+{328328+ ide_hwif_t *hwif = drive->hwif;329329+ struct it821x_dev *itdev = ide_get_hwifdata(hwif);330330+ int unit = drive->select.b.unit;331331+ int channel = hwif->channel;332332+ u8 conf;333333+334334+ static u16 udma[] = { 0x4433, 0x4231, 0x3121, 0x2121, 0x1111, 0x2211, 0x1111 };335335+ static u8 udma_want[] = { ATA_ANY, ATA_50, ATA_ANY, ATA_66, ATA_66, ATA_50, ATA_66 };336336+337337+ itdev->want[unit][1] = udma_want[mode_wanted];338338+ itdev->want[unit][0] = 3; /* UDMA is high priority */339339+ itdev->mwdma[unit] = MWDMA_OFF;340340+ itdev->udma[unit] = udma[mode_wanted];341341+ if(mode_wanted >= 5)342342+ itdev->udma[unit] |= 0x8080; /* UDMA 5/6 select on */343343+344344+ /* UDMA on. Again revision 0x10 must do the pair */345345+ pci_read_config_byte(hwif->pci_dev, 0x50, &conf);346346+ if(itdev->timing10)347347+ conf &= channel ? 0x9F: 0xE7;348348+ else349349+ conf &= ~ (1 << (3 + 2 * channel + unit));350350+ pci_write_config_byte(hwif->pci_dev, 0x50, conf);351351+352352+ it821x_clock_strategy(drive);353353+ it821x_program_udma(drive, itdev->udma[unit]);354354+355355+}356356+357357+/**358358+ * config_it821x_chipset_for_pio - set drive timings359359+ * @drive: drive to tune360360+ * @speed we want361361+ *362362+ * Compute the best pio mode we can for a given device. We must363363+ * pick a speed that does not cause problems with the other device364364+ * on the cable.365365+ */366366+367367+static void config_it821x_chipset_for_pio (ide_drive_t *drive, byte set_speed)368368+{369369+ u8 unit = drive->select.b.unit;370370+ ide_hwif_t *hwif = drive->hwif;371371+ ide_drive_t *pair = &hwif->drives[1-unit];372372+ u8 speed = 0, set_pio = ide_get_best_pio_mode(drive, 255, 5, NULL);373373+ u8 pair_pio;374374+375375+ /* We have to deal with this mess in pairs */376376+ if(pair != NULL) {377377+ pair_pio = ide_get_best_pio_mode(pair, 255, 5, NULL);378378+ /* Trim PIO to the slowest of the master/slave */379379+ if(pair_pio < set_pio)380380+ set_pio = pair_pio;381381+ }382382+ it821x_tuneproc(drive, set_pio);383383+ speed = XFER_PIO_0 + set_pio;384384+ /* XXX - We trim to the lowest of the pair so the other drive385385+ will always be fine at this point until we do hotplug passthru */386386+387387+ if (set_speed)388388+ (void) ide_config_drive_speed(drive, speed);389389+}390390+391391+/**392392+ * it821x_dma_read - DMA hook393393+ * @drive: drive for DMA394394+ *395395+ * The IT821x has a single timing register for MWDMA and for PIO396396+ * operations. As we flip back and forth we have to reload the397397+ * clock. In addition the rev 0x10 device only works if the same398398+ * timing value is loaded into the master and slave UDMA clock399399+ * so we must also reload that.400400+ *401401+ * FIXME: we could figure out in advance if we need to do reloads402402+ */403403+404404+static void it821x_dma_start(ide_drive_t *drive)405405+{406406+ ide_hwif_t *hwif = drive->hwif;407407+ struct it821x_dev *itdev = ide_get_hwifdata(hwif);408408+ int unit = drive->select.b.unit;409409+ if(itdev->mwdma[unit] != MWDMA_OFF)410410+ it821x_program(drive, itdev->mwdma[unit]);411411+ else if(itdev->udma[unit] != UDMA_OFF && itdev->timing10)412412+ it821x_program_udma(drive, itdev->udma[unit]);413413+ ide_dma_start(drive);414414+}415415+416416+/**417417+ * it821x_dma_write - DMA hook418418+ * @drive: drive for DMA stop419419+ *420420+ * The IT821x has a single timing register for MWDMA and for PIO421421+ * operations. As we flip back and forth we have to reload the422422+ * clock.423423+ */424424+425425+static int it821x_dma_end(ide_drive_t *drive)426426+{427427+ ide_hwif_t *hwif = drive->hwif;428428+ int unit = drive->select.b.unit;429429+ struct it821x_dev *itdev = ide_get_hwifdata(hwif);430430+ int ret = __ide_dma_end(drive);431431+ if(itdev->mwdma[unit] != MWDMA_OFF)432432+ it821x_program(drive, itdev->pio[unit]);433433+ return ret;434434+}435435+436436+437437+/**438438+ * it821x_tune_chipset - set controller timings439439+ * @drive: Drive to set up440440+ * @xferspeed: speed we want to achieve441441+ *442442+ * Tune the ITE chipset for the desired mode. If we can't achieve443443+ * the desired mode then tune for a lower one, but ultimately444444+ * make the thing work.445445+ */446446+447447+static int it821x_tune_chipset (ide_drive_t *drive, byte xferspeed)448448+{449449+450450+ ide_hwif_t *hwif = drive->hwif;451451+ struct it821x_dev *itdev = ide_get_hwifdata(hwif);452452+ u8 speed = ide_rate_filter(it821x_ratemask(drive), xferspeed);453453+454454+ if(!itdev->smart) {455455+ switch(speed) {456456+ case XFER_PIO_4:457457+ case XFER_PIO_3:458458+ case XFER_PIO_2:459459+ case XFER_PIO_1:460460+ case XFER_PIO_0:461461+ it821x_tuneproc(drive, (speed - XFER_PIO_0));462462+ break;463463+ /* MWDMA tuning is really hard because our MWDMA and PIO464464+ timings are kept in the same place. We can switch in the465465+ host dma on/off callbacks */466466+ case XFER_MW_DMA_2:467467+ case XFER_MW_DMA_1:468468+ case XFER_MW_DMA_0:469469+ it821x_tune_mwdma(drive, (speed - XFER_MW_DMA_0));470470+ break;471471+ case XFER_UDMA_6:472472+ case XFER_UDMA_5:473473+ case XFER_UDMA_4:474474+ case XFER_UDMA_3:475475+ case XFER_UDMA_2:476476+ case XFER_UDMA_1:477477+ case XFER_UDMA_0:478478+ it821x_tune_udma(drive, (speed - XFER_UDMA_0));479479+ break;480480+ default:481481+ return 1;482482+ }483483+ }484484+ /*485485+ * In smart mode the clocking is done by the host controller486486+ * snooping the mode we picked. The rest of it is not our problem487487+ */488488+ return ide_config_drive_speed(drive, speed);489489+}490490+491491+/**492492+ * config_chipset_for_dma - configure for DMA493493+ * @drive: drive to configure494494+ *495495+ * Called by the IDE layer when it wants the timings set up.496496+ */497497+498498+static int config_chipset_for_dma (ide_drive_t *drive)499499+{500500+ u8 speed = ide_dma_speed(drive, it821x_ratemask(drive));501501+502502+ config_it821x_chipset_for_pio(drive, !speed);503503+ it821x_tune_chipset(drive, speed);504504+ return ide_dma_enable(drive);505505+}506506+507507+/**508508+ * it821x_configure_drive_for_dma - set up for DMA transfers509509+ * @drive: drive we are going to set up510510+ *511511+ * Set up the drive for DMA, tune the controller and drive as512512+ * required. If the drive isn't suitable for DMA or we hit513513+ * other problems then we will drop down to PIO and set up514514+ * PIO appropriately515515+ */516516+517517+static int it821x_config_drive_for_dma (ide_drive_t *drive)518518+{519519+ ide_hwif_t *hwif = drive->hwif;520520+521521+ if (ide_use_dma(drive)) {522522+ if (config_chipset_for_dma(drive))523523+ return hwif->ide_dma_on(drive);524524+ }525525+ config_it821x_chipset_for_pio(drive, 1);526526+ return hwif->ide_dma_off_quietly(drive);527527+}528528+529529+/**530530+ * ata66_it821x - check for 80 pin cable531531+ * @hwif: interface to check532532+ *533533+ * Check for the presence of an ATA66 capable cable on the534534+ * interface. Problematic as it seems some cards don't have535535+ * the needed logic onboard.536536+ */537537+538538+static unsigned int __devinit ata66_it821x(ide_hwif_t *hwif)539539+{540540+ /* The reference driver also only does disk side */541541+ return 1;542542+}543543+544544+/**545545+ * it821x_fixup - post init callback546546+ * @hwif: interface547547+ *548548+ * This callback is run after the drives have been probed but549549+ * before anything gets attached. It allows drivers to do any550550+ * final tuning that is needed, or fixups to work around bugs.551551+ */552552+553553+static void __devinit it821x_fixups(ide_hwif_t *hwif)554554+{555555+ struct it821x_dev *itdev = ide_get_hwifdata(hwif);556556+ int i;557557+558558+ if(!itdev->smart) {559559+ /*560560+ * If we are in pass through mode then not much561561+ * needs to be done, but we do bother to clear the562562+ * IRQ mask as we may well be in PIO (eg rev 0x10)563563+ * for now and we know unmasking is safe on this chipset.564564+ */565565+ for (i = 0; i < 2; i++) {566566+ ide_drive_t *drive = &hwif->drives[i];567567+ if(drive->present)568568+ drive->unmask = 1;569569+ }570570+ return;571571+ }572572+ /*573573+ * Perform fixups on smart mode. We need to "lose" some574574+ * capabilities the firmware lacks but does not filter, and575575+ * also patch up some capability bits that it forgets to set576576+ * in RAID mode.577577+ */578578+579579+ for(i = 0; i < 2; i++) {580580+ ide_drive_t *drive = &hwif->drives[i];581581+ struct hd_driveid *id;582582+ u16 *idbits;583583+584584+ if(!drive->present)585585+ continue;586586+ id = drive->id;587587+ idbits = (u16 *)drive->id;588588+589589+ /* Check for RAID v native */590590+ if(strstr(id->model, "Integrated Technology Express")) {591591+ /* In raid mode the ident block is slightly buggy592592+ We need to set the bits so that the IDE layer knows593593+ LBA28. LBA48 and DMA ar valid */594594+ id->capability |= 3; /* LBA28, DMA */595595+ id->command_set_2 |= 0x0400; /* LBA48 valid */596596+ id->cfs_enable_2 |= 0x0400; /* LBA48 on */597597+ /* Reporting logic */598598+ printk(KERN_INFO "%s: IT8212 %sRAID %d volume",599599+ drive->name,600600+ idbits[147] ? "Bootable ":"",601601+ idbits[129]);602602+ if(idbits[129] != 1)603603+ printk("(%dK stripe)", idbits[146]);604604+ printk(".\n");605605+ /* Now the core code will have wrongly decided no DMA606606+ so we need to fix this */607607+ hwif->ide_dma_off_quietly(drive);608608+#ifdef CONFIG_IDEDMA_ONLYDISK609609+ if (drive->media == ide_disk)610610+#endif611611+ hwif->ide_dma_check(drive);612612+ } else {613613+ /* Non RAID volume. Fixups to stop the core code614614+ doing unsupported things */615615+ id->field_valid &= 1;616616+ id->queue_depth = 0;617617+ id->command_set_1 = 0;618618+ id->command_set_2 &= 0xC400;619619+ id->cfsse &= 0xC000;620620+ id->cfs_enable_1 = 0;621621+ id->cfs_enable_2 &= 0xC400;622622+ id->csf_default &= 0xC000;623623+ id->word127 = 0;624624+ id->dlf = 0;625625+ id->csfo = 0;626626+ id->cfa_power = 0;627627+ printk(KERN_INFO "%s: Performing identify fixups.\n",628628+ drive->name);629629+ }630630+ }631631+632632+}633633+634634+/**635635+ * init_hwif_it821x - set up hwif structs636636+ * @hwif: interface to set up637637+ *638638+ * We do the basic set up of the interface structure. The IT8212639639+ * requires several custom handlers so we override the default640640+ * ide DMA handlers appropriately641641+ */642642+643643+static void __devinit init_hwif_it821x(ide_hwif_t *hwif)644644+{645645+ struct it821x_dev *idev = kmalloc(sizeof(struct it821x_dev), GFP_KERNEL);646646+ u8 conf;647647+648648+ if(idev == NULL) {649649+ printk(KERN_ERR "it821x: out of memory, falling back to legacy behaviour.\n");650650+ goto fallback;651651+ }652652+ memset(idev, 0, sizeof(struct it821x_dev));653653+ ide_set_hwifdata(hwif, idev);654654+655655+ pci_read_config_byte(hwif->pci_dev, 0x50, &conf);656656+ if(conf & 1) {657657+ idev->smart = 1;658658+ hwif->atapi_dma = 0;659659+ /* Long I/O's although allowed in LBA48 space cause the660660+ onboard firmware to enter the twighlight zone */661661+ hwif->rqsize = 256;662662+ }663663+664664+ /* Pull the current clocks from 0x50 also */665665+ if (conf & (1 << (1 + hwif->channel)))666666+ idev->clock_mode = ATA_50;667667+ else668668+ idev->clock_mode = ATA_66;669669+670670+ idev->want[0][1] = ATA_ANY;671671+ idev->want[1][1] = ATA_ANY;672672+673673+ /*674674+ * Not in the docs but according to the reference driver675675+ * this is neccessary.676676+ */677677+678678+ pci_read_config_byte(hwif->pci_dev, 0x08, &conf);679679+ if(conf == 0x10) {680680+ idev->timing10 = 1;681681+ hwif->atapi_dma = 0;682682+ if(!idev->smart)683683+ printk(KERN_WARNING "it821x: Revision 0x10, workarounds activated.\n");684684+ }685685+686686+ hwif->speedproc = &it821x_tune_chipset;687687+ hwif->tuneproc = &it821x_tuneproc;688688+689689+ /* MWDMA/PIO clock switching for pass through mode */690690+ if(!idev->smart) {691691+ hwif->dma_start = &it821x_dma_start;692692+ hwif->ide_dma_end = &it821x_dma_end;693693+ }694694+695695+ hwif->drives[0].autotune = 1;696696+ hwif->drives[1].autotune = 1;697697+698698+ if (!hwif->dma_base)699699+ goto fallback;700700+701701+ hwif->ultra_mask = 0x7f;702702+ hwif->mwdma_mask = 0x07;703703+ hwif->swdma_mask = 0x07;704704+705705+ hwif->ide_dma_check = &it821x_config_drive_for_dma;706706+ if (!(hwif->udma_four))707707+ hwif->udma_four = ata66_it821x(hwif);708708+709709+ /*710710+ * The BIOS often doesn't set up DMA on this controller711711+ * so we always do it.712712+ */713713+714714+ hwif->autodma = 1;715715+ hwif->drives[0].autodma = hwif->autodma;716716+ hwif->drives[1].autodma = hwif->autodma;717717+ return;718718+fallback:719719+ hwif->autodma = 0;720720+ return;721721+}722722+723723+static void __devinit it8212_disable_raid(struct pci_dev *dev)724724+{725725+ /* Reset local CPU, and set BIOS not ready */726726+ pci_write_config_byte(dev, 0x5E, 0x01);727727+728728+ /* Set to bypass mode, and reset PCI bus */729729+ pci_write_config_byte(dev, 0x50, 0x00);730730+ pci_write_config_word(dev, PCI_COMMAND,731731+ PCI_COMMAND_PARITY | PCI_COMMAND_IO |732732+ PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER);733733+ pci_write_config_word(dev, 0x40, 0xA0F3);734734+735735+ pci_write_config_dword(dev,0x4C, 0x02040204);736736+ pci_write_config_byte(dev, 0x42, 0x36);737737+ pci_write_config_byte(dev, PCI_LATENCY_TIMER, 0);738738+}739739+740740+static unsigned int __devinit init_chipset_it821x(struct pci_dev *dev, const char *name)741741+{742742+ u8 conf;743743+ static char *mode[2] = { "pass through", "smart" };744744+745745+ /* Force the card into bypass mode if so requested */746746+ if (it8212_noraid) {747747+ printk(KERN_INFO "it8212: forcing bypass mode.\n");748748+ it8212_disable_raid(dev);749749+ }750750+ pci_read_config_byte(dev, 0x50, &conf);751751+ printk(KERN_INFO "it821x: controller in %s mode.\n", mode[conf & 1]);752752+ return 0;753753+}754754+755755+756756+#define DECLARE_ITE_DEV(name_str) \757757+ { \758758+ .name = name_str, \759759+ .init_chipset = init_chipset_it821x, \760760+ .init_hwif = init_hwif_it821x, \761761+ .channels = 2, \762762+ .autodma = AUTODMA, \763763+ .bootable = ON_BOARD, \764764+ .fixup = it821x_fixups \765765+ }766766+767767+static ide_pci_device_t it821x_chipsets[] __devinitdata = {768768+ /* 0 */ DECLARE_ITE_DEV("IT8212"),769769+};770770+771771+/**772772+ * it821x_init_one - pci layer discovery entry773773+ * @dev: PCI device774774+ * @id: ident table entry775775+ *776776+ * Called by the PCI code when it finds an ITE821x controller.777777+ * We then use the IDE PCI generic helper to do most of the work.778778+ */779779+780780+static int __devinit it821x_init_one(struct pci_dev *dev, const struct pci_device_id *id)781781+{782782+ ide_setup_pci_device(dev, &it821x_chipsets[id->driver_data]);783783+ return 0;784784+}785785+786786+static struct pci_device_id it821x_pci_tbl[] = {787787+ { PCI_VENDOR_ID_ITE, PCI_DEVICE_ID_ITE_8211, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},788788+ { PCI_VENDOR_ID_ITE, PCI_DEVICE_ID_ITE_8212, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},789789+ { 0, },790790+};791791+792792+MODULE_DEVICE_TABLE(pci, it821x_pci_tbl);793793+794794+static struct pci_driver driver = {795795+ .name = "ITE821x IDE",796796+ .id_table = it821x_pci_tbl,797797+ .probe = it821x_init_one,798798+};799799+800800+static int __init it821x_ide_init(void)801801+{802802+ return ide_pci_register_driver(&driver);803803+}804804+805805+module_init(it821x_ide_init);806806+807807+module_param_named(noraid, it8212_noraid, int, S_IRUGO);808808+MODULE_PARM_DESC(it8212_noraid, "Force card into bypass mode");809809+810810+MODULE_AUTHOR("Alan Cox");811811+MODULE_DESCRIPTION("PCI driver module for the ITE 821x");812812+MODULE_LICENSE("GPL");
+5-5
drivers/ide/pci/serverworks.c
···442442 return (dev->irq) ? dev->irq : 0;443443}444444445445-static unsigned int __init ata66_svwks_svwks (ide_hwif_t *hwif)445445+static unsigned int __devinit ata66_svwks_svwks (ide_hwif_t *hwif)446446{447447 return 1;448448}···454454 * Bit 14 clear = primary IDE channel does not have 80-pin cable.455455 * Bit 14 set = primary IDE channel has 80-pin cable.456456 */457457-static unsigned int __init ata66_svwks_dell (ide_hwif_t *hwif)457457+static unsigned int __devinit ata66_svwks_dell (ide_hwif_t *hwif)458458{459459 struct pci_dev *dev = hwif->pci_dev;460460 if (dev->subsystem_vendor == PCI_VENDOR_ID_DELL &&···472472 *473473 * WARNING: this only works on Alpine hardware!474474 */475475-static unsigned int __init ata66_svwks_cobalt (ide_hwif_t *hwif)475475+static unsigned int __devinit ata66_svwks_cobalt (ide_hwif_t *hwif)476476{477477 struct pci_dev *dev = hwif->pci_dev;478478 if (dev->subsystem_vendor == PCI_VENDOR_ID_SUN &&···483483 return 0;484484}485485486486-static unsigned int __init ata66_svwks (ide_hwif_t *hwif)486486+static unsigned int __devinit ata66_svwks (ide_hwif_t *hwif)487487{488488 struct pci_dev *dev = hwif->pci_dev;489489···573573 return ide_setup_pci_device(dev, d);574574}575575576576-static int __init init_setup_csb6 (struct pci_dev *dev, ide_pci_device_t *d)576576+static int __devinit init_setup_csb6 (struct pci_dev *dev, ide_pci_device_t *d)577577{578578 if (!(PCI_FUNC(dev->devfn) & 1)) {579579 d->bootable = NEVER_BOARD;
+12-19
drivers/input/gameport/gameport.c
···1717#include <linux/init.h>1818#include <linux/gameport.h>1919#include <linux/wait.h>2020-#include <linux/completion.h>2120#include <linux/sched.h>2222-#include <linux/smp_lock.h>2321#include <linux/slab.h>2422#include <linux/delay.h>2323+#include <linux/kthread.h>25242625/*#include <asm/io.h>*/2726···237238static DEFINE_SPINLOCK(gameport_event_lock); /* protects gameport_event_list */238239static LIST_HEAD(gameport_event_list);239240static DECLARE_WAIT_QUEUE_HEAD(gameport_wait);240240-static DECLARE_COMPLETION(gameport_exited);241241-static int gameport_pid;241241+static struct task_struct *gameport_task;242242243243static void gameport_queue_event(void *object, struct module *owner,244244 enum gameport_event_type event_type)···248250 spin_lock_irqsave(&gameport_event_lock, flags);249251250252 /*251251- * Scan event list for the other events for the same gameport port,253253+ * Scan event list for the other events for the same gameport port,252254 * starting with the most recent one. If event is the same we253255 * do not need add new one. If event is of different type we254256 * need to add this event and should not look further because255257 * we need to preseve sequence of distinct events.256256- */258258+ */257259 list_for_each_entry_reverse(event, &gameport_event_list, node) {258260 if (event->object == object) {259261 if (event->type == event_type)···430432431433static int gameport_thread(void *nothing)432434{433433- lock_kernel();434434- daemonize("kgameportd");435435- allow_signal(SIGTERM);436436-437435 do {438436 gameport_handle_events();439439- wait_event_interruptible(gameport_wait, !list_empty(&gameport_event_list));437437+ wait_event_interruptible(gameport_wait,438438+ kthread_should_stop() || !list_empty(&gameport_event_list));440439 try_to_freeze();441441- } while (!signal_pending(current));440440+ } while (!kthread_should_stop());442441443442 printk(KERN_DEBUG "gameport: kgameportd exiting\n");444444-445445- unlock_kernel();446446- complete_and_exit(&gameport_exited, 0);443443+ return 0;447444}448445449446···766773767774static int __init gameport_init(void)768775{769769- if (!(gameport_pid = kernel_thread(gameport_thread, NULL, CLONE_KERNEL))) {776776+ gameport_task = kthread_run(gameport_thread, NULL, "kgameportd");777777+ if (IS_ERR(gameport_task)) {770778 printk(KERN_ERR "gameport: Failed to start kgameportd\n");771771- return -1;779779+ return PTR_ERR(gameport_task);772780 }773781774782 gameport_bus.dev_attrs = gameport_device_attrs;···783789static void __exit gameport_exit(void)784790{785791 bus_unregister(&gameport_bus);786786- kill_proc(gameport_pid, SIGTERM, 1);787787- wait_for_completion(&gameport_exited);792792+ kthread_stop(gameport_task);788793}789794790795module_init(gameport_init);
+62-27
drivers/input/serio/serio.c
···3131#include <linux/serio.h>3232#include <linux/errno.h>3333#include <linux/wait.h>3434-#include <linux/completion.h>3534#include <linux/sched.h>3636-#include <linux/smp_lock.h>3735#include <linux/slab.h>3636+#include <linux/kthread.h>38373938MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>");4039MODULE_DESCRIPTION("Serio abstraction core");···4243EXPORT_SYMBOL(serio_interrupt);4344EXPORT_SYMBOL(__serio_register_port);4445EXPORT_SYMBOL(serio_unregister_port);4646+EXPORT_SYMBOL(serio_unregister_child_port);4547EXPORT_SYMBOL(__serio_unregister_port_delayed);4648EXPORT_SYMBOL(__serio_register_driver);4749EXPORT_SYMBOL(serio_unregister_driver);···6868static void serio_reconnect_port(struct serio *serio);6969static void serio_disconnect_port(struct serio *serio);70707171+static int serio_connect_driver(struct serio *serio, struct serio_driver *drv)7272+{7373+ int retval;7474+7575+ down(&serio->drv_sem);7676+ retval = drv->connect(serio, drv);7777+ up(&serio->drv_sem);7878+7979+ return retval;8080+}8181+8282+static int serio_reconnect_driver(struct serio *serio)8383+{8484+ int retval = -1;8585+8686+ down(&serio->drv_sem);8787+ if (serio->drv && serio->drv->reconnect)8888+ retval = serio->drv->reconnect(serio);8989+ up(&serio->drv_sem);9090+9191+ return retval;9292+}9393+9494+static void serio_disconnect_driver(struct serio *serio)9595+{9696+ down(&serio->drv_sem);9797+ if (serio->drv)9898+ serio->drv->disconnect(serio);9999+ up(&serio->drv_sem);100100+}101101+71102static int serio_match_port(const struct serio_device_id *ids, struct serio *serio)72103{73104 while (ids->type || ids->proto) {···1229112392 if (serio_match_port(drv->id_table, serio)) {12493 serio->dev.driver = &drv->driver;125125- if (drv->connect(serio, drv)) {9494+ if (serio_connect_driver(serio, drv)) {12695 serio->dev.driver = NULL;12796 goto out;12897 }···169138static DEFINE_SPINLOCK(serio_event_lock); /* protects serio_event_list */170139static LIST_HEAD(serio_event_list);171140static DECLARE_WAIT_QUEUE_HEAD(serio_wait);172172-static DECLARE_COMPLETION(serio_exited);173173-static int serio_pid;141141+static struct task_struct *serio_task;174142175143static void serio_queue_event(void *object, struct module *owner,176144 enum serio_event_type event_type)···180150 spin_lock_irqsave(&serio_event_lock, flags);181151182152 /*183183- * Scan event list for the other events for the same serio port,153153+ * Scan event list for the other events for the same serio port,184154 * starting with the most recent one. If event is the same we185155 * do not need add new one. If event is of different type we186156 * need to add this event and should not look further because187157 * we need to preseve sequence of distinct events.188188- */158158+ */189159 list_for_each_entry_reverse(event, &serio_event_list, node) {190160 if (event->object == object) {191161 if (event->type == event_type)···367337368338static int serio_thread(void *nothing)369339{370370- lock_kernel();371371- daemonize("kseriod");372372- allow_signal(SIGTERM);373373-374340 do {375341 serio_handle_events();376376- wait_event_interruptible(serio_wait, !list_empty(&serio_event_list));342342+ wait_event_interruptible(serio_wait,343343+ kthread_should_stop() || !list_empty(&serio_event_list));377344 try_to_freeze();378378- } while (!signal_pending(current));345345+ } while (!kthread_should_stop());379346380347 printk(KERN_DEBUG "serio: kseriod exiting\n");381381-382382- unlock_kernel();383383- complete_and_exit(&serio_exited, 0);348348+ return 0;384349}385350386351···582557static void serio_reconnect_port(struct serio *serio)583558{584559 do {585585- if (!serio->drv || !serio->drv->reconnect || serio->drv->reconnect(serio)) {560560+ if (serio_reconnect_driver(serio)) {586561 serio_disconnect_port(serio);587562 serio_find_driver(serio);588563 /* Ok, old children are now gone, we are done */···655630}656631657632/*633633+ * Safely unregisters child port if one is present.634634+ */635635+void serio_unregister_child_port(struct serio *serio)636636+{637637+ down(&serio_sem);638638+ if (serio->child) {639639+ serio_disconnect_port(serio->child);640640+ serio_destroy_port(serio->child);641641+ }642642+ up(&serio_sem);643643+}644644+645645+/*658646 * Submits register request to kseriod for subsequent execution.659647 * Can be used when it is not obvious whether the serio_sem is660648 * taken or not and when delayed execution is feasible.···724686 struct serio *serio = to_serio_port(dev);725687 struct serio_driver *drv = to_serio_driver(dev->driver);726688727727- return drv->connect(serio, drv);689689+ return serio_connect_driver(serio, drv);728690}729691730692static int serio_driver_remove(struct device *dev)731693{732694 struct serio *serio = to_serio_port(dev);733733- struct serio_driver *drv = to_serio_driver(dev->driver);734695735735- drv->disconnect(serio);696696+ serio_disconnect_driver(serio);736697 return 0;737698}738699···767730768731static void serio_set_drv(struct serio *serio, struct serio_driver *drv)769732{770770- down(&serio->drv_sem);771733 serio_pause_rx(serio);772734 serio->drv = drv;773735 serio_continue_rx(serio);774774- up(&serio->drv_sem);775736}776737777738static int serio_bus_match(struct device *dev, struct device_driver *drv)···829794{830795 struct serio *serio = to_serio_port(dev);831796832832- if (!serio->drv || !serio->drv->reconnect || serio->drv->reconnect(serio)) {797797+ if (serio_reconnect_driver(serio)) {833798 /*834799 * Driver re-probing can take a while, so better let kseriod835800 * deal with it.···883848884849static int __init serio_init(void)885850{886886- if (!(serio_pid = kernel_thread(serio_thread, NULL, CLONE_KERNEL))) {851851+ serio_task = kthread_run(serio_thread, NULL, "kseriod");852852+ if (IS_ERR(serio_task)) {887853 printk(KERN_ERR "serio: Failed to start kseriod\n");888888- return -1;854854+ return PTR_ERR(serio_task);889855 }890856891857 serio_bus.dev_attrs = serio_device_attrs;···902866static void __exit serio_exit(void)903867{904868 bus_unregister(&serio_bus);905905- kill_proc(serio_pid, SIGTERM, 1);906906- wait_for_completion(&serio_exited);869869+ kthread_stop(serio_task);907870}908871909872module_init(serio_init);
···607607 cards are usually around 4-16MiB in size. This does not include608608 Compact Flash cards which are treated as IDE devices.609609610610+config MTD_PCMCIA_ANONYMOUS611611+ bool "Use PCMCIA MTD drivers for anonymous PCMCIA cards"612612+ depends on MTD_PCMCIA613613+ default N614614+ help615615+ If this option is enabled, PCMCIA cards which do not report616616+ anything about themselves are assumed to be MTD cards.617617+618618+ If unsure, say N.619619+610620config MTD_UCLINUX611621 tristate "Generic uClinux RAM/ROM filesystem support"612622 depends on MTD_PARTITIONS && !MMU
···1414 Say Y here if you want to attach PCMCIA- or PC-cards to your Linux1515 computer. These are credit-card size devices such as network cards,1616 modems or hard drives often used with laptops computers. There are1717- actually two varieties of these cards: the older 16 bit PCMCIA cards1818- and the newer 32 bit CardBus cards.1717+ actually two varieties of these cards: 16 bit PCMCIA and 32 bit1818+ CardBus cards.19192020 To compile this driver as modules, choose M here: the2121 module will be called pcmcia_core.···42424343config PCMCIA4444 tristate "16-bit PCMCIA support"4545+ select CRC324546 default y4647 ---help---4748 This option enables support for 16-bit PCMCIA cards. Most older4849 PC-cards are such 16-bit PCMCIA cards, so unless you know you're4950 only using 32-bit CardBus cards, say Y or M here.50515151- To use 16-bit PCMCIA cards, you will need supporting software from 5252- David Hinds' pcmcia-cs package (see the file <file:Documentation/Changes>5353- for location). Please also read the PCMCIA-HOWTO, available from5454- <http://www.tldp.org/docs.html#howto>.5252+ To use 16-bit PCMCIA cards, you will need supporting software in5353+ most cases. (see the file <file:Documentation/Changes> for5454+ location and details).55555656 To compile this driver as modules, choose M here: the5757 module will be called pcmcia.58585959 If unsure, say Y.6060+6161+config PCMCIA_LOAD_CIS6262+ bool "Load CIS updates from userspace (EXPERIMENTAL)"6363+ depends on PCMCIA && EXPERIMENTAL6464+ select FW_LOADER6565+ default y6666+ help6767+ Some PCMCIA cards require an updated Card Information Structure (CIS)6868+ to be loaded from userspace to work correctly. If you say Y here,6969+ and your userspace is arranged correctly, this will be loaded7070+ automatically using the in-kernel firmware loader and the hotplug7171+ subsystem, instead of relying on cardmgr from pcmcia-cs to do so.7272+7373+ If unsure, say Y.7474+7575+config PCMCIA_IOCTL7676+ bool7777+ depends on PCMCIA7878+ default y7979+ help8080+ If you say Y here, the deprecated ioctl interface to the PCMCIA8181+ subsystem will be built. It is needed by cardmgr and cardctl8282+ (pcmcia-cs) to function properly.8383+8484+ If you do not use the new pcmciautils package, and have a8585+ yenta, Cirrus PD6729, i82092, i82365 or tcic compatible bridge,8686+ you need to say Y here to be able to use 16-bit PCMCIA cards.8787+8888+ If unsure, say Y.60896190config CARDBUS6291 bool "32-bit CardBus support" ···1067710778config YENTA10879 tristate "CardBus yenta-compatible bridge support"109109- depends on PCI110110-#fixme: remove dependendcy on CARDBUS11180 depends on CARDBUS11281 select PCCARD_NONSTATIC11382 ---help---
···669669 if ((stat & I365_CS_DETECT) && (stat & I365_CS_POWERON) &&670670 (i365_get(sock, I365_INTCTL) & I365_PC_IOCARD) &&671671 (i365_get(sock, I365_ADDRWIN) & I365_ENA_IO(0)) &&672672- (check_region(start, stop-start+1) != 0) &&673673- ((start & 0xfeef) != 0x02e8))674674- return 1;675675- else676676- return 0;672672+ ((start & 0xfeef) != 0x02e8)) {673673+ if (!request_region(start, stop-start+1, "i82365"))674674+ return 1;675675+ release_region(start, stop-start+1);676676+ }677677+678678+ return 0;677679}678680679681/*====================================================================*/···698696 struct i82365_socket *t = &socket[sockets-ns];699697700698 base = sockets-ns;701701- if (t->ioaddr > 0) request_region(t->ioaddr, 2, "i82365");699699+ if (t->ioaddr > 0) {700700+ if (!request_region(t->ioaddr, 2, "i82365")) {701701+ printk(KERN_ERR "i82365: IO region conflict at %#lx, not available\n",702702+ t->ioaddr);703703+ return;704704+ }705705+ }702706703707 if (base == 0) printk("\n");704708 printk(KERN_INFO " %s", pcic[type].name);···811803 }812804#endif813805814814- if (check_region(i365_base, 2) != 0) {806806+ if (!request_region(i365_base, 2, "i82365")) {815807 if (sockets == 0)816808 printk("port conflict at %#lx\n", i365_base);817809 return;···14491441 i365_set(i, I365_CSCINT, 0);14501442 release_region(socket[i].ioaddr, 2);14511443 }14441444+ release_region(i365_base, 2);14521445#ifdef CONFIG_PNP14531446 if (i82365_pnpdev)14541447 pnp_disable_dev(i82365_pnpdev);
-34
drivers/pcmcia/pcmcia_compat.c
···7474}7575EXPORT_SYMBOL(pcmcia_validate_cis);76767777-int pcmcia_get_configuration_info(client_handle_t handle,7878- config_info_t *config)7979-{8080- struct pcmcia_socket *s;8181-8282- if ((CHECK_HANDLE(handle)) || !config)8383- return CS_BAD_HANDLE;8484- s = SOCKET(handle);8585- if (!s)8686- return CS_BAD_HANDLE;8787- return pccard_get_configuration_info(s, handle->Function, config);8888-}8989-EXPORT_SYMBOL(pcmcia_get_configuration_info);90779178int pcmcia_reset_card(client_handle_t handle, client_req_t *req)9279{···88101 return pccard_reset_card(skt);89102}90103EXPORT_SYMBOL(pcmcia_reset_card);9191-9292-int pcmcia_get_status(client_handle_t handle, cs_status_t *status)9393-{9494- struct pcmcia_socket *s;9595- if (CHECK_HANDLE(handle))9696- return CS_BAD_HANDLE;9797- s = SOCKET(handle);9898- return pccard_get_status(s, handle->Function, status);9999-}100100-EXPORT_SYMBOL(pcmcia_get_status);101101-102102-int pcmcia_access_configuration_register(client_handle_t handle,103103- conf_reg_t *reg)104104-{105105- struct pcmcia_socket *s;106106- if (CHECK_HANDLE(handle))107107- return CS_BAD_HANDLE;108108- s = SOCKET(handle);109109- return pccard_access_configuration_register(s, handle->Function, reg);110110-}111111-EXPORT_SYMBOL(pcmcia_access_configuration_register);112104
+786
drivers/pcmcia/pcmcia_ioctl.c
···11+/*22+ * pcmcia_ioctl.c -- ioctl interface for cardmgr and cardctl33+ *44+ * This program is free software; you can redistribute it and/or modify55+ * it under the terms of the GNU General Public License version 2 as66+ * published by the Free Software Foundation.77+ *88+ * The initial developer of the original code is David A. Hinds99+ * <dahinds@users.sourceforge.net>. Portions created by David A. Hinds1010+ * are Copyright (C) 1999 David A. Hinds. All Rights Reserved.1111+ *1212+ * (C) 1999 David A. Hinds1313+ * (C) 2003 - 2004 Dominik Brodowski1414+ */1515+1616+/*1717+ * This file will go away soon.1818+ */1919+2020+2121+#include <linux/config.h>2222+#include <linux/kernel.h>2323+#include <linux/module.h>2424+#include <linux/init.h>2525+#include <linux/major.h>2626+#include <linux/errno.h>2727+#include <linux/ioctl.h>2828+#include <linux/proc_fs.h>2929+#include <linux/poll.h>3030+#include <linux/pci.h>3131+#include <linux/workqueue.h>3232+3333+#define IN_CARD_SERVICES3434+#include <pcmcia/version.h>3535+#include <pcmcia/cs_types.h>3636+#include <pcmcia/cs.h>3737+#include <pcmcia/cistpl.h>3838+#include <pcmcia/ds.h>3939+#include <pcmcia/ss.h>4040+4141+#include "cs_internal.h"4242+#include "ds_internal.h"4343+4444+static int major_dev = -1;4545+4646+4747+/* Device user information */4848+#define MAX_EVENTS 324949+#define USER_MAGIC 0x7ea45050+#define CHECK_USER(u) \5151+ (((u) == NULL) || ((u)->user_magic != USER_MAGIC))5252+5353+typedef struct user_info_t {5454+ u_int user_magic;5555+ int event_head, event_tail;5656+ event_t event[MAX_EVENTS];5757+ struct user_info_t *next;5858+ struct pcmcia_socket *socket;5959+} user_info_t;6060+6161+6262+#ifdef DEBUG6363+extern int ds_pc_debug;6464+#define cs_socket_name(skt) ((skt)->dev.class_id)6565+6666+#define ds_dbg(lvl, fmt, arg...) do { \6767+ if (ds_pc_debug >= lvl) \6868+ printk(KERN_DEBUG "ds: " fmt , ## arg); \6969+} while (0)7070+#else7171+#define ds_dbg(lvl, fmt, arg...) do { } while (0)7272+#endif7373+7474+static const char *release = "Linux Kernel Card Services";7575+7676+/** pcmcia_get_card_services_info7777+ *7878+ * Return information about this version of Card Services7979+ */8080+static int pcmcia_get_card_services_info(servinfo_t *info)8181+{8282+ unsigned int socket_count = 0;8383+ struct list_head *tmp;8484+ info->Signature[0] = 'C';8585+ info->Signature[1] = 'S';8686+ down_read(&pcmcia_socket_list_rwsem);8787+ list_for_each(tmp, &pcmcia_socket_list)8888+ socket_count++;8989+ up_read(&pcmcia_socket_list_rwsem);9090+ info->Count = socket_count;9191+ info->Revision = CS_RELEASE_CODE;9292+ info->CSLevel = 0x0210;9393+ info->VendorString = (char *)release;9494+ return CS_SUCCESS;9595+} /* get_card_services_info */9696+9797+9898+/* backwards-compatible accessing of driver --- by name! */9999+100100+static struct pcmcia_driver * get_pcmcia_driver (dev_info_t *dev_info)101101+{102102+ struct device_driver *drv;103103+ struct pcmcia_driver *p_drv;104104+105105+ drv = driver_find((char *) dev_info, &pcmcia_bus_type);106106+ if (!drv)107107+ return NULL;108108+109109+ p_drv = container_of(drv, struct pcmcia_driver, drv);110110+111111+ return (p_drv);112112+}113113+114114+115115+#ifdef CONFIG_PROC_FS116116+static struct proc_dir_entry *proc_pccard = NULL;117117+118118+static int proc_read_drivers_callback(struct device_driver *driver, void *d)119119+{120120+ char **p = d;121121+ struct pcmcia_driver *p_drv = container_of(driver,122122+ struct pcmcia_driver, drv);123123+124124+ *p += sprintf(*p, "%-24.24s 1 %d\n", p_drv->drv.name,125125+#ifdef CONFIG_MODULE_UNLOAD126126+ (p_drv->owner) ? module_refcount(p_drv->owner) : 1127127+#else128128+ 1129129+#endif130130+ );131131+ d = (void *) p;132132+133133+ return 0;134134+}135135+136136+static int proc_read_drivers(char *buf, char **start, off_t pos,137137+ int count, int *eof, void *data)138138+{139139+ char *p = buf;140140+141141+ bus_for_each_drv(&pcmcia_bus_type, NULL,142142+ (void *) &p, proc_read_drivers_callback);143143+144144+ return (p - buf);145145+}146146+#endif147147+148148+/*======================================================================149149+150150+ These manage a ring buffer of events pending for one user process151151+152152+======================================================================*/153153+154154+155155+static int queue_empty(user_info_t *user)156156+{157157+ return (user->event_head == user->event_tail);158158+}159159+160160+static event_t get_queued_event(user_info_t *user)161161+{162162+ user->event_tail = (user->event_tail+1) % MAX_EVENTS;163163+ return user->event[user->event_tail];164164+}165165+166166+static void queue_event(user_info_t *user, event_t event)167167+{168168+ user->event_head = (user->event_head+1) % MAX_EVENTS;169169+ if (user->event_head == user->event_tail)170170+ user->event_tail = (user->event_tail+1) % MAX_EVENTS;171171+ user->event[user->event_head] = event;172172+}173173+174174+void handle_event(struct pcmcia_socket *s, event_t event)175175+{176176+ user_info_t *user;177177+ for (user = s->user; user; user = user->next)178178+ queue_event(user, event);179179+ wake_up_interruptible(&s->queue);180180+}181181+182182+183183+/*======================================================================184184+185185+ bind_request() and bind_device() are merged by now. Register_client()186186+ is called right at the end of bind_request(), during the driver's187187+ ->attach() call. Individual descriptions:188188+189189+ bind_request() connects a socket to a particular client driver.190190+ It looks up the specified device ID in the list of registered191191+ drivers, binds it to the socket, and tries to create an instance192192+ of the device. unbind_request() deletes a driver instance.193193+194194+ Bind_device() associates a device driver with a particular socket.195195+ It is normally called by Driver Services after it has identified196196+ a newly inserted card. An instance of that driver will then be197197+ eligible to register as a client of this socket.198198+199199+ Register_client() uses the dev_info_t handle to match the200200+ caller with a socket. The driver must have already been bound201201+ to a socket with bind_device() -- in fact, bind_device()202202+ allocates the client structure that will be used.203203+204204+======================================================================*/205205+206206+static int bind_request(struct pcmcia_socket *s, bind_info_t *bind_info)207207+{208208+ struct pcmcia_driver *p_drv;209209+ struct pcmcia_device *p_dev;210210+ int ret = 0;211211+ unsigned long flags;212212+213213+ s = pcmcia_get_socket(s);214214+ if (!s)215215+ return -EINVAL;216216+217217+ ds_dbg(2, "bind_request(%d, '%s')\n", s->sock,218218+ (char *)bind_info->dev_info);219219+220220+ p_drv = get_pcmcia_driver(&bind_info->dev_info);221221+ if (!p_drv) {222222+ ret = -EINVAL;223223+ goto err_put;224224+ }225225+226226+ if (!try_module_get(p_drv->owner)) {227227+ ret = -EINVAL;228228+ goto err_put_driver;229229+ }230230+231231+ spin_lock_irqsave(&pcmcia_dev_list_lock, flags);232232+ list_for_each_entry(p_dev, &s->devices_list, socket_device_list) {233233+ if (p_dev->func == bind_info->function) {234234+ if ((p_dev->dev.driver == &p_drv->drv)) {235235+ if (p_dev->cardmgr) {236236+ /* if there's already a device237237+ * registered, and it was registered238238+ * by userspace before, we need to239239+ * return the "instance". */240240+ spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags);241241+ bind_info->instance = p_dev->instance;242242+ ret = -EBUSY;243243+ goto err_put_module;244244+ } else {245245+ /* the correct driver managed to bind246246+ * itself magically to the correct247247+ * device. */248248+ spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags);249249+ p_dev->cardmgr = p_drv;250250+ ret = 0;251251+ goto err_put_module;252252+ }253253+ } else if (!p_dev->dev.driver) {254254+ /* there's already a device available where255255+ * no device has been bound to yet. So we don't256256+ * need to register a device! */257257+ spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags);258258+ goto rescan;259259+ }260260+ }261261+ }262262+ spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags);263263+264264+ p_dev = pcmcia_device_add(s, bind_info->function);265265+ if (!p_dev) {266266+ ret = -EIO;267267+ goto err_put_module;268268+ }269269+270270+rescan:271271+ p_dev->cardmgr = p_drv;272272+273273+ /* if a driver is already running, we can abort */274274+ if (p_dev->dev.driver)275275+ goto err_put_module;276276+277277+ /*278278+ * Prevent this racing with a card insertion.279279+ */280280+ down(&s->skt_sem);281281+ bus_rescan_devices(&pcmcia_bus_type);282282+ up(&s->skt_sem);283283+284284+ /* check whether the driver indeed matched. I don't care if this285285+ * is racy or not, because it can only happen on cardmgr access286286+ * paths...287287+ */288288+ if (!(p_dev->dev.driver == &p_drv->drv))289289+ p_dev->cardmgr = NULL;290290+291291+ err_put_module:292292+ module_put(p_drv->owner);293293+ err_put_driver:294294+ put_driver(&p_drv->drv);295295+ err_put:296296+ pcmcia_put_socket(s);297297+298298+ return (ret);299299+} /* bind_request */300300+301301+#ifdef CONFIG_CARDBUS302302+303303+static struct pci_bus *pcmcia_lookup_bus(struct pcmcia_socket *s)304304+{305305+ if (!s || !(s->state & SOCKET_CARDBUS))306306+ return NULL;307307+308308+ return s->cb_dev->subordinate;309309+}310310+#endif311311+312312+static int get_device_info(struct pcmcia_socket *s, bind_info_t *bind_info, int first)313313+{314314+ dev_node_t *node;315315+ struct pcmcia_device *p_dev;316316+ unsigned long flags;317317+ int ret = 0;318318+319319+#ifdef CONFIG_CARDBUS320320+ /*321321+ * Some unbelievably ugly code to associate the PCI cardbus322322+ * device and its driver with the PCMCIA "bind" information.323323+ */324324+ {325325+ struct pci_bus *bus;326326+327327+ bus = pcmcia_lookup_bus(s);328328+ if (bus) {329329+ struct list_head *list;330330+ struct pci_dev *dev = NULL;331331+332332+ list = bus->devices.next;333333+ while (list != &bus->devices) {334334+ struct pci_dev *pdev = pci_dev_b(list);335335+ list = list->next;336336+337337+ if (first) {338338+ dev = pdev;339339+ break;340340+ }341341+342342+ /* Try to handle "next" here some way? */343343+ }344344+ if (dev && dev->driver) {345345+ strlcpy(bind_info->name, dev->driver->name, DEV_NAME_LEN);346346+ bind_info->major = 0;347347+ bind_info->minor = 0;348348+ bind_info->next = NULL;349349+ return 0;350350+ }351351+ }352352+ }353353+#endif354354+355355+ spin_lock_irqsave(&pcmcia_dev_list_lock, flags);356356+ list_for_each_entry(p_dev, &s->devices_list, socket_device_list) {357357+ if (p_dev->func == bind_info->function) {358358+ p_dev = pcmcia_get_dev(p_dev);359359+ if (!p_dev)360360+ continue;361361+ goto found;362362+ }363363+ }364364+ spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags);365365+ return -ENODEV;366366+367367+ found:368368+ spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags);369369+370370+ if ((!p_dev->instance) ||371371+ (p_dev->instance->state & DEV_CONFIG_PENDING)) {372372+ ret = -EAGAIN;373373+ goto err_put;374374+ }375375+376376+ if (first)377377+ node = p_dev->instance->dev;378378+ else379379+ for (node = p_dev->instance->dev; node; node = node->next)380380+ if (node == bind_info->next)381381+ break;382382+ if (!node) {383383+ ret = -ENODEV;384384+ goto err_put;385385+ }386386+387387+ strlcpy(bind_info->name, node->dev_name, DEV_NAME_LEN);388388+ bind_info->major = node->major;389389+ bind_info->minor = node->minor;390390+ bind_info->next = node->next;391391+392392+ err_put:393393+ pcmcia_put_dev(p_dev);394394+ return (ret);395395+} /* get_device_info */396396+397397+398398+static int ds_open(struct inode *inode, struct file *file)399399+{400400+ socket_t i = iminor(inode);401401+ struct pcmcia_socket *s;402402+ user_info_t *user;403403+404404+ ds_dbg(0, "ds_open(socket %d)\n", i);405405+406406+ s = pcmcia_get_socket_by_nr(i);407407+ if (!s)408408+ return -ENODEV;409409+ s = pcmcia_get_socket(s);410410+ if (!s)411411+ return -ENODEV;412412+413413+ if ((file->f_flags & O_ACCMODE) != O_RDONLY) {414414+ if (s->pcmcia_state.busy) {415415+ pcmcia_put_socket(s);416416+ return -EBUSY;417417+ }418418+ else419419+ s->pcmcia_state.busy = 1;420420+ }421421+422422+ user = kmalloc(sizeof(user_info_t), GFP_KERNEL);423423+ if (!user) {424424+ pcmcia_put_socket(s);425425+ return -ENOMEM;426426+ }427427+ user->event_tail = user->event_head = 0;428428+ user->next = s->user;429429+ user->user_magic = USER_MAGIC;430430+ user->socket = s;431431+ s->user = user;432432+ file->private_data = user;433433+434434+ if (s->pcmcia_state.present)435435+ queue_event(user, CS_EVENT_CARD_INSERTION);436436+ return 0;437437+} /* ds_open */438438+439439+/*====================================================================*/440440+441441+static int ds_release(struct inode *inode, struct file *file)442442+{443443+ struct pcmcia_socket *s;444444+ user_info_t *user, **link;445445+446446+ ds_dbg(0, "ds_release(socket %d)\n", iminor(inode));447447+448448+ user = file->private_data;449449+ if (CHECK_USER(user))450450+ goto out;451451+452452+ s = user->socket;453453+454454+ /* Unlink user data structure */455455+ if ((file->f_flags & O_ACCMODE) != O_RDONLY) {456456+ s->pcmcia_state.busy = 0;457457+ }458458+ file->private_data = NULL;459459+ for (link = &s->user; *link; link = &(*link)->next)460460+ if (*link == user) break;461461+ if (link == NULL)462462+ goto out;463463+ *link = user->next;464464+ user->user_magic = 0;465465+ kfree(user);466466+ pcmcia_put_socket(s);467467+out:468468+ return 0;469469+} /* ds_release */470470+471471+/*====================================================================*/472472+473473+static ssize_t ds_read(struct file *file, char __user *buf,474474+ size_t count, loff_t *ppos)475475+{476476+ struct pcmcia_socket *s;477477+ user_info_t *user;478478+ int ret;479479+480480+ ds_dbg(2, "ds_read(socket %d)\n", iminor(file->f_dentry->d_inode));481481+482482+ if (count < 4)483483+ return -EINVAL;484484+485485+ user = file->private_data;486486+ if (CHECK_USER(user))487487+ return -EIO;488488+489489+ s = user->socket;490490+ if (s->pcmcia_state.dead)491491+ return -EIO;492492+493493+ ret = wait_event_interruptible(s->queue, !queue_empty(user));494494+ if (ret == 0)495495+ ret = put_user(get_queued_event(user), (int __user *)buf) ? -EFAULT : 4;496496+497497+ return ret;498498+} /* ds_read */499499+500500+/*====================================================================*/501501+502502+static ssize_t ds_write(struct file *file, const char __user *buf,503503+ size_t count, loff_t *ppos)504504+{505505+ ds_dbg(2, "ds_write(socket %d)\n", iminor(file->f_dentry->d_inode));506506+507507+ if (count != 4)508508+ return -EINVAL;509509+ if ((file->f_flags & O_ACCMODE) == O_RDONLY)510510+ return -EBADF;511511+512512+ return -EIO;513513+} /* ds_write */514514+515515+/*====================================================================*/516516+517517+/* No kernel lock - fine */518518+static u_int ds_poll(struct file *file, poll_table *wait)519519+{520520+ struct pcmcia_socket *s;521521+ user_info_t *user;522522+523523+ ds_dbg(2, "ds_poll(socket %d)\n", iminor(file->f_dentry->d_inode));524524+525525+ user = file->private_data;526526+ if (CHECK_USER(user))527527+ return POLLERR;528528+ s = user->socket;529529+ /*530530+ * We don't check for a dead socket here since that531531+ * will send cardmgr into an endless spin.532532+ */533533+ poll_wait(file, &s->queue, wait);534534+ if (!queue_empty(user))535535+ return POLLIN | POLLRDNORM;536536+ return 0;537537+} /* ds_poll */538538+539539+/*====================================================================*/540540+541541+extern int pcmcia_adjust_resource_info(adjust_t *adj);542542+543543+static int ds_ioctl(struct inode * inode, struct file * file,544544+ u_int cmd, u_long arg)545545+{546546+ struct pcmcia_socket *s;547547+ void __user *uarg = (char __user *)arg;548548+ u_int size;549549+ int ret, err;550550+ ds_ioctl_arg_t *buf;551551+ user_info_t *user;552552+553553+ ds_dbg(2, "ds_ioctl(socket %d, %#x, %#lx)\n", iminor(inode), cmd, arg);554554+555555+ user = file->private_data;556556+ if (CHECK_USER(user))557557+ return -EIO;558558+559559+ s = user->socket;560560+ if (s->pcmcia_state.dead)561561+ return -EIO;562562+563563+ size = (cmd & IOCSIZE_MASK) >> IOCSIZE_SHIFT;564564+ if (size > sizeof(ds_ioctl_arg_t)) return -EINVAL;565565+566566+ /* Permission check */567567+ if (!(cmd & IOC_OUT) && !capable(CAP_SYS_ADMIN))568568+ return -EPERM;569569+570570+ if (cmd & IOC_IN) {571571+ if (!access_ok(VERIFY_READ, uarg, size)) {572572+ ds_dbg(3, "ds_ioctl(): verify_read = %d\n", -EFAULT);573573+ return -EFAULT;574574+ }575575+ }576576+ if (cmd & IOC_OUT) {577577+ if (!access_ok(VERIFY_WRITE, uarg, size)) {578578+ ds_dbg(3, "ds_ioctl(): verify_write = %d\n", -EFAULT);579579+ return -EFAULT;580580+ }581581+ }582582+ buf = kmalloc(sizeof(ds_ioctl_arg_t), GFP_KERNEL);583583+ if (!buf)584584+ return -ENOMEM;585585+586586+ err = ret = 0;587587+588588+ if (cmd & IOC_IN) __copy_from_user((char *)buf, uarg, size);589589+590590+ switch (cmd) {591591+ case DS_ADJUST_RESOURCE_INFO:592592+ ret = pcmcia_adjust_resource_info(&buf->adjust);593593+ break;594594+ case DS_GET_CARD_SERVICES_INFO:595595+ ret = pcmcia_get_card_services_info(&buf->servinfo);596596+ break;597597+ case DS_GET_CONFIGURATION_INFO:598598+ if (buf->config.Function &&599599+ (buf->config.Function >= s->functions))600600+ ret = CS_BAD_ARGS;601601+ else602602+ ret = pccard_get_configuration_info(s,603603+ buf->config.Function, &buf->config);604604+ break;605605+ case DS_GET_FIRST_TUPLE:606606+ down(&s->skt_sem);607607+ pcmcia_validate_mem(s);608608+ up(&s->skt_sem);609609+ ret = pccard_get_first_tuple(s, BIND_FN_ALL, &buf->tuple);610610+ break;611611+ case DS_GET_NEXT_TUPLE:612612+ ret = pccard_get_next_tuple(s, BIND_FN_ALL, &buf->tuple);613613+ break;614614+ case DS_GET_TUPLE_DATA:615615+ buf->tuple.TupleData = buf->tuple_parse.data;616616+ buf->tuple.TupleDataMax = sizeof(buf->tuple_parse.data);617617+ ret = pccard_get_tuple_data(s, &buf->tuple);618618+ break;619619+ case DS_PARSE_TUPLE:620620+ buf->tuple.TupleData = buf->tuple_parse.data;621621+ ret = pccard_parse_tuple(&buf->tuple, &buf->tuple_parse.parse);622622+ break;623623+ case DS_RESET_CARD:624624+ ret = pccard_reset_card(s);625625+ break;626626+ case DS_GET_STATUS:627627+ if (buf->status.Function &&628628+ (buf->status.Function >= s->functions))629629+ ret = CS_BAD_ARGS;630630+ else631631+ ret = pccard_get_status(s, buf->status.Function, &buf->status);632632+ break;633633+ case DS_VALIDATE_CIS:634634+ down(&s->skt_sem);635635+ pcmcia_validate_mem(s);636636+ up(&s->skt_sem);637637+ ret = pccard_validate_cis(s, BIND_FN_ALL, &buf->cisinfo);638638+ break;639639+ case DS_SUSPEND_CARD:640640+ ret = pcmcia_suspend_card(s);641641+ break;642642+ case DS_RESUME_CARD:643643+ ret = pcmcia_resume_card(s);644644+ break;645645+ case DS_EJECT_CARD:646646+ err = pcmcia_eject_card(s);647647+ break;648648+ case DS_INSERT_CARD:649649+ err = pcmcia_insert_card(s);650650+ break;651651+ case DS_ACCESS_CONFIGURATION_REGISTER:652652+ if ((buf->conf_reg.Action == CS_WRITE) && !capable(CAP_SYS_ADMIN)) {653653+ err = -EPERM;654654+ goto free_out;655655+ }656656+ if (buf->conf_reg.Function &&657657+ (buf->conf_reg.Function >= s->functions))658658+ ret = CS_BAD_ARGS;659659+ else660660+ ret = pccard_access_configuration_register(s,661661+ buf->conf_reg.Function, &buf->conf_reg);662662+ break;663663+ case DS_GET_FIRST_REGION:664664+ case DS_GET_NEXT_REGION:665665+ case DS_BIND_MTD:666666+ if (!capable(CAP_SYS_ADMIN)) {667667+ err = -EPERM;668668+ goto free_out;669669+ } else {670670+ static int printed = 0;671671+ if (!printed) {672672+ printk(KERN_WARNING "2.6. kernels use pcmciamtd instead of memory_cs.c and do not require special\n");673673+ printk(KERN_WARNING "MTD handling any more.\n");674674+ printed++;675675+ }676676+ }677677+ err = -EINVAL;678678+ goto free_out;679679+ break;680680+ case DS_GET_FIRST_WINDOW:681681+ ret = pcmcia_get_window(s, &buf->win_info.handle, 0,682682+ &buf->win_info.window);683683+ break;684684+ case DS_GET_NEXT_WINDOW:685685+ ret = pcmcia_get_window(s, &buf->win_info.handle,686686+ buf->win_info.handle->index + 1, &buf->win_info.window);687687+ break;688688+ case DS_GET_MEM_PAGE:689689+ ret = pcmcia_get_mem_page(buf->win_info.handle,690690+ &buf->win_info.map);691691+ break;692692+ case DS_REPLACE_CIS:693693+ ret = pcmcia_replace_cis(s, &buf->cisdump);694694+ break;695695+ case DS_BIND_REQUEST:696696+ if (!capable(CAP_SYS_ADMIN)) {697697+ err = -EPERM;698698+ goto free_out;699699+ }700700+ err = bind_request(s, &buf->bind_info);701701+ break;702702+ case DS_GET_DEVICE_INFO:703703+ err = get_device_info(s, &buf->bind_info, 1);704704+ break;705705+ case DS_GET_NEXT_DEVICE:706706+ err = get_device_info(s, &buf->bind_info, 0);707707+ break;708708+ case DS_UNBIND_REQUEST:709709+ err = 0;710710+ break;711711+ default:712712+ err = -EINVAL;713713+ }714714+715715+ if ((err == 0) && (ret != CS_SUCCESS)) {716716+ ds_dbg(2, "ds_ioctl: ret = %d\n", ret);717717+ switch (ret) {718718+ case CS_BAD_SOCKET: case CS_NO_CARD:719719+ err = -ENODEV; break;720720+ case CS_BAD_ARGS: case CS_BAD_ATTRIBUTE: case CS_BAD_IRQ:721721+ case CS_BAD_TUPLE:722722+ err = -EINVAL; break;723723+ case CS_IN_USE:724724+ err = -EBUSY; break;725725+ case CS_OUT_OF_RESOURCE:726726+ err = -ENOSPC; break;727727+ case CS_NO_MORE_ITEMS:728728+ err = -ENODATA; break;729729+ case CS_UNSUPPORTED_FUNCTION:730730+ err = -ENOSYS; break;731731+ default:732732+ err = -EIO; break;733733+ }734734+ }735735+736736+ if (cmd & IOC_OUT) {737737+ if (__copy_to_user(uarg, (char *)buf, size))738738+ err = -EFAULT;739739+ }740740+741741+free_out:742742+ kfree(buf);743743+ return err;744744+} /* ds_ioctl */745745+746746+/*====================================================================*/747747+748748+static struct file_operations ds_fops = {749749+ .owner = THIS_MODULE,750750+ .open = ds_open,751751+ .release = ds_release,752752+ .ioctl = ds_ioctl,753753+ .read = ds_read,754754+ .write = ds_write,755755+ .poll = ds_poll,756756+};757757+758758+void __init pcmcia_setup_ioctl(void) {759759+ int i;760760+761761+ /* Set up character device for user mode clients */762762+ i = register_chrdev(0, "pcmcia", &ds_fops);763763+ if (i < 0)764764+ printk(KERN_NOTICE "unable to find a free device # for "765765+ "Driver Services (error=%d)\n", i);766766+ else767767+ major_dev = i;768768+769769+#ifdef CONFIG_PROC_FS770770+ proc_pccard = proc_mkdir("pccard", proc_bus);771771+ if (proc_pccard)772772+ create_proc_read_entry("drivers",0,proc_pccard,proc_read_drivers,NULL);773773+#endif774774+}775775+776776+777777+void __exit pcmcia_cleanup_ioctl(void) {778778+#ifdef CONFIG_PROC_FS779779+ if (proc_pccard) {780780+ remove_proc_entry("drivers", proc_pccard);781781+ remove_proc_entry("pccard", proc_bus);782782+ }783783+#endif784784+ if (major_dev != -1)785785+ unregister_chrdev(major_dev, "pcmcia");786786+}
+998
drivers/pcmcia/pcmcia_resource.c
···11+/*22+ * PCMCIA 16-bit resource management functions33+ *44+ * The initial developer of the original code is David A. Hinds55+ * <dahinds@users.sourceforge.net>. Portions created by David A. Hinds66+ * are Copyright (C) 1999 David A. Hinds. All Rights Reserved.77+ *88+ * Copyright (C) 1999 David A. Hinds99+ * Copyright (C) 2004-2005 Dominik Brodowski1010+ *1111+ * This program is free software; you can redistribute it and/or modify1212+ * it under the terms of the GNU General Public License version 2 as1313+ * published by the Free Software Foundation.1414+ *1515+ */1616+1717+#include <linux/config.h>1818+#include <linux/module.h>1919+#include <linux/kernel.h>2020+#include <linux/interrupt.h>2121+#include <linux/delay.h>2222+#include <linux/pci.h>2323+#include <linux/device.h>2424+2525+#define IN_CARD_SERVICES2626+#include <pcmcia/version.h>2727+#include <pcmcia/cs_types.h>2828+#include <pcmcia/ss.h>2929+#include <pcmcia/cs.h>3030+#include <pcmcia/bulkmem.h>3131+#include <pcmcia/cistpl.h>3232+#include <pcmcia/cisreg.h>3333+#include <pcmcia/ds.h>3434+3535+#include "cs_internal.h"3636+#include "ds_internal.h"3737+3838+3939+/* Access speed for IO windows */4040+static int io_speed = 0;4141+module_param(io_speed, int, 0444);4242+4343+4444+#ifdef CONFIG_PCMCIA_PROBE4545+/* mask of IRQs already reserved by other cards, we should avoid using them */4646+static u8 pcmcia_used_irq[NR_IRQS];4747+#endif4848+4949+5050+#ifdef DEBUG5151+extern int ds_pc_debug;5252+#define cs_socket_name(skt) ((skt)->dev.class_id)5353+5454+#define ds_dbg(skt, lvl, fmt, arg...) do { \5555+ if (ds_pc_debug >= lvl) \5656+ printk(KERN_DEBUG "pcmcia_resource: %s: " fmt, \5757+ cs_socket_name(skt) , ## arg); \5858+} while (0)5959+#else6060+#define ds_dbg(lvl, fmt, arg...) do { } while (0)6161+#endif6262+6363+6464+6565+/** alloc_io_space6666+ *6767+ * Special stuff for managing IO windows, because they are scarce6868+ */6969+7070+static int alloc_io_space(struct pcmcia_socket *s, u_int attr, ioaddr_t *base,7171+ ioaddr_t num, u_int lines)7272+{7373+ int i;7474+ kio_addr_t try, align;7575+7676+ align = (*base) ? (lines ? 1<<lines : 0) : 1;7777+ if (align && (align < num)) {7878+ if (*base) {7979+ ds_dbg(s, 0, "odd IO request: num %#x align %#lx\n",8080+ num, align);8181+ align = 0;8282+ } else8383+ while (align && (align < num)) align <<= 1;8484+ }8585+ if (*base & ~(align-1)) {8686+ ds_dbg(s, 0, "odd IO request: base %#x align %#lx\n",8787+ *base, align);8888+ align = 0;8989+ }9090+ if ((s->features & SS_CAP_STATIC_MAP) && s->io_offset) {9191+ *base = s->io_offset | (*base & 0x0fff);9292+ s->io[0].Attributes = attr;9393+ return 0;9494+ }9595+ /* Check for an already-allocated window that must conflict with9696+ * what was asked for. It is a hack because it does not catch all9797+ * potential conflicts, just the most obvious ones.9898+ */9999+ for (i = 0; i < MAX_IO_WIN; i++)100100+ if ((s->io[i].NumPorts != 0) &&101101+ ((s->io[i].BasePort & (align-1)) == *base))102102+ return 1;103103+ for (i = 0; i < MAX_IO_WIN; i++) {104104+ if (s->io[i].NumPorts == 0) {105105+ s->io[i].res = pcmcia_find_io_region(*base, num, align, s);106106+ if (s->io[i].res) {107107+ s->io[i].Attributes = attr;108108+ s->io[i].BasePort = *base = s->io[i].res->start;109109+ s->io[i].NumPorts = s->io[i].InUse = num;110110+ break;111111+ } else112112+ return 1;113113+ } else if (s->io[i].Attributes != attr)114114+ continue;115115+ /* Try to extend top of window */116116+ try = s->io[i].BasePort + s->io[i].NumPorts;117117+ if ((*base == 0) || (*base == try))118118+ if (pcmcia_adjust_io_region(s->io[i].res, s->io[i].res->start,119119+ s->io[i].res->end + num, s) == 0) {120120+ *base = try;121121+ s->io[i].NumPorts += num;122122+ s->io[i].InUse += num;123123+ break;124124+ }125125+ /* Try to extend bottom of window */126126+ try = s->io[i].BasePort - num;127127+ if ((*base == 0) || (*base == try))128128+ if (pcmcia_adjust_io_region(s->io[i].res, s->io[i].res->start - num,129129+ s->io[i].res->end, s) == 0) {130130+ s->io[i].BasePort = *base = try;131131+ s->io[i].NumPorts += num;132132+ s->io[i].InUse += num;133133+ break;134134+ }135135+ }136136+ return (i == MAX_IO_WIN);137137+} /* alloc_io_space */138138+139139+140140+static void release_io_space(struct pcmcia_socket *s, ioaddr_t base,141141+ ioaddr_t num)142142+{143143+ int i;144144+145145+ for (i = 0; i < MAX_IO_WIN; i++) {146146+ if ((s->io[i].BasePort <= base) &&147147+ (s->io[i].BasePort+s->io[i].NumPorts >= base+num)) {148148+ s->io[i].InUse -= num;149149+ /* Free the window if no one else is using it */150150+ if (s->io[i].InUse == 0) {151151+ s->io[i].NumPorts = 0;152152+ release_resource(s->io[i].res);153153+ kfree(s->io[i].res);154154+ s->io[i].res = NULL;155155+ }156156+ }157157+ }158158+} /* release_io_space */159159+160160+161161+/** pccard_access_configuration_register162162+ *163163+ * Access_configuration_register() reads and writes configuration164164+ * registers in attribute memory. Memory window 0 is reserved for165165+ * this and the tuple reading services.166166+ */167167+168168+int pccard_access_configuration_register(struct pcmcia_socket *s,169169+ unsigned int function,170170+ conf_reg_t *reg)171171+{172172+ config_t *c;173173+ int addr;174174+ u_char val;175175+176176+ if (!s || !s->config)177177+ return CS_NO_CARD;178178+179179+ c = &s->config[function];180180+181181+ if (c == NULL)182182+ return CS_NO_CARD;183183+184184+ if (!(c->state & CONFIG_LOCKED))185185+ return CS_CONFIGURATION_LOCKED;186186+187187+ addr = (c->ConfigBase + reg->Offset) >> 1;188188+189189+ switch (reg->Action) {190190+ case CS_READ:191191+ pcmcia_read_cis_mem(s, 1, addr, 1, &val);192192+ reg->Value = val;193193+ break;194194+ case CS_WRITE:195195+ val = reg->Value;196196+ pcmcia_write_cis_mem(s, 1, addr, 1, &val);197197+ break;198198+ default:199199+ return CS_BAD_ARGS;200200+ break;201201+ }202202+ return CS_SUCCESS;203203+} /* pccard_access_configuration_register */204204+205205+int pcmcia_access_configuration_register(client_handle_t handle,206206+ conf_reg_t *reg)207207+{208208+ struct pcmcia_socket *s;209209+ if (CHECK_HANDLE(handle))210210+ return CS_BAD_HANDLE;211211+ s = SOCKET(handle);212212+ return pccard_access_configuration_register(s, handle->Function, reg);213213+}214214+EXPORT_SYMBOL(pcmcia_access_configuration_register);215215+216216+217217+218218+int pccard_get_configuration_info(struct pcmcia_socket *s,219219+ unsigned int function,220220+ config_info_t *config)221221+{222222+ config_t *c;223223+224224+ if (!(s->state & SOCKET_PRESENT))225225+ return CS_NO_CARD;226226+227227+ config->Function = function;228228+229229+#ifdef CONFIG_CARDBUS230230+ if (s->state & SOCKET_CARDBUS) {231231+ memset(config, 0, sizeof(config_info_t));232232+ config->Vcc = s->socket.Vcc;233233+ config->Vpp1 = config->Vpp2 = s->socket.Vpp;234234+ config->Option = s->cb_dev->subordinate->number;235235+ if (s->state & SOCKET_CARDBUS_CONFIG) {236236+ config->Attributes = CONF_VALID_CLIENT;237237+ config->IntType = INT_CARDBUS;238238+ config->AssignedIRQ = s->irq.AssignedIRQ;239239+ if (config->AssignedIRQ)240240+ config->Attributes |= CONF_ENABLE_IRQ;241241+ config->BasePort1 = s->io[0].BasePort;242242+ config->NumPorts1 = s->io[0].NumPorts;243243+ }244244+ return CS_SUCCESS;245245+ }246246+#endif247247+248248+ c = (s->config != NULL) ? &s->config[function] : NULL;249249+250250+ if ((c == NULL) || !(c->state & CONFIG_LOCKED)) {251251+ config->Attributes = 0;252252+ config->Vcc = s->socket.Vcc;253253+ config->Vpp1 = config->Vpp2 = s->socket.Vpp;254254+ return CS_SUCCESS;255255+ }256256+257257+ /* !!! This is a hack !!! */258258+ memcpy(&config->Attributes, &c->Attributes, sizeof(config_t));259259+ config->Attributes |= CONF_VALID_CLIENT;260260+ config->CardValues = c->CardValues;261261+ config->IRQAttributes = c->irq.Attributes;262262+ config->AssignedIRQ = s->irq.AssignedIRQ;263263+ config->BasePort1 = c->io.BasePort1;264264+ config->NumPorts1 = c->io.NumPorts1;265265+ config->Attributes1 = c->io.Attributes1;266266+ config->BasePort2 = c->io.BasePort2;267267+ config->NumPorts2 = c->io.NumPorts2;268268+ config->Attributes2 = c->io.Attributes2;269269+ config->IOAddrLines = c->io.IOAddrLines;270270+271271+ return CS_SUCCESS;272272+} /* pccard_get_configuration_info */273273+274274+int pcmcia_get_configuration_info(client_handle_t handle,275275+ config_info_t *config)276276+{277277+ struct pcmcia_socket *s;278278+279279+ if ((CHECK_HANDLE(handle)) || !config)280280+ return CS_BAD_HANDLE;281281+ s = SOCKET(handle);282282+ if (!s)283283+ return CS_BAD_HANDLE;284284+ return pccard_get_configuration_info(s, handle->Function, config);285285+}286286+EXPORT_SYMBOL(pcmcia_get_configuration_info);287287+288288+289289+/** pcmcia_get_window290290+ */291291+int pcmcia_get_window(struct pcmcia_socket *s, window_handle_t *handle,292292+ int idx, win_req_t *req)293293+{294294+ window_t *win;295295+ int w;296296+297297+ if (!s || !(s->state & SOCKET_PRESENT))298298+ return CS_NO_CARD;299299+ for (w = idx; w < MAX_WIN; w++)300300+ if (s->state & SOCKET_WIN_REQ(w))301301+ break;302302+ if (w == MAX_WIN)303303+ return CS_NO_MORE_ITEMS;304304+ win = &s->win[w];305305+ req->Base = win->ctl.res->start;306306+ req->Size = win->ctl.res->end - win->ctl.res->start + 1;307307+ req->AccessSpeed = win->ctl.speed;308308+ req->Attributes = 0;309309+ if (win->ctl.flags & MAP_ATTRIB)310310+ req->Attributes |= WIN_MEMORY_TYPE_AM;311311+ if (win->ctl.flags & MAP_ACTIVE)312312+ req->Attributes |= WIN_ENABLE;313313+ if (win->ctl.flags & MAP_16BIT)314314+ req->Attributes |= WIN_DATA_WIDTH_16;315315+ if (win->ctl.flags & MAP_USE_WAIT)316316+ req->Attributes |= WIN_USE_WAIT;317317+ *handle = win;318318+ return CS_SUCCESS;319319+} /* pcmcia_get_window */320320+EXPORT_SYMBOL(pcmcia_get_window);321321+322322+323323+/** pccard_get_status324324+ *325325+ * Get the current socket state bits. We don't support the latched326326+ * SocketState yet: I haven't seen any point for it.327327+ */328328+329329+int pccard_get_status(struct pcmcia_socket *s, unsigned int function,330330+ cs_status_t *status)331331+{332332+ config_t *c;333333+ int val;334334+335335+ s->ops->get_status(s, &val);336336+ status->CardState = status->SocketState = 0;337337+ status->CardState |= (val & SS_DETECT) ? CS_EVENT_CARD_DETECT : 0;338338+ status->CardState |= (val & SS_CARDBUS) ? CS_EVENT_CB_DETECT : 0;339339+ status->CardState |= (val & SS_3VCARD) ? CS_EVENT_3VCARD : 0;340340+ status->CardState |= (val & SS_XVCARD) ? CS_EVENT_XVCARD : 0;341341+ if (s->state & SOCKET_SUSPEND)342342+ status->CardState |= CS_EVENT_PM_SUSPEND;343343+ if (!(s->state & SOCKET_PRESENT))344344+ return CS_NO_CARD;345345+346346+ c = (s->config != NULL) ? &s->config[function] : NULL;347347+ if ((c != NULL) && (c->state & CONFIG_LOCKED) &&348348+ (c->IntType & (INT_MEMORY_AND_IO | INT_ZOOMED_VIDEO))) {349349+ u_char reg;350350+ if (c->Present & PRESENT_PIN_REPLACE) {351351+ pcmcia_read_cis_mem(s, 1, (c->ConfigBase+CISREG_PRR)>>1, 1, ®);352352+ status->CardState |=353353+ (reg & PRR_WP_STATUS) ? CS_EVENT_WRITE_PROTECT : 0;354354+ status->CardState |=355355+ (reg & PRR_READY_STATUS) ? CS_EVENT_READY_CHANGE : 0;356356+ status->CardState |=357357+ (reg & PRR_BVD2_STATUS) ? CS_EVENT_BATTERY_LOW : 0;358358+ status->CardState |=359359+ (reg & PRR_BVD1_STATUS) ? CS_EVENT_BATTERY_DEAD : 0;360360+ } else {361361+ /* No PRR? Then assume we're always ready */362362+ status->CardState |= CS_EVENT_READY_CHANGE;363363+ }364364+ if (c->Present & PRESENT_EXT_STATUS) {365365+ pcmcia_read_cis_mem(s, 1, (c->ConfigBase+CISREG_ESR)>>1, 1, ®);366366+ status->CardState |=367367+ (reg & ESR_REQ_ATTN) ? CS_EVENT_REQUEST_ATTENTION : 0;368368+ }369369+ return CS_SUCCESS;370370+ }371371+ status->CardState |=372372+ (val & SS_WRPROT) ? CS_EVENT_WRITE_PROTECT : 0;373373+ status->CardState |=374374+ (val & SS_BATDEAD) ? CS_EVENT_BATTERY_DEAD : 0;375375+ status->CardState |=376376+ (val & SS_BATWARN) ? CS_EVENT_BATTERY_LOW : 0;377377+ status->CardState |=378378+ (val & SS_READY) ? CS_EVENT_READY_CHANGE : 0;379379+ return CS_SUCCESS;380380+} /* pccard_get_status */381381+382382+int pcmcia_get_status(client_handle_t handle, cs_status_t *status)383383+{384384+ struct pcmcia_socket *s;385385+ if (CHECK_HANDLE(handle))386386+ return CS_BAD_HANDLE;387387+ s = SOCKET(handle);388388+ return pccard_get_status(s, handle->Function, status);389389+}390390+EXPORT_SYMBOL(pcmcia_get_status);391391+392392+393393+394394+/** pcmcia_get_mem_page395395+ *396396+ * Change the card address of an already open memory window.397397+ */398398+int pcmcia_get_mem_page(window_handle_t win, memreq_t *req)399399+{400400+ if ((win == NULL) || (win->magic != WINDOW_MAGIC))401401+ return CS_BAD_HANDLE;402402+ req->Page = 0;403403+ req->CardOffset = win->ctl.card_start;404404+ return CS_SUCCESS;405405+} /* pcmcia_get_mem_page */406406+EXPORT_SYMBOL(pcmcia_get_mem_page);407407+408408+409409+int pcmcia_map_mem_page(window_handle_t win, memreq_t *req)410410+{411411+ struct pcmcia_socket *s;412412+ if ((win == NULL) || (win->magic != WINDOW_MAGIC))413413+ return CS_BAD_HANDLE;414414+ if (req->Page != 0)415415+ return CS_BAD_PAGE;416416+ s = win->sock;417417+ win->ctl.card_start = req->CardOffset;418418+ if (s->ops->set_mem_map(s, &win->ctl) != 0)419419+ return CS_BAD_OFFSET;420420+ return CS_SUCCESS;421421+} /* pcmcia_map_mem_page */422422+EXPORT_SYMBOL(pcmcia_map_mem_page);423423+424424+425425+/** pcmcia_modify_configuration426426+ *427427+ * Modify a locked socket configuration428428+ */429429+int pcmcia_modify_configuration(client_handle_t handle,430430+ modconf_t *mod)431431+{432432+ struct pcmcia_socket *s;433433+ config_t *c;434434+435435+ if (CHECK_HANDLE(handle))436436+ return CS_BAD_HANDLE;437437+ s = SOCKET(handle);438438+ c = CONFIG(handle);439439+ if (!(s->state & SOCKET_PRESENT))440440+ return CS_NO_CARD;441441+ if (!(c->state & CONFIG_LOCKED))442442+ return CS_CONFIGURATION_LOCKED;443443+444444+ if (mod->Attributes & CONF_IRQ_CHANGE_VALID) {445445+ if (mod->Attributes & CONF_ENABLE_IRQ) {446446+ c->Attributes |= CONF_ENABLE_IRQ;447447+ s->socket.io_irq = s->irq.AssignedIRQ;448448+ } else {449449+ c->Attributes &= ~CONF_ENABLE_IRQ;450450+ s->socket.io_irq = 0;451451+ }452452+ s->ops->set_socket(s, &s->socket);453453+ }454454+455455+ if (mod->Attributes & CONF_VCC_CHANGE_VALID)456456+ return CS_BAD_VCC;457457+458458+ /* We only allow changing Vpp1 and Vpp2 to the same value */459459+ if ((mod->Attributes & CONF_VPP1_CHANGE_VALID) &&460460+ (mod->Attributes & CONF_VPP2_CHANGE_VALID)) {461461+ if (mod->Vpp1 != mod->Vpp2)462462+ return CS_BAD_VPP;463463+ c->Vpp1 = c->Vpp2 = s->socket.Vpp = mod->Vpp1;464464+ if (s->ops->set_socket(s, &s->socket))465465+ return CS_BAD_VPP;466466+ } else if ((mod->Attributes & CONF_VPP1_CHANGE_VALID) ||467467+ (mod->Attributes & CONF_VPP2_CHANGE_VALID))468468+ return CS_BAD_VPP;469469+470470+ return CS_SUCCESS;471471+} /* modify_configuration */472472+EXPORT_SYMBOL(pcmcia_modify_configuration);473473+474474+475475+int pcmcia_release_configuration(client_handle_t handle)476476+{477477+ pccard_io_map io = { 0, 0, 0, 0, 1 };478478+ struct pcmcia_socket *s;479479+ int i;480480+481481+ if (CHECK_HANDLE(handle) ||482482+ !(handle->state & CLIENT_CONFIG_LOCKED))483483+ return CS_BAD_HANDLE;484484+ handle->state &= ~CLIENT_CONFIG_LOCKED;485485+ s = SOCKET(handle);486486+487487+#ifdef CONFIG_CARDBUS488488+ if (handle->state & CLIENT_CARDBUS)489489+ return CS_SUCCESS;490490+#endif491491+492492+ if (!(handle->state & CLIENT_STALE)) {493493+ config_t *c = CONFIG(handle);494494+ if (--(s->lock_count) == 0) {495495+ s->socket.flags = SS_OUTPUT_ENA; /* Is this correct? */496496+ s->socket.Vpp = 0;497497+ s->socket.io_irq = 0;498498+ s->ops->set_socket(s, &s->socket);499499+ }500500+ if (c->state & CONFIG_IO_REQ)501501+ for (i = 0; i < MAX_IO_WIN; i++) {502502+ if (s->io[i].NumPorts == 0)503503+ continue;504504+ s->io[i].Config--;505505+ if (s->io[i].Config != 0)506506+ continue;507507+ io.map = i;508508+ s->ops->set_io_map(s, &io);509509+ }510510+ c->state &= ~CONFIG_LOCKED;511511+ }512512+513513+ return CS_SUCCESS;514514+} /* pcmcia_release_configuration */515515+EXPORT_SYMBOL(pcmcia_release_configuration);516516+517517+518518+/** pcmcia_release_io519519+ *520520+ * Release_io() releases the I/O ranges allocated by a client. This521521+ * may be invoked some time after a card ejection has already dumped522522+ * the actual socket configuration, so if the client is "stale", we523523+ * don't bother checking the port ranges against the current socket524524+ * values.525525+ */526526+int pcmcia_release_io(client_handle_t handle, io_req_t *req)527527+{528528+ struct pcmcia_socket *s;529529+530530+ if (CHECK_HANDLE(handle) || !(handle->state & CLIENT_IO_REQ))531531+ return CS_BAD_HANDLE;532532+ handle->state &= ~CLIENT_IO_REQ;533533+ s = SOCKET(handle);534534+535535+#ifdef CONFIG_CARDBUS536536+ if (handle->state & CLIENT_CARDBUS)537537+ return CS_SUCCESS;538538+#endif539539+540540+ if (!(handle->state & CLIENT_STALE)) {541541+ config_t *c = CONFIG(handle);542542+ if (c->state & CONFIG_LOCKED)543543+ return CS_CONFIGURATION_LOCKED;544544+ if ((c->io.BasePort1 != req->BasePort1) ||545545+ (c->io.NumPorts1 != req->NumPorts1) ||546546+ (c->io.BasePort2 != req->BasePort2) ||547547+ (c->io.NumPorts2 != req->NumPorts2))548548+ return CS_BAD_ARGS;549549+ c->state &= ~CONFIG_IO_REQ;550550+ }551551+552552+ release_io_space(s, req->BasePort1, req->NumPorts1);553553+ if (req->NumPorts2)554554+ release_io_space(s, req->BasePort2, req->NumPorts2);555555+556556+ return CS_SUCCESS;557557+} /* pcmcia_release_io */558558+EXPORT_SYMBOL(pcmcia_release_io);559559+560560+561561+int pcmcia_release_irq(client_handle_t handle, irq_req_t *req)562562+{563563+ struct pcmcia_socket *s;564564+ if (CHECK_HANDLE(handle) || !(handle->state & CLIENT_IRQ_REQ))565565+ return CS_BAD_HANDLE;566566+ handle->state &= ~CLIENT_IRQ_REQ;567567+ s = SOCKET(handle);568568+569569+ if (!(handle->state & CLIENT_STALE)) {570570+ config_t *c = CONFIG(handle);571571+ if (c->state & CONFIG_LOCKED)572572+ return CS_CONFIGURATION_LOCKED;573573+ if (c->irq.Attributes != req->Attributes)574574+ return CS_BAD_ATTRIBUTE;575575+ if (s->irq.AssignedIRQ != req->AssignedIRQ)576576+ return CS_BAD_IRQ;577577+ if (--s->irq.Config == 0) {578578+ c->state &= ~CONFIG_IRQ_REQ;579579+ s->irq.AssignedIRQ = 0;580580+ }581581+ }582582+583583+ if (req->Attributes & IRQ_HANDLE_PRESENT) {584584+ free_irq(req->AssignedIRQ, req->Instance);585585+ }586586+587587+#ifdef CONFIG_PCMCIA_PROBE588588+ pcmcia_used_irq[req->AssignedIRQ]--;589589+#endif590590+591591+ return CS_SUCCESS;592592+} /* pcmcia_release_irq */593593+EXPORT_SYMBOL(pcmcia_release_irq);594594+595595+596596+int pcmcia_release_window(window_handle_t win)597597+{598598+ struct pcmcia_socket *s;599599+600600+ if ((win == NULL) || (win->magic != WINDOW_MAGIC))601601+ return CS_BAD_HANDLE;602602+ s = win->sock;603603+ if (!(win->handle->state & CLIENT_WIN_REQ(win->index)))604604+ return CS_BAD_HANDLE;605605+606606+ /* Shut down memory window */607607+ win->ctl.flags &= ~MAP_ACTIVE;608608+ s->ops->set_mem_map(s, &win->ctl);609609+ s->state &= ~SOCKET_WIN_REQ(win->index);610610+611611+ /* Release system memory */612612+ if (win->ctl.res) {613613+ release_resource(win->ctl.res);614614+ kfree(win->ctl.res);615615+ win->ctl.res = NULL;616616+ }617617+ win->handle->state &= ~CLIENT_WIN_REQ(win->index);618618+619619+ win->magic = 0;620620+621621+ return CS_SUCCESS;622622+} /* pcmcia_release_window */623623+EXPORT_SYMBOL(pcmcia_release_window);624624+625625+626626+int pcmcia_request_configuration(client_handle_t handle,627627+ config_req_t *req)628628+{629629+ int i;630630+ u_int base;631631+ struct pcmcia_socket *s;632632+ config_t *c;633633+ pccard_io_map iomap;634634+635635+ if (CHECK_HANDLE(handle))636636+ return CS_BAD_HANDLE;637637+ s = SOCKET(handle);638638+ if (!(s->state & SOCKET_PRESENT))639639+ return CS_NO_CARD;640640+641641+#ifdef CONFIG_CARDBUS642642+ if (handle->state & CLIENT_CARDBUS)643643+ return CS_UNSUPPORTED_MODE;644644+#endif645645+646646+ if (req->IntType & INT_CARDBUS)647647+ return CS_UNSUPPORTED_MODE;648648+ c = CONFIG(handle);649649+ if (c->state & CONFIG_LOCKED)650650+ return CS_CONFIGURATION_LOCKED;651651+652652+ /* Do power control. We don't allow changes in Vcc. */653653+ if (s->socket.Vcc != req->Vcc)654654+ return CS_BAD_VCC;655655+ if (req->Vpp1 != req->Vpp2)656656+ return CS_BAD_VPP;657657+ s->socket.Vpp = req->Vpp1;658658+ if (s->ops->set_socket(s, &s->socket))659659+ return CS_BAD_VPP;660660+661661+ c->Vcc = req->Vcc; c->Vpp1 = c->Vpp2 = req->Vpp1;662662+663663+ /* Pick memory or I/O card, DMA mode, interrupt */664664+ c->IntType = req->IntType;665665+ c->Attributes = req->Attributes;666666+ if (req->IntType & INT_MEMORY_AND_IO)667667+ s->socket.flags |= SS_IOCARD;668668+ if (req->IntType & INT_ZOOMED_VIDEO)669669+ s->socket.flags |= SS_ZVCARD | SS_IOCARD;670670+ if (req->Attributes & CONF_ENABLE_DMA)671671+ s->socket.flags |= SS_DMA_MODE;672672+ if (req->Attributes & CONF_ENABLE_SPKR)673673+ s->socket.flags |= SS_SPKR_ENA;674674+ if (req->Attributes & CONF_ENABLE_IRQ)675675+ s->socket.io_irq = s->irq.AssignedIRQ;676676+ else677677+ s->socket.io_irq = 0;678678+ s->ops->set_socket(s, &s->socket);679679+ s->lock_count++;680680+681681+ /* Set up CIS configuration registers */682682+ base = c->ConfigBase = req->ConfigBase;683683+ c->Present = c->CardValues = req->Present;684684+ if (req->Present & PRESENT_COPY) {685685+ c->Copy = req->Copy;686686+ pcmcia_write_cis_mem(s, 1, (base + CISREG_SCR)>>1, 1, &c->Copy);687687+ }688688+ if (req->Present & PRESENT_OPTION) {689689+ if (s->functions == 1) {690690+ c->Option = req->ConfigIndex & COR_CONFIG_MASK;691691+ } else {692692+ c->Option = req->ConfigIndex & COR_MFC_CONFIG_MASK;693693+ c->Option |= COR_FUNC_ENA|COR_IREQ_ENA;694694+ if (req->Present & PRESENT_IOBASE_0)695695+ c->Option |= COR_ADDR_DECODE;696696+ }697697+ if (c->state & CONFIG_IRQ_REQ)698698+ if (!(c->irq.Attributes & IRQ_FORCED_PULSE))699699+ c->Option |= COR_LEVEL_REQ;700700+ pcmcia_write_cis_mem(s, 1, (base + CISREG_COR)>>1, 1, &c->Option);701701+ mdelay(40);702702+ }703703+ if (req->Present & PRESENT_STATUS) {704704+ c->Status = req->Status;705705+ pcmcia_write_cis_mem(s, 1, (base + CISREG_CCSR)>>1, 1, &c->Status);706706+ }707707+ if (req->Present & PRESENT_PIN_REPLACE) {708708+ c->Pin = req->Pin;709709+ pcmcia_write_cis_mem(s, 1, (base + CISREG_PRR)>>1, 1, &c->Pin);710710+ }711711+ if (req->Present & PRESENT_EXT_STATUS) {712712+ c->ExtStatus = req->ExtStatus;713713+ pcmcia_write_cis_mem(s, 1, (base + CISREG_ESR)>>1, 1, &c->ExtStatus);714714+ }715715+ if (req->Present & PRESENT_IOBASE_0) {716716+ u_char b = c->io.BasePort1 & 0xff;717717+ pcmcia_write_cis_mem(s, 1, (base + CISREG_IOBASE_0)>>1, 1, &b);718718+ b = (c->io.BasePort1 >> 8) & 0xff;719719+ pcmcia_write_cis_mem(s, 1, (base + CISREG_IOBASE_1)>>1, 1, &b);720720+ }721721+ if (req->Present & PRESENT_IOSIZE) {722722+ u_char b = c->io.NumPorts1 + c->io.NumPorts2 - 1;723723+ pcmcia_write_cis_mem(s, 1, (base + CISREG_IOSIZE)>>1, 1, &b);724724+ }725725+726726+ /* Configure I/O windows */727727+ if (c->state & CONFIG_IO_REQ) {728728+ iomap.speed = io_speed;729729+ for (i = 0; i < MAX_IO_WIN; i++)730730+ if (s->io[i].NumPorts != 0) {731731+ iomap.map = i;732732+ iomap.flags = MAP_ACTIVE;733733+ switch (s->io[i].Attributes & IO_DATA_PATH_WIDTH) {734734+ case IO_DATA_PATH_WIDTH_16:735735+ iomap.flags |= MAP_16BIT; break;736736+ case IO_DATA_PATH_WIDTH_AUTO:737737+ iomap.flags |= MAP_AUTOSZ; break;738738+ default:739739+ break;740740+ }741741+ iomap.start = s->io[i].BasePort;742742+ iomap.stop = iomap.start + s->io[i].NumPorts - 1;743743+ s->ops->set_io_map(s, &iomap);744744+ s->io[i].Config++;745745+ }746746+ }747747+748748+ c->state |= CONFIG_LOCKED;749749+ handle->state |= CLIENT_CONFIG_LOCKED;750750+ return CS_SUCCESS;751751+} /* pcmcia_request_configuration */752752+EXPORT_SYMBOL(pcmcia_request_configuration);753753+754754+755755+/** pcmcia_request_io756756+ *757757+ * Request_io() reserves ranges of port addresses for a socket.758758+ * I have not implemented range sharing or alias addressing.759759+ */760760+int pcmcia_request_io(client_handle_t handle, io_req_t *req)761761+{762762+ struct pcmcia_socket *s;763763+ config_t *c;764764+765765+ if (CHECK_HANDLE(handle))766766+ return CS_BAD_HANDLE;767767+ s = SOCKET(handle);768768+ if (!(s->state & SOCKET_PRESENT))769769+ return CS_NO_CARD;770770+771771+ if (handle->state & CLIENT_CARDBUS) {772772+#ifdef CONFIG_CARDBUS773773+ handle->state |= CLIENT_IO_REQ;774774+ return CS_SUCCESS;775775+#else776776+ return CS_UNSUPPORTED_FUNCTION;777777+#endif778778+ }779779+780780+ if (!req)781781+ return CS_UNSUPPORTED_MODE;782782+ c = CONFIG(handle);783783+ if (c->state & CONFIG_LOCKED)784784+ return CS_CONFIGURATION_LOCKED;785785+ if (c->state & CONFIG_IO_REQ)786786+ return CS_IN_USE;787787+ if (req->Attributes1 & (IO_SHARED | IO_FORCE_ALIAS_ACCESS))788788+ return CS_BAD_ATTRIBUTE;789789+ if ((req->NumPorts2 > 0) &&790790+ (req->Attributes2 & (IO_SHARED | IO_FORCE_ALIAS_ACCESS)))791791+ return CS_BAD_ATTRIBUTE;792792+793793+ if (alloc_io_space(s, req->Attributes1, &req->BasePort1,794794+ req->NumPorts1, req->IOAddrLines))795795+ return CS_IN_USE;796796+797797+ if (req->NumPorts2) {798798+ if (alloc_io_space(s, req->Attributes2, &req->BasePort2,799799+ req->NumPorts2, req->IOAddrLines)) {800800+ release_io_space(s, req->BasePort1, req->NumPorts1);801801+ return CS_IN_USE;802802+ }803803+ }804804+805805+ c->io = *req;806806+ c->state |= CONFIG_IO_REQ;807807+ handle->state |= CLIENT_IO_REQ;808808+ return CS_SUCCESS;809809+} /* pcmcia_request_io */810810+EXPORT_SYMBOL(pcmcia_request_io);811811+812812+813813+/** pcmcia_request_irq814814+ *815815+ * Request_irq() reserves an irq for this client.816816+ *817817+ * Also, since Linux only reserves irq's when they are actually818818+ * hooked, we don't guarantee that an irq will still be available819819+ * when the configuration is locked. Now that I think about it,820820+ * there might be a way to fix this using a dummy handler.821821+ */822822+823823+#ifdef CONFIG_PCMCIA_PROBE824824+static irqreturn_t test_action(int cpl, void *dev_id, struct pt_regs *regs)825825+{826826+ return IRQ_NONE;827827+}828828+#endif829829+830830+int pcmcia_request_irq(client_handle_t handle, irq_req_t *req)831831+{832832+ struct pcmcia_socket *s;833833+ config_t *c;834834+ int ret = CS_IN_USE, irq = 0;835835+ struct pcmcia_device *p_dev = handle_to_pdev(handle);836836+837837+ if (CHECK_HANDLE(handle))838838+ return CS_BAD_HANDLE;839839+ s = SOCKET(handle);840840+ if (!(s->state & SOCKET_PRESENT))841841+ return CS_NO_CARD;842842+ c = CONFIG(handle);843843+ if (c->state & CONFIG_LOCKED)844844+ return CS_CONFIGURATION_LOCKED;845845+ if (c->state & CONFIG_IRQ_REQ)846846+ return CS_IN_USE;847847+848848+#ifdef CONFIG_PCMCIA_PROBE849849+ if (s->irq.AssignedIRQ != 0) {850850+ /* If the interrupt is already assigned, it must be the same */851851+ irq = s->irq.AssignedIRQ;852852+ } else {853853+ int try;854854+ u32 mask = s->irq_mask;855855+ void *data = NULL;856856+857857+ for (try = 0; try < 64; try++) {858858+ irq = try % 32;859859+860860+ /* marked as available by driver, and not blocked by userspace? */861861+ if (!((mask >> irq) & 1))862862+ continue;863863+864864+ /* avoid an IRQ which is already used by a PCMCIA card */865865+ if ((try < 32) && pcmcia_used_irq[irq])866866+ continue;867867+868868+ /* register the correct driver, if possible, of check whether869869+ * registering a dummy handle works, i.e. if the IRQ isn't870870+ * marked as used by the kernel resource management core */871871+ ret = request_irq(irq,872872+ (req->Attributes & IRQ_HANDLE_PRESENT) ? req->Handler : test_action,873873+ ((req->Attributes & IRQ_TYPE_DYNAMIC_SHARING) ||874874+ (s->functions > 1) ||875875+ (irq == s->pci_irq)) ? SA_SHIRQ : 0,876876+ p_dev->dev.bus_id,877877+ (req->Attributes & IRQ_HANDLE_PRESENT) ? req->Instance : data);878878+ if (!ret) {879879+ if (!(req->Attributes & IRQ_HANDLE_PRESENT))880880+ free_irq(irq, data);881881+ break;882882+ }883883+ }884884+ }885885+#endif886886+ if (ret) {887887+ if (!s->pci_irq)888888+ return ret;889889+ irq = s->pci_irq;890890+ }891891+892892+ if (ret && req->Attributes & IRQ_HANDLE_PRESENT) {893893+ if (request_irq(irq, req->Handler,894894+ ((req->Attributes & IRQ_TYPE_DYNAMIC_SHARING) ||895895+ (s->functions > 1) ||896896+ (irq == s->pci_irq)) ? SA_SHIRQ : 0,897897+ p_dev->dev.bus_id, req->Instance))898898+ return CS_IN_USE;899899+ }900900+901901+ c->irq.Attributes = req->Attributes;902902+ s->irq.AssignedIRQ = req->AssignedIRQ = irq;903903+ s->irq.Config++;904904+905905+ c->state |= CONFIG_IRQ_REQ;906906+ handle->state |= CLIENT_IRQ_REQ;907907+908908+#ifdef CONFIG_PCMCIA_PROBE909909+ pcmcia_used_irq[irq]++;910910+#endif911911+912912+ return CS_SUCCESS;913913+} /* pcmcia_request_irq */914914+EXPORT_SYMBOL(pcmcia_request_irq);915915+916916+917917+/** pcmcia_request_window918918+ *919919+ * Request_window() establishes a mapping between card memory space920920+ * and system memory space.921921+ */922922+int pcmcia_request_window(client_handle_t *handle, win_req_t *req, window_handle_t *wh)923923+{924924+ struct pcmcia_socket *s;925925+ window_t *win;926926+ u_long align;927927+ int w;928928+929929+ if (CHECK_HANDLE(*handle))930930+ return CS_BAD_HANDLE;931931+ s = (*handle)->Socket;932932+ if (!(s->state & SOCKET_PRESENT))933933+ return CS_NO_CARD;934934+ if (req->Attributes & (WIN_PAGED | WIN_SHARED))935935+ return CS_BAD_ATTRIBUTE;936936+937937+ /* Window size defaults to smallest available */938938+ if (req->Size == 0)939939+ req->Size = s->map_size;940940+ align = (((s->features & SS_CAP_MEM_ALIGN) ||941941+ (req->Attributes & WIN_STRICT_ALIGN)) ?942942+ req->Size : s->map_size);943943+ if (req->Size & (s->map_size-1))944944+ return CS_BAD_SIZE;945945+ if ((req->Base && (s->features & SS_CAP_STATIC_MAP)) ||946946+ (req->Base & (align-1)))947947+ return CS_BAD_BASE;948948+ if (req->Base)949949+ align = 0;950950+951951+ /* Allocate system memory window */952952+ for (w = 0; w < MAX_WIN; w++)953953+ if (!(s->state & SOCKET_WIN_REQ(w))) break;954954+ if (w == MAX_WIN)955955+ return CS_OUT_OF_RESOURCE;956956+957957+ win = &s->win[w];958958+ win->magic = WINDOW_MAGIC;959959+ win->index = w;960960+ win->handle = *handle;961961+ win->sock = s;962962+963963+ if (!(s->features & SS_CAP_STATIC_MAP)) {964964+ win->ctl.res = pcmcia_find_mem_region(req->Base, req->Size, align,965965+ (req->Attributes & WIN_MAP_BELOW_1MB), s);966966+ if (!win->ctl.res)967967+ return CS_IN_USE;968968+ }969969+ (*handle)->state |= CLIENT_WIN_REQ(w);970970+971971+ /* Configure the socket controller */972972+ win->ctl.map = w+1;973973+ win->ctl.flags = 0;974974+ win->ctl.speed = req->AccessSpeed;975975+ if (req->Attributes & WIN_MEMORY_TYPE)976976+ win->ctl.flags |= MAP_ATTRIB;977977+ if (req->Attributes & WIN_ENABLE)978978+ win->ctl.flags |= MAP_ACTIVE;979979+ if (req->Attributes & WIN_DATA_WIDTH_16)980980+ win->ctl.flags |= MAP_16BIT;981981+ if (req->Attributes & WIN_USE_WAIT)982982+ win->ctl.flags |= MAP_USE_WAIT;983983+ win->ctl.card_start = 0;984984+ if (s->ops->set_mem_map(s, &win->ctl) != 0)985985+ return CS_BAD_ARGS;986986+ s->state |= SOCKET_WIN_REQ(w);987987+988988+ /* Return window handle */989989+ if (s->features & SS_CAP_STATIC_MAP) {990990+ req->Base = win->ctl.static_start;991991+ } else {992992+ req->Base = win->ctl.res->start;993993+ }994994+ *wh = win;995995+996996+ return CS_SUCCESS;997997+} /* pcmcia_request_window */998998+EXPORT_SYMBOL(pcmcia_request_window);
+7-4
drivers/pcmcia/rsrc_mgr.c
···7272 /* you can't use the old interface if the new7373 * one was used before */7474 spin_lock_irqsave(&s->lock, flags);7575- if ((s->resource_setup_done) &&7575+ if ((s->resource_setup_new) &&7676 !(s->resource_setup_old)) {7777 spin_unlock_irqrestore(&s->lock, flags);7878 continue;···105105}106106EXPORT_SYMBOL(pcmcia_validate_mem);107107108108-int adjust_io_region(struct resource *res, unsigned long r_start,108108+int pcmcia_adjust_io_region(struct resource *res, unsigned long r_start,109109 unsigned long r_end, struct pcmcia_socket *s)110110{111111 if (s->resource_ops->adjust_io_region)112112 return s->resource_ops->adjust_io_region(res, r_start, r_end, s);113113 return -ENOMEM;114114}115115+EXPORT_SYMBOL(pcmcia_adjust_io_region);115116116116-struct resource *find_io_region(unsigned long base, int num,117117+struct resource *pcmcia_find_io_region(unsigned long base, int num,117118 unsigned long align, struct pcmcia_socket *s)118119{119120 if (s->resource_ops->find_io)120121 return s->resource_ops->find_io(base, num, align, s);121122 return NULL;122123}124124+EXPORT_SYMBOL(pcmcia_find_io_region);123125124124-struct resource *find_mem_region(u_long base, u_long num, u_long align,126126+struct resource *pcmcia_find_mem_region(u_long base, u_long num, u_long align,125127 int low, struct pcmcia_socket *s)126128{127129 if (s->resource_ops->find_mem)128130 return s->resource_ops->find_mem(base, num, align, low, s);129131 return NULL;130132}133133+EXPORT_SYMBOL(pcmcia_find_mem_region);131134132135void release_resource_db(struct pcmcia_socket *s)133136{
+114-56
drivers/pcmcia/rsrc_nonstatic.c
···372372 base, base+num-1);373373 bad = fail = 0;374374 step = (num < 0x20000) ? 0x2000 : ((num>>4) & ~0x1fff);375375+ /* don't allow too large steps */376376+ if (step > 0x800000)377377+ step = 0x800000;375378 /* cis_readable wants to map 2x map_size */376379 if (step < 2 * s->map_size)377380 step = 2 * s->map_size;···468465469466 for (m = s_data->mem_db.next; m != &s_data->mem_db; m = mm.next) {470467 mm = *m;471471- if (do_mem_probe(mm.base, mm.num, s))472472- break;468468+ do_mem_probe(mm.base, mm.num, s);473469 }474470}475471···603601604602======================================================================*/605603606606-struct resource *nonstatic_find_io_region(unsigned long base, int num,604604+static struct resource *nonstatic_find_io_region(unsigned long base, int num,607605 unsigned long align, struct pcmcia_socket *s)608606{609607 struct resource *res = make_resource(0, num, IORESOURCE_IO, s->dev.class_id);···637635 return res;638636}639637640640-struct resource * nonstatic_find_mem_region(u_long base, u_long num, u_long align,641641- int low, struct pcmcia_socket *s)638638+static struct resource * nonstatic_find_mem_region(u_long base, u_long num,639639+ u_long align, int low, struct pcmcia_socket *s)642640{643641 struct resource *res = make_resource(0, num, IORESOURCE_MEM, s->dev.class_id);644642 struct socket_data *s_data = s->resource_data;···685683}686684687685688688-static int adjust_memory(struct pcmcia_socket *s, adjust_t *adj)686686+static int adjust_memory(struct pcmcia_socket *s, unsigned int action, unsigned long start, unsigned long end)689687{690690- u_long base, num;691688 struct socket_data *data = s->resource_data;692692- int ret;689689+ unsigned long size = end - start + 1;690690+ int ret = 0;693691694694- base = adj->resource.memory.Base;695695- num = adj->resource.memory.Size;696696- if ((num == 0) || (base+num-1 < base))697697- return CS_BAD_SIZE;698698-699699- ret = CS_SUCCESS;692692+ if (end <= start)693693+ return -EINVAL;700694701695 down(&rsrc_sem);702702- switch (adj->Action) {696696+ switch (action) {703697 case ADD_MANAGED_RESOURCE:704704- ret = add_interval(&data->mem_db, base, num);698698+ ret = add_interval(&data->mem_db, start, size);705699 break;706700 case REMOVE_MANAGED_RESOURCE:707707- ret = sub_interval(&data->mem_db, base, num);708708- if (ret == CS_SUCCESS) {701701+ ret = sub_interval(&data->mem_db, start, size);702702+ if (!ret) {709703 struct pcmcia_socket *socket;710704 down_read(&pcmcia_socket_list_rwsem);711705 list_for_each_entry(socket, &pcmcia_socket_list, socket_list)···710712 }711713 break;712714 default:713713- ret = CS_UNSUPPORTED_FUNCTION;715715+ ret = -EINVAL;714716 }715717 up(&rsrc_sem);716718···718720}719721720722721721-static int adjust_io(struct pcmcia_socket *s, adjust_t *adj)723723+static int adjust_io(struct pcmcia_socket *s, unsigned int action, unsigned long start, unsigned long end)722724{723725 struct socket_data *data = s->resource_data;724724- kio_addr_t base, num;725725- int ret = CS_SUCCESS;726726+ unsigned long size = end - start + 1;727727+ int ret = 0;726728727727- base = adj->resource.io.BasePort;728728- num = adj->resource.io.NumPorts;729729- if ((base < 0) || (base > 0xffff))730730- return CS_BAD_BASE;731731- if ((num <= 0) || (base+num > 0x10000) || (base+num <= base))732732- return CS_BAD_SIZE;729729+ if (end <= start)730730+ return -EINVAL;731731+732732+ if (end > IO_SPACE_LIMIT)733733+ return -EINVAL;733734734735 down(&rsrc_sem);735735- switch (adj->Action) {736736+ switch (action) {736737 case ADD_MANAGED_RESOURCE:737737- if (add_interval(&data->io_db, base, num) != 0) {738738- ret = CS_IN_USE;738738+ if (add_interval(&data->io_db, start, size) != 0) {739739+ ret = -EBUSY;739740 break;740741 }741742#ifdef CONFIG_PCMCIA_PROBE742743 if (probe_io)743743- do_io_probe(s, base, num);744744+ do_io_probe(s, start, size);744745#endif745746 break;746747 case REMOVE_MANAGED_RESOURCE:747747- sub_interval(&data->io_db, base, num);748748+ sub_interval(&data->io_db, start, size);748749 break;749750 default:750750- ret = CS_UNSUPPORTED_FUNCTION;751751+ ret = -EINVAL;751752 break;752753 }753754 up(&rsrc_sem);···757760758761static int nonstatic_adjust_resource_info(struct pcmcia_socket *s, adjust_t *adj)759762{763763+ unsigned long end;764764+760765 switch (adj->Resource) {761766 case RES_MEMORY_RANGE:762762- return adjust_memory(s, adj);767767+ end = adj->resource.memory.Base + adj->resource.memory.Size - 1;768768+ return adjust_memory(s, adj->Action, adj->resource.memory.Base, end);763769 case RES_IO_RANGE:764764- return adjust_io(s, adj);770770+ end = adj->resource.io.BasePort + adj->resource.io.NumPorts - 1;771771+ return adjust_io(s, adj->Action, adj->resource.io.BasePort, end);765772 }766773 return CS_UNSUPPORTED_FUNCTION;767774}775775+776776+#ifdef CONFIG_PCI777777+static int nonstatic_autoadd_resources(struct pcmcia_socket *s)778778+{779779+ struct resource *res;780780+ int i, done = 0;781781+782782+ if (!s->cb_dev || !s->cb_dev->bus)783783+ return -ENODEV;784784+785785+#if defined(CONFIG_X86) || defined(CONFIG_X86_64)786786+ /* If this is the root bus, the risk of hitting787787+ * some strange system devices which aren't protected788788+ * by either ACPI resource tables or properly requested789789+ * resources is too big. Therefore, don't do auto-adding790790+ * of resources at the moment.791791+ */792792+ if (s->cb_dev->bus->number == 0)793793+ return -EINVAL;794794+#endif795795+796796+ for (i=0; i < PCI_BUS_NUM_RESOURCES; i++) {797797+ res = s->cb_dev->bus->resource[i];798798+ if (!res)799799+ continue;800800+801801+ if (res->flags & IORESOURCE_IO) {802802+ if (res == &ioport_resource)803803+ continue;804804+ printk(KERN_INFO "pcmcia: parent PCI bridge I/O window: 0x%lx - 0x%lx\n",805805+ res->start, res->end);806806+ if (!adjust_io(s, ADD_MANAGED_RESOURCE, res->start, res->end))807807+ done |= IORESOURCE_IO;808808+809809+ }810810+811811+ if (res->flags & IORESOURCE_MEM) {812812+ if (res == &iomem_resource)813813+ continue;814814+ printk(KERN_INFO "pcmcia: parent PCI bridge Memory window: 0x%lx - 0x%lx\n",815815+ res->start, res->end);816816+ if (!adjust_memory(s, ADD_MANAGED_RESOURCE, res->start, res->end))817817+ done |= IORESOURCE_MEM;818818+ }819819+ }820820+821821+ /* if we got at least one of IO, and one of MEM, we can be glad and822822+ * activate the PCMCIA subsystem */823823+ if (done & (IORESOURCE_MEM | IORESOURCE_IO))824824+ s->resource_setup_done = 1;825825+826826+ return 0;827827+}828828+829829+#else830830+831831+static inline int nonstatic_autoadd_resources(struct pcmcia_socket *s)832832+{833833+ return -ENODEV;834834+}835835+836836+#endif837837+768838769839static int nonstatic_init(struct pcmcia_socket *s)770840{···846782 data->io_db.next = &data->io_db;847783848784 s->resource_data = (void *) data;785785+786786+ nonstatic_autoadd_resources(s);849787850788 return 0;851789}···911845{912846 struct pcmcia_socket *s = class_get_devdata(class_dev);913847 unsigned long start_addr, end_addr;914914- unsigned int add = 1;915915- adjust_t adj;848848+ unsigned int add = ADD_MANAGED_RESOURCE;916849 ssize_t ret = 0;917850918851 ret = sscanf (buf, "+ 0x%lx - 0x%lx", &start_addr, &end_addr);919852 if (ret != 2) {920853 ret = sscanf (buf, "- 0x%lx - 0x%lx", &start_addr, &end_addr);921921- add = 0;854854+ add = REMOVE_MANAGED_RESOURCE;922855 if (ret != 2) {923856 ret = sscanf (buf, "0x%lx - 0x%lx", &start_addr, &end_addr);924924- add = 1;857857+ add = ADD_MANAGED_RESOURCE;925858 if (ret != 2)926859 return -EINVAL;927860 }···928863 if (end_addr <= start_addr)929864 return -EINVAL;930865931931- adj.Action = add ? ADD_MANAGED_RESOURCE : REMOVE_MANAGED_RESOURCE;932932- adj.Resource = RES_IO_RANGE;933933- adj.resource.io.BasePort = start_addr;934934- adj.resource.io.NumPorts = end_addr - start_addr + 1;935935-936936- ret = adjust_io(s, &adj);866866+ ret = adjust_io(s, add, start_addr, end_addr);867867+ if (!ret)868868+ s->resource_setup_new = 1;937869938870 return ret ? ret : count;939871}···963901{964902 struct pcmcia_socket *s = class_get_devdata(class_dev);965903 unsigned long start_addr, end_addr;966966- unsigned int add = 1;967967- adjust_t adj;904904+ unsigned int add = ADD_MANAGED_RESOURCE;968905 ssize_t ret = 0;969906970907 ret = sscanf (buf, "+ 0x%lx - 0x%lx", &start_addr, &end_addr);971908 if (ret != 2) {972909 ret = sscanf (buf, "- 0x%lx - 0x%lx", &start_addr, &end_addr);973973- add = 0;910910+ add = REMOVE_MANAGED_RESOURCE;974911 if (ret != 2) {975912 ret = sscanf (buf, "0x%lx - 0x%lx", &start_addr, &end_addr);976976- add = 1;913913+ add = ADD_MANAGED_RESOURCE;977914 if (ret != 2)978915 return -EINVAL;979916 }···980919 if (end_addr <= start_addr)981920 return -EINVAL;982921983983- adj.Action = add ? ADD_MANAGED_RESOURCE : REMOVE_MANAGED_RESOURCE;984984- adj.Resource = RES_MEMORY_RANGE;985985- adj.resource.memory.Base = start_addr;986986- adj.resource.memory.Size = end_addr - start_addr + 1;987987-988988- ret = adjust_memory(s, &adj);922922+ ret = adjust_memory(s, add, start_addr, end_addr);923923+ if (!ret)924924+ s->resource_setup_new = 1;989925990926 return ret ? ret : count;991927}
+162-16
drivers/pcmcia/socket_sysfs.c
···163163 return -EINVAL;164164165165 spin_lock_irqsave(&s->lock, flags);166166- if (!s->resource_setup_done) {166166+ if (!s->resource_setup_done)167167 s->resource_setup_done = 1;168168- spin_unlock_irqrestore(&s->lock, flags);169169-170170- down(&s->skt_sem);171171- if ((s->callback) &&172172- (s->state & SOCKET_PRESENT) &&173173- !(s->state & SOCKET_CARDBUS)) {174174- if (try_module_get(s->callback->owner)) {175175- s->callback->resources_done(s);176176- module_put(s->callback->owner);177177- }178178- }179179- up(&s->skt_sem);180180-181181- return count;182182- }183168 spin_unlock_irqrestore(&s->lock, flags);169169+170170+ down(&s->skt_sem);171171+ if ((s->callback) &&172172+ (s->state & SOCKET_PRESENT) &&173173+ !(s->state & SOCKET_CARDBUS)) {174174+ if (try_module_get(s->callback->owner)) {175175+ s->callback->requery(s);176176+ module_put(s->callback->owner);177177+ }178178+ }179179+ up(&s->skt_sem);184180185181 return count;186182}187183static CLASS_DEVICE_ATTR(available_resources_setup_done, 0600, pccard_show_resource, pccard_store_resource);184184+185185+186186+static ssize_t pccard_extract_cis(struct pcmcia_socket *s, char *buf, loff_t off, size_t count)187187+{188188+ tuple_t tuple;189189+ int status, i;190190+ loff_t pointer = 0;191191+ ssize_t ret = 0;192192+ u_char *tuplebuffer;193193+ u_char *tempbuffer;194194+195195+ tuplebuffer = kmalloc(sizeof(u_char) * 256, GFP_KERNEL);196196+ if (!tuplebuffer)197197+ return -ENOMEM;198198+199199+ tempbuffer = kmalloc(sizeof(u_char) * 258, GFP_KERNEL);200200+ if (!tempbuffer) {201201+ ret = -ENOMEM;202202+ goto free_tuple;203203+ }204204+205205+ memset(&tuple, 0, sizeof(tuple_t));206206+207207+ tuple.Attributes = TUPLE_RETURN_LINK | TUPLE_RETURN_COMMON;208208+ tuple.DesiredTuple = RETURN_FIRST_TUPLE;209209+ tuple.TupleOffset = 0;210210+211211+ status = pccard_get_first_tuple(s, BIND_FN_ALL, &tuple);212212+ while (!status) {213213+ tuple.TupleData = tuplebuffer;214214+ tuple.TupleDataMax = 255;215215+ memset(tuplebuffer, 0, sizeof(u_char) * 255);216216+217217+ status = pccard_get_tuple_data(s, &tuple);218218+ if (status)219219+ break;220220+221221+ if (off < (pointer + 2 + tuple.TupleDataLen)) {222222+ tempbuffer[0] = tuple.TupleCode & 0xff;223223+ tempbuffer[1] = tuple.TupleLink & 0xff;224224+ for (i = 0; i < tuple.TupleDataLen; i++)225225+ tempbuffer[i + 2] = tuplebuffer[i] & 0xff;226226+227227+ for (i = 0; i < (2 + tuple.TupleDataLen); i++) {228228+ if (((i + pointer) >= off) &&229229+ (i + pointer) < (off + count)) {230230+ buf[ret] = tempbuffer[i];231231+ ret++;232232+ }233233+ }234234+ }235235+236236+ pointer += 2 + tuple.TupleDataLen;237237+238238+ if (pointer >= (off + count))239239+ break;240240+241241+ if (tuple.TupleCode == CISTPL_END)242242+ break;243243+ status = pccard_get_next_tuple(s, BIND_FN_ALL, &tuple);244244+ }245245+246246+ kfree(tempbuffer);247247+ free_tuple:248248+ kfree(tuplebuffer);249249+250250+ return (ret);251251+}252252+253253+static ssize_t pccard_show_cis(struct kobject *kobj, char *buf, loff_t off, size_t count)254254+{255255+ unsigned int size = 0x200;256256+257257+ if (off >= size)258258+ count = 0;259259+ else {260260+ struct pcmcia_socket *s;261261+ cisinfo_t cisinfo;262262+263263+ if (off + count > size)264264+ count = size - off;265265+266266+ s = to_socket(container_of(kobj, struct class_device, kobj));267267+268268+ if (!(s->state & SOCKET_PRESENT))269269+ return -ENODEV;270270+ if (pccard_validate_cis(s, BIND_FN_ALL, &cisinfo))271271+ return -EIO;272272+ if (!cisinfo.Chains)273273+ return -ENODATA;274274+275275+ count = pccard_extract_cis(s, buf, off, count);276276+ }277277+278278+ return (count);279279+}280280+281281+static ssize_t pccard_store_cis(struct kobject *kobj, char *buf, loff_t off, size_t count)282282+{283283+ struct pcmcia_socket *s = to_socket(container_of(kobj, struct class_device, kobj));284284+ cisdump_t *cis;285285+ ssize_t ret = count;286286+287287+ if (off)288288+ return -EINVAL;289289+290290+ if (count >= 0x200)291291+ return -EINVAL;292292+293293+ if (!(s->state & SOCKET_PRESENT))294294+ return -ENODEV;295295+296296+ cis = kmalloc(sizeof(cisdump_t), GFP_KERNEL);297297+ if (!cis)298298+ return -ENOMEM;299299+ memset(cis, 0, sizeof(cisdump_t));300300+301301+ cis->Length = count + 1;302302+ memcpy(cis->Data, buf, count);303303+304304+ if (pcmcia_replace_cis(s, cis))305305+ ret = -EIO;306306+307307+ kfree(cis);308308+309309+ if (!ret) {310310+ down(&s->skt_sem);311311+ if ((s->callback) && (s->state & SOCKET_PRESENT) &&312312+ !(s->state & SOCKET_CARDBUS)) {313313+ if (try_module_get(s->callback->owner)) {314314+ s->callback->requery(s);315315+ module_put(s->callback->owner);316316+ }317317+ }318318+ up(&s->skt_sem);319319+ }320320+321321+322322+ return (ret);323323+}188324189325190326static struct class_device_attribute *pccard_socket_attributes[] = {···335199 NULL,336200};337201202202+static struct bin_attribute pccard_cis_attr = {203203+ .attr = { .name = "cis", .mode = S_IRUGO | S_IWUSR, .owner = THIS_MODULE},204204+ .size = 0x200,205205+ .read = pccard_show_cis,206206+ .write = pccard_store_cis,207207+};208208+338209static int __devinit pccard_sysfs_add_socket(struct class_device *class_dev)339210{340211 struct class_device_attribute **attr;···352209 if (ret)353210 break;354211 }212212+ if (!ret)213213+ ret = sysfs_create_bin_file(&class_dev->kobj, &pccard_cis_attr);355214356215 return ret;357216}···362217{363218 struct class_device_attribute **attr;364219220220+ sysfs_remove_bin_file(&class_dev->kobj, &pccard_cis_attr);365221 for (attr = pccard_socket_attributes; *attr; attr++)366222 class_device_remove_file(class_dev, *attr);367223}
+5-1
drivers/pcmcia/yenta_socket.c
···549549 unsigned offset;550550 unsigned mask;551551552552+ res = socket->dev->resource + PCI_BRIDGE_RESOURCES + nr;553553+ /* Already allocated? */554554+ if (res->parent)555555+ return 0;556556+552557 /* The granularity of the memory limit is 4kB, on IO it's 4 bytes */553558 mask = ~0xfff;554559 if (type & IORESOURCE_IO)···561556562557 offset = 0x1c + 8*nr;563558 bus = socket->dev->subordinate;564564- res = socket->dev->resource + PCI_BRIDGE_RESOURCES + nr;565559 res->name = bus->name;566560 res->flags = type;567561 res->start = 0;
···159159 * underruns. If non-zero, doing_pdma encodes the direction of160160 * the transfer for debugging. 1=read 2=write161161 */162162-char *pdma_vaddr;162162+unsigned char *pdma_vaddr;163163unsigned long pdma_size;164164volatile int doing_pdma = 0;165165···209209 pdma_areasize = pdma_size;210210}211211212212-/* Our low-level entry point in arch/sparc/kernel/entry.S */213213-extern irqreturn_t floppy_hardint(int irq, void *unused, struct pt_regs *regs);212212+extern irqreturn_t sparc_floppy_irq(int, void *, struct pt_regs *);214213215214static int sun_fd_request_irq(void)216215{···219220 if(!once) {220221 once = 1;221222222222- error = request_fast_irq(FLOPPY_IRQ, floppy_hardint, 223223- SA_INTERRUPT, "floppy", NULL);223223+ error = request_irq(FLOPPY_IRQ, sparc_floppy_irq, 224224+ SA_INTERRUPT, "floppy", NULL);224225225226 return ((error == 0) ? 0 : -1);226227 }···614615 struct linux_ebus *ebus;615616 struct linux_ebus_device *edev = NULL;616617 unsigned long config = 0;617617- unsigned long auxio_reg;618618+ void __iomem *auxio_reg;618619619620 for_each_ebus(ebus) {620621 for_each_ebusdev(edev, ebus) {···641642 /* Make sure the high density bit is set, some systems642643 * (most notably Ultra5/Ultra10) come up with it clear.643644 */644644- auxio_reg = edev->resource[2].start;645645+ auxio_reg = (void __iomem *) edev->resource[2].start;645646 writel(readl(auxio_reg)|0x2, auxio_reg);646647647648 sun_pci_ebus_dev = ebus->self;···649650 spin_lock_init(&sun_pci_fd_ebus_dma.lock);650651651652 /* XXX ioremap */652652- sun_pci_fd_ebus_dma.regs = edev->resource[1].start;653653+ sun_pci_fd_ebus_dma.regs = (void __iomem *)654654+ edev->resource[1].start;653655 if (!sun_pci_fd_ebus_dma.regs)654656 return 0;655657
+1-6
include/asm-sparc64/irq.h
···1919/* You should not mess with this directly. That's the job of irq.c.2020 *2121 * If you make changes here, please update hand coded assembler of2222- * SBUS/floppy interrupt handler in entry.S -DaveM2222+ * the vectored interrupt trap handler in entry.S -DaveM2323 *2424 * This is currently one DCACHE line, two buckets per L2 cache2525 * line. Keep this in mind please.···121121extern void enable_irq(unsigned int);122122extern unsigned int build_irq(int pil, int inofixup, unsigned long iclr, unsigned long imap);123123extern unsigned int sbus_build_irq(void *sbus, unsigned int ino);124124-125125-extern int request_fast_irq(unsigned int irq,126126- irqreturn_t (*handler)(int, void *, struct pt_regs *),127127- unsigned long flags, __const__ char *devname,128128- void *dev_id);129124130125static __inline__ void set_softint(unsigned long bits)131126{