diff options
Diffstat (limited to 'drivers')
232 files changed, 7976 insertions, 9275 deletions
diff --git a/drivers/Kconfig b/drivers/Kconfig index 9f5c0da57c9..5c91d6afb11 100644 --- a/drivers/Kconfig +++ b/drivers/Kconfig @@ -64,6 +64,8 @@ source "drivers/usb/Kconfig" source "drivers/mmc/Kconfig" +source "drivers/leds/Kconfig" + source "drivers/infiniband/Kconfig" source "drivers/sn/Kconfig" diff --git a/drivers/Makefile b/drivers/Makefile index 2449ec55ca2..447d8e68887 100644 --- a/drivers/Makefile +++ b/drivers/Makefile @@ -25,9 +25,6 @@ obj-$(CONFIG_CONNECTOR) += connector/ obj-$(CONFIG_FB_I810) += video/i810/ obj-$(CONFIG_FB_INTEL) += video/intelfb/ -# we also need input/serio early so serio bus is initialized by the time -# serial drivers start registering their serio ports -obj-$(CONFIG_SERIO) += input/serio/ obj-y += serial/ obj-$(CONFIG_PARPORT) += parport/ obj-y += base/ block/ misc/ mfd/ net/ media/ @@ -53,6 +50,7 @@ obj-$(CONFIG_TC) += tc/ obj-$(CONFIG_USB) += usb/ obj-$(CONFIG_PCI) += usb/ obj-$(CONFIG_USB_GADGET) += usb/gadget/ +obj-$(CONFIG_SERIO) += input/serio/ obj-$(CONFIG_GAMEPORT) += input/gameport/ obj-$(CONFIG_INPUT) += input/ obj-$(CONFIG_I2O) += message/ @@ -69,6 +67,7 @@ obj-$(CONFIG_MCA) += mca/ obj-$(CONFIG_EISA) += eisa/ obj-$(CONFIG_CPU_FREQ) += cpufreq/ obj-$(CONFIG_MMC) += mmc/ +obj-$(CONFIG_NEW_LEDS) += leds/ obj-$(CONFIG_INFINIBAND) += infiniband/ obj-$(CONFIG_IPATH_CORE) += infiniband/ obj-$(CONFIG_SGI_SN) += sn/ diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c index 79b09d76c18..eee0864ba30 100644 --- a/drivers/acpi/ec.c +++ b/drivers/acpi/ec.c @@ -1572,7 +1572,7 @@ static void __exit acpi_ec_exit(void) static int __init acpi_fake_ecdt_setup(char *str) { acpi_fake_ecdt_enabled = 1; - return 0; + return 1; } __setup("acpi_fake_ecdt", acpi_fake_ecdt_setup); @@ -1591,7 +1591,7 @@ static int __init acpi_ec_set_intr_mode(char *str) acpi_ec_driver.ops.add = acpi_ec_poll_add; } printk(KERN_INFO PREFIX "EC %s mode.\n", intr ? "interrupt" : "polling"); - return 0; + return 1; } __setup("ec_intr=", acpi_ec_set_intr_mode); diff --git a/drivers/block/amiflop.c b/drivers/block/amiflop.c index b6e29095621..2a8af685926 100644 --- a/drivers/block/amiflop.c +++ b/drivers/block/amiflop.c @@ -1850,6 +1850,7 @@ static int __init amiga_floppy_setup (char *str) return 0; printk (KERN_INFO "amiflop: Setting default df0 to %x\n", n); fd_def_df0 = n; + return 1; } __setup("floppy=", amiga_floppy_setup); diff --git a/drivers/bluetooth/bluecard_cs.c b/drivers/bluetooth/bluecard_cs.c index 9888bc15175..473a13b22b2 100644 --- a/drivers/bluetooth/bluecard_cs.c +++ b/drivers/bluetooth/bluecard_cs.c @@ -65,7 +65,7 @@ MODULE_LICENSE("GPL"); typedef struct bluecard_info_t { - dev_link_t link; + struct pcmcia_device *p_dev; dev_node_t node; struct hci_dev *hdev; @@ -85,8 +85,8 @@ typedef struct bluecard_info_t { } bluecard_info_t; -static void bluecard_config(dev_link_t *link); -static void bluecard_release(dev_link_t *link); +static int bluecard_config(struct pcmcia_device *link); +static void bluecard_release(struct pcmcia_device *link); static void bluecard_detach(struct pcmcia_device *p_dev); @@ -162,7 +162,7 @@ static void bluecard_detach(struct pcmcia_device *p_dev); static void bluecard_activity_led_timeout(u_long arg) { bluecard_info_t *info = (bluecard_info_t *)arg; - unsigned int iobase = info->link.io.BasePort1; + unsigned int iobase = info->p_dev->io.BasePort1; if (!test_bit(CARD_HAS_PCCARD_ID, &(info->hw_state))) return; @@ -179,7 +179,7 @@ static void bluecard_activity_led_timeout(u_long arg) static void bluecard_enable_activity_led(bluecard_info_t *info) { - unsigned int iobase = info->link.io.BasePort1; + unsigned int iobase = info->p_dev->io.BasePort1; if (!test_bit(CARD_HAS_PCCARD_ID, &(info->hw_state))) return; @@ -235,7 +235,7 @@ static void bluecard_write_wakeup(bluecard_info_t *info) } do { - register unsigned int iobase = info->link.io.BasePort1; + register unsigned int iobase = info->p_dev->io.BasePort1; register unsigned int offset; register unsigned char command; register unsigned long ready_bit; @@ -244,7 +244,7 @@ static void bluecard_write_wakeup(bluecard_info_t *info) clear_bit(XMIT_WAKEUP, &(info->tx_state)); - if (!(info->link.state & DEV_PRESENT)) + if (!pcmcia_dev_present(info->p_dev)) return; if (test_bit(XMIT_BUFFER_NUMBER, &(info->tx_state))) { @@ -382,7 +382,7 @@ static void bluecard_receive(bluecard_info_t *info, unsigned int offset) return; } - iobase = info->link.io.BasePort1; + iobase = info->p_dev->io.BasePort1; if (test_bit(XMIT_SENDING_READY, &(info->tx_state))) bluecard_enable_activity_led(info); @@ -512,7 +512,7 @@ static irqreturn_t bluecard_interrupt(int irq, void *dev_inst, struct pt_regs *r if (!test_bit(CARD_READY, &(info->hw_state))) return IRQ_HANDLED; - iobase = info->link.io.BasePort1; + iobase = info->p_dev->io.BasePort1; spin_lock(&(info->lock)); @@ -626,7 +626,7 @@ static int bluecard_hci_flush(struct hci_dev *hdev) static int bluecard_hci_open(struct hci_dev *hdev) { bluecard_info_t *info = (bluecard_info_t *)(hdev->driver_data); - unsigned int iobase = info->link.io.BasePort1; + unsigned int iobase = info->p_dev->io.BasePort1; if (test_bit(CARD_HAS_PCCARD_ID, &(info->hw_state))) bluecard_hci_set_baud_rate(hdev, DEFAULT_BAUD_RATE); @@ -646,7 +646,7 @@ static int bluecard_hci_open(struct hci_dev *hdev) static int bluecard_hci_close(struct hci_dev *hdev) { bluecard_info_t *info = (bluecard_info_t *)(hdev->driver_data); - unsigned int iobase = info->link.io.BasePort1; + unsigned int iobase = info->p_dev->io.BasePort1; if (!test_and_clear_bit(HCI_RUNNING, &(hdev->flags))) return 0; @@ -713,7 +713,7 @@ static int bluecard_hci_ioctl(struct hci_dev *hdev, unsigned int cmd, unsigned l static int bluecard_open(bluecard_info_t *info) { - unsigned int iobase = info->link.io.BasePort1; + unsigned int iobase = info->p_dev->io.BasePort1; struct hci_dev *hdev; unsigned char id; @@ -831,7 +831,7 @@ static int bluecard_open(bluecard_info_t *info) static int bluecard_close(bluecard_info_t *info) { - unsigned int iobase = info->link.io.BasePort1; + unsigned int iobase = info->p_dev->io.BasePort1; struct hci_dev *hdev = info->hdev; if (!hdev) @@ -856,17 +856,16 @@ static int bluecard_close(bluecard_info_t *info) return 0; } -static int bluecard_attach(struct pcmcia_device *p_dev) +static int bluecard_probe(struct pcmcia_device *link) { bluecard_info_t *info; - dev_link_t *link; /* Create new info device */ info = kzalloc(sizeof(*info), GFP_KERNEL); if (!info) return -ENOMEM; - link = &info->link; + info->p_dev = link; link->priv = info; link->io.Attributes1 = IO_DATA_PATH_WIDTH_8; @@ -878,32 +877,22 @@ static int bluecard_attach(struct pcmcia_device *p_dev) link->irq.Instance = info; link->conf.Attributes = CONF_ENABLE_IRQ; - link->conf.Vcc = 50; link->conf.IntType = INT_MEMORY_AND_IO; - link->handle = p_dev; - p_dev->instance = link; - - link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; - bluecard_config(link); - - return 0; + return bluecard_config(link); } -static void bluecard_detach(struct pcmcia_device *p_dev) +static void bluecard_detach(struct pcmcia_device *link) { - dev_link_t *link = dev_to_instance(p_dev); bluecard_info_t *info = link->priv; - if (link->state & DEV_CONFIG) - bluecard_release(link); - + bluecard_release(link); kfree(info); } -static int first_tuple(client_handle_t handle, tuple_t *tuple, cisparse_t *parse) +static int first_tuple(struct pcmcia_device *handle, tuple_t *tuple, cisparse_t *parse) { int i; @@ -918,14 +907,12 @@ static int first_tuple(client_handle_t handle, tuple_t *tuple, cisparse_t *parse return pcmcia_parse_tuple(handle, tuple, parse); } -static void bluecard_config(dev_link_t *link) +static int bluecard_config(struct pcmcia_device *link) { - client_handle_t handle = link->handle; bluecard_info_t *info = link->priv; tuple_t tuple; u_short buf[256]; cisparse_t parse; - config_info_t config; int i, n, last_ret, last_fn; tuple.TupleData = (cisdata_t *)buf; @@ -935,7 +922,7 @@ static void bluecard_config(dev_link_t *link) /* Get configuration register information */ tuple.DesiredTuple = CISTPL_CONFIG; - last_ret = first_tuple(handle, &tuple, &parse); + last_ret = first_tuple(link, &tuple, &parse); if (last_ret != CS_SUCCESS) { last_fn = ParseTuple; goto cs_failed; @@ -943,36 +930,31 @@ static void bluecard_config(dev_link_t *link) link->conf.ConfigBase = parse.config.base; link->conf.Present = parse.config.rmask[0]; - /* Configure card */ - link->state |= DEV_CONFIG; - i = pcmcia_get_configuration_info(handle, &config); - link->conf.Vcc = config.Vcc; - link->conf.ConfigIndex = 0x20; link->io.NumPorts1 = 64; link->io.IOAddrLines = 6; for (n = 0; n < 0x400; n += 0x40) { link->io.BasePort1 = n ^ 0x300; - i = pcmcia_request_io(link->handle, &link->io); + i = pcmcia_request_io(link, &link->io); if (i == CS_SUCCESS) break; } if (i != CS_SUCCESS) { - cs_error(link->handle, RequestIO, i); + cs_error(link, RequestIO, i); goto failed; } - i = pcmcia_request_irq(link->handle, &link->irq); + i = pcmcia_request_irq(link, &link->irq); if (i != CS_SUCCESS) { - cs_error(link->handle, RequestIRQ, i); + cs_error(link, RequestIRQ, i); link->irq.AssignedIRQ = 0; } - i = pcmcia_request_configuration(link->handle, &link->conf); + i = pcmcia_request_configuration(link, &link->conf); if (i != CS_SUCCESS) { - cs_error(link->handle, RequestConfiguration, i); + cs_error(link, RequestConfiguration, i); goto failed; } @@ -980,57 +962,28 @@ static void bluecard_config(dev_link_t *link) goto failed; strcpy(info->node.dev_name, info->hdev->name); - link->dev = &info->node; - link->state &= ~DEV_CONFIG_PENDING; + link->dev_node = &info->node; - return; + return 0; cs_failed: - cs_error(link->handle, last_fn, last_ret); + cs_error(link, last_fn, last_ret); failed: bluecard_release(link); + return -ENODEV; } -static void bluecard_release(dev_link_t *link) +static void bluecard_release(struct pcmcia_device *link) { bluecard_info_t *info = link->priv; - if (link->state & DEV_PRESENT) - bluecard_close(info); + bluecard_close(info); del_timer(&(info->timer)); - link->dev = NULL; - - pcmcia_release_configuration(link->handle); - pcmcia_release_io(link->handle, &link->io); - pcmcia_release_irq(link->handle, &link->irq); - - link->state &= ~DEV_CONFIG; -} - -static int bluecard_suspend(struct pcmcia_device *dev) -{ - dev_link_t *link = dev_to_instance(dev); - - link->state |= DEV_SUSPEND; - if (link->state & DEV_CONFIG) - pcmcia_release_configuration(link->handle); - - return 0; -} - -static int bluecard_resume(struct pcmcia_device *dev) -{ - dev_link_t *link = dev_to_instance(dev); - - link->state &= ~DEV_SUSPEND; - if (DEV_OK(link)) - pcmcia_request_configuration(link->handle, &link->conf); - - return 0; + pcmcia_disable_device(link); } static struct pcmcia_device_id bluecard_ids[] = { @@ -1046,11 +999,9 @@ static struct pcmcia_driver bluecard_driver = { .drv = { .name = "bluecard_cs", }, - .probe = bluecard_attach, + .probe = bluecard_probe, .remove = bluecard_detach, .id_table = bluecard_ids, - .suspend = bluecard_suspend, - .resume = bluecard_resume, }; static int __init init_bluecard_cs(void) diff --git a/drivers/bluetooth/bt3c_cs.c b/drivers/bluetooth/bt3c_cs.c index 7e21b1ff27c..b94ac2f9f7b 100644 --- a/drivers/bluetooth/bt3c_cs.c +++ b/drivers/bluetooth/bt3c_cs.c @@ -72,7 +72,7 @@ MODULE_LICENSE("GPL"); typedef struct bt3c_info_t { - dev_link_t link; + struct pcmcia_device *p_dev; dev_node_t node; struct hci_dev *hdev; @@ -88,8 +88,8 @@ typedef struct bt3c_info_t { } bt3c_info_t; -static void bt3c_config(dev_link_t *link); -static void bt3c_release(dev_link_t *link); +static int bt3c_config(struct pcmcia_device *link); +static void bt3c_release(struct pcmcia_device *link); static void bt3c_detach(struct pcmcia_device *p_dev); @@ -191,11 +191,11 @@ static void bt3c_write_wakeup(bt3c_info_t *info) return; do { - register unsigned int iobase = info->link.io.BasePort1; + register unsigned int iobase = info->p_dev->io.BasePort1; register struct sk_buff *skb; register int len; - if (!(info->link.state & DEV_PRESENT)) + if (!pcmcia_dev_present(info->p_dev)) break; @@ -229,7 +229,7 @@ static void bt3c_receive(bt3c_info_t *info) return; } - iobase = info->link.io.BasePort1; + iobase = info->p_dev->io.BasePort1; avail = bt3c_read(iobase, 0x7006); //printk("bt3c_cs: receiving %d bytes\n", avail); @@ -350,7 +350,7 @@ static irqreturn_t bt3c_interrupt(int irq, void *dev_inst, struct pt_regs *regs) return IRQ_NONE; } - iobase = info->link.io.BasePort1; + iobase = info->p_dev->io.BasePort1; spin_lock(&(info->lock)); @@ -481,7 +481,7 @@ static int bt3c_load_firmware(bt3c_info_t *info, unsigned char *firmware, int co unsigned int iobase, size, addr, fcs, tmp; int i, err = 0; - iobase = info->link.io.BasePort1; + iobase = info->p_dev->io.BasePort1; /* Reset */ bt3c_io_write(iobase, 0x8040, 0x0404); @@ -562,7 +562,6 @@ static int bt3c_open(bt3c_info_t *info) { const struct firmware *firmware; struct hci_dev *hdev; - client_handle_t handle; int err; spin_lock_init(&(info->lock)); @@ -594,10 +593,8 @@ static int bt3c_open(bt3c_info_t *info) hdev->owner = THIS_MODULE; - handle = info->link.handle; - /* Load firmware */ - err = request_firmware(&firmware, "BT3CPCC.bin", &handle_to_dev(handle)); + err = request_firmware(&firmware, "BT3CPCC.bin", &info->p_dev->dev); if (err < 0) { BT_ERR("Firmware request failed"); goto error; @@ -648,17 +645,16 @@ static int bt3c_close(bt3c_info_t *info) return 0; } -static int bt3c_attach(struct pcmcia_device *p_dev) +static int bt3c_probe(struct pcmcia_device *link) { bt3c_info_t *info; - dev_link_t *link; /* Create new info device */ info = kzalloc(sizeof(*info), GFP_KERNEL); if (!info) return -ENOMEM; - link = &info->link; + info->p_dev = link; link->priv = info; link->io.Attributes1 = IO_DATA_PATH_WIDTH_8; @@ -670,31 +666,21 @@ static int bt3c_attach(struct pcmcia_device *p_dev) link->irq.Instance = info; link->conf.Attributes = CONF_ENABLE_IRQ; - link->conf.Vcc = 50; link->conf.IntType = INT_MEMORY_AND_IO; - link->handle = p_dev; - p_dev->instance = link; - - link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; - bt3c_config(link); - - return 0; + return bt3c_config(link); } -static void bt3c_detach(struct pcmcia_device *p_dev) +static void bt3c_detach(struct pcmcia_device *link) { - dev_link_t *link = dev_to_instance(p_dev); bt3c_info_t *info = link->priv; - if (link->state & DEV_CONFIG) - bt3c_release(link); - + bt3c_release(link); kfree(info); } -static int get_tuple(client_handle_t handle, tuple_t *tuple, cisparse_t *parse) +static int get_tuple(struct pcmcia_device *handle, tuple_t *tuple, cisparse_t *parse) { int i; @@ -705,30 +691,28 @@ static int get_tuple(client_handle_t handle, tuple_t *tuple, cisparse_t *parse) return pcmcia_parse_tuple(handle, tuple, parse); } -static int first_tuple(client_handle_t handle, tuple_t *tuple, cisparse_t *parse) +static int first_tuple(struct pcmcia_device *handle, tuple_t *tuple, cisparse_t *parse) { if (pcmcia_get_first_tuple(handle, tuple) != CS_SUCCESS) return CS_NO_MORE_ITEMS; return get_tuple(handle, tuple, parse); } -static int next_tuple(client_handle_t handle, tuple_t *tuple, cisparse_t *parse) +static int next_tuple(struct pcmcia_device *handle, tuple_t *tuple, cisparse_t *parse) { if (pcmcia_get_next_tuple(handle, tuple) != CS_SUCCESS) return CS_NO_MORE_ITEMS; return get_tuple(handle, tuple, parse); } -static void bt3c_config(dev_link_t *link) +static int bt3c_config(struct pcmcia_device *link) { static kio_addr_t base[5] = { 0x3f8, 0x2f8, 0x3e8, 0x2e8, 0x0 }; - client_handle_t handle = link->handle; bt3c_info_t *info = link->priv; tuple_t tuple; u_short buf[256]; cisparse_t parse; cistpl_cftable_entry_t *cf = &parse.cftable_entry; - config_info_t config; int i, j, try, last_ret, last_fn; tuple.TupleData = (cisdata_t *)buf; @@ -738,7 +722,7 @@ static void bt3c_config(dev_link_t *link) /* Get configuration register information */ tuple.DesiredTuple = CISTPL_CONFIG; - last_ret = first_tuple(handle, &tuple, &parse); + last_ret = first_tuple(link, &tuple, &parse); if (last_ret != CS_SUCCESS) { last_fn = ParseTuple; goto cs_failed; @@ -746,11 +730,6 @@ static void bt3c_config(dev_link_t *link) link->conf.ConfigBase = parse.config.base; link->conf.Present = parse.config.rmask[0]; - /* Configure card */ - link->state |= DEV_CONFIG; - i = pcmcia_get_configuration_info(handle, &config); - link->conf.Vcc = config.Vcc; - /* First pass: look for a config entry that looks normal. */ tuple.TupleData = (cisdata_t *)buf; tuple.TupleOffset = 0; @@ -759,59 +738,59 @@ static void bt3c_config(dev_link_t *link) tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; /* Two tries: without IO aliases, then with aliases */ for (try = 0; try < 2; try++) { - i = first_tuple(handle, &tuple, &parse); + i = first_tuple(link, &tuple, &parse); while (i != CS_NO_MORE_ITEMS) { if (i != CS_SUCCESS) goto next_entry; if (cf->vpp1.present & (1 << CISTPL_POWER_VNOM)) - link->conf.Vpp1 = link->conf.Vpp2 = cf->vpp1.param[CISTPL_POWER_VNOM] / 10000; + link->conf.Vpp = cf->vpp1.param[CISTPL_POWER_VNOM] / 10000; if ((cf->io.nwin > 0) && (cf->io.win[0].len == 8) && (cf->io.win[0].base != 0)) { link->conf.ConfigIndex = cf->index; link->io.BasePort1 = cf->io.win[0].base; link->io.IOAddrLines = (try == 0) ? 16 : cf->io.flags & CISTPL_IO_LINES_MASK; - i = pcmcia_request_io(link->handle, &link->io); + i = pcmcia_request_io(link, &link->io); if (i == CS_SUCCESS) goto found_port; } next_entry: - i = next_tuple(handle, &tuple, &parse); + i = next_tuple(link, &tuple, &parse); } } /* Second pass: try to find an entry that isn't picky about its base address, then try to grab any standard serial port address, and finally try to get any free port. */ - i = first_tuple(handle, &tuple, &parse); + i = first_tuple(link, &tuple, &parse); while (i != CS_NO_MORE_ITEMS) { if ((i == CS_SUCCESS) && (cf->io.nwin > 0) && ((cf->io.flags & CISTPL_IO_LINES_MASK) <= 3)) { link->conf.ConfigIndex = cf->index; for (j = 0; j < 5; j++) { link->io.BasePort1 = base[j]; link->io.IOAddrLines = base[j] ? 16 : 3; - i = pcmcia_request_io(link->handle, &link->io); + i = pcmcia_request_io(link, &link->io); if (i == CS_SUCCESS) goto found_port; } } - i = next_tuple(handle, &tuple, &parse); + i = next_tuple(link, &tuple, &parse); } found_port: if (i != CS_SUCCESS) { BT_ERR("No usable port range found"); - cs_error(link->handle, RequestIO, i); + cs_error(link, RequestIO, i); goto failed; } - i = pcmcia_request_irq(link->handle, &link->irq); + i = pcmcia_request_irq(link, &link->irq); if (i != CS_SUCCESS) { - cs_error(link->handle, RequestIRQ, i); + cs_error(link, RequestIRQ, i); link->irq.AssignedIRQ = 0; } - i = pcmcia_request_configuration(link->handle, &link->conf); + i = pcmcia_request_configuration(link, &link->conf); if (i != CS_SUCCESS) { - cs_error(link->handle, RequestConfiguration, i); + cs_error(link, RequestConfiguration, i); goto failed; } @@ -819,55 +798,26 @@ found_port: goto failed; strcpy(info->node.dev_name, info->hdev->name); - link->dev = &info->node; - link->state &= ~DEV_CONFIG_PENDING; + link->dev_node = &info->node; - return; + return 0; cs_failed: - cs_error(link->handle, last_fn, last_ret); + cs_error(link, last_fn, last_ret); failed: bt3c_release(link); + return -ENODEV; } -static void bt3c_release(dev_link_t *link) +static void bt3c_release(struct pcmcia_device *link) { bt3c_info_t *info = link->priv; - if (link->state & DEV_PRESENT) - bt3c_close(info); - - link->dev = NULL; - - pcmcia_release_configuration(link->handle); - pcmcia_release_io(link->handle, &link->io); - pcmcia_release_irq(link->handle, &link->irq); - - link->state &= ~DEV_CONFIG; -} - -static int bt3c_suspend(struct pcmcia_device *dev) -{ - dev_link_t *link = dev_to_instance(dev); + bt3c_close(info); - link->state |= DEV_SUSPEND; - if (link->state & DEV_CONFIG) - pcmcia_release_configuration(link->handle); - - return 0; -} - -static int bt3c_resume(struct pcmcia_device *dev) -{ - dev_link_t *link = dev_to_instance(dev); - - link->state &= ~DEV_SUSPEND; - if (DEV_OK(link)) - pcmcia_request_configuration(link->handle, &link->conf); - - return 0; + pcmcia_disable_device(link); } @@ -882,11 +832,9 @@ static struct pcmcia_driver bt3c_driver = { .drv = { .name = "bt3c_cs", }, - .probe = bt3c_attach, + .probe = bt3c_probe, .remove = bt3c_detach, .id_table = bt3c_ids, - .suspend = bt3c_suspend, - .resume = bt3c_resume, }; static int __init init_bt3c_cs(void) diff --git a/drivers/bluetooth/btuart_cs.c b/drivers/bluetooth/btuart_cs.c index 7b4bff4cfa2..9ce4c93467e 100644 --- a/drivers/bluetooth/btuart_cs.c +++ b/drivers/bluetooth/btuart_cs.c @@ -68,7 +68,7 @@ MODULE_LICENSE("GPL"); typedef struct btuart_info_t { - dev_link_t link; + struct pcmcia_device *p_dev; dev_node_t node; struct hci_dev *hdev; @@ -84,8 +84,8 @@ typedef struct btuart_info_t { } btuart_info_t; -static void btuart_config(dev_link_t *link); -static void btuart_release(dev_link_t *link); +static int btuart_config(struct pcmcia_device *link); +static void btuart_release(struct pcmcia_device *link); static void btuart_detach(struct pcmcia_device *p_dev); @@ -146,13 +146,13 @@ static void btuart_write_wakeup(btuart_info_t *info) } do { - register unsigned int iobase = info->link.io.BasePort1; + register unsigned int iobase = info->p_dev->io.BasePort1; register struct sk_buff *skb; register int len; clear_bit(XMIT_WAKEUP, &(info->tx_state)); - if (!(info->link.state & DEV_PRESENT)) + if (!pcmcia_dev_present(info->p_dev)) return; if (!(skb = skb_dequeue(&(info->txq)))) @@ -187,7 +187,7 @@ static void btuart_receive(btuart_info_t *info) return; } - iobase = info->link.io.BasePort1; + iobase = info->p_dev->io.BasePort1; do { info->hdev->stat.byte_rx++; @@ -301,7 +301,7 @@ static irqreturn_t btuart_interrupt(int irq, void *dev_inst, struct pt_regs *reg return IRQ_NONE; } - iobase = info->link.io.BasePort1; + iobase = info->p_dev->io.BasePort1; spin_lock(&(info->lock)); @@ -357,7 +357,7 @@ static void btuart_change_speed(btuart_info_t *info, unsigned int speed) return; } - iobase = info->link.io.BasePort1; + iobase = info->p_dev->io.BasePort1; spin_lock_irqsave(&(info->lock), flags); @@ -481,7 +481,7 @@ static int btuart_hci_ioctl(struct hci_dev *hdev, unsigned int cmd, unsigned lon static int btuart_open(btuart_info_t *info) { unsigned long flags; - unsigned int iobase = info->link.io.BasePort1; + unsigned int iobase = info->p_dev->io.BasePort1; struct hci_dev *hdev; spin_lock_init(&(info->lock)); @@ -550,7 +550,7 @@ static int btuart_open(btuart_info_t *info) static int btuart_close(btuart_info_t *info) { unsigned long flags; - unsigned int iobase = info->link.io.BasePort1; + unsigned int iobase = info->p_dev->io.BasePort1; struct hci_dev *hdev = info->hdev; if (!hdev) @@ -576,17 +576,16 @@ static int btuart_close(btuart_info_t *info) return 0; } -static int btuart_attach(struct pcmcia_device *p_dev) +static int btuart_probe(struct pcmcia_device *link) { btuart_info_t *info; - dev_link_t *link; /* Create new info device */ info = kzalloc(sizeof(*info), GFP_KERNEL); if (!info) return -ENOMEM; - link = &info->link; + info->p_dev = link; link->priv = info; link->io.Attributes1 = IO_DATA_PATH_WIDTH_8; @@ -598,31 +597,21 @@ static int btuart_attach(struct pcmcia_device *p_dev) link->irq.Instance = info; link->conf.Attributes = CONF_ENABLE_IRQ; - link->conf.Vcc = 50; link->conf.IntType = INT_MEMORY_AND_IO; - link->handle = p_dev; - p_dev->instance = link; - - link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; - btuart_config(link); - - return 0; + return btuart_config(link); } -static void btuart_detach(struct pcmcia_device *p_dev) +static void btuart_detach(struct pcmcia_device *link) { - dev_link_t *link = dev_to_instance(p_dev); btuart_info_t *info = link->priv; - if (link->state & DEV_CONFIG) - btuart_release(link); - + btuart_release(link); kfree(info); } -static int get_tuple(client_handle_t handle, tuple_t *tuple, cisparse_t *parse) +static int get_tuple(struct pcmcia_device *handle, tuple_t *tuple, cisparse_t *parse) { int i; @@ -633,30 +622,28 @@ static int get_tuple(client_handle_t handle, tuple_t *tuple, cisparse_t *parse) return pcmcia_parse_tuple(handle, tuple, parse); } -static int first_tuple(client_handle_t handle, tuple_t *tuple, cisparse_t *parse) +static int first_tuple(struct pcmcia_device *handle, tuple_t *tuple, cisparse_t *parse) { if (pcmcia_get_first_tuple(handle, tuple) != CS_SUCCESS) return CS_NO_MORE_ITEMS; return get_tuple(handle, tuple, parse); } -static int next_tuple(client_handle_t handle, tuple_t *tuple, cisparse_t *parse) +static int next_tuple(struct pcmcia_device *handle, tuple_t *tuple, cisparse_t *parse) { if (pcmcia_get_next_tuple(handle, tuple) != CS_SUCCESS) return CS_NO_MORE_ITEMS; return get_tuple(handle, tuple, parse); } -static void btuart_config(dev_link_t *link) +static int btuart_config(struct pcmcia_device *link) { static kio_addr_t base[5] = { 0x3f8, 0x2f8, 0x3e8, 0x2e8, 0x0 }; - client_handle_t handle = link->handle; btuart_info_t *info = link->priv; tuple_t tuple; u_short buf[256]; cisparse_t parse; cistpl_cftable_entry_t *cf = &parse.cftable_entry; - config_info_t config; int i, j, try, last_ret, last_fn; tuple.TupleData = (cisdata_t *)buf; @@ -666,7 +653,7 @@ static void btuart_config(dev_link_t *link) /* Get configuration register information */ tuple.DesiredTuple = CISTPL_CONFIG; - last_ret = first_tuple(handle, &tuple, &parse); + last_ret = first_tuple(link, &tuple, &parse); if (last_ret != CS_SUCCESS) { last_fn = ParseTuple; goto cs_failed; @@ -674,11 +661,6 @@ static void btuart_config(dev_link_t *link) link->conf.ConfigBase = parse.config.base; link->conf.Present = parse.config.rmask[0]; - /* Configure card */ - link->state |= DEV_CONFIG; - i = pcmcia_get_configuration_info(handle, &config); - link->conf.Vcc = config.Vcc; - /* First pass: look for a config entry that looks normal. */ tuple.TupleData = (cisdata_t *) buf; tuple.TupleOffset = 0; @@ -687,29 +669,29 @@ static void btuart_config(dev_link_t *link) tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; /* Two tries: without IO aliases, then with aliases */ for (try = 0; try < 2; try++) { - i = first_tuple(handle, &tuple, &parse); + i = first_tuple(link, &tuple, &parse); while (i != CS_NO_MORE_ITEMS) { if (i != CS_SUCCESS) goto next_entry; if (cf->vpp1.present & (1 << CISTPL_POWER_VNOM)) - link->conf.Vpp1 = link->conf.Vpp2 = cf->vpp1.param[CISTPL_POWER_VNOM] / 10000; + link->conf.Vpp = cf->vpp1.param[CISTPL_POWER_VNOM] / 10000; if ((cf->io.nwin > 0) && (cf->io.win[0].len == 8) && (cf->io.win[0].base != 0)) { link->conf.ConfigIndex = cf->index; link->io.BasePort1 = cf->io.win[0].base; link->io.IOAddrLines = (try == 0) ? 16 : cf->io.flags & CISTPL_IO_LINES_MASK; - i = pcmcia_request_io(link->handle, &link->io); + i = pcmcia_request_io(link, &link->io); if (i == CS_SUCCESS) goto found_port; } next_entry: - i = next_tuple(handle, &tuple, &parse); + i = next_tuple(link, &tuple, &parse); } } /* Second pass: try to find an entry that isn't picky about its base address, then try to grab any standard serial port address, and finally try to get any free port. */ - i = first_tuple(handle, &tuple, &parse); + i = first_tuple(link, &tuple, &parse); while (i != CS_NO_MORE_ITEMS) { if ((i == CS_SUCCESS) && (cf->io.nwin > 0) && ((cf->io.flags & CISTPL_IO_LINES_MASK) <= 3)) { @@ -717,30 +699,30 @@ next_entry: for (j = 0; j < 5; j++) { link->io.BasePort1 = base[j]; link->io.IOAddrLines = base[j] ? 16 : 3; - i = pcmcia_request_io(link->handle, &link->io); + i = pcmcia_request_io(link, &link->io); if (i == CS_SUCCESS) goto found_port; } } - i = next_tuple(handle, &tuple, &parse); + i = next_tuple(link, &tuple, &parse); } found_port: if (i != CS_SUCCESS) { BT_ERR("No usable port range found"); - cs_error(link->handle, RequestIO, i); + cs_error(link, RequestIO, i); goto failed; } - i = pcmcia_request_irq(link->handle, &link->irq); + i = pcmcia_request_irq(link, &link->irq); if (i != CS_SUCCESS) { - cs_error(link->handle, RequestIRQ, i); + cs_error(link, RequestIRQ, i); link->irq.AssignedIRQ = 0; } - i = pcmcia_request_configuration(link->handle, &link->conf); + i = pcmcia_request_configuration(link, &link->conf); if (i != CS_SUCCESS) { - cs_error(link->handle, RequestConfiguration, i); + cs_error(link, RequestConfiguration, i); goto failed; } @@ -748,58 +730,28 @@ found_port: goto failed; strcpy(info->node.dev_name, info->hdev->name); - link->dev = &info->node; - link->state &= ~DEV_CONFIG_PENDING; + link->dev_node = &info->node; - return; + return 0; cs_failed: - cs_error(link->handle, last_fn, last_ret); + cs_error(link, last_fn, last_ret); failed: btuart_release(link); + return -ENODEV; } -static void btuart_release(dev_link_t *link) +static void btuart_release(struct pcmcia_device *link) { btuart_info_t *info = link->priv; - if (link->state & DEV_PRESENT) - btuart_close(info); - - link->dev = NULL; - - pcmcia_release_configuration(link->handle); - pcmcia_release_io(link->handle, &link->io); - pcmcia_release_irq(link->handle, &link->irq); - - link->state &= ~DEV_CONFIG; -} - -static int btuart_suspend(struct pcmcia_device *dev) -{ - dev_link_t *link = dev_to_instance(dev); - - link->state |= DEV_SUSPEND; - if (link->state & DEV_CONFIG) - pcmcia_release_configuration(link->handle); + btuart_close(info); - return 0; + pcmcia_disable_device(link); } -static int btuart_resume(struct pcmcia_device *dev) -{ - dev_link_t *link = dev_to_instance(dev); - - link->state &= ~DEV_SUSPEND; - if (DEV_OK(link)) - pcmcia_request_configuration(link->handle, &link->conf); - - return 0; -} - - static struct pcmcia_device_id btuart_ids[] = { /* don't use this driver. Use serial_cs + hci_uart instead */ PCMCIA_DEVICE_NULL @@ -811,11 +763,9 @@ static struct pcmcia_driver btuart_driver = { .drv = { .name = "btuart_cs", }, - .probe = btuart_attach, + .probe = btuart_probe, .remove = btuart_detach, .id_table = btuart_ids, - .suspend = btuart_suspend, - .resume = btuart_resume, }; static int __init init_btuart_cs(void) diff --git a/drivers/bluetooth/dtl1_cs.c b/drivers/bluetooth/dtl1_cs.c index 0449bc45ae5..a71a240611e 100644 --- a/drivers/bluetooth/dtl1_cs.c +++ b/drivers/bluetooth/dtl1_cs.c @@ -68,7 +68,7 @@ MODULE_LICENSE("GPL"); typedef struct dtl1_info_t { - dev_link_t link; + struct pcmcia_device *p_dev; dev_node_t node; struct hci_dev *hdev; @@ -87,8 +87,8 @@ typedef struct dtl1_info_t { } dtl1_info_t; -static void dtl1_config(dev_link_t *link); -static void dtl1_release(dev_link_t *link); +static int dtl1_config(struct pcmcia_device *link); +static void dtl1_release(struct pcmcia_device *link); static void dtl1_detach(struct pcmcia_device *p_dev); @@ -153,13 +153,13 @@ static void dtl1_write_wakeup(dtl1_info_t *info) } do { - register unsigned int iobase = info->link.io.BasePort1; + register unsigned int iobase = info->p_dev->io.BasePort1; register struct sk_buff *skb; register int len; clear_bit(XMIT_WAKEUP, &(info->tx_state)); - if (!(info->link.state & DEV_PRESENT)) + if (!pcmcia_dev_present(info->p_dev)) return; if (!(skb = skb_dequeue(&(info->txq)))) @@ -218,7 +218,7 @@ static void dtl1_receive(dtl1_info_t *info) return; } - iobase = info->link.io.BasePort1; + iobase = info->p_dev->io.BasePort1; do { info->hdev->stat.byte_rx++; @@ -305,7 +305,7 @@ static irqreturn_t dtl1_interrupt(int irq, void *dev_inst, struct pt_regs *regs) return IRQ_NONE; } - iobase = info->link.io.BasePort1; + iobase = info->p_dev->io.BasePort1; spin_lock(&(info->lock)); @@ -458,7 +458,7 @@ static int dtl1_hci_ioctl(struct hci_dev *hdev, unsigned int cmd, unsigned long static int dtl1_open(dtl1_info_t *info) { unsigned long flags; - unsigned int iobase = info->link.io.BasePort1; + unsigned int iobase = info->p_dev->io.BasePort1; struct hci_dev *hdev; spin_lock_init(&(info->lock)); @@ -504,7 +504,7 @@ static int dtl1_open(dtl1_info_t *info) outb(UART_LCR_WLEN8, iobase + UART_LCR); /* Reset DLAB */ outb((UART_MCR_DTR | UART_MCR_RTS | UART_MCR_OUT2), iobase + UART_MCR); - info->ri_latch = inb(info->link.io.BasePort1 + UART_MSR) & UART_MSR_RI; + info->ri_latch = inb(info->p_dev->io.BasePort1 + UART_MSR) & UART_MSR_RI; /* Turn on interrupts */ outb(UART_IER_RLSI | UART_IER_RDI | UART_IER_THRI, iobase + UART_IER); @@ -529,7 +529,7 @@ static int dtl1_open(dtl1_info_t *info) static int dtl1_close(dtl1_info_t *info) { unsigned long flags; - unsigned int iobase = info->link.io.BasePort1; + unsigned int iobase = info->p_dev->io.BasePort1; struct hci_dev *hdev = info->hdev; if (!hdev) @@ -555,17 +555,16 @@ static int dtl1_close(dtl1_info_t *info) return 0; } -static int dtl1_attach(struct pcmcia_device *p_dev) +static int dtl1_probe(struct pcmcia_device *link) { dtl1_info_t *info; - dev_link_t *link; /* Create new info device */ info = kzalloc(sizeof(*info), GFP_KERNEL); if (!info) return -ENOMEM; - link = &info->link; + info->p_dev = link; link->priv = info; link->io.Attributes1 = IO_DATA_PATH_WIDTH_8; @@ -577,31 +576,22 @@ static int dtl1_attach(struct pcmcia_device *p_dev) link->irq.Instance = info; link->conf.Attributes = CONF_ENABLE_IRQ; - link->conf.Vcc = 50; link->conf.IntType = INT_MEMORY_AND_IO; - link->handle = p_dev; - p_dev->instance = link; - - link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; - dtl1_config(link); - - return 0; + return dtl1_config(link); } -static void dtl1_detach(struct pcmcia_device *p_dev) +static void dtl1_detach(struct pcmcia_device *link) { - dev_link_t *link = dev_to_instance(p_dev); dtl1_info_t *info = link->priv; - if (link->state & DEV_CONFIG) - dtl1_release(link); + dtl1_release(link); kfree(info); } -static int get_tuple(client_handle_t handle, tuple_t *tuple, cisparse_t *parse) +static int get_tuple(struct pcmcia_device *handle, tuple_t *tuple, cisparse_t *parse) { int i; @@ -612,29 +602,27 @@ static int get_tuple(client_handle_t handle, tuple_t *tuple, cisparse_t *parse) return pcmcia_parse_tuple(handle, tuple, parse); } -static int first_tuple(client_handle_t handle, tuple_t *tuple, cisparse_t *parse) +static int first_tuple(struct pcmcia_device *handle, tuple_t *tuple, cisparse_t *parse) { if (pcmcia_get_first_tuple(handle, tuple) != CS_SUCCESS) return CS_NO_MORE_ITEMS; return get_tuple(handle, tuple, parse); } -static int next_tuple(client_handle_t handle, tuple_t *tuple, cisparse_t *parse) +static int next_tuple(struct pcmcia_device *handle, tuple_t *tuple, cisparse_t *parse) { if (pcmcia_get_next_tuple(handle, tuple) != CS_SUCCESS) return CS_NO_MORE_ITEMS; return get_tuple(handle, tuple, parse); } -static void dtl1_config(dev_link_t *link) +static int dtl1_config(struct pcmcia_device *link) { - client_handle_t handle = link->handle; dtl1_info_t *info = link->priv; tuple_t tuple; u_short buf[256]; cisparse_t parse; cistpl_cftable_entry_t *cf = &parse.cftable_entry; - config_info_t config; int i, last_ret, last_fn; tuple.TupleData = (cisdata_t *)buf; @@ -644,7 +632,7 @@ static void dtl1_config(dev_link_t *link) /* Get configuration register information */ tuple.DesiredTuple = CISTPL_CONFIG; - last_ret = first_tuple(handle, &tuple, &parse); + last_ret = first_tuple(link, &tuple, &parse); if (last_ret != CS_SUCCESS) { last_fn = ParseTuple; goto cs_failed; @@ -652,11 +640,6 @@ static void dtl1_config(dev_link_t *link) link->conf.ConfigBase = parse.config.base; link->conf.Present = parse.config.rmask[0]; - /* Configure card */ - link->state |= DEV_CONFIG; - i = pcmcia_get_configuration_info(handle, &config); - link->conf.Vcc = config.Vcc; - tuple.TupleData = (cisdata_t *)buf; tuple.TupleOffset = 0; tuple.TupleDataMax = 255; @@ -665,34 +648,34 @@ static void dtl1_config(dev_link_t *link) /* Look for a generic full-sized window */ link->io.NumPorts1 = 8; - i = first_tuple(handle, &tuple, &parse); + i = first_tuple(link, &tuple, &parse); while (i != CS_NO_MORE_ITEMS) { if ((i == CS_SUCCESS) && (cf->io.nwin == 1) && (cf->io.win[0].len > 8)) { link->conf.ConfigIndex = cf->index; link->io.BasePort1 = cf->io.win[0].base; link->io.NumPorts1 = cf->io.win[0].len; /*yo */ link->io.IOAddrLines = cf->io.flags & CISTPL_IO_LINES_MASK; - i = pcmcia_request_io(link->handle, &link->io); + i = pcmcia_request_io(link, &link->io); if (i == CS_SUCCESS) break; } - i = next_tuple(handle, &tuple, &parse); + i = next_tuple(link, &tuple, &parse); } if (i != CS_SUCCESS) { - cs_error(link->handle, RequestIO, i); + cs_error(link, RequestIO, i); goto failed; } - i = pcmcia_request_irq(link->handle, &link->irq); + i = pcmcia_request_irq(link, &link->irq); if (i != CS_SUCCESS) { - cs_error(link->handle, RequestIRQ, i); + cs_error(link, RequestIRQ, i); link->irq.AssignedIRQ = 0; } - i = pcmcia_request_configuration(link->handle, &link->conf); + i = pcmcia_request_configuration(link, &link->conf); if (i != CS_SUCCESS) { - cs_error(link->handle, RequestConfiguration, i); + cs_error(link, RequestConfiguration, i); goto failed; } @@ -700,55 +683,26 @@ static void dtl1_config(dev_link_t *link) goto failed; strcpy(info->node.dev_name, info->hdev->name); - link->dev = &info->node; - link->state &= ~DEV_CONFIG_PENDING; + link->dev_node = &info->node; - return; + return 0; cs_failed: - cs_error(link->handle, last_fn, last_ret); + cs_error(link, last_fn, last_ret); failed: dtl1_release(link); + return -ENODEV; } -static void dtl1_release(dev_link_t *link) +static void dtl1_release(struct pcmcia_device *link) { dtl1_info_t *info = link->priv; - if (link->state & DEV_PRESENT) - dtl1_close(info); - - link->dev = NULL; - - pcmcia_release_configuration(link->handle); - pcmcia_release_io(link->handle, &link->io); - pcmcia_release_irq(link->handle, &link->irq); - - link->state &= ~DEV_CONFIG; -} - -static int dtl1_suspend(struct pcmcia_device *dev) -{ - dev_link_t *link = dev_to_instance(dev); - - link->state |= DEV_SUSPEND; - if (link->state & DEV_CONFIG) - pcmcia_release_configuration(link->handle); - - return 0; -} - -static int dtl1_resume(struct pcmcia_device *dev) -{ - dev_link_t *link = dev_to_instance(dev); + dtl1_close(info); - link->state &= ~DEV_SUSPEND; - if (DEV_OK(link)) - pcmcia_request_configuration(link->handle, &link->conf); - - return 0; + pcmcia_disable_device(link); } @@ -765,11 +719,9 @@ static struct pcmcia_driver dtl1_driver = { .drv = { .name = "dtl1_cs", }, - .probe = dtl1_attach, + .probe = dtl1_probe, .remove = dtl1_detach, .id_table = dtl1_ids, - .suspend = dtl1_suspend, - .resume = dtl1_resume, }; static int __init init_dtl1_cs(void) diff --git a/drivers/char/hvcs.c b/drivers/char/hvcs.c index 327b00c3c45..8d97b391129 100644 --- a/drivers/char/hvcs.c +++ b/drivers/char/hvcs.c @@ -904,7 +904,7 @@ static int hvcs_enable_device(struct hvcs_struct *hvcsd, uint32_t unit_address, * It is possible the vty-server was removed after the irq was * requested but before we have time to enable interrupts. */ - if (vio_enable_interrupts(vdev) == H_Success) + if (vio_enable_interrupts(vdev) == H_SUCCESS) return 0; else { printk(KERN_ERR "HVCS: int enable failed for" diff --git a/drivers/char/ipmi/ipmi_devintf.c b/drivers/char/ipmi/ipmi_devintf.c index 932feedda26..e1c95374984 100644 --- a/drivers/char/ipmi/ipmi_devintf.c +++ b/drivers/char/ipmi/ipmi_devintf.c @@ -42,7 +42,7 @@ #include <linux/slab.h> #include <linux/devfs_fs_kernel.h> #include <linux/ipmi.h> -#include <asm/semaphore.h> +#include <linux/mutex.h> #include <linux/init.h> #include <linux/device.h> #include <linux/compat.h> @@ -55,7 +55,7 @@ struct ipmi_file_private struct file *file; struct fasync_struct *fasync_queue; wait_queue_head_t wait; - struct semaphore recv_sem; + struct mutex recv_mutex; int default_retries; unsigned int default_retry_time_ms; }; @@ -141,7 +141,7 @@ static int ipmi_open(struct inode *inode, struct file *file) INIT_LIST_HEAD(&(priv->recv_msgs)); init_waitqueue_head(&priv->wait); priv->fasync_queue = NULL; - sema_init(&(priv->recv_sem), 1); + mutex_init(&priv->recv_mutex); /* Use the low-level defaults. */ priv->default_retries = -1; @@ -285,15 +285,15 @@ static int ipmi_ioctl(struct inode *inode, break; } - /* We claim a semaphore because we don't want two + /* We claim a mutex because we don't want two users getting something from the queue at a time. Since we have to release the spinlock before we can copy the data to the user, it's possible another user will grab something from the queue, too. Then the messages might get out of order if something fails and the message gets put back onto the - queue. This semaphore prevents that problem. */ - down(&(priv->recv_sem)); + queue. This mutex prevents that problem. */ + mutex_lock(&priv->recv_mutex); /* Grab the message off the list. */ spin_lock_irqsave(&(priv->recv_msg_lock), flags); @@ -352,7 +352,7 @@ static int ipmi_ioctl(struct inode *inode, goto recv_putback_on_err; } - up(&(priv->recv_sem)); + mutex_unlock(&priv->recv_mutex); ipmi_free_recv_msg(msg); break; @@ -362,11 +362,11 @@ static int ipmi_ioctl(struct inode *inode, spin_lock_irqsave(&(priv->recv_msg_lock), flags); list_add(entry, &(priv->recv_msgs)); spin_unlock_irqrestore(&(priv->recv_msg_lock), flags); - up(&(priv->recv_sem)); + mutex_unlock(&priv->recv_mutex); break; recv_err: - up(&(priv->recv_sem)); + mutex_unlock(&priv->recv_mutex); break; } diff --git a/drivers/char/ipmi/ipmi_kcs_sm.c b/drivers/char/ipmi/ipmi_kcs_sm.c index da1554194d3..2062675f9e9 100644 --- a/drivers/char/ipmi/ipmi_kcs_sm.c +++ b/drivers/char/ipmi/ipmi_kcs_sm.c @@ -227,7 +227,7 @@ static inline int check_ibf(struct si_sm_data *kcs, unsigned char status, static inline int check_obf(struct si_sm_data *kcs, unsigned char status, long time) { - if (! GET_STATUS_OBF(status)) { + if (!GET_STATUS_OBF(status)) { kcs->obf_timeout -= time; if (kcs->obf_timeout < 0) { start_error_recovery(kcs, "OBF not ready in time"); @@ -407,7 +407,7 @@ static enum si_sm_result kcs_event(struct si_sm_data *kcs, long time) } if (state == KCS_READ_STATE) { - if (! check_obf(kcs, status, time)) + if (!check_obf(kcs, status, time)) return SI_SM_CALL_WITH_DELAY; read_next_byte(kcs); } else { @@ -447,7 +447,7 @@ static enum si_sm_result kcs_event(struct si_sm_data *kcs, long time) "Not in read state for error2"); break; } - if (! check_obf(kcs, status, time)) + if (!check_obf(kcs, status, time)) return SI_SM_CALL_WITH_DELAY; clear_obf(kcs, status); @@ -462,7 +462,7 @@ static enum si_sm_result kcs_event(struct si_sm_data *kcs, long time) break; } - if (! check_obf(kcs, status, time)) + if (!check_obf(kcs, status, time)) return SI_SM_CALL_WITH_DELAY; clear_obf(kcs, status); diff --git a/drivers/char/ipmi/ipmi_msghandler.c b/drivers/char/ipmi/ipmi_msghandler.c index 40eb005b9d7..0ded046d5aa 100644 --- a/drivers/char/ipmi/ipmi_msghandler.c +++ b/drivers/char/ipmi/ipmi_msghandler.c @@ -38,6 +38,7 @@ #include <linux/sched.h> #include <linux/poll.h> #include <linux/spinlock.h> +#include <linux/mutex.h> #include <linux/slab.h> #include <linux/ipmi.h> #include <linux/ipmi_smi.h> @@ -234,7 +235,7 @@ struct ipmi_smi /* The list of command receivers that are registered for commands on this interface. */ - struct semaphore cmd_rcvrs_lock; + struct mutex cmd_rcvrs_mutex; struct list_head cmd_rcvrs; /* Events that were queues because no one was there to receive @@ -387,10 +388,10 @@ static void clean_up_interface_data(ipmi_smi_t intf) /* Wholesale remove all the entries from the list in the * interface and wait for RCU to know that none are in use. */ - down(&intf->cmd_rcvrs_lock); + mutex_lock(&intf->cmd_rcvrs_mutex); list_add_rcu(&list, &intf->cmd_rcvrs); list_del_rcu(&intf->cmd_rcvrs); - up(&intf->cmd_rcvrs_lock); + mutex_unlock(&intf->cmd_rcvrs_mutex); synchronize_rcu(); list_for_each_entry_safe(rcvr, rcvr2, &list, link) @@ -557,7 +558,7 @@ unsigned int ipmi_addr_length(int addr_type) static void deliver_response(struct ipmi_recv_msg *msg) { - if (! msg->user) { + if (!msg->user) { ipmi_smi_t intf = msg->user_msg_data; unsigned long flags; @@ -598,11 +599,11 @@ static int intf_next_seq(ipmi_smi_t intf, (i+1)%IPMI_IPMB_NUM_SEQ != intf->curr_seq; i = (i+1)%IPMI_IPMB_NUM_SEQ) { - if (! intf->seq_table[i].inuse) + if (!intf->seq_table[i].inuse) break; } - if (! intf->seq_table[i].inuse) { + if (!intf->seq_table[i].inuse) { intf->seq_table[i].recv_msg = recv_msg; /* Start with the maximum timeout, when the send response @@ -763,7 +764,7 @@ int ipmi_create_user(unsigned int if_num, } new_user = kmalloc(sizeof(*new_user), GFP_KERNEL); - if (! new_user) + if (!new_user) return -ENOMEM; spin_lock_irqsave(&interfaces_lock, flags); @@ -819,14 +820,13 @@ static void free_user(struct kref *ref) int ipmi_destroy_user(ipmi_user_t user) { - int rv = -ENODEV; ipmi_smi_t intf = user->intf; int i; unsigned long flags; struct cmd_rcvr *rcvr; struct cmd_rcvr *rcvrs = NULL; - user->valid = 1; + user->valid = 0; /* Remove the user from the interface's sequence table. */ spin_lock_irqsave(&intf->seq_lock, flags); @@ -847,7 +847,7 @@ int ipmi_destroy_user(ipmi_user_t user) * since other things may be using it till we do * synchronize_rcu()) then free everything in that list. */ - down(&intf->cmd_rcvrs_lock); + mutex_lock(&intf->cmd_rcvrs_mutex); list_for_each_entry_rcu(rcvr, &intf->cmd_rcvrs, link) { if (rcvr->user == user) { list_del_rcu(&rcvr->link); @@ -855,7 +855,7 @@ int ipmi_destroy_user(ipmi_user_t user) rcvrs = rcvr; } } - up(&intf->cmd_rcvrs_lock); + mutex_unlock(&intf->cmd_rcvrs_mutex); synchronize_rcu(); while (rcvrs) { rcvr = rcvrs; @@ -871,7 +871,7 @@ int ipmi_destroy_user(ipmi_user_t user) kref_put(&user->refcount, free_user); - return rv; + return 0; } void ipmi_get_version(ipmi_user_t user, @@ -936,7 +936,8 @@ int ipmi_set_gets_events(ipmi_user_t user, int val) if (val) { /* Deliver any queued events. */ - list_for_each_entry_safe(msg, msg2, &intf->waiting_events, link) { + list_for_each_entry_safe(msg, msg2, &intf->waiting_events, + link) { list_del(&msg->link); list_add_tail(&msg->link, &msgs); } @@ -978,13 +979,13 @@ int ipmi_register_for_cmd(ipmi_user_t user, rcvr = kmalloc(sizeof(*rcvr), GFP_KERNEL); - if (! rcvr) + if (!rcvr) return -ENOMEM; rcvr->cmd = cmd; rcvr->netfn = netfn; rcvr->user = user; - down(&intf->cmd_rcvrs_lock); + mutex_lock(&intf->cmd_rcvrs_mutex); /* Make sure the command/netfn is not already registered. */ entry = find_cmd_rcvr(intf, netfn, cmd); if (entry) { @@ -995,7 +996,7 @@ int ipmi_register_for_cmd(ipmi_user_t user, list_add_rcu(&rcvr->link, &intf->cmd_rcvrs); out_unlock: - up(&intf->cmd_rcvrs_lock); + mutex_unlock(&intf->cmd_rcvrs_mutex); if (rv) kfree(rcvr); @@ -1009,17 +1010,17 @@ int ipmi_unregister_for_cmd(ipmi_user_t user, ipmi_smi_t intf = user->intf; struct cmd_rcvr *rcvr; - down(&intf->cmd_rcvrs_lock); + mutex_lock(&intf->cmd_rcvrs_mutex); /* Make sure the command/netfn is not already registered. */ rcvr = find_cmd_rcvr(intf, netfn, cmd); if ((rcvr) && (rcvr->user == user)) { list_del_rcu(&rcvr->link); - up(&intf->cmd_rcvrs_lock); + mutex_unlock(&intf->cmd_rcvrs_mutex); synchronize_rcu(); kfree(rcvr); return 0; } else { - up(&intf->cmd_rcvrs_lock); + mutex_unlock(&intf->cmd_rcvrs_mutex); return -ENOENT; } } @@ -1514,7 +1515,7 @@ int ipmi_request_settime(ipmi_user_t user, unsigned char saddr, lun; int rv; - if (! user) + if (!user) return -EINVAL; rv = check_addr(user->intf, addr, &saddr, &lun); if (rv) @@ -1545,7 +1546,7 @@ int ipmi_request_supply_msgs(ipmi_user_t user, unsigned char saddr, lun; int rv; - if (! user) + if (!user) return -EINVAL; rv = check_addr(user->intf, addr, &saddr, &lun); if (rv) @@ -1570,7 +1571,7 @@ static int ipmb_file_read_proc(char *page, char **start, off_t off, char *out = (char *) page; ipmi_smi_t intf = data; int i; - int rv= 0; + int rv = 0; for (i = 0; i < IPMI_MAX_CHANNELS; i++) rv += sprintf(out+rv, "%x ", intf->channels[i].address); @@ -1989,7 +1990,7 @@ static int ipmi_bmc_register(ipmi_smi_t intf) } else { bmc->dev = platform_device_alloc("ipmi_bmc", bmc->id.device_id); - if (! bmc->dev) { + if (!bmc->dev) { printk(KERN_ERR "ipmi_msghandler:" " Unable to allocate platform device\n"); @@ -2305,8 +2306,7 @@ int ipmi_register_smi(struct ipmi_smi_handlers *handlers, void *send_info, struct ipmi_device_id *device_id, struct device *si_dev, - unsigned char slave_addr, - ipmi_smi_t *new_intf) + unsigned char slave_addr) { int i, j; int rv; @@ -2366,7 +2366,7 @@ int ipmi_register_smi(struct ipmi_smi_handlers *handlers, spin_lock_init(&intf->events_lock); INIT_LIST_HEAD(&intf->waiting_events); intf->waiting_events_count = 0; - init_MUTEX(&intf->cmd_rcvrs_lock); + mutex_init(&intf->cmd_rcvrs_mutex); INIT_LIST_HEAD(&intf->cmd_rcvrs); init_waitqueue_head(&intf->waitq); @@ -2388,9 +2388,9 @@ int ipmi_register_smi(struct ipmi_smi_handlers *handlers, if (rv) goto out; - /* FIXME - this is an ugly kludge, this sets the intf for the - caller before sending any messages with it. */ - *new_intf = intf; + rv = handlers->start_processing(send_info, intf); + if (rv) + goto out; get_guid(intf); @@ -2622,7 +2622,7 @@ static int handle_ipmb_get_msg_cmd(ipmi_smi_t intf, spin_unlock_irqrestore(&intf->counter_lock, flags); recv_msg = ipmi_alloc_recv_msg(); - if (! recv_msg) { + if (!recv_msg) { /* We couldn't allocate memory for the message, so requeue it for handling later. */ @@ -2777,7 +2777,7 @@ static int handle_lan_get_msg_cmd(ipmi_smi_t intf, spin_unlock_irqrestore(&intf->counter_lock, flags); recv_msg = ipmi_alloc_recv_msg(); - if (! recv_msg) { + if (!recv_msg) { /* We couldn't allocate memory for the message, so requeue it for handling later. */ @@ -2869,13 +2869,14 @@ static int handle_read_event_rsp(ipmi_smi_t intf, events. */ rcu_read_lock(); list_for_each_entry_rcu(user, &intf->users, link) { - if (! user->gets_events) + if (!user->gets_events) continue; recv_msg = ipmi_alloc_recv_msg(); - if (! recv_msg) { + if (!recv_msg) { rcu_read_unlock(); - list_for_each_entry_safe(recv_msg, recv_msg2, &msgs, link) { + list_for_each_entry_safe(recv_msg, recv_msg2, &msgs, + link) { list_del(&recv_msg->link); ipmi_free_recv_msg(recv_msg); } @@ -2905,7 +2906,7 @@ static int handle_read_event_rsp(ipmi_smi_t intf, /* No one to receive the message, put it in queue if there's not already too many things in the queue. */ recv_msg = ipmi_alloc_recv_msg(); - if (! recv_msg) { + if (!recv_msg) { /* We couldn't allocate memory for the message, so requeue it for handling later. */ @@ -3190,7 +3191,7 @@ void ipmi_smi_watchdog_pretimeout(ipmi_smi_t intf) rcu_read_lock(); list_for_each_entry_rcu(user, &intf->users, link) { - if (! user->handler->ipmi_watchdog_pretimeout) + if (!user->handler->ipmi_watchdog_pretimeout) continue; user->handler->ipmi_watchdog_pretimeout(user->handler_data); @@ -3278,7 +3279,7 @@ static void check_msg_timeout(ipmi_smi_t intf, struct seq_table *ent, smi_msg = smi_from_recv_msg(intf, ent->recv_msg, slot, ent->seqid); - if (! smi_msg) + if (!smi_msg) return; spin_unlock_irqrestore(&intf->seq_lock, *flags); @@ -3314,8 +3315,9 @@ static void ipmi_timeout_handler(long timeout_period) /* See if any waiting messages need to be processed. */ spin_lock_irqsave(&intf->waiting_msgs_lock, flags); - list_for_each_entry_safe(smi_msg, smi_msg2, &intf->waiting_msgs, link) { - if (! handle_new_recv_msg(intf, smi_msg)) { + list_for_each_entry_safe(smi_msg, smi_msg2, + &intf->waiting_msgs, link) { + if (!handle_new_recv_msg(intf, smi_msg)) { list_del(&smi_msg->link); ipmi_free_smi_msg(smi_msg); } else { diff --git a/drivers/char/ipmi/ipmi_poweroff.c b/drivers/char/ipmi/ipmi_poweroff.c index 786a2802ca3..d0b5c08e7b4 100644 --- a/drivers/char/ipmi/ipmi_poweroff.c +++ b/drivers/char/ipmi/ipmi_poweroff.c @@ -346,7 +346,7 @@ static int ipmi_dell_chassis_detect (ipmi_user_t user) { const char ipmi_version_major = ipmi_version & 0xF; const char ipmi_version_minor = (ipmi_version >> 4) & 0xF; - const char mfr[3]=DELL_IANA_MFR_ID; + const char mfr[3] = DELL_IANA_MFR_ID; if (!memcmp(mfr, &mfg_id, sizeof(mfr)) && ipmi_version_major <= 1 && ipmi_version_minor < 5) diff --git a/drivers/char/ipmi/ipmi_si_intf.c b/drivers/char/ipmi/ipmi_si_intf.c index 35fbd4d8ed4..a86c0f29953 100644 --- a/drivers/char/ipmi/ipmi_si_intf.c +++ b/drivers/char/ipmi/ipmi_si_intf.c @@ -803,7 +803,7 @@ static int ipmi_thread(void *data) set_user_nice(current, 19); while (!kthread_should_stop()) { spin_lock_irqsave(&(smi_info->si_lock), flags); - smi_result=smi_event_handler(smi_info, 0); + smi_result = smi_event_handler(smi_info, 0); spin_unlock_irqrestore(&(smi_info->si_lock), flags); if (smi_result == SI_SM_CALL_WITHOUT_DELAY) { /* do nothing */ @@ -972,10 +972,37 @@ static irqreturn_t si_bt_irq_handler(int irq, void *data, struct pt_regs *regs) return si_irq_handler(irq, data, regs); } +static int smi_start_processing(void *send_info, + ipmi_smi_t intf) +{ + struct smi_info *new_smi = send_info; + + new_smi->intf = intf; + + /* Set up the timer that drives the interface. */ + setup_timer(&new_smi->si_timer, smi_timeout, (long)new_smi); + new_smi->last_timeout_jiffies = jiffies; + mod_timer(&new_smi->si_timer, jiffies + SI_TIMEOUT_JIFFIES); + + if (new_smi->si_type != SI_BT) { + new_smi->thread = kthread_run(ipmi_thread, new_smi, + "kipmi%d", new_smi->intf_num); + if (IS_ERR(new_smi->thread)) { + printk(KERN_NOTICE "ipmi_si_intf: Could not start" + " kernel thread due to error %ld, only using" + " timers to drive the interface\n", + PTR_ERR(new_smi->thread)); + new_smi->thread = NULL; + } + } + + return 0; +} static struct ipmi_smi_handlers handlers = { .owner = THIS_MODULE, + .start_processing = smi_start_processing, .sender = sender, .request_events = request_events, .set_run_to_completion = set_run_to_completion, @@ -987,7 +1014,7 @@ static struct ipmi_smi_handlers handlers = #define SI_MAX_PARMS 4 static LIST_HEAD(smi_infos); -static DECLARE_MUTEX(smi_infos_lock); +static DEFINE_MUTEX(smi_infos_lock); static int smi_num; /* Used to sequence the SMIs */ #define DEFAULT_REGSPACING 1 @@ -2162,9 +2189,13 @@ static void setup_xaction_handlers(struct smi_info *smi_info) static inline void wait_for_timer_and_thread(struct smi_info *smi_info) { - if (smi_info->thread != NULL && smi_info->thread != ERR_PTR(-ENOMEM)) - kthread_stop(smi_info->thread); - del_timer_sync(&smi_info->si_timer); + if (smi_info->intf) { + /* The timer and thread are only running if the + interface has been started up and registered. */ + if (smi_info->thread != NULL) + kthread_stop(smi_info->thread); + del_timer_sync(&smi_info->si_timer); + } } static struct ipmi_default_vals @@ -2245,7 +2276,7 @@ static int try_smi_init(struct smi_info *new_smi) new_smi->slave_addr, new_smi->irq); } - down(&smi_infos_lock); + mutex_lock(&smi_infos_lock); if (!is_new_interface(new_smi)) { printk(KERN_WARNING "ipmi_si: duplicate interface\n"); rv = -EBUSY; @@ -2341,21 +2372,6 @@ static int try_smi_init(struct smi_info *new_smi) if (new_smi->irq) new_smi->si_state = SI_CLEARING_FLAGS_THEN_SET_IRQ; - /* The ipmi_register_smi() code does some operations to - determine the channel information, so we must be ready to - handle operations before it is called. This means we have - to stop the timer if we get an error after this point. */ - init_timer(&(new_smi->si_timer)); - new_smi->si_timer.data = (long) new_smi; - new_smi->si_timer.function = smi_timeout; - new_smi->last_timeout_jiffies = jiffies; - new_smi->si_timer.expires = jiffies + SI_TIMEOUT_JIFFIES; - - add_timer(&(new_smi->si_timer)); - if (new_smi->si_type != SI_BT) - new_smi->thread = kthread_run(ipmi_thread, new_smi, - "kipmi%d", new_smi->intf_num); - if (!new_smi->dev) { /* If we don't already have a device from something * else (like PCI), then register a new one. */ @@ -2365,7 +2381,7 @@ static int try_smi_init(struct smi_info *new_smi) printk(KERN_ERR "ipmi_si_intf:" " Unable to allocate platform device\n"); - goto out_err_stop_timer; + goto out_err; } new_smi->dev = &new_smi->pdev->dev; new_smi->dev->driver = &ipmi_driver; @@ -2377,7 +2393,7 @@ static int try_smi_init(struct smi_info *new_smi) " Unable to register system interface device:" " %d\n", rv); - goto out_err_stop_timer; + goto out_err; } new_smi->dev_registered = 1; } @@ -2386,8 +2402,7 @@ static int try_smi_init(struct smi_info *new_smi) new_smi, &new_smi->device_id, new_smi->dev, - new_smi->slave_addr, - &(new_smi->intf)); + new_smi->slave_addr); if (rv) { printk(KERN_ERR "ipmi_si: Unable to register device: error %d\n", @@ -2417,7 +2432,7 @@ static int try_smi_init(struct smi_info *new_smi) list_add_tail(&new_smi->link, &smi_infos); - up(&smi_infos_lock); + mutex_unlock(&smi_infos_lock); printk(" IPMI %s interface initialized\n",si_to_str[new_smi->si_type]); @@ -2454,7 +2469,7 @@ static int try_smi_init(struct smi_info *new_smi) kfree(new_smi); - up(&smi_infos_lock); + mutex_unlock(&smi_infos_lock); return rv; } @@ -2512,26 +2527,26 @@ static __devinit int init_ipmi_si(void) #endif if (si_trydefaults) { - down(&smi_infos_lock); + mutex_lock(&smi_infos_lock); if (list_empty(&smi_infos)) { /* No BMC was found, try defaults. */ - up(&smi_infos_lock); + mutex_unlock(&smi_infos_lock); default_find_bmc(); } else { - up(&smi_infos_lock); + mutex_unlock(&smi_infos_lock); } } - down(&smi_infos_lock); + mutex_lock(&smi_infos_lock); if (list_empty(&smi_infos)) { - up(&smi_infos_lock); + mutex_unlock(&smi_infos_lock); #ifdef CONFIG_PCI pci_unregister_driver(&ipmi_pci_driver); #endif printk("ipmi_si: Unable to find any System Interface(s)\n"); return -ENODEV; } else { - up(&smi_infos_lock); + mutex_unlock(&smi_infos_lock); return 0; } } @@ -2607,10 +2622,10 @@ static __exit void cleanup_ipmi_si(void) pci_unregister_driver(&ipmi_pci_driver); #endif - down(&smi_infos_lock); + mutex_lock(&smi_infos_lock); list_for_each_entry_safe(e, tmp_e, &smi_infos, link) cleanup_one_si(e); - up(&smi_infos_lock); + mutex_unlock(&smi_infos_lock); driver_unregister(&ipmi_driver); } diff --git a/drivers/char/ipmi/ipmi_watchdog.c b/drivers/char/ipmi/ipmi_watchdog.c index 7ece9f3c8f7..2d11ddd99e5 100644 --- a/drivers/char/ipmi/ipmi_watchdog.c +++ b/drivers/char/ipmi/ipmi_watchdog.c @@ -39,6 +39,7 @@ #include <linux/watchdog.h> #include <linux/miscdevice.h> #include <linux/init.h> +#include <linux/completion.h> #include <linux/rwsem.h> #include <linux/errno.h> #include <asm/uaccess.h> @@ -303,21 +304,22 @@ static int ipmi_heartbeat(void); static void panic_halt_ipmi_heartbeat(void); -/* We use a semaphore to make sure that only one thing can send a set +/* We use a mutex to make sure that only one thing can send a set timeout at one time, because we only have one copy of the data. - The semaphore is claimed when the set_timeout is sent and freed + The mutex is claimed when the set_timeout is sent and freed when both messages are free. */ static atomic_t set_timeout_tofree = ATOMIC_INIT(0); -static DECLARE_MUTEX(set_timeout_lock); +static DEFINE_MUTEX(set_timeout_lock); +static DECLARE_COMPLETION(set_timeout_wait); static void set_timeout_free_smi(struct ipmi_smi_msg *msg) { if (atomic_dec_and_test(&set_timeout_tofree)) - up(&set_timeout_lock); + complete(&set_timeout_wait); } static void set_timeout_free_recv(struct ipmi_recv_msg *msg) { if (atomic_dec_and_test(&set_timeout_tofree)) - up(&set_timeout_lock); + complete(&set_timeout_wait); } static struct ipmi_smi_msg set_timeout_smi_msg = { @@ -399,7 +401,7 @@ static int ipmi_set_timeout(int do_heartbeat) /* We can only send one of these at a time. */ - down(&set_timeout_lock); + mutex_lock(&set_timeout_lock); atomic_set(&set_timeout_tofree, 2); @@ -407,16 +409,21 @@ static int ipmi_set_timeout(int do_heartbeat) &set_timeout_recv_msg, &send_heartbeat_now); if (rv) { - up(&set_timeout_lock); - } else { - if ((do_heartbeat == IPMI_SET_TIMEOUT_FORCE_HB) - || ((send_heartbeat_now) - && (do_heartbeat == IPMI_SET_TIMEOUT_HB_IF_NECESSARY))) - { - rv = ipmi_heartbeat(); - } + mutex_unlock(&set_timeout_lock); + goto out; } + wait_for_completion(&set_timeout_wait); + + if ((do_heartbeat == IPMI_SET_TIMEOUT_FORCE_HB) + || ((send_heartbeat_now) + && (do_heartbeat == IPMI_SET_TIMEOUT_HB_IF_NECESSARY))) + { + rv = ipmi_heartbeat(); + } + mutex_unlock(&set_timeout_lock); + +out: return rv; } @@ -458,17 +465,17 @@ static void panic_halt_ipmi_set_timeout(void) The semaphore is claimed when the set_timeout is sent and freed when both messages are free. */ static atomic_t heartbeat_tofree = ATOMIC_INIT(0); -static DECLARE_MUTEX(heartbeat_lock); -static DECLARE_MUTEX_LOCKED(heartbeat_wait_lock); +static DEFINE_MUTEX(heartbeat_lock); +static DECLARE_COMPLETION(heartbeat_wait); static void heartbeat_free_smi(struct ipmi_smi_msg *msg) { if (atomic_dec_and_test(&heartbeat_tofree)) - up(&heartbeat_wait_lock); + complete(&heartbeat_wait); } static void heartbeat_free_recv(struct ipmi_recv_msg *msg) { if (atomic_dec_and_test(&heartbeat_tofree)) - up(&heartbeat_wait_lock); + complete(&heartbeat_wait); } static struct ipmi_smi_msg heartbeat_smi_msg = { @@ -511,14 +518,14 @@ static int ipmi_heartbeat(void) return ipmi_set_timeout(IPMI_SET_TIMEOUT_HB_IF_NECESSARY); } - down(&heartbeat_lock); + mutex_lock(&heartbeat_lock); atomic_set(&heartbeat_tofree, 2); /* Don't reset the timer if we have the timer turned off, that re-enables the watchdog. */ if (ipmi_watchdog_state == WDOG_TIMEOUT_NONE) { - up(&heartbeat_lock); + mutex_unlock(&heartbeat_lock); return 0; } @@ -539,14 +546,14 @@ static int ipmi_heartbeat(void) &heartbeat_recv_msg, 1); if (rv) { - up(&heartbeat_lock); + mutex_unlock(&heartbeat_lock); printk(KERN_WARNING PFX "heartbeat failure: %d\n", rv); return rv; } /* Wait for the heartbeat to be sent. */ - down(&heartbeat_wait_lock); + wait_for_completion(&heartbeat_wait); if (heartbeat_recv_msg.msg.data[0] != 0) { /* Got an error in the heartbeat response. It was already @@ -555,7 +562,7 @@ static int ipmi_heartbeat(void) rv = -EINVAL; } - up(&heartbeat_lock); + mutex_unlock(&heartbeat_lock); return rv; } @@ -589,7 +596,7 @@ static void panic_halt_ipmi_heartbeat(void) 1); } -static struct watchdog_info ident= +static struct watchdog_info ident = { .options = 0, /* WDIOF_SETTIMEOUT, */ .firmware_version = 1, @@ -790,13 +797,13 @@ static int ipmi_fasync(int fd, struct file *file, int on) static int ipmi_close(struct inode *ino, struct file *filep) { - if (iminor(ino)==WATCHDOG_MINOR) - { + if (iminor(ino) == WATCHDOG_MINOR) { if (expect_close == 42) { ipmi_watchdog_state = WDOG_TIMEOUT_NONE; ipmi_set_timeout(IPMI_SET_TIMEOUT_NO_HB); } else { - printk(KERN_CRIT PFX "Unexpected close, not stopping watchdog!\n"); + printk(KERN_CRIT PFX + "Unexpected close, not stopping watchdog!\n"); ipmi_heartbeat(); } clear_bit(0, &ipmi_wdog_open); diff --git a/drivers/char/istallion.c b/drivers/char/istallion.c index e5247f85a44..ef20c1fc9c4 100644 --- a/drivers/char/istallion.c +++ b/drivers/char/istallion.c @@ -706,7 +706,6 @@ static int stli_portcmdstats(stliport_t *portp); static int stli_clrportstats(stliport_t *portp, comstats_t __user *cp); static int stli_getportstruct(stliport_t __user *arg); static int stli_getbrdstruct(stlibrd_t __user *arg); -static void *stli_memalloc(int len); static stlibrd_t *stli_allocbrd(void); static void stli_ecpinit(stlibrd_t *brdp); @@ -997,17 +996,6 @@ static int stli_parsebrd(stlconf_t *confp, char **argp) /*****************************************************************************/ -/* - * Local driver kernel malloc routine. - */ - -static void *stli_memalloc(int len) -{ - return((void *) kmalloc(len, GFP_KERNEL)); -} - -/*****************************************************************************/ - static int stli_open(struct tty_struct *tty, struct file *filp) { stlibrd_t *brdp; @@ -3227,13 +3215,12 @@ static int stli_initports(stlibrd_t *brdp) #endif for (i = 0, panelnr = 0, panelport = 0; (i < brdp->nrports); i++) { - portp = (stliport_t *) stli_memalloc(sizeof(stliport_t)); - if (portp == (stliport_t *) NULL) { + portp = kzalloc(sizeof(stliport_t), GFP_KERNEL); + if (!portp) { printk("STALLION: failed to allocate port structure\n"); continue; } - memset(portp, 0, sizeof(stliport_t)); portp->magic = STLI_PORTMAGIC; portp->portnr = i; portp->brdnr = brdp->brdnr; @@ -4610,14 +4597,13 @@ static stlibrd_t *stli_allocbrd(void) { stlibrd_t *brdp; - brdp = (stlibrd_t *) stli_memalloc(sizeof(stlibrd_t)); - if (brdp == (stlibrd_t *) NULL) { + brdp = kzalloc(sizeof(stlibrd_t), GFP_KERNEL); + if (!brdp) { printk(KERN_ERR "STALLION: failed to allocate memory " "(size=%d)\n", sizeof(stlibrd_t)); - return((stlibrd_t *) NULL); + return NULL; } - memset(brdp, 0, sizeof(stlibrd_t)); brdp->magic = STLI_BOARDMAGIC; return(brdp); } @@ -5210,12 +5196,12 @@ int __init stli_init(void) /* * Allocate a temporary write buffer. */ - stli_tmpwritebuf = (char *) stli_memalloc(STLI_TXBUFSIZE); - if (stli_tmpwritebuf == (char *) NULL) + stli_tmpwritebuf = kmalloc(STLI_TXBUFSIZE, GFP_KERNEL); + if (!stli_tmpwritebuf) printk(KERN_ERR "STALLION: failed to allocate memory " "(size=%d)\n", STLI_TXBUFSIZE); - stli_txcookbuf = stli_memalloc(STLI_TXBUFSIZE); - if (stli_txcookbuf == (char *) NULL) + stli_txcookbuf = kmalloc(STLI_TXBUFSIZE, GFP_KERNEL); + if (!stli_txcookbuf) printk(KERN_ERR "STALLION: failed to allocate memory " "(size=%d)\n", STLI_TXBUFSIZE); diff --git a/drivers/char/keyboard.c b/drivers/char/keyboard.c index 8b603b2d1c4..935670a3cd9 100644 --- a/drivers/char/keyboard.c +++ b/drivers/char/keyboard.c @@ -74,7 +74,7 @@ void compute_shiftstate(void); k_self, k_fn, k_spec, k_pad,\ k_dead, k_cons, k_cur, k_shift,\ k_meta, k_ascii, k_lock, k_lowercase,\ - k_slock, k_dead2, k_ignore, k_ignore + k_slock, k_dead2, k_brl, k_ignore typedef void (k_handler_fn)(struct vc_data *vc, unsigned char value, char up_flag, struct pt_regs *regs); @@ -100,7 +100,7 @@ static fn_handler_fn *fn_handler[] = { FN_HANDLERS }; const int max_vals[] = { 255, ARRAY_SIZE(func_table) - 1, ARRAY_SIZE(fn_handler) - 1, NR_PAD - 1, NR_DEAD - 1, 255, 3, NR_SHIFT - 1, 255, NR_ASCII - 1, NR_LOCK - 1, - 255, NR_LOCK - 1, 255 + 255, NR_LOCK - 1, 255, NR_BRL - 1 }; const int NR_TYPES = ARRAY_SIZE(max_vals); @@ -126,7 +126,7 @@ static unsigned long key_down[NBITS(KEY_MAX)]; /* keyboard key bitmap */ static unsigned char shift_down[NR_SHIFT]; /* shift state counters.. */ static int dead_key_next; static int npadch = -1; /* -1 or number assembled on pad */ -static unsigned char diacr; +static unsigned int diacr; static char rep; /* flag telling character repeat */ static unsigned char ledstate = 0xff; /* undefined */ @@ -394,22 +394,30 @@ void compute_shiftstate(void) * Otherwise, conclude that DIACR was not combining after all, * queue it and return CH. */ -static unsigned char handle_diacr(struct vc_data *vc, unsigned char ch) +static unsigned int handle_diacr(struct vc_data *vc, unsigned int ch) { - int d = diacr; + unsigned int d = diacr; unsigned int i; diacr = 0; - for (i = 0; i < accent_table_size; i++) { - if (accent_table[i].diacr == d && accent_table[i].base == ch) - return accent_table[i].result; + if ((d & ~0xff) == BRL_UC_ROW) { + if ((ch & ~0xff) == BRL_UC_ROW) + return d | ch; + } else { + for (i = 0; i < accent_table_size; i++) + if (accent_table[i].diacr == d && accent_table[i].base == ch) + return accent_table[i].result; } - if (ch == ' ' || ch == d) + if (ch == ' ' || ch == (BRL_UC_ROW|0) || ch == d) return d; - put_queue(vc, d); + if (kbd->kbdmode == VC_UNICODE) + to_utf8(vc, d); + else if (d < 0x100) + put_queue(vc, d); + return ch; } @@ -419,7 +427,10 @@ static unsigned char handle_diacr(struct vc_data *vc, unsigned char ch) static void fn_enter(struct vc_data *vc, struct pt_regs *regs) { if (diacr) { - put_queue(vc, diacr); + if (kbd->kbdmode == VC_UNICODE) + to_utf8(vc, diacr); + else if (diacr < 0x100) + put_queue(vc, diacr); diacr = 0; } put_queue(vc, 13); @@ -615,7 +626,7 @@ static void k_lowercase(struct vc_data *vc, unsigned char value, char up_flag, s printk(KERN_ERR "keyboard.c: k_lowercase was called - impossible\n"); } -static void k_self(struct vc_data *vc, unsigned char value, char up_flag, struct pt_regs *regs) +static void k_unicode(struct vc_data *vc, unsigned int value, char up_flag, struct pt_regs *regs) { if (up_flag) return; /* no action, if this is a key release */ @@ -628,7 +639,10 @@ static void k_self(struct vc_data *vc, unsigned char value, char up_flag, struct diacr = value; return; } - put_queue(vc, value); + if (kbd->kbdmode == VC_UNICODE) + to_utf8(vc, value); + else if (value < 0x100) + put_queue(vc, value); } /* @@ -636,13 +650,23 @@ static void k_self(struct vc_data *vc, unsigned char value, char up_flag, struct * dead keys modifying the same character. Very useful * for Vietnamese. */ -static void k_dead2(struct vc_data *vc, unsigned char value, char up_flag, struct pt_regs *regs) +static void k_deadunicode(struct vc_data *vc, unsigned int value, char up_flag, struct pt_regs *regs) { if (up_flag) return; diacr = (diacr ? handle_diacr(vc, value) : value); } +static void k_self(struct vc_data *vc, unsigned char value, char up_flag, struct pt_regs *regs) +{ + k_unicode(vc, value, up_flag, regs); +} + +static void k_dead2(struct vc_data *vc, unsigned char value, char up_flag, struct pt_regs *regs) +{ + k_deadunicode(vc, value, up_flag, regs); +} + /* * Obsolete - for backwards compatibility only */ @@ -650,7 +674,7 @@ static void k_dead(struct vc_data *vc, unsigned char value, char up_flag, struct { static unsigned char ret_diacr[NR_DEAD] = {'`', '\'', '^', '~', '"', ',' }; value = ret_diacr[value]; - k_dead2(vc, value, up_flag, regs); + k_deadunicode(vc, value, up_flag, regs); } static void k_cons(struct vc_data *vc, unsigned char value, char up_flag, struct pt_regs *regs) @@ -835,6 +859,62 @@ static void k_slock(struct vc_data *vc, unsigned char value, char up_flag, struc } } +/* by default, 300ms interval for combination release */ +static long brl_timeout = 300; +MODULE_PARM_DESC(brl_timeout, "Braille keys release delay in ms (0 for combination on first release, < 0 for dead characters)"); +module_param(brl_timeout, long, 0644); +static void k_brl(struct vc_data *vc, unsigned char value, char up_flag, struct pt_regs *regs) +{ + static unsigned pressed,committing; + static unsigned long releasestart; + + if (kbd->kbdmode != VC_UNICODE) { + if (!up_flag) + printk("keyboard mode must be unicode for braille patterns\n"); + return; + } + + if (!value) { + k_unicode(vc, BRL_UC_ROW, up_flag, regs); + return; + } + + if (value > 8) + return; + + if (brl_timeout < 0) { + k_deadunicode(vc, BRL_UC_ROW | (1 << (value - 1)), up_flag, regs); + return; + } + + if (up_flag) { + if (brl_timeout) { + if (!committing || + jiffies - releasestart > (brl_timeout * HZ) / 1000) { + committing = pressed; + releasestart = jiffies; + } + pressed &= ~(1 << (value - 1)); + if (!pressed) { + if (committing) { + k_unicode(vc, BRL_UC_ROW | committing, 0, regs); + committing = 0; + } + } + } else { + if (committing) { + k_unicode(vc, BRL_UC_ROW | committing, 0, regs); + committing = 0; + } + pressed &= ~(1 << (value - 1)); + } + } else { + pressed |= 1 << (value - 1); + if (!brl_timeout) + committing = pressed; + } +} + /* * The leds display either (i) the status of NumLock, CapsLock, ScrollLock, * or (ii) whatever pattern of lights people want to show using KDSETLED, @@ -1125,9 +1205,13 @@ static void kbd_keycode(unsigned int keycode, int down, } if (keycode > NR_KEYS) - return; + if (keycode >= KEY_BRL_DOT1 && keycode <= KEY_BRL_DOT8) + keysym = K(KT_BRL, keycode - KEY_BRL_DOT1 + 1); + else + return; + else + keysym = key_map[keycode]; - keysym = key_map[keycode]; type = KTYP(keysym); if (type < 0xf0) { diff --git a/drivers/char/pcmcia/cm4000_cs.c b/drivers/char/pcmcia/cm4000_cs.c index 5fdf1851543..02114a0bd0d 100644 --- a/drivers/char/pcmcia/cm4000_cs.c +++ b/drivers/char/pcmcia/cm4000_cs.c @@ -46,7 +46,7 @@ /* #define ATR_CSUM */ #ifdef PCMCIA_DEBUG -#define reader_to_dev(x) (&handle_to_dev(x->link.handle)) +#define reader_to_dev(x) (&handle_to_dev(x->p_dev->handle)) static int pc_debug = PCMCIA_DEBUG; module_param(pc_debug, int, 0600); #define DEBUGP(n, rdr, x, args...) do { \ @@ -67,7 +67,7 @@ static char *version = "cm4000_cs.c v2.4.0gm6 - All bugs added by Harald Welte"; #define T_100MSEC msecs_to_jiffies(100) #define T_500MSEC msecs_to_jiffies(500) -static void cm4000_release(dev_link_t *link); +static void cm4000_release(struct pcmcia_device *link); static int major; /* major number we get from the kernel */ @@ -106,7 +106,7 @@ static int major; /* major number we get from the kernel */ #define REG_STOPBITS(x) (x + 7) struct cm4000_dev { - dev_link_t link; /* pcmcia link */ + struct pcmcia_device *p_dev; dev_node_t node; /* OS node (major,minor) */ unsigned char atr[MAX_ATR]; @@ -149,14 +149,14 @@ struct cm4000_dev { #define ZERO_DEV(dev) \ memset(&dev->atr_csum,0, \ sizeof(struct cm4000_dev) - \ - /*link*/ sizeof(dev_link_t) - \ + /*link*/ sizeof(struct pcmcia_device) - \ /*node*/ sizeof(dev_node_t) - \ /*atr*/ MAX_ATR*sizeof(char) - \ /*rbuf*/ 512*sizeof(char) - \ /*sbuf*/ 512*sizeof(char) - \ /*queue*/ 4*sizeof(wait_queue_head_t)) -static dev_link_t *dev_table[CM4000_MAX_DEV]; +static struct pcmcia_device *dev_table[CM4000_MAX_DEV]; static struct class *cmm_class; /* This table doesn't use spaces after the comma between fields and thus @@ -454,7 +454,7 @@ static struct card_fixup card_fixups[] = { static void set_cardparameter(struct cm4000_dev *dev) { int i; - ioaddr_t iobase = dev->link.io.BasePort1; + ioaddr_t iobase = dev->p_dev->io.BasePort1; u_int8_t stopbits = 0x02; /* ISO default */ DEBUGP(3, dev, "-> set_cardparameter\n"); @@ -487,7 +487,7 @@ static int set_protocol(struct cm4000_dev *dev, struct ptsreq *ptsreq) unsigned short num_bytes_read; unsigned char pts_reply[4]; ssize_t rc; - ioaddr_t iobase = dev->link.io.BasePort1; + ioaddr_t iobase = dev->p_dev->io.BasePort1; rc = 0; @@ -699,7 +699,7 @@ static void terminate_monitor(struct cm4000_dev *dev) static void monitor_card(unsigned long p) { struct cm4000_dev *dev = (struct cm4000_dev *) p; - ioaddr_t iobase = dev->link.io.BasePort1; + ioaddr_t iobase = dev->p_dev->io.BasePort1; unsigned short s; struct ptsreq ptsreq; int i, atrc; @@ -962,7 +962,7 @@ static ssize_t cmm_read(struct file *filp, __user char *buf, size_t count, loff_t *ppos) { struct cm4000_dev *dev = filp->private_data; - ioaddr_t iobase = dev->link.io.BasePort1; + ioaddr_t iobase = dev->p_dev->io.BasePort1; ssize_t rc; int i, j, k; @@ -971,7 +971,7 @@ static ssize_t cmm_read(struct file *filp, __user char *buf, size_t count, if (count == 0) /* according to manpage */ return 0; - if ((dev->link.state & DEV_PRESENT) == 0 || /* socket removed */ + if (!pcmcia_dev_present(dev->p_dev) || /* device removed */ test_bit(IS_CMM_ABSENT, &dev->flags)) return -ENODEV; @@ -1083,7 +1083,7 @@ static ssize_t cmm_write(struct file *filp, const char __user *buf, size_t count, loff_t *ppos) { struct cm4000_dev *dev = (struct cm4000_dev *) filp->private_data; - ioaddr_t iobase = dev->link.io.BasePort1; + ioaddr_t iobase = dev->p_dev->io.BasePort1; unsigned short s; unsigned char tmp; unsigned char infolen; @@ -1108,7 +1108,7 @@ static ssize_t cmm_write(struct file *filp, const char __user *buf, sendT0 = dev->proto ? 0 : nr > 5 ? 0x08 : 0; - if ((dev->link.state & DEV_PRESENT) == 0 || /* socket removed */ + if (!pcmcia_dev_present(dev->p_dev) || /* device removed */ test_bit(IS_CMM_ABSENT, &dev->flags)) return -ENODEV; @@ -1440,8 +1440,8 @@ static int cmm_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg) { struct cm4000_dev *dev = filp->private_data; - ioaddr_t iobase = dev->link.io.BasePort1; - dev_link_t *link; + ioaddr_t iobase = dev->p_dev->io.BasePort1; + struct pcmcia_device *link; int size; int rc; void __user *argp = (void __user *)arg; @@ -1458,7 +1458,7 @@ static int cmm_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, iminor(inode), ioctl_names[_IOC_NR(cmd)]); link = dev_table[iminor(inode)]; - if (!(DEV_OK(link))) { + if (!pcmcia_dev_present(link)) { DEBUGP(4, dev, "DEV_OK false\n"); return -ENODEV; } @@ -1660,14 +1660,14 @@ static int cmm_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, static int cmm_open(struct inode *inode, struct file *filp) { struct cm4000_dev *dev; - dev_link_t *link; + struct pcmcia_device *link; int rc, minor = iminor(inode); if (minor >= CM4000_MAX_DEV) return -ENODEV; link = dev_table[minor]; - if (link == NULL || !(DEV_OK(link))) + if (link == NULL || !pcmcia_dev_present(link)) return -ENODEV; if (link->open) @@ -1709,7 +1709,7 @@ static int cmm_open(struct inode *inode, struct file *filp) static int cmm_close(struct inode *inode, struct file *filp) { struct cm4000_dev *dev; - dev_link_t *link; + struct pcmcia_device *link; int minor = iminor(inode); if (minor >= CM4000_MAX_DEV) @@ -1735,7 +1735,7 @@ static int cmm_close(struct inode *inode, struct file *filp) return 0; } -static void cmm_cm4000_release(dev_link_t * link) +static void cmm_cm4000_release(struct pcmcia_device * link) { struct cm4000_dev *dev = link->priv; @@ -1759,13 +1759,11 @@ static void cmm_cm4000_release(dev_link_t * link) /*==== Interface to PCMCIA Layer =======================================*/ -static void cm4000_config(dev_link_t * link, int devno) +static int cm4000_config(struct pcmcia_device * link, int devno) { - client_handle_t handle = link->handle; struct cm4000_dev *dev; tuple_t tuple; cisparse_t parse; - config_info_t conf; u_char buf[64]; int fail_fn, fail_rc; int rc; @@ -1777,41 +1775,34 @@ static void cm4000_config(dev_link_t * link, int devno) tuple.TupleDataMax = sizeof(buf); tuple.TupleOffset = 0; - if ((fail_rc = pcmcia_get_first_tuple(handle, &tuple)) != CS_SUCCESS) { + if ((fail_rc = pcmcia_get_first_tuple(link, &tuple)) != CS_SUCCESS) { fail_fn = GetFirstTuple; goto cs_failed; } - if ((fail_rc = pcmcia_get_tuple_data(handle, &tuple)) != CS_SUCCESS) { + if ((fail_rc = pcmcia_get_tuple_data(link, &tuple)) != CS_SUCCESS) { fail_fn = GetTupleData; goto cs_failed; } if ((fail_rc = - pcmcia_parse_tuple(handle, &tuple, &parse)) != CS_SUCCESS) { + pcmcia_parse_tuple(link, &tuple, &parse)) != CS_SUCCESS) { fail_fn = ParseTuple; goto cs_failed; } - if ((fail_rc = - pcmcia_get_configuration_info(handle, &conf)) != CS_SUCCESS) { - fail_fn = GetConfigurationInfo; - goto cs_failed; - } - link->state |= DEV_CONFIG; link->conf.ConfigBase = parse.config.base; link->conf.Present = parse.config.rmask[0]; - link->conf.Vcc = conf.Vcc; link->io.BasePort2 = 0; link->io.NumPorts2 = 0; link->io.Attributes2 = 0; tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; - for (rc = pcmcia_get_first_tuple(handle, &tuple); - rc == CS_SUCCESS; rc = pcmcia_get_next_tuple(handle, &tuple)) { + for (rc = pcmcia_get_first_tuple(link, &tuple); + rc == CS_SUCCESS; rc = pcmcia_get_next_tuple(link, &tuple)) { - rc = pcmcia_get_tuple_data(handle, &tuple); + rc = pcmcia_get_tuple_data(link, &tuple); if (rc != CS_SUCCESS) continue; - rc = pcmcia_parse_tuple(handle, &tuple, &parse); + rc = pcmcia_parse_tuple(link, &tuple, &parse); if (rc != CS_SUCCESS) continue; @@ -1831,7 +1822,7 @@ static void cm4000_config(dev_link_t * link, int devno) link->io.IOAddrLines = parse.cftable_entry.io.flags & CISTPL_IO_LINES_MASK; - rc = pcmcia_request_io(handle, &link->io); + rc = pcmcia_request_io(link, &link->io); if (rc == CS_SUCCESS) break; /* we are done */ } @@ -1841,7 +1832,7 @@ static void cm4000_config(dev_link_t * link, int devno) link->conf.IntType = 00000002; if ((fail_rc = - pcmcia_request_configuration(handle, &link->conf)) != CS_SUCCESS) { + pcmcia_request_configuration(link, &link->conf)) != CS_SUCCESS) { fail_fn = RequestConfiguration; goto cs_release; } @@ -1851,63 +1842,48 @@ static void cm4000_config(dev_link_t * link, int devno) dev->node.major = major; dev->node.minor = devno; dev->node.next = NULL; - link->dev = &dev->node; - link->state &= ~DEV_CONFIG_PENDING; + link->dev_node = &dev->node; - return; + return 0; cs_failed: - cs_error(handle, fail_fn, fail_rc); + cs_error(link, fail_fn, fail_rc); cs_release: cm4000_release(link); - - link->state &= ~DEV_CONFIG_PENDING; + return -ENODEV; } -static int cm4000_suspend(struct pcmcia_device *p_dev) +static int cm4000_suspend(struct pcmcia_device *link) { - dev_link_t *link = dev_to_instance(p_dev); struct cm4000_dev *dev; dev = link->priv; - - link->state |= DEV_SUSPEND; - if (link->state & DEV_CONFIG) - pcmcia_release_configuration(link->handle); stop_monitor(dev); return 0; } -static int cm4000_resume(struct pcmcia_device *p_dev) +static int cm4000_resume(struct pcmcia_device *link) { - dev_link_t *link = dev_to_instance(p_dev); struct cm4000_dev *dev; dev = link->priv; - - link->state &= ~DEV_SUSPEND; - if (link->state & DEV_CONFIG) - pcmcia_request_configuration(link->handle, &link->conf); - if (link->open) start_monitor(dev); return 0; } -static void cm4000_release(dev_link_t *link) +static void cm4000_release(struct pcmcia_device *link) { cmm_cm4000_release(link->priv); /* delay release until device closed */ - pcmcia_release_configuration(link->handle); - pcmcia_release_io(link->handle, &link->io); + pcmcia_disable_device(link); } -static int cm4000_attach(struct pcmcia_device *p_dev) +static int cm4000_probe(struct pcmcia_device *link) { struct cm4000_dev *dev; - dev_link_t *link; - int i; + int i, ret; for (i = 0; i < CM4000_MAX_DEV; i++) if (dev_table[i] == NULL) @@ -1923,7 +1899,7 @@ static int cm4000_attach(struct pcmcia_device *p_dev) if (dev == NULL) return -ENOMEM; - link = &dev->link; + dev->p_dev = link; link->priv = dev; link->conf.IntType = INT_MEMORY_AND_IO; dev_table[i] = link; @@ -1933,11 +1909,9 @@ static int cm4000_attach(struct pcmcia_device *p_dev) init_waitqueue_head(&dev->atrq); init_waitqueue_head(&dev->readq); - link->handle = p_dev; - p_dev->instance = link; - - link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; - cm4000_config(link, i); + ret = cm4000_config(link, i); + if (ret) + return ret; class_device_create(cmm_class, NULL, MKDEV(major, i), NULL, "cmm%d", i); @@ -1945,9 +1919,8 @@ static int cm4000_attach(struct pcmcia_device *p_dev) return 0; } -static void cm4000_detach(struct pcmcia_device *p_dev) +static void cm4000_detach(struct pcmcia_device *link) { - dev_link_t *link = dev_to_instance(p_dev); struct cm4000_dev *dev = link->priv; int devno; @@ -1958,11 +1931,9 @@ static void cm4000_detach(struct pcmcia_device *p_dev) if (devno == CM4000_MAX_DEV) return; - link->state &= ~DEV_PRESENT; stop_monitor(dev); - if (link->state & DEV_CONFIG) - cm4000_release(link); + cm4000_release(link); dev_table[devno] = NULL; kfree(dev); @@ -1993,7 +1964,7 @@ static struct pcmcia_driver cm4000_driver = { .drv = { .name = "cm4000_cs", }, - .probe = cm4000_attach, + .probe = cm4000_probe, .remove = cm4000_detach, .suspend = cm4000_suspend, .resume = cm4000_resume, diff --git a/drivers/char/pcmcia/cm4040_cs.c b/drivers/char/pcmcia/cm4040_cs.c index 466e33bab02..29efa64580a 100644 --- a/drivers/char/pcmcia/cm4040_cs.c +++ b/drivers/char/pcmcia/cm4040_cs.c @@ -41,7 +41,7 @@ #ifdef PCMCIA_DEBUG -#define reader_to_dev(x) (&handle_to_dev(x->link.handle)) +#define reader_to_dev(x) (&handle_to_dev(x->p_dev->handle)) static int pc_debug = PCMCIA_DEBUG; module_param(pc_debug, int, 0600); #define DEBUGP(n, rdr, x, args...) do { \ @@ -65,7 +65,7 @@ static char *version = /* how often to poll for fifo status change */ #define POLL_PERIOD msecs_to_jiffies(10) -static void reader_release(dev_link_t *link); +static void reader_release(struct pcmcia_device *link); static int major; static struct class *cmx_class; @@ -74,7 +74,7 @@ static struct class *cmx_class; #define BS_WRITABLE 0x02 struct reader_dev { - dev_link_t link; + struct pcmcia_device *p_dev; dev_node_t node; wait_queue_head_t devq; wait_queue_head_t poll_wait; @@ -87,7 +87,7 @@ struct reader_dev { struct timer_list poll_timer; }; -static dev_link_t *dev_table[CM_MAX_DEV]; +static struct pcmcia_device *dev_table[CM_MAX_DEV]; #ifndef PCMCIA_DEBUG #define xoutb outb @@ -116,7 +116,7 @@ static inline unsigned char xinb(unsigned short port) static void cm4040_do_poll(unsigned long dummy) { struct reader_dev *dev = (struct reader_dev *) dummy; - unsigned int obs = xinb(dev->link.io.BasePort1 + unsigned int obs = xinb(dev->p_dev->io.BasePort1 + REG_OFFSET_BUFFER_STATUS); if ((obs & BSR_BULK_IN_FULL)) { @@ -147,7 +147,7 @@ static void cm4040_stop_poll(struct reader_dev *dev) static int wait_for_bulk_out_ready(struct reader_dev *dev) { int i, rc; - int iobase = dev->link.io.BasePort1; + int iobase = dev->p_dev->io.BasePort1; for (i = 0; i < POLL_LOOP_COUNT; i++) { if ((xinb(iobase + REG_OFFSET_BUFFER_STATUS) @@ -177,7 +177,7 @@ static int wait_for_bulk_out_ready(struct reader_dev *dev) /* Write to Sync Control Register */ static int write_sync_reg(unsigned char val, struct reader_dev *dev) { - int iobase = dev->link.io.BasePort1; + int iobase = dev->p_dev->io.BasePort1; int rc; rc = wait_for_bulk_out_ready(dev); @@ -195,7 +195,7 @@ static int write_sync_reg(unsigned char val, struct reader_dev *dev) static int wait_for_bulk_in_ready(struct reader_dev *dev) { int i, rc; - int iobase = dev->link.io.BasePort1; + int iobase = dev->p_dev->io.BasePort1; for (i = 0; i < POLL_LOOP_COUNT; i++) { if ((xinb(iobase + REG_OFFSET_BUFFER_STATUS) @@ -225,7 +225,7 @@ static ssize_t cm4040_read(struct file *filp, char __user *buf, size_t count, loff_t *ppos) { struct reader_dev *dev = filp->private_data; - int iobase = dev->link.io.BasePort1; + int iobase = dev->p_dev->io.BasePort1; size_t bytes_to_read; unsigned long i; size_t min_bytes_to_read; @@ -246,7 +246,7 @@ static ssize_t cm4040_read(struct file *filp, char __user *buf, return -EAGAIN; } - if ((dev->link.state & DEV_PRESENT)==0) + if (!pcmcia_dev_present(dev->p_dev)) return -ENODEV; for (i = 0; i < 5; i++) { @@ -328,7 +328,7 @@ static ssize_t cm4040_write(struct file *filp, const char __user *buf, size_t count, loff_t *ppos) { struct reader_dev *dev = filp->private_data; - int iobase = dev->link.io.BasePort1; + int iobase = dev->p_dev->io.BasePort1; ssize_t rc; int i; unsigned int bytes_to_write; @@ -351,7 +351,7 @@ static ssize_t cm4040_write(struct file *filp, const char __user *buf, return -EAGAIN; } - if ((dev->link.state & DEV_PRESENT) == 0) + if (!pcmcia_dev_present(dev->p_dev)) return -ENODEV; bytes_to_write = count; @@ -445,14 +445,14 @@ static unsigned int cm4040_poll(struct file *filp, poll_table *wait) static int cm4040_open(struct inode *inode, struct file *filp) { struct reader_dev *dev; - dev_link_t *link; + struct pcmcia_device *link; int minor = iminor(inode); if (minor >= CM_MAX_DEV) return -ENODEV; link = dev_table[minor]; - if (link == NULL || !(DEV_OK(link))) + if (link == NULL || !pcmcia_dev_present(link)) return -ENODEV; if (link->open) @@ -478,7 +478,7 @@ static int cm4040_open(struct inode *inode, struct file *filp) static int cm4040_close(struct inode *inode, struct file *filp) { struct reader_dev *dev = filp->private_data; - dev_link_t *link; + struct pcmcia_device *link; int minor = iminor(inode); DEBUGP(2, dev, "-> cm4040_close(maj/min=%d.%d)\n", imajor(inode), @@ -500,7 +500,7 @@ static int cm4040_close(struct inode *inode, struct file *filp) return 0; } -static void cm4040_reader_release(dev_link_t *link) +static void cm4040_reader_release(struct pcmcia_device *link) { struct reader_dev *dev = link->priv; @@ -514,60 +514,49 @@ static void cm4040_reader_release(dev_link_t *link) return; } -static void reader_config(dev_link_t *link, int devno) +static int reader_config(struct pcmcia_device *link, int devno) { - client_handle_t handle; struct reader_dev *dev; tuple_t tuple; cisparse_t parse; - config_info_t conf; u_char buf[64]; int fail_fn, fail_rc; int rc; - handle = link->handle; - tuple.DesiredTuple = CISTPL_CONFIG; tuple.Attributes = 0; tuple.TupleData = buf; tuple.TupleDataMax = sizeof(buf); tuple.TupleOffset = 0; - if ((fail_rc = pcmcia_get_first_tuple(handle, &tuple)) != CS_SUCCESS) { + if ((fail_rc = pcmcia_get_first_tuple(link, &tuple)) != CS_SUCCESS) { fail_fn = GetFirstTuple; goto cs_failed; } - if ((fail_rc = pcmcia_get_tuple_data(handle, &tuple)) != CS_SUCCESS) { + if ((fail_rc = pcmcia_get_tuple_data(link, &tuple)) != CS_SUCCESS) { fail_fn = GetTupleData; goto cs_failed; } - if ((fail_rc = pcmcia_parse_tuple(handle, &tuple, &parse)) + if ((fail_rc = pcmcia_parse_tuple(link, &tuple, &parse)) != CS_SUCCESS) { fail_fn = ParseTuple; goto cs_failed; } - if ((fail_rc = pcmcia_get_configuration_info(handle, &conf)) - != CS_SUCCESS) { - fail_fn = GetConfigurationInfo; - goto cs_failed; - } - link->state |= DEV_CONFIG; link->conf.ConfigBase = parse.config.base; link->conf.Present = parse.config.rmask[0]; - link->conf.Vcc = conf.Vcc; link->io.BasePort2 = 0; link->io.NumPorts2 = 0; link->io.Attributes2 = 0; tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; - for (rc = pcmcia_get_first_tuple(handle, &tuple); + for (rc = pcmcia_get_first_tuple(link, &tuple); rc == CS_SUCCESS; - rc = pcmcia_get_next_tuple(handle, &tuple)) { - rc = pcmcia_get_tuple_data(handle, &tuple); + rc = pcmcia_get_next_tuple(link, &tuple)) { + rc = pcmcia_get_tuple_data(link, &tuple); if (rc != CS_SUCCESS) continue; - rc = pcmcia_parse_tuple(handle, &tuple, &parse); + rc = pcmcia_parse_tuple(link, &tuple, &parse); if (rc != CS_SUCCESS) continue; @@ -585,13 +574,13 @@ static void reader_config(dev_link_t *link, int devno) link->io.Attributes1 = IO_DATA_PATH_WIDTH_8; link->io.IOAddrLines = parse.cftable_entry.io.flags & CISTPL_IO_LINES_MASK; - rc = pcmcia_request_io(handle, &link->io); + rc = pcmcia_request_io(link, &link->io); - dev_printk(KERN_INFO, &handle_to_dev(handle), "foo"); + dev_printk(KERN_INFO, &handle_to_dev(link), "foo"); if (rc == CS_SUCCESS) break; else - dev_printk(KERN_INFO, &handle_to_dev(handle), + dev_printk(KERN_INFO, &handle_to_dev(link), "pcmcia_request_io failed 0x%x\n", rc); } if (rc != CS_SUCCESS) @@ -599,10 +588,10 @@ static void reader_config(dev_link_t *link, int devno) link->conf.IntType = 00000002; - if ((fail_rc = pcmcia_request_configuration(handle,&link->conf)) + if ((fail_rc = pcmcia_request_configuration(link,&link->conf)) !=CS_SUCCESS) { fail_fn = RequestConfiguration; - dev_printk(KERN_INFO, &handle_to_dev(handle), + dev_printk(KERN_INFO, &handle_to_dev(link), "pcmcia_request_configuration failed 0x%x\n", fail_rc); goto cs_release; @@ -612,57 +601,31 @@ static void reader_config(dev_link_t *link, int devno) sprintf(dev->node.dev_name, DEVICE_NAME "%d", devno); dev->node.major = major; dev->node.minor = devno; - dev->node.next = NULL; - link->dev = &dev->node; - link->state &= ~DEV_CONFIG_PENDING; + dev->node.next = &dev->node; DEBUGP(2, dev, "device " DEVICE_NAME "%d at 0x%.4x-0x%.4x\n", devno, link->io.BasePort1, link->io.BasePort1+link->io.NumPorts1); DEBUGP(2, dev, "<- reader_config (succ)\n"); - return; + return 0; cs_failed: - cs_error(handle, fail_fn, fail_rc); + cs_error(link, fail_fn, fail_rc); cs_release: reader_release(link); - link->state &= ~DEV_CONFIG_PENDING; -} - -static int reader_suspend(struct pcmcia_device *p_dev) -{ - dev_link_t *link = dev_to_instance(p_dev); - - link->state |= DEV_SUSPEND; - if (link->state & DEV_CONFIG) - pcmcia_release_configuration(link->handle); - - return 0; + return -ENODEV; } -static int reader_resume(struct pcmcia_device *p_dev) -{ - dev_link_t *link = dev_to_instance(p_dev); - - link->state &= ~DEV_SUSPEND; - if (link->state & DEV_CONFIG) - pcmcia_request_configuration(link->handle, &link->conf); - - return 0; -} - -static void reader_release(dev_link_t *link) +static void reader_release(struct pcmcia_device *link) { cm4040_reader_release(link->priv); - pcmcia_release_configuration(link->handle); - pcmcia_release_io(link->handle, &link->io); + pcmcia_disable_device(link); } -static int reader_attach(struct pcmcia_device *p_dev) +static int reader_probe(struct pcmcia_device *link) { struct reader_dev *dev; - dev_link_t *link; - int i; + int i, ret; for (i = 0; i < CM_MAX_DEV; i++) { if (dev_table[i] == NULL) @@ -679,8 +642,8 @@ static int reader_attach(struct pcmcia_device *p_dev) dev->timeout = CCID_DRIVER_MINIMUM_TIMEOUT; dev->buffer_status = 0; - link = &dev->link; link->priv = dev; + dev->p_dev = link; link->conf.IntType = INT_MEMORY_AND_IO; dev_table[i] = link; @@ -692,11 +655,9 @@ static int reader_attach(struct pcmcia_device *p_dev) init_timer(&dev->poll_timer); dev->poll_timer.function = &cm4040_do_poll; - link->handle = p_dev; - p_dev->instance = link; - - link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; - reader_config(link, i); + ret = reader_config(link, i); + if (ret) + return ret; class_device_create(cmx_class, NULL, MKDEV(major, i), NULL, "cmx%d", i); @@ -704,9 +665,8 @@ static int reader_attach(struct pcmcia_device *p_dev) return 0; } -static void reader_detach(struct pcmcia_device *p_dev) +static void reader_detach(struct pcmcia_device *link) { - dev_link_t *link = dev_to_instance(p_dev); struct reader_dev *dev = link->priv; int devno; @@ -718,10 +678,7 @@ static void reader_detach(struct pcmcia_device *p_dev) if (devno == CM_MAX_DEV) return; - link->state &= ~DEV_PRESENT; - - if (link->state & DEV_CONFIG) - reader_release(link); + reader_release(link); dev_table[devno] = NULL; kfree(dev); @@ -753,10 +710,8 @@ static struct pcmcia_driver reader_driver = { .drv = { .name = "cm4040_cs", }, - .probe = reader_attach, + .probe = reader_probe, .remove = reader_detach, - .suspend = reader_suspend, - .resume = reader_resume, .id_table = cm4040_ids, }; diff --git a/drivers/char/pcmcia/synclink_cs.c b/drivers/char/pcmcia/synclink_cs.c index e6b714b6390..07213454c45 100644 --- a/drivers/char/pcmcia/synclink_cs.c +++ b/drivers/char/pcmcia/synclink_cs.c @@ -228,7 +228,7 @@ typedef struct _mgslpc_info { struct _input_signal_events input_signal_events; /* PCMCIA support */ - dev_link_t link; + struct pcmcia_device *p_dev; dev_node_t node; int stop; @@ -484,7 +484,7 @@ static void mgslpc_wait_until_sent(struct tty_struct *tty, int timeout); /* PCMCIA prototypes */ -static void mgslpc_config(dev_link_t *link); +static int mgslpc_config(struct pcmcia_device *link); static void mgslpc_release(u_long arg); static void mgslpc_detach(struct pcmcia_device *p_dev); @@ -533,14 +533,14 @@ static void ldisc_receive_buf(struct tty_struct *tty, } } -static int mgslpc_attach(struct pcmcia_device *p_dev) +static int mgslpc_probe(struct pcmcia_device *link) { MGSLPC_INFO *info; - dev_link_t *link; - + int ret; + if (debug_level >= DEBUG_LEVEL_INFO) printk("mgslpc_attach\n"); - + info = (MGSLPC_INFO *)kmalloc(sizeof(MGSLPC_INFO), GFP_KERNEL); if (!info) { printk("Error can't allocate device instance data\n"); @@ -565,25 +565,22 @@ static int mgslpc_attach(struct pcmcia_device *p_dev) info->imrb_value = 0xffff; info->pim_value = 0xff; - link = &info->link; + info->p_dev = link; link->priv = info; - - /* Initialize the dev_link_t structure */ + + /* Initialize the struct pcmcia_device structure */ /* Interrupt setup */ link->irq.Attributes = IRQ_TYPE_EXCLUSIVE; link->irq.IRQInfo1 = IRQ_LEVEL_ID; link->irq.Handler = NULL; - + link->conf.Attributes = 0; - link->conf.Vcc = 50; link->conf.IntType = INT_MEMORY_AND_IO; - link->handle = p_dev; - p_dev->instance = link; - - link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; - mgslpc_config(link); + ret = mgslpc_config(link); + if (ret) + return ret; mgslpc_add_device(info); @@ -596,15 +593,13 @@ static int mgslpc_attach(struct pcmcia_device *p_dev) #define CS_CHECK(fn, ret) \ do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0) -static void mgslpc_config(dev_link_t *link) +static int mgslpc_config(struct pcmcia_device *link) { - client_handle_t handle = link->handle; MGSLPC_INFO *info = link->priv; tuple_t tuple; cisparse_t parse; int last_fn, last_ret; u_char buf[64]; - config_info_t conf; cistpl_cftable_entry_t dflt = { 0 }; cistpl_cftable_entry_t *cfg; @@ -617,27 +612,20 @@ static void mgslpc_config(dev_link_t *link) tuple.TupleData = buf; tuple.TupleDataMax = sizeof(buf); tuple.TupleOffset = 0; - CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple)); - CS_CHECK(GetTupleData, pcmcia_get_tuple_data(handle, &tuple)); - CS_CHECK(ParseTuple, pcmcia_parse_tuple(handle, &tuple, &parse)); + CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); + CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple)); + CS_CHECK(ParseTuple, pcmcia_parse_tuple(link, &tuple, &parse)); link->conf.ConfigBase = parse.config.base; link->conf.Present = parse.config.rmask[0]; - - /* Configure card */ - link->state |= DEV_CONFIG; - - /* Look up the current Vcc */ - CS_CHECK(GetConfigurationInfo, pcmcia_get_configuration_info(handle, &conf)); - link->conf.Vcc = conf.Vcc; /* get CIS configuration entry */ tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; - CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple)); + CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); cfg = &(parse.cftable_entry); - CS_CHECK(GetTupleData, pcmcia_get_tuple_data(handle, &tuple)); - CS_CHECK(ParseTuple, pcmcia_parse_tuple(handle, &tuple, &parse)); + CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple)); + CS_CHECK(ParseTuple, pcmcia_parse_tuple(link, &tuple, &parse)); if (cfg->flags & CISTPL_CFTABLE_DEFAULT) dflt = *cfg; if (cfg->index == 0) @@ -658,11 +646,10 @@ static void mgslpc_config(dev_link_t *link) link->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK; link->io.BasePort1 = io->win[0].base; link->io.NumPorts1 = io->win[0].len; - CS_CHECK(RequestIO, pcmcia_request_io(link->handle, &link->io)); + CS_CHECK(RequestIO, pcmcia_request_io(link, &link->io)); } link->conf.Attributes = CONF_ENABLE_IRQ; - link->conf.Vcc = 50; link->conf.IntType = INT_MEMORY_AND_IO; link->conf.ConfigIndex = 8; link->conf.Present = PRESENT_OPTION; @@ -670,9 +657,9 @@ static void mgslpc_config(dev_link_t *link) link->irq.Attributes |= IRQ_HANDLE_PRESENT; link->irq.Handler = mgslpc_isr; link->irq.Instance = info; - CS_CHECK(RequestIRQ, pcmcia_request_irq(link->handle, &link->irq)); + CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq)); - CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link->handle, &link->conf)); + CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf)); info->io_base = link->io.BasePort1; info->irq_level = link->irq.AssignedIRQ; @@ -680,7 +667,7 @@ static void mgslpc_config(dev_link_t *link) /* add to linked list of devices */ sprintf(info->node.dev_name, "mgslpc0"); info->node.major = info->node.minor = 0; - link->dev = &info->node; + link->dev_node = &info->node; printk(KERN_INFO "%s: index 0x%02x:", info->node.dev_name, link->conf.ConfigIndex); @@ -690,13 +677,12 @@ static void mgslpc_config(dev_link_t *link) printk(", io 0x%04x-0x%04x", link->io.BasePort1, link->io.BasePort1+link->io.NumPorts1-1); printk("\n"); - - link->state &= ~DEV_CONFIG_PENDING; - return; + return 0; cs_failed: - cs_error(link->handle, last_fn, last_ret); + cs_error(link, last_fn, last_ret); mgslpc_release((u_long)link); + return -ENODEV; } /* Card has been removed. @@ -705,58 +691,38 @@ cs_failed: */ static void mgslpc_release(u_long arg) { - dev_link_t *link = (dev_link_t *)arg; + struct pcmcia_device *link = (struct pcmcia_device *)arg; - if (debug_level >= DEBUG_LEVEL_INFO) - printk("mgslpc_release(0x%p)\n", link); - - /* Unlink the device chain */ - link->dev = NULL; - link->state &= ~DEV_CONFIG; + if (debug_level >= DEBUG_LEVEL_INFO) + printk("mgslpc_release(0x%p)\n", link); - pcmcia_release_configuration(link->handle); - if (link->io.NumPorts1) - pcmcia_release_io(link->handle, &link->io); - if (link->irq.AssignedIRQ) - pcmcia_release_irq(link->handle, &link->irq); + pcmcia_disable_device(link); } -static void mgslpc_detach(struct pcmcia_device *p_dev) +static void mgslpc_detach(struct pcmcia_device *link) { - dev_link_t *link = dev_to_instance(p_dev); - - if (debug_level >= DEBUG_LEVEL_INFO) - printk("mgslpc_detach(0x%p)\n", link); + if (debug_level >= DEBUG_LEVEL_INFO) + printk("mgslpc_detach(0x%p)\n", link); - if (link->state & DEV_CONFIG) { - ((MGSLPC_INFO *)link->priv)->stop = 1; - mgslpc_release((u_long)link); - } + ((MGSLPC_INFO *)link->priv)->stop = 1; + mgslpc_release((u_long)link); - mgslpc_remove_device((MGSLPC_INFO *)link->priv); + mgslpc_remove_device((MGSLPC_INFO *)link->priv); } -static int mgslpc_suspend(struct pcmcia_device *dev) +static int mgslpc_suspend(struct pcmcia_device *link) { - dev_link_t *link = dev_to_instance(dev); MGSLPC_INFO *info = link->priv; - link->state |= DEV_SUSPEND; info->stop = 1; - if (link->state & DEV_CONFIG) - pcmcia_release_configuration(link->handle); return 0; } -static int mgslpc_resume(struct pcmcia_device *dev) +static int mgslpc_resume(struct pcmcia_device *link) { - dev_link_t *link = dev_to_instance(dev); MGSLPC_INFO *info = link->priv; - link->state &= ~DEV_SUSPEND; - if (link->state & DEV_CONFIG) - pcmcia_request_configuration(link->handle, &link->conf); info->stop = 0; return 0; @@ -1280,7 +1246,7 @@ static irqreturn_t mgslpc_isr(int irq, void *dev_id, struct pt_regs * regs) if (!info) return IRQ_NONE; - if (!(info->link.state & DEV_CONFIG)) + if (!(info->p_dev->_locked)) return IRQ_HANDLED; spin_lock(&info->lock); @@ -3033,7 +2999,7 @@ static struct pcmcia_driver mgslpc_driver = { .drv = { .name = "synclink_cs", }, - .probe = mgslpc_attach, + .probe = mgslpc_probe, .remove = mgslpc_detach, .id_table = mgslpc_ids, .suspend = mgslpc_suspend, diff --git a/drivers/char/stallion.c b/drivers/char/stallion.c index 3f5d6077f39..a9c5a7230f8 100644 --- a/drivers/char/stallion.c +++ b/drivers/char/stallion.c @@ -504,7 +504,6 @@ static int stl_echmcaintr(stlbrd_t *brdp); static int stl_echpciintr(stlbrd_t *brdp); static int stl_echpci64intr(stlbrd_t *brdp); static void stl_offintr(void *private); -static void *stl_memalloc(int len); static stlbrd_t *stl_allocbrd(void); static stlport_t *stl_getport(int brdnr, int panelnr, int portnr); @@ -940,17 +939,6 @@ static int stl_parsebrd(stlconf_t *confp, char **argp) /*****************************************************************************/ /* - * Local driver kernel memory allocation routine. - */ - -static void *stl_memalloc(int len) -{ - return (void *) kmalloc(len, GFP_KERNEL); -} - -/*****************************************************************************/ - -/* * Allocate a new board structure. Fill out the basic info in it. */ @@ -958,14 +946,13 @@ static stlbrd_t *stl_allocbrd(void) { stlbrd_t *brdp; - brdp = (stlbrd_t *) stl_memalloc(sizeof(stlbrd_t)); - if (brdp == (stlbrd_t *) NULL) { + brdp = kzalloc(sizeof(stlbrd_t), GFP_KERNEL); + if (!brdp) { printk("STALLION: failed to allocate memory (size=%d)\n", sizeof(stlbrd_t)); - return (stlbrd_t *) NULL; + return NULL; } - memset(brdp, 0, sizeof(stlbrd_t)); brdp->magic = STL_BOARDMAGIC; return brdp; } @@ -1017,9 +1004,9 @@ static int stl_open(struct tty_struct *tty, struct file *filp) portp->refcount++; if ((portp->flags & ASYNC_INITIALIZED) == 0) { - if (portp->tx.buf == (char *) NULL) { - portp->tx.buf = (char *) stl_memalloc(STL_TXBUFSIZE); - if (portp->tx.buf == (char *) NULL) + if (!portp->tx.buf) { + portp->tx.buf = kmalloc(STL_TXBUFSIZE, GFP_KERNEL); + if (!portp->tx.buf) return -ENOMEM; portp->tx.head = portp->tx.buf; portp->tx.tail = portp->tx.buf; @@ -2178,13 +2165,12 @@ static int __init stl_initports(stlbrd_t *brdp, stlpanel_t *panelp) * each ports data structures. */ for (i = 0; (i < panelp->nrports); i++) { - portp = (stlport_t *) stl_memalloc(sizeof(stlport_t)); - if (portp == (stlport_t *) NULL) { + portp = kzalloc(sizeof(stlport_t), GFP_KERNEL); + if (!portp) { printk("STALLION: failed to allocate memory " "(size=%d)\n", sizeof(stlport_t)); break; } - memset(portp, 0, sizeof(stlport_t)); portp->magic = STL_PORTMAGIC; portp->portnr = i; @@ -2315,13 +2301,12 @@ static inline int stl_initeio(stlbrd_t *brdp) * can complete the setup. */ - panelp = (stlpanel_t *) stl_memalloc(sizeof(stlpanel_t)); - if (panelp == (stlpanel_t *) NULL) { + panelp = kzalloc(sizeof(stlpanel_t), GFP_KERNEL); + if (!panelp) { printk(KERN_WARNING "STALLION: failed to allocate memory " "(size=%d)\n", sizeof(stlpanel_t)); - return(-ENOMEM); + return -ENOMEM; } - memset(panelp, 0, sizeof(stlpanel_t)); panelp->magic = STL_PANELMAGIC; panelp->brdnr = brdp->brdnr; @@ -2490,13 +2475,12 @@ static inline int stl_initech(stlbrd_t *brdp) status = inb(ioaddr + ECH_PNLSTATUS); if ((status & ECH_PNLIDMASK) != nxtid) break; - panelp = (stlpanel_t *) stl_memalloc(sizeof(stlpanel_t)); - if (panelp == (stlpanel_t *) NULL) { + panelp = kzalloc(sizeof(stlpanel_t), GFP_KERNEL); + if (!panelp) { printk("STALLION: failed to allocate memory " "(size=%d)\n", sizeof(stlpanel_t)); break; } - memset(panelp, 0, sizeof(stlpanel_t)); panelp->magic = STL_PANELMAGIC; panelp->brdnr = brdp->brdnr; panelp->panelnr = panelnr; @@ -3074,8 +3058,8 @@ static int __init stl_init(void) /* * Allocate a temporary write buffer. */ - stl_tmpwritebuf = (char *) stl_memalloc(STL_TXBUFSIZE); - if (stl_tmpwritebuf == (char *) NULL) + stl_tmpwritebuf = kmalloc(STL_TXBUFSIZE, GFP_KERNEL); + if (!stl_tmpwritebuf) printk("STALLION: failed to allocate memory (size=%d)\n", STL_TXBUFSIZE); diff --git a/drivers/char/tty_io.c b/drivers/char/tty_io.c index 0bfd1b63662..98b126c2ded 100644 --- a/drivers/char/tty_io.c +++ b/drivers/char/tty_io.c @@ -376,7 +376,7 @@ int tty_insert_flip_string(struct tty_struct *tty, const unsigned char *chars, s return copied; } -EXPORT_SYMBOL_GPL(tty_insert_flip_string); +EXPORT_SYMBOL(tty_insert_flip_string); int tty_insert_flip_string_flags(struct tty_struct *tty, const unsigned char *chars, const char *flags, size_t size) { diff --git a/drivers/char/vt.c b/drivers/char/vt.c index ca4844c527d..acc5d47844e 100644 --- a/drivers/char/vt.c +++ b/drivers/char/vt.c @@ -2328,6 +2328,10 @@ int tioclinux(struct tty_struct *tty, unsigned long arg) case TIOCL_SETVESABLANK: set_vesa_blanking(p); break; + case TIOCL_GETKMSGREDIRECT: + data = kmsg_redirect; + ret = __put_user(data, p); + break; case TIOCL_SETKMSGREDIRECT: if (!capable(CAP_SYS_ADMIN)) { ret = -EPERM; diff --git a/drivers/edac/Kconfig b/drivers/edac/Kconfig index b582d0cdc24..4f0898400c6 100644 --- a/drivers/edac/Kconfig +++ b/drivers/edac/Kconfig @@ -71,7 +71,7 @@ config EDAC_E7XXX config EDAC_E752X tristate "Intel e752x (e7520, e7525, e7320)" - depends on EDAC_MM_EDAC && PCI && X86 + depends on EDAC_MM_EDAC && PCI && X86 && HOTPLUG help Support for error detection and correction on the Intel E7520, E7525, E7320 server chipsets. diff --git a/drivers/ide/ide-disk.c b/drivers/ide/ide-disk.c index ccf528d733b..a5017de72da 100644 --- a/drivers/ide/ide-disk.c +++ b/drivers/ide/ide-disk.c @@ -61,6 +61,7 @@ #include <linux/slab.h> #include <linux/delay.h> #include <linux/mutex.h> +#include <linux/leds.h> #define _IDE_DISK @@ -317,6 +318,8 @@ static ide_startstop_t ide_do_rw_disk (ide_drive_t *drive, struct request *rq, s return ide_stopped; } + ledtrig_ide_activity(); + pr_debug("%s: %sing: block=%llu, sectors=%lu, buffer=0x%08lx\n", drive->name, rq_data_dir(rq) == READ ? "read" : "writ", (unsigned long long)block, rq->nr_sectors, diff --git a/drivers/ide/ide-taskfile.c b/drivers/ide/ide-taskfile.c index 0606bd2f602..9233b8109a0 100644 --- a/drivers/ide/ide-taskfile.c +++ b/drivers/ide/ide-taskfile.c @@ -375,7 +375,13 @@ static void task_end_request(ide_drive_t *drive, struct request *rq, u8 stat) } } - ide_end_request(drive, 1, rq->hard_nr_sectors); + if (rq->rq_disk) { + ide_driver_t *drv; + + drv = *(ide_driver_t **)rq->rq_disk->private_data;; + drv->end_request(drive, 1, rq->hard_nr_sectors); + } else + ide_end_request(drive, 1, rq->hard_nr_sectors); } /* diff --git a/drivers/ide/legacy/ide-cs.c b/drivers/ide/legacy/ide-cs.c index 6213bd3caee..4961f1e764a 100644 --- a/drivers/ide/legacy/ide-cs.c +++ b/drivers/ide/legacy/ide-cs.c @@ -81,14 +81,14 @@ static const char ide_major[] = { }; typedef struct ide_info_t { - dev_link_t link; + struct pcmcia_device *p_dev; int ndev; dev_node_t node; int hd; } ide_info_t; -static void ide_release(dev_link_t *); -static void ide_config(dev_link_t *); +static void ide_release(struct pcmcia_device *); +static int ide_config(struct pcmcia_device *); static void ide_detach(struct pcmcia_device *p_dev); @@ -103,10 +103,9 @@ static void ide_detach(struct pcmcia_device *p_dev); ======================================================================*/ -static int ide_attach(struct pcmcia_device *p_dev) +static int ide_probe(struct pcmcia_device *link) { ide_info_t *info; - dev_link_t *link; DEBUG(0, "ide_attach()\n"); @@ -114,7 +113,9 @@ static int ide_attach(struct pcmcia_device *p_dev) info = kzalloc(sizeof(*info), GFP_KERNEL); if (!info) return -ENOMEM; - link = &info->link; link->priv = info; + + info->p_dev = link; + link->priv = info; link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO; link->io.Attributes2 = IO_DATA_PATH_WIDTH_8; @@ -122,16 +123,9 @@ static int ide_attach(struct pcmcia_device *p_dev) link->irq.Attributes = IRQ_TYPE_EXCLUSIVE; link->irq.IRQInfo1 = IRQ_LEVEL_ID; link->conf.Attributes = CONF_ENABLE_IRQ; - link->conf.Vcc = 50; link->conf.IntType = INT_MEMORY_AND_IO; - link->handle = p_dev; - p_dev->instance = link; - - link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; - ide_config(link); - - return 0; + return ide_config(link); } /* ide_attach */ /*====================================================================== @@ -143,14 +137,11 @@ static int ide_attach(struct pcmcia_device *p_dev) ======================================================================*/ -static void ide_detach(struct pcmcia_device *p_dev) +static void ide_detach(struct pcmcia_device *link) { - dev_link_t *link = dev_to_instance(p_dev); - DEBUG(0, "ide_detach(0x%p)\n", link); - if (link->state & DEV_CONFIG) - ide_release(link); + ide_release(link); kfree(link->priv); } /* ide_detach */ @@ -177,9 +168,8 @@ static int idecs_register(unsigned long io, unsigned long ctl, unsigned long irq #define CS_CHECK(fn, ret) \ do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0) -static void ide_config(dev_link_t *link) +static int ide_config(struct pcmcia_device *link) { - client_handle_t handle = link->handle; ide_info_t *info = link->priv; tuple_t tuple; struct { @@ -203,34 +193,30 @@ static void ide_config(dev_link_t *link) tuple.TupleDataMax = 255; tuple.Attributes = 0; tuple.DesiredTuple = CISTPL_CONFIG; - CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple)); - CS_CHECK(GetTupleData, pcmcia_get_tuple_data(handle, &tuple)); - CS_CHECK(ParseTuple, pcmcia_parse_tuple(handle, &tuple, &stk->parse)); + CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); + CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple)); + CS_CHECK(ParseTuple, pcmcia_parse_tuple(link, &tuple, &stk->parse)); link->conf.ConfigBase = stk->parse.config.base; link->conf.Present = stk->parse.config.rmask[0]; tuple.DesiredTuple = CISTPL_MANFID; - if (!pcmcia_get_first_tuple(handle, &tuple) && - !pcmcia_get_tuple_data(handle, &tuple) && - !pcmcia_parse_tuple(handle, &tuple, &stk->parse)) + if (!pcmcia_get_first_tuple(link, &tuple) && + !pcmcia_get_tuple_data(link, &tuple) && + !pcmcia_parse_tuple(link, &tuple, &stk->parse)) is_kme = ((stk->parse.manfid.manf == MANFID_KME) && ((stk->parse.manfid.card == PRODID_KME_KXLC005_A) || (stk->parse.manfid.card == PRODID_KME_KXLC005_B))); - /* Configure card */ - link->state |= DEV_CONFIG; - /* Not sure if this is right... look up the current Vcc */ - CS_CHECK(GetConfigurationInfo, pcmcia_get_configuration_info(handle, &stk->conf)); - link->conf.Vcc = stk->conf.Vcc; + CS_CHECK(GetConfigurationInfo, pcmcia_get_configuration_info(link, &stk->conf)); pass = io_base = ctl_base = 0; tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; tuple.Attributes = 0; - CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple)); + CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); while (1) { - if (pcmcia_get_tuple_data(handle, &tuple) != 0) goto next_entry; - if (pcmcia_parse_tuple(handle, &tuple, &stk->parse) != 0) goto next_entry; + if (pcmcia_get_tuple_data(link, &tuple) != 0) goto next_entry; + if (pcmcia_parse_tuple(link, &tuple, &stk->parse) != 0) goto next_entry; /* Check for matching Vcc, unless we're desperate */ if (!pass) { @@ -244,10 +230,10 @@ static void ide_config(dev_link_t *link) } if (cfg->vpp1.present & (1 << CISTPL_POWER_VNOM)) - link->conf.Vpp1 = link->conf.Vpp2 = + link->conf.Vpp = cfg->vpp1.param[CISTPL_POWER_VNOM] / 10000; else if (stk->dflt.vpp1.present & (1 << CISTPL_POWER_VNOM)) - link->conf.Vpp1 = link->conf.Vpp2 = + link->conf.Vpp = stk->dflt.vpp1.param[CISTPL_POWER_VNOM] / 10000; if ((cfg->io.nwin > 0) || (stk->dflt.io.nwin > 0)) { @@ -261,14 +247,14 @@ static void ide_config(dev_link_t *link) link->io.NumPorts1 = 8; link->io.BasePort2 = io->win[1].base; link->io.NumPorts2 = (is_kme) ? 2 : 1; - if (pcmcia_request_io(link->handle, &link->io) != 0) + if (pcmcia_request_io(link, &link->io) != 0) goto next_entry; io_base = link->io.BasePort1; ctl_base = link->io.BasePort2; } else if ((io->nwin == 1) && (io->win[0].len >= 16)) { link->io.NumPorts1 = io->win[0].len; link->io.NumPorts2 = 0; - if (pcmcia_request_io(link->handle, &link->io) != 0) + if (pcmcia_request_io(link, &link->io) != 0) goto next_entry; io_base = link->io.BasePort1; ctl_base = link->io.BasePort1 + 0x0e; @@ -281,16 +267,16 @@ static void ide_config(dev_link_t *link) if (cfg->flags & CISTPL_CFTABLE_DEFAULT) memcpy(&stk->dflt, cfg, sizeof(stk->dflt)); if (pass) { - CS_CHECK(GetNextTuple, pcmcia_get_next_tuple(handle, &tuple)); - } else if (pcmcia_get_next_tuple(handle, &tuple) != 0) { - CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple)); + CS_CHECK(GetNextTuple, pcmcia_get_next_tuple(link, &tuple)); + } else if (pcmcia_get_next_tuple(link, &tuple) != 0) { + CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); memset(&stk->dflt, 0, sizeof(stk->dflt)); pass++; } } - CS_CHECK(RequestIRQ, pcmcia_request_irq(handle, &link->irq)); - CS_CHECK(RequestConfiguration, pcmcia_request_configuration(handle, &link->conf)); + CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq)); + CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf)); /* disable drive interrupts during IDE probe */ outb(0x02, ctl_base); @@ -301,12 +287,12 @@ static void ide_config(dev_link_t *link) /* retry registration in case device is still spinning up */ for (hd = -1, i = 0; i < 10; i++) { - hd = idecs_register(io_base, ctl_base, link->irq.AssignedIRQ, handle); + hd = idecs_register(io_base, ctl_base, link->irq.AssignedIRQ, link); if (hd >= 0) break; if (link->io.NumPorts1 == 0x20) { outb(0x02, ctl_base + 0x10); hd = idecs_register(io_base + 0x10, ctl_base + 0x10, - link->irq.AssignedIRQ, handle); + link->irq.AssignedIRQ, link); if (hd >= 0) { io_base += 0x10; ctl_base += 0x10; @@ -328,25 +314,23 @@ static void ide_config(dev_link_t *link) info->node.major = ide_major[hd]; info->node.minor = 0; info->hd = hd; - link->dev = &info->node; - printk(KERN_INFO "ide-cs: %s: Vcc = %d.%d, Vpp = %d.%d\n", - info->node.dev_name, link->conf.Vcc / 10, link->conf.Vcc % 10, - link->conf.Vpp1 / 10, link->conf.Vpp1 % 10); + link->dev_node = &info->node; + printk(KERN_INFO "ide-cs: %s: Vpp = %d.%d\n", + info->node.dev_name, link->conf.Vpp / 10, link->conf.Vpp % 10); - link->state &= ~DEV_CONFIG_PENDING; kfree(stk); - return; + return 0; err_mem: printk(KERN_NOTICE "ide-cs: ide_config failed memory allocation\n"); goto failed; cs_failed: - cs_error(link->handle, last_fn, last_ret); + cs_error(link, last_fn, last_ret); failed: kfree(stk); ide_release(link); - link->state &= ~DEV_CONFIG_PENDING; + return -ENODEV; } /* ide_config */ /*====================================================================== @@ -357,7 +341,7 @@ failed: ======================================================================*/ -void ide_release(dev_link_t *link) +void ide_release(struct pcmcia_device *link) { ide_info_t *info = link->priv; @@ -369,37 +353,10 @@ void ide_release(dev_link_t *link) ide_unregister(info->hd); } info->ndev = 0; - link->dev = NULL; - - pcmcia_release_configuration(link->handle); - pcmcia_release_io(link->handle, &link->io); - pcmcia_release_irq(link->handle, &link->irq); - - link->state &= ~DEV_CONFIG; + pcmcia_disable_device(link); } /* ide_release */ -static int ide_suspend(struct pcmcia_device *dev) -{ - dev_link_t *link = dev_to_instance(dev); - - link->state |= DEV_SUSPEND; - if (link->state & DEV_CONFIG) - pcmcia_release_configuration(link->handle); - - return 0; -} - -static int ide_resume(struct pcmcia_device *dev) -{ - dev_link_t *link = dev_to_instance(dev); - - link->state &= ~DEV_SUSPEND; - if (DEV_OK(link)) - pcmcia_request_configuration(link->handle, &link->conf); - - return 0; -} /*====================================================================== @@ -459,11 +416,9 @@ static struct pcmcia_driver ide_cs_driver = { .drv = { .name = "ide-cs", }, - .probe = ide_attach, + .probe = ide_probe, .remove = ide_detach, .id_table = ide_ids, - .suspend = ide_suspend, - .resume = ide_resume, }; static int __init init_ide_cs(void) diff --git a/drivers/input/evbug.c b/drivers/input/evbug.c index d7828936fd8..07358fb51b8 100644 --- a/drivers/input/evbug.c +++ b/drivers/input/evbug.c @@ -49,9 +49,8 @@ static struct input_handle *evbug_connect(struct input_handler *handler, struct { struct input_handle *handle; - if (!(handle = kmalloc(sizeof(struct input_handle), GFP_KERNEL))) + if (!(handle = kzalloc(sizeof(struct input_handle), GFP_KERNEL))) return NULL; - memset(handle, 0, sizeof(struct input_handle)); handle->dev = dev; handle->handler = handler; diff --git a/drivers/input/evdev.c b/drivers/input/evdev.c index 745979f33dc..a34e3d91d9e 100644 --- a/drivers/input/evdev.c +++ b/drivers/input/evdev.c @@ -130,9 +130,8 @@ static int evdev_open(struct inode * inode, struct file * file) if ((accept_err = input_accept_process(&(evdev_table[i]->handle), file))) return accept_err; - if (!(list = kmalloc(sizeof(struct evdev_list), GFP_KERNEL))) + if (!(list = kzalloc(sizeof(struct evdev_list), GFP_KERNEL))) return -ENOMEM; - memset(list, 0, sizeof(struct evdev_list)); list->evdev = evdev_table[i]; list_add_tail(&list->node, &evdev_table[i]->list); @@ -609,9 +608,8 @@ static struct input_handle *evdev_connect(struct input_handler *handler, struct return NULL; } - if (!(evdev = kmalloc(sizeof(struct evdev), GFP_KERNEL))) + if (!(evdev = kzalloc(sizeof(struct evdev), GFP_KERNEL))) return NULL; - memset(evdev, 0, sizeof(struct evdev)); INIT_LIST_HEAD(&evdev->list); init_waitqueue_head(&evdev->wait); diff --git a/drivers/input/gameport/gameport.c b/drivers/input/gameport/gameport.c index b765a155c00..36644bff379 100644 --- a/drivers/input/gameport/gameport.c +++ b/drivers/input/gameport/gameport.c @@ -22,6 +22,7 @@ #include <linux/delay.h> #include <linux/kthread.h> #include <linux/sched.h> /* HZ */ +#include <linux/mutex.h> /*#include <asm/io.h>*/ @@ -43,10 +44,10 @@ EXPORT_SYMBOL(gameport_start_polling); EXPORT_SYMBOL(gameport_stop_polling); /* - * gameport_sem protects entire gameport subsystem and is taken + * gameport_mutex protects entire gameport subsystem and is taken * every time gameport port or driver registrered or unregistered. */ -static DECLARE_MUTEX(gameport_sem); +static DEFINE_MUTEX(gameport_mutex); static LIST_HEAD(gameport_list); @@ -265,6 +266,7 @@ static void gameport_queue_event(void *object, struct module *owner, if ((event = kmalloc(sizeof(struct gameport_event), GFP_ATOMIC))) { if (!try_module_get(owner)) { printk(KERN_WARNING "gameport: Can't get module reference, dropping event %d\n", event_type); + kfree(event); goto out; } @@ -342,7 +344,7 @@ static void gameport_handle_event(void) struct gameport_event *event; struct gameport_driver *gameport_drv; - down(&gameport_sem); + mutex_lock(&gameport_mutex); /* * Note that we handle only one event here to give swsusp @@ -379,7 +381,7 @@ static void gameport_handle_event(void) gameport_free_event(event); } - up(&gameport_sem); + mutex_unlock(&gameport_mutex); } /* @@ -464,7 +466,7 @@ static ssize_t gameport_rebind_driver(struct device *dev, struct device_attribut struct device_driver *drv; int retval; - retval = down_interruptible(&gameport_sem); + retval = mutex_lock_interruptible(&gameport_mutex); if (retval) return retval; @@ -484,7 +486,7 @@ static ssize_t gameport_rebind_driver(struct device *dev, struct device_attribut retval = -EINVAL; } - up(&gameport_sem); + mutex_unlock(&gameport_mutex); return retval; } @@ -521,7 +523,7 @@ static void gameport_init_port(struct gameport *gameport) __module_get(THIS_MODULE); - init_MUTEX(&gameport->drv_sem); + mutex_init(&gameport->drv_mutex); device_initialize(&gameport->dev); snprintf(gameport->dev.bus_id, sizeof(gameport->dev.bus_id), "gameport%lu", (unsigned long)atomic_inc_return(&gameport_no) - 1); @@ -661,10 +663,10 @@ void __gameport_register_port(struct gameport *gameport, struct module *owner) */ void gameport_unregister_port(struct gameport *gameport) { - down(&gameport_sem); + mutex_lock(&gameport_mutex); gameport_disconnect_port(gameport); gameport_destroy_port(gameport); - up(&gameport_sem); + mutex_unlock(&gameport_mutex); } @@ -717,7 +719,7 @@ void gameport_unregister_driver(struct gameport_driver *drv) { struct gameport *gameport; - down(&gameport_sem); + mutex_lock(&gameport_mutex); drv->ignore = 1; /* so gameport_find_driver ignores it */ start_over: @@ -731,7 +733,7 @@ start_over: } driver_unregister(&drv->driver); - up(&gameport_sem); + mutex_unlock(&gameport_mutex); } static int gameport_bus_match(struct device *dev, struct device_driver *drv) @@ -743,9 +745,9 @@ static int gameport_bus_match(struct device *dev, struct device_driver *drv) static void gameport_set_drv(struct gameport *gameport, struct gameport_driver *drv) { - down(&gameport->drv_sem); + mutex_lock(&gameport->drv_mutex); gameport->drv = drv; - up(&gameport->drv_sem); + mutex_unlock(&gameport->drv_mutex); } int gameport_open(struct gameport *gameport, struct gameport_driver *drv, int mode) @@ -796,5 +798,5 @@ static void __exit gameport_exit(void) kthread_stop(gameport_task); } -module_init(gameport_init); +subsys_initcall(gameport_init); module_exit(gameport_exit); diff --git a/drivers/input/gameport/ns558.c b/drivers/input/gameport/ns558.c index d2e55dc956b..3e2d28f263e 100644 --- a/drivers/input/gameport/ns558.c +++ b/drivers/input/gameport/ns558.c @@ -252,14 +252,14 @@ static struct pnp_driver ns558_pnp_driver; #endif -static int pnp_registered = 0; - static int __init ns558_init(void) { int i = 0; + int error; - if (pnp_register_driver(&ns558_pnp_driver) >= 0) - pnp_registered = 1; + error = pnp_register_driver(&ns558_pnp_driver); + if (error && error != -ENODEV) /* should be ENOSYS really */ + return error; /* * Probe ISA ports after PnP, so that PnP ports that are already @@ -270,7 +270,7 @@ static int __init ns558_init(void) while (ns558_isa_portlist[i]) ns558_isa_probe(ns558_isa_portlist[i++]); - return (list_empty(&ns558_list) && !pnp_registered) ? -ENODEV : 0; + return list_empty(&ns558_list) && error ? -ENODEV : 0; } static void __exit ns558_exit(void) @@ -283,8 +283,7 @@ static void __exit ns558_exit(void) kfree(ns558); } - if (pnp_registered) - pnp_unregister_driver(&ns558_pnp_driver); + pnp_unregister_driver(&ns558_pnp_driver); } module_init(ns558_init); diff --git a/drivers/input/input.c b/drivers/input/input.c index f8af0945964..a935abeffff 100644 --- a/drivers/input/input.c +++ b/drivers/input/input.c @@ -18,9 +18,11 @@ #include <linux/random.h> #include <linux/major.h> #include <linux/proc_fs.h> +#include <linux/seq_file.h> #include <linux/interrupt.h> #include <linux/poll.h> #include <linux/device.h> +#include <linux/mutex.h> MODULE_AUTHOR("Vojtech Pavlik <vojtech@suse.cz>"); MODULE_DESCRIPTION("Input core"); @@ -224,7 +226,7 @@ int input_open_device(struct input_handle *handle) struct input_dev *dev = handle->dev; int err; - err = down_interruptible(&dev->sem); + err = mutex_lock_interruptible(&dev->mutex); if (err) return err; @@ -236,7 +238,7 @@ int input_open_device(struct input_handle *handle) if (err) handle->open--; - up(&dev->sem); + mutex_unlock(&dev->mutex); return err; } @@ -255,13 +257,13 @@ void input_close_device(struct input_handle *handle) input_release_device(handle); - down(&dev->sem); + mutex_lock(&dev->mutex); if (!--dev->users && dev->close) dev->close(dev); handle->open--; - up(&dev->sem); + mutex_unlock(&dev->mutex); } static void input_link_handle(struct input_handle *handle) @@ -315,21 +317,6 @@ static struct input_device_id *input_match_device(struct input_device_id *id, st return NULL; } -static int input_print_bitmap(char *buf, int buf_size, unsigned long *bitmap, int max) -{ - int i; - int len = 0; - - for (i = NBITS(max) - 1; i > 0; i--) - if (bitmap[i]) - break; - - for (; i >= 0; i--) - len += snprintf(buf + len, max(buf_size - len, 0), - "%lx%s", bitmap[i], i > 0 ? " " : ""); - return len; -} - #ifdef CONFIG_PROC_FS static struct proc_dir_entry *proc_bus_input_dir; @@ -342,7 +329,7 @@ static inline void input_wakeup_procfs_readers(void) wake_up(&input_devices_poll_wait); } -static unsigned int input_devices_poll(struct file *file, poll_table *wait) +static unsigned int input_proc_devices_poll(struct file *file, poll_table *wait) { int state = input_devices_state; poll_wait(file, &input_devices_poll_wait, wait); @@ -351,115 +338,171 @@ static unsigned int input_devices_poll(struct file *file, poll_table *wait) return 0; } -#define SPRINTF_BIT(ev, bm) \ - do { \ - len += sprintf(buf + len, "B: %s=", #ev); \ - len += input_print_bitmap(buf + len, INT_MAX, \ - dev->bm##bit, ev##_MAX); \ - len += sprintf(buf + len, "\n"); \ - } while (0) +static struct list_head *list_get_nth_element(struct list_head *list, loff_t *pos) +{ + struct list_head *node; + loff_t i = 0; -#define TEST_AND_SPRINTF_BIT(ev, bm) \ - do { \ - if (test_bit(EV_##ev, dev->evbit)) \ - SPRINTF_BIT(ev, bm); \ - } while (0) + list_for_each(node, list) + if (i++ == *pos) + return node; + + return NULL; +} -static int input_devices_read(char *buf, char **start, off_t pos, int count, int *eof, void *data) +static struct list_head *list_get_next_element(struct list_head *list, struct list_head *element, loff_t *pos) { - struct input_dev *dev; - struct input_handle *handle; - const char *path; + if (element->next == list) + return NULL; + + ++(*pos); + return element->next; +} + +static void *input_devices_seq_start(struct seq_file *seq, loff_t *pos) +{ + /* acquire lock here ... Yes, we do need locking, I knowi, I know... */ + + return list_get_nth_element(&input_dev_list, pos); +} - off_t at = 0; - int len, cnt = 0; +static void *input_devices_seq_next(struct seq_file *seq, void *v, loff_t *pos) +{ + return list_get_next_element(&input_dev_list, v, pos); +} - list_for_each_entry(dev, &input_dev_list, node) { +static void input_devices_seq_stop(struct seq_file *seq, void *v) +{ + /* release lock here */ +} - path = kobject_get_path(&dev->cdev.kobj, GFP_KERNEL); +static void input_seq_print_bitmap(struct seq_file *seq, const char *name, + unsigned long *bitmap, int max) +{ + int i; - len = sprintf(buf, "I: Bus=%04x Vendor=%04x Product=%04x Version=%04x\n", - dev->id.bustype, dev->id.vendor, dev->id.product, dev->id.version); + for (i = NBITS(max) - 1; i > 0; i--) + if (bitmap[i]) + break; - len += sprintf(buf + len, "N: Name=\"%s\"\n", dev->name ? dev->name : ""); - len += sprintf(buf + len, "P: Phys=%s\n", dev->phys ? dev->phys : ""); - len += sprintf(buf + len, "S: Sysfs=%s\n", path ? path : ""); - len += sprintf(buf + len, "H: Handlers="); + seq_printf(seq, "B: %s=", name); + for (; i >= 0; i--) + seq_printf(seq, "%lx%s", bitmap[i], i > 0 ? " " : ""); + seq_putc(seq, '\n'); +} - list_for_each_entry(handle, &dev->h_list, d_node) - len += sprintf(buf + len, "%s ", handle->name); - - len += sprintf(buf + len, "\n"); - - SPRINTF_BIT(EV, ev); - TEST_AND_SPRINTF_BIT(KEY, key); - TEST_AND_SPRINTF_BIT(REL, rel); - TEST_AND_SPRINTF_BIT(ABS, abs); - TEST_AND_SPRINTF_BIT(MSC, msc); - TEST_AND_SPRINTF_BIT(LED, led); - TEST_AND_SPRINTF_BIT(SND, snd); - TEST_AND_SPRINTF_BIT(FF, ff); - TEST_AND_SPRINTF_BIT(SW, sw); - - len += sprintf(buf + len, "\n"); - - at += len; - - if (at >= pos) { - if (!*start) { - *start = buf + (pos - (at - len)); - cnt = at - pos; - } else cnt += len; - buf += len; - if (cnt >= count) - break; - } +static int input_devices_seq_show(struct seq_file *seq, void *v) +{ + struct input_dev *dev = container_of(v, struct input_dev, node); + const char *path = kobject_get_path(&dev->cdev.kobj, GFP_KERNEL); + struct input_handle *handle; - kfree(path); - } + seq_printf(seq, "I: Bus=%04x Vendor=%04x Product=%04x Version=%04x\n", + dev->id.bustype, dev->id.vendor, dev->id.product, dev->id.version); - if (&dev->node == &input_dev_list) - *eof = 1; + seq_printf(seq, "N: Name=\"%s\"\n", dev->name ? dev->name : ""); + seq_printf(seq, "P: Phys=%s\n", dev->phys ? dev->phys : ""); + seq_printf(seq, "S: Sysfs=%s\n", path ? path : ""); + seq_printf(seq, "H: Handlers="); - return (count > cnt) ? cnt : count; + list_for_each_entry(handle, &dev->h_list, d_node) + seq_printf(seq, "%s ", handle->name); + seq_putc(seq, '\n'); + + input_seq_print_bitmap(seq, "EV", dev->evbit, EV_MAX); + if (test_bit(EV_KEY, dev->evbit)) + input_seq_print_bitmap(seq, "KEY", dev->keybit, KEY_MAX); + if (test_bit(EV_REL, dev->evbit)) + input_seq_print_bitmap(seq, "REL", dev->relbit, REL_MAX); + if (test_bit(EV_ABS, dev->evbit)) + input_seq_print_bitmap(seq, "ABS", dev->absbit, ABS_MAX); + if (test_bit(EV_MSC, dev->evbit)) + input_seq_print_bitmap(seq, "MSC", dev->mscbit, MSC_MAX); + if (test_bit(EV_LED, dev->evbit)) + input_seq_print_bitmap(seq, "LED", dev->ledbit, LED_MAX); + if (test_bit(EV_SND, dev->evbit)) + input_seq_print_bitmap(seq, "SND", dev->sndbit, SND_MAX); + if (test_bit(EV_FF, dev->evbit)) + input_seq_print_bitmap(seq, "FF", dev->ffbit, FF_MAX); + if (test_bit(EV_SW, dev->evbit)) + input_seq_print_bitmap(seq, "SW", dev->swbit, SW_MAX); + + seq_putc(seq, '\n'); + + kfree(path); + return 0; } -static int input_handlers_read(char *buf, char **start, off_t pos, int count, int *eof, void *data) +static struct seq_operations input_devices_seq_ops = { + .start = input_devices_seq_start, + .next = input_devices_seq_next, + .stop = input_devices_seq_stop, + .show = input_devices_seq_show, +}; + +static int input_proc_devices_open(struct inode *inode, struct file *file) { - struct input_handler *handler; + return seq_open(file, &input_devices_seq_ops); +} - off_t at = 0; - int len = 0, cnt = 0; - int i = 0; +static struct file_operations input_devices_fileops = { + .owner = THIS_MODULE, + .open = input_proc_devices_open, + .poll = input_proc_devices_poll, + .read = seq_read, + .llseek = seq_lseek, + .release = seq_release, +}; - list_for_each_entry(handler, &input_handler_list, node) { +static void *input_handlers_seq_start(struct seq_file *seq, loff_t *pos) +{ + /* acquire lock here ... Yes, we do need locking, I knowi, I know... */ + seq->private = (void *)(unsigned long)*pos; + return list_get_nth_element(&input_handler_list, pos); +} + +static void *input_handlers_seq_next(struct seq_file *seq, void *v, loff_t *pos) +{ + seq->private = (void *)(unsigned long)(*pos + 1); + return list_get_next_element(&input_handler_list, v, pos); +} - if (handler->fops) - len = sprintf(buf, "N: Number=%d Name=%s Minor=%d\n", - i++, handler->name, handler->minor); - else - len = sprintf(buf, "N: Number=%d Name=%s\n", - i++, handler->name); +static void input_handlers_seq_stop(struct seq_file *seq, void *v) +{ + /* release lock here */ +} - at += len; +static int input_handlers_seq_show(struct seq_file *seq, void *v) +{ + struct input_handler *handler = container_of(v, struct input_handler, node); - if (at >= pos) { - if (!*start) { - *start = buf + (pos - (at - len)); - cnt = at - pos; - } else cnt += len; - buf += len; - if (cnt >= count) - break; - } - } - if (&handler->node == &input_handler_list) - *eof = 1; + seq_printf(seq, "N: Number=%ld Name=%s", + (unsigned long)seq->private, handler->name); + if (handler->fops) + seq_printf(seq, " Minor=%d", handler->minor); + seq_putc(seq, '\n'); - return (count > cnt) ? cnt : count; + return 0; } +static struct seq_operations input_handlers_seq_ops = { + .start = input_handlers_seq_start, + .next = input_handlers_seq_next, + .stop = input_handlers_seq_stop, + .show = input_handlers_seq_show, +}; -static struct file_operations input_fileops; +static int input_proc_handlers_open(struct inode *inode, struct file *file) +{ + return seq_open(file, &input_handlers_seq_ops); +} + +static struct file_operations input_handlers_fileops = { + .owner = THIS_MODULE, + .open = input_proc_handlers_open, + .read = seq_read, + .llseek = seq_lseek, + .release = seq_release, +}; static int __init input_proc_init(void) { @@ -471,20 +514,19 @@ static int __init input_proc_init(void) proc_bus_input_dir->owner = THIS_MODULE; - entry = create_proc_read_entry("devices", 0, proc_bus_input_dir, input_devices_read, NULL); + entry = create_proc_entry("devices", 0, proc_bus_input_dir); if (!entry) goto fail1; entry->owner = THIS_MODULE; - input_fileops = *entry->proc_fops; - input_fileops.poll = input_devices_poll; - entry->proc_fops = &input_fileops; + entry->proc_fops = &input_devices_fileops; - entry = create_proc_read_entry("handlers", 0, proc_bus_input_dir, input_handlers_read, NULL); + entry = create_proc_entry("handlers", 0, proc_bus_input_dir); if (!entry) goto fail2; entry->owner = THIS_MODULE; + entry->proc_fops = &input_handlers_fileops; return 0; @@ -512,13 +554,14 @@ static ssize_t input_dev_show_##name(struct class_device *dev, char *buf) \ struct input_dev *input_dev = to_input_dev(dev); \ int retval; \ \ - retval = down_interruptible(&input_dev->sem); \ + retval = mutex_lock_interruptible(&input_dev->mutex); \ if (retval) \ return retval; \ \ - retval = sprintf(buf, "%s\n", input_dev->name ? input_dev->name : ""); \ + retval = scnprintf(buf, PAGE_SIZE, \ + "%s\n", input_dev->name ? input_dev->name : ""); \ \ - up(&input_dev->sem); \ + mutex_unlock(&input_dev->mutex); \ \ return retval; \ } \ @@ -528,46 +571,51 @@ INPUT_DEV_STRING_ATTR_SHOW(name); INPUT_DEV_STRING_ATTR_SHOW(phys); INPUT_DEV_STRING_ATTR_SHOW(uniq); -static int print_modalias_bits(char *buf, int size, char prefix, unsigned long *arr, - unsigned int min, unsigned int max) +static int input_print_modalias_bits(char *buf, int size, + char name, unsigned long *bm, + unsigned int min_bit, unsigned int max_bit) { - int len, i; + int len = 0, i; - len = snprintf(buf, size, "%c", prefix); - for (i = min; i < max; i++) - if (arr[LONG(i)] & BIT(i)) - len += snprintf(buf + len, size - len, "%X,", i); + len += snprintf(buf, max(size, 0), "%c", name); + for (i = min_bit; i < max_bit; i++) + if (bm[LONG(i)] & BIT(i)) + len += snprintf(buf + len, max(size - len, 0), "%X,", i); return len; } -static int print_modalias(char *buf, int size, struct input_dev *id) +static int input_print_modalias(char *buf, int size, struct input_dev *id, + int add_cr) { int len; - len = snprintf(buf, size, "input:b%04Xv%04Xp%04Xe%04X-", - id->id.bustype, - id->id.vendor, - id->id.product, - id->id.version); - - len += print_modalias_bits(buf + len, size - len, 'e', id->evbit, - 0, EV_MAX); - len += print_modalias_bits(buf + len, size - len, 'k', id->keybit, - KEY_MIN_INTERESTING, KEY_MAX); - len += print_modalias_bits(buf + len, size - len, 'r', id->relbit, - 0, REL_MAX); - len += print_modalias_bits(buf + len, size - len, 'a', id->absbit, - 0, ABS_MAX); - len += print_modalias_bits(buf + len, size - len, 'm', id->mscbit, - 0, MSC_MAX); - len += print_modalias_bits(buf + len, size - len, 'l', id->ledbit, - 0, LED_MAX); - len += print_modalias_bits(buf + len, size - len, 's', id->sndbit, - 0, SND_MAX); - len += print_modalias_bits(buf + len, size - len, 'f', id->ffbit, - 0, FF_MAX); - len += print_modalias_bits(buf + len, size - len, 'w', id->swbit, - 0, SW_MAX); + len = snprintf(buf, max(size, 0), + "input:b%04Xv%04Xp%04Xe%04X-", + id->id.bustype, id->id.vendor, + id->id.product, id->id.version); + + len += input_print_modalias_bits(buf + len, size - len, + 'e', id->evbit, 0, EV_MAX); + len += input_print_modalias_bits(buf + len, size - len, + 'k', id->keybit, KEY_MIN_INTERESTING, KEY_MAX); + len += input_print_modalias_bits(buf + len, size - len, + 'r', id->relbit, 0, REL_MAX); + len += input_print_modalias_bits(buf + len, size - len, + 'a', id->absbit, 0, ABS_MAX); + len += input_print_modalias_bits(buf + len, size - len, + 'm', id->mscbit, 0, MSC_MAX); + len += input_print_modalias_bits(buf + len, size - len, + 'l', id->ledbit, 0, LED_MAX); + len += input_print_modalias_bits(buf + len, size - len, + 's', id->sndbit, 0, SND_MAX); + len += input_print_modalias_bits(buf + len, size - len, + 'f', id->ffbit, 0, FF_MAX); + len += input_print_modalias_bits(buf + len, size - len, + 'w', id->swbit, 0, SW_MAX); + + if (add_cr) + len += snprintf(buf + len, max(size - len, 0), "\n"); + return len; } @@ -576,9 +624,9 @@ static ssize_t input_dev_show_modalias(struct class_device *dev, char *buf) struct input_dev *id = to_input_dev(dev); ssize_t len; - len = print_modalias(buf, PAGE_SIZE, id); - len += snprintf(buf + len, PAGE_SIZE-len, "\n"); - return len; + len = input_print_modalias(buf, PAGE_SIZE, id, 1); + + return max_t(int, len, PAGE_SIZE); } static CLASS_DEVICE_ATTR(modalias, S_IRUGO, input_dev_show_modalias, NULL); @@ -598,7 +646,7 @@ static struct attribute_group input_dev_attr_group = { static ssize_t input_dev_show_id_##name(struct class_device *dev, char *buf) \ { \ struct input_dev *input_dev = to_input_dev(dev); \ - return sprintf(buf, "%04x\n", input_dev->id.name); \ + return scnprintf(buf, PAGE_SIZE, "%04x\n", input_dev->id.name); \ } \ static CLASS_DEVICE_ATTR(name, S_IRUGO, input_dev_show_id_##name, NULL); @@ -620,11 +668,33 @@ static struct attribute_group input_dev_id_attr_group = { .attrs = input_dev_id_attrs, }; +static int input_print_bitmap(char *buf, int buf_size, unsigned long *bitmap, + int max, int add_cr) +{ + int i; + int len = 0; + + for (i = NBITS(max) - 1; i > 0; i--) + if (bitmap[i]) + break; + + for (; i >= 0; i--) + len += snprintf(buf + len, max(buf_size - len, 0), + "%lx%s", bitmap[i], i > 0 ? " " : ""); + + if (add_cr) + len += snprintf(buf + len, max(buf_size - len, 0), "\n"); + + return len; +} + #define INPUT_DEV_CAP_ATTR(ev, bm) \ static ssize_t input_dev_show_cap_##bm(struct class_device *dev, char *buf) \ { \ struct input_dev *input_dev = to_input_dev(dev); \ - return input_print_bitmap(buf, PAGE_SIZE, input_dev->bm##bit, ev##_MAX);\ + int len = input_print_bitmap(buf, PAGE_SIZE, \ + input_dev->bm##bit, ev##_MAX, 1); \ + return min_t(int, len, PAGE_SIZE); \ } \ static CLASS_DEVICE_ATTR(bm, S_IRUGO, input_dev_show_cap_##bm, NULL); @@ -669,8 +739,8 @@ static void input_dev_release(struct class_device *class_dev) * device bitfields. */ static int input_add_uevent_bm_var(char **envp, int num_envp, int *cur_index, - char *buffer, int buffer_size, int *cur_len, - const char *name, unsigned long *bitmap, int max) + char *buffer, int buffer_size, int *cur_len, + const char *name, unsigned long *bitmap, int max) { if (*cur_index >= num_envp - 1) return -ENOMEM; @@ -678,12 +748,36 @@ static int input_add_uevent_bm_var(char **envp, int num_envp, int *cur_index, envp[*cur_index] = buffer + *cur_len; *cur_len += snprintf(buffer + *cur_len, max(buffer_size - *cur_len, 0), name); - if (*cur_len > buffer_size) + if (*cur_len >= buffer_size) return -ENOMEM; *cur_len += input_print_bitmap(buffer + *cur_len, max(buffer_size - *cur_len, 0), - bitmap, max) + 1; + bitmap, max, 0) + 1; + if (*cur_len > buffer_size) + return -ENOMEM; + + (*cur_index)++; + return 0; +} + +static int input_add_uevent_modalias_var(char **envp, int num_envp, int *cur_index, + char *buffer, int buffer_size, int *cur_len, + struct input_dev *dev) +{ + if (*cur_index >= num_envp - 1) + return -ENOMEM; + + envp[*cur_index] = buffer + *cur_len; + + *cur_len += snprintf(buffer + *cur_len, max(buffer_size - *cur_len, 0), + "MODALIAS="); + if (*cur_len >= buffer_size) + return -ENOMEM; + + *cur_len += input_print_modalias(buffer + *cur_len, + max(buffer_size - *cur_len, 0), + dev, 0) + 1; if (*cur_len > buffer_size) return -ENOMEM; @@ -693,7 +787,7 @@ static int input_add_uevent_bm_var(char **envp, int num_envp, int *cur_index, #define INPUT_ADD_HOTPLUG_VAR(fmt, val...) \ do { \ - int err = add_uevent_var(envp, num_envp, &i, \ + int err = add_uevent_var(envp, num_envp, &i, \ buffer, buffer_size, &len, \ fmt, val); \ if (err) \ @@ -709,6 +803,16 @@ static int input_add_uevent_bm_var(char **envp, int num_envp, int *cur_index, return err; \ } while (0) +#define INPUT_ADD_HOTPLUG_MODALIAS_VAR(dev) \ + do { \ + int err = input_add_uevent_modalias_var(envp, \ + num_envp, &i, \ + buffer, buffer_size, &len, \ + dev); \ + if (err) \ + return err; \ + } while (0) + static int input_dev_uevent(struct class_device *cdev, char **envp, int num_envp, char *buffer, int buffer_size) { @@ -744,9 +848,7 @@ static int input_dev_uevent(struct class_device *cdev, char **envp, if (test_bit(EV_SW, dev->evbit)) INPUT_ADD_HOTPLUG_BM_VAR("SW=", dev->swbit, SW_MAX); - envp[i++] = buffer + len; - len += snprintf(buffer + len, buffer_size - len, "MODALIAS="); - len += print_modalias(buffer + len, buffer_size - len, dev) + 1; + INPUT_ADD_HOTPLUG_MODALIAS_VAR(dev); envp[i] = NULL; return 0; @@ -790,7 +892,7 @@ int input_register_device(struct input_dev *dev) return -EINVAL; } - init_MUTEX(&dev->sem); + mutex_init(&dev->mutex); set_bit(EV_SYN, dev->evbit); /* diff --git a/drivers/input/joydev.c b/drivers/input/joydev.c index 20e2972b920..949bdcef8c2 100644 --- a/drivers/input/joydev.c +++ b/drivers/input/joydev.c @@ -171,9 +171,8 @@ static int joydev_open(struct inode *inode, struct file *file) if (i >= JOYDEV_MINORS || !joydev_table[i]) return -ENODEV; - if (!(list = kmalloc(sizeof(struct joydev_list), GFP_KERNEL))) + if (!(list = kzalloc(sizeof(struct joydev_list), GFP_KERNEL))) return -ENOMEM; - memset(list, 0, sizeof(struct joydev_list)); list->joydev = joydev_table[i]; list_add_tail(&list->node, &joydev_table[i]->list); @@ -457,9 +456,8 @@ static struct input_handle *joydev_connect(struct input_handler *handler, struct return NULL; } - if (!(joydev = kmalloc(sizeof(struct joydev), GFP_KERNEL))) + if (!(joydev = kzalloc(sizeof(struct joydev), GFP_KERNEL))) return NULL; - memset(joydev, 0, sizeof(struct joydev)); INIT_LIST_HEAD(&joydev->list); init_waitqueue_head(&joydev->wait); diff --git a/drivers/input/joystick/amijoy.c b/drivers/input/joystick/amijoy.c index ec55a29fc86..7249d324297 100644 --- a/drivers/input/joystick/amijoy.c +++ b/drivers/input/joystick/amijoy.c @@ -36,6 +36,7 @@ #include <linux/init.h> #include <linux/input.h> #include <linux/interrupt.h> +#include <linux/mutex.h> #include <asm/system.h> #include <asm/amigahw.h> @@ -52,7 +53,7 @@ MODULE_PARM_DESC(map, "Map of attached joysticks in form of <a>,<b> (default is __obsolete_setup("amijoy="); static int amijoy_used; -static DECLARE_MUTEX(amijoy_sem); +static DEFINE_MUTEX(amijoy_mutex); static struct input_dev *amijoy_dev[2]; static char *amijoy_phys[2] = { "amijoy/input0", "amijoy/input1" }; @@ -85,7 +86,7 @@ static int amijoy_open(struct input_dev *dev) { int err; - err = down_interruptible(&amijoy_sem); + err = mutex_lock_interruptible(&amijoy_mutex); if (err) return err; @@ -97,16 +98,16 @@ static int amijoy_open(struct input_dev *dev) amijoy_used++; out: - up(&amijoy_sem); + mutex_unlock(&amijoy_mutex); return err; } static void amijoy_close(struct input_dev *dev) { - down(&amijoy_sem); + mutex_lock(&amijoy_mutex); if (!--amijoy_used) free_irq(IRQ_AMIGA_VERTB, amijoy_interrupt); - up(&amijoy_sem); + mutex_unlock(&amijoy_mutex); } static int __init amijoy_init(void) diff --git a/drivers/input/joystick/db9.c b/drivers/input/joystick/db9.c index dcffc34f30c..e61894685cb 100644 --- a/drivers/input/joystick/db9.c +++ b/drivers/input/joystick/db9.c @@ -38,6 +38,7 @@ #include <linux/init.h> #include <linux/parport.h> #include <linux/input.h> +#include <linux/mutex.h> MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>"); MODULE_DESCRIPTION("Atari, Amstrad, Commodore, Amiga, Sega, etc. joystick driver"); @@ -111,7 +112,7 @@ struct db9 { struct pardevice *pd; int mode; int used; - struct semaphore sem; + struct mutex mutex; char phys[DB9_MAX_DEVICES][32]; }; @@ -525,7 +526,7 @@ static int db9_open(struct input_dev *dev) struct parport *port = db9->pd->port; int err; - err = down_interruptible(&db9->sem); + err = mutex_lock_interruptible(&db9->mutex); if (err) return err; @@ -539,7 +540,7 @@ static int db9_open(struct input_dev *dev) mod_timer(&db9->timer, jiffies + DB9_REFRESH_TIME); } - up(&db9->sem); + mutex_unlock(&db9->mutex); return 0; } @@ -548,14 +549,14 @@ static void db9_close(struct input_dev *dev) struct db9 *db9 = dev->private; struct parport *port = db9->pd->port; - down(&db9->sem); + mutex_lock(&db9->mutex); if (!--db9->used) { del_timer_sync(&db9->timer); parport_write_control(port, 0x00); parport_data_forward(port); parport_release(db9->pd); } - up(&db9->sem); + mutex_unlock(&db9->mutex); } static struct db9 __init *db9_probe(int parport, int mode) @@ -603,7 +604,7 @@ static struct db9 __init *db9_probe(int parport, int mode) goto err_unreg_pardev; } - init_MUTEX(&db9->sem); + mutex_init(&db9->mutex); db9->pd = pd; db9->mode = mode; init_timer(&db9->timer); diff --git a/drivers/input/joystick/gamecon.c b/drivers/input/joystick/gamecon.c index 900587acdb4..ecbdb6b9bbd 100644 --- a/drivers/input/joystick/gamecon.c +++ b/drivers/input/joystick/gamecon.c @@ -7,6 +7,7 @@ * Based on the work of: * Andree Borrmann John Dahlstrom * David Kuder Nathan Hand + * Raphael Assenat */ /* @@ -36,6 +37,7 @@ #include <linux/init.h> #include <linux/parport.h> #include <linux/input.h> +#include <linux/mutex.h> MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>"); MODULE_DESCRIPTION("NES, SNES, N64, MultiSystem, PSX gamepad driver"); @@ -72,8 +74,9 @@ __obsolete_setup("gc_3="); #define GC_N64 6 #define GC_PSX 7 #define GC_DDR 8 +#define GC_SNESMOUSE 9 -#define GC_MAX 8 +#define GC_MAX 9 #define GC_REFRESH_TIME HZ/100 @@ -83,7 +86,7 @@ struct gc { struct timer_list timer; unsigned char pads[GC_MAX + 1]; int used; - struct semaphore sem; + struct mutex mutex; char phys[GC_MAX_DEVICES][32]; }; @@ -93,7 +96,7 @@ static int gc_status_bit[] = { 0x40, 0x80, 0x20, 0x10, 0x08 }; static char *gc_names[] = { NULL, "SNES pad", "NES pad", "NES FourPort", "Multisystem joystick", "Multisystem 2-button joystick", "N64 controller", "PSX controller", - "PSX DDR controller" }; + "PSX DDR controller", "SNES mouse" }; /* * N64 support. */ @@ -205,9 +208,12 @@ static void gc_n64_process_packet(struct gc *gc) * NES/SNES support. */ -#define GC_NES_DELAY 6 /* Delay between bits - 6us */ -#define GC_NES_LENGTH 8 /* The NES pads use 8 bits of data */ -#define GC_SNES_LENGTH 12 /* The SNES true length is 16, but the last 4 bits are unused */ +#define GC_NES_DELAY 6 /* Delay between bits - 6us */ +#define GC_NES_LENGTH 8 /* The NES pads use 8 bits of data */ +#define GC_SNES_LENGTH 12 /* The SNES true length is 16, but the + last 4 bits are unused */ +#define GC_SNESMOUSE_LENGTH 32 /* The SNES mouse uses 32 bits, the first + 16 bits are equivalent to a gamepad */ #define GC_NES_POWER 0xfc #define GC_NES_CLOCK 0x01 @@ -242,11 +248,15 @@ static void gc_nes_read_packet(struct gc *gc, int length, unsigned char *data) static void gc_nes_process_packet(struct gc *gc) { - unsigned char data[GC_SNES_LENGTH]; + unsigned char data[GC_SNESMOUSE_LENGTH]; struct input_dev *dev; - int i, j, s; + int i, j, s, len; + char x_rel, y_rel; + + len = gc->pads[GC_SNESMOUSE] ? GC_SNESMOUSE_LENGTH : + (gc->pads[GC_SNES] ? GC_SNES_LENGTH : GC_NES_LENGTH); - gc_nes_read_packet(gc, gc->pads[GC_SNES] ? GC_SNES_LENGTH : GC_NES_LENGTH, data); + gc_nes_read_packet(gc, len, data); for (i = 0; i < GC_MAX_DEVICES; i++) { @@ -269,6 +279,44 @@ static void gc_nes_process_packet(struct gc *gc) for (j = 0; j < 8; j++) input_report_key(dev, gc_snes_btn[j], s & data[gc_snes_bytes[j]]); + if (s & gc->pads[GC_SNESMOUSE]) { + /* + * The 4 unused bits from SNES controllers appear to be ID bits + * so use them to make sure iwe are dealing with a mouse. + * gamepad is connected. This is important since + * my SNES gamepad sends 1's for bits 16-31, which + * cause the mouse pointer to quickly move to the + * upper left corner of the screen. + */ + if (!(s & data[12]) && !(s & data[13]) && + !(s & data[14]) && (s & data[15])) { + input_report_key(dev, BTN_LEFT, s & data[9]); + input_report_key(dev, BTN_RIGHT, s & data[8]); + + x_rel = y_rel = 0; + for (j = 0; j < 7; j++) { + x_rel <<= 1; + if (data[25 + j] & s) + x_rel |= 1; + + y_rel <<= 1; + if (data[17 + j] & s) + y_rel |= 1; + } + + if (x_rel) { + if (data[24] & s) + x_rel = -x_rel; + input_report_rel(dev, REL_X, x_rel); + } + + if (y_rel) { + if (data[16] & s) + y_rel = -y_rel; + input_report_rel(dev, REL_Y, y_rel); + } + } + } input_sync(dev); } } @@ -524,10 +572,10 @@ static void gc_timer(unsigned long private) gc_n64_process_packet(gc); /* - * NES and SNES pads + * NES and SNES pads or mouse */ - if (gc->pads[GC_NES] || gc->pads[GC_SNES]) + if (gc->pads[GC_NES] || gc->pads[GC_SNES] || gc->pads[GC_SNESMOUSE]) gc_nes_process_packet(gc); /* @@ -552,7 +600,7 @@ static int gc_open(struct input_dev *dev) struct gc *gc = dev->private; int err; - err = down_interruptible(&gc->sem); + err = mutex_lock_interruptible(&gc->mutex); if (err) return err; @@ -562,7 +610,7 @@ static int gc_open(struct input_dev *dev) mod_timer(&gc->timer, jiffies + GC_REFRESH_TIME); } - up(&gc->sem); + mutex_unlock(&gc->mutex); return 0; } @@ -570,13 +618,13 @@ static void gc_close(struct input_dev *dev) { struct gc *gc = dev->private; - down(&gc->sem); + mutex_lock(&gc->mutex); if (!--gc->used) { del_timer_sync(&gc->timer); parport_write_control(gc->pd->port, 0x00); parport_release(gc->pd); } - up(&gc->sem); + mutex_unlock(&gc->mutex); } static int __init gc_setup_pad(struct gc *gc, int idx, int pad_type) @@ -609,10 +657,13 @@ static int __init gc_setup_pad(struct gc *gc, int idx, int pad_type) input_dev->open = gc_open; input_dev->close = gc_close; - input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); + if (pad_type != GC_SNESMOUSE) { + input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); - for (i = 0; i < 2; i++) - input_set_abs_params(input_dev, ABS_X + i, -1, 1, 0, 0); + for (i = 0; i < 2; i++) + input_set_abs_params(input_dev, ABS_X + i, -1, 1, 0, 0); + } else + input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REL); gc->pads[0] |= gc_status_bit[idx]; gc->pads[pad_type] |= gc_status_bit[idx]; @@ -630,6 +681,13 @@ static int __init gc_setup_pad(struct gc *gc, int idx, int pad_type) break; + case GC_SNESMOUSE: + set_bit(BTN_LEFT, input_dev->keybit); + set_bit(BTN_RIGHT, input_dev->keybit); + set_bit(REL_X, input_dev->relbit); + set_bit(REL_Y, input_dev->relbit); + break; + case GC_SNES: for (i = 4; i < 8; i++) set_bit(gc_snes_btn[i], input_dev->keybit); @@ -693,7 +751,7 @@ static struct gc __init *gc_probe(int parport, int *pads, int n_pads) goto err_unreg_pardev; } - init_MUTEX(&gc->sem); + mutex_init(&gc->mutex); gc->pd = pd; init_timer(&gc->timer); gc->timer.data = (long) gc; diff --git a/drivers/input/joystick/iforce/iforce-ff.c b/drivers/input/joystick/iforce/iforce-ff.c index 4678b6dab43..2b8e8456c9f 100644 --- a/drivers/input/joystick/iforce/iforce-ff.c +++ b/drivers/input/joystick/iforce/iforce-ff.c @@ -42,14 +42,14 @@ static int make_magnitude_modifier(struct iforce* iforce, unsigned char data[3]; if (!no_alloc) { - down(&iforce->mem_mutex); + mutex_lock(&iforce->mem_mutex); if (allocate_resource(&(iforce->device_memory), mod_chunk, 2, iforce->device_memory.start, iforce->device_memory.end, 2L, NULL, NULL)) { - up(&iforce->mem_mutex); + mutex_unlock(&iforce->mem_mutex); return -ENOMEM; } - up(&iforce->mem_mutex); + mutex_unlock(&iforce->mem_mutex); } data[0] = LO(mod_chunk->start); @@ -75,14 +75,14 @@ static int make_period_modifier(struct iforce* iforce, period = TIME_SCALE(period); if (!no_alloc) { - down(&iforce->mem_mutex); + mutex_lock(&iforce->mem_mutex); if (allocate_resource(&(iforce->device_memory), mod_chunk, 0x0c, iforce->device_memory.start, iforce->device_memory.end, 2L, NULL, NULL)) { - up(&iforce->mem_mutex); + mutex_unlock(&iforce->mem_mutex); return -ENOMEM; } - up(&iforce->mem_mutex); + mutex_unlock(&iforce->mem_mutex); } data[0] = LO(mod_chunk->start); @@ -115,14 +115,14 @@ static int make_envelope_modifier(struct iforce* iforce, fade_duration = TIME_SCALE(fade_duration); if (!no_alloc) { - down(&iforce->mem_mutex); + mutex_lock(&iforce->mem_mutex); if (allocate_resource(&(iforce->device_memory), mod_chunk, 0x0e, iforce->device_memory.start, iforce->device_memory.end, 2L, NULL, NULL)) { - up(&iforce->mem_mutex); + mutex_unlock(&iforce->mem_mutex); return -ENOMEM; } - up(&iforce->mem_mutex); + mutex_unlock(&iforce->mem_mutex); } data[0] = LO(mod_chunk->start); @@ -152,14 +152,14 @@ static int make_condition_modifier(struct iforce* iforce, unsigned char data[10]; if (!no_alloc) { - down(&iforce->mem_mutex); + mutex_lock(&iforce->mem_mutex); if (allocate_resource(&(iforce->device_memory), mod_chunk, 8, iforce->device_memory.start, iforce->device_memory.end, 2L, NULL, NULL)) { - up(&iforce->mem_mutex); + mutex_unlock(&iforce->mem_mutex); return -ENOMEM; } - up(&iforce->mem_mutex); + mutex_unlock(&iforce->mem_mutex); } data[0] = LO(mod_chunk->start); diff --git a/drivers/input/joystick/iforce/iforce-main.c b/drivers/input/joystick/iforce/iforce-main.c index b6bc0499804..ab0a26b924c 100644 --- a/drivers/input/joystick/iforce/iforce-main.c +++ b/drivers/input/joystick/iforce/iforce-main.c @@ -350,7 +350,7 @@ int iforce_init_device(struct iforce *iforce) init_waitqueue_head(&iforce->wait); spin_lock_init(&iforce->xmit_lock); - init_MUTEX(&iforce->mem_mutex); + mutex_init(&iforce->mem_mutex); iforce->xmit.buf = iforce->xmit_data; iforce->dev = input_dev; diff --git a/drivers/input/joystick/iforce/iforce.h b/drivers/input/joystick/iforce/iforce.h index 146f406b8f8..668f24535ba 100644 --- a/drivers/input/joystick/iforce/iforce.h +++ b/drivers/input/joystick/iforce/iforce.h @@ -37,7 +37,7 @@ #include <linux/serio.h> #include <linux/config.h> #include <linux/circ_buf.h> -#include <asm/semaphore.h> +#include <linux/mutex.h> /* This module provides arbitrary resource management routines. * I use it to manage the device's memory. @@ -45,6 +45,7 @@ */ #include <linux/ioport.h> + #define IFORCE_MAX_LENGTH 16 /* iforce::bus */ @@ -146,7 +147,7 @@ struct iforce { wait_queue_head_t wait; struct resource device_memory; struct iforce_core_effect core_effects[FF_EFFECTS_MAX]; - struct semaphore mem_mutex; + struct mutex mem_mutex; }; /* Get hi and low bytes of a 16-bits int */ diff --git a/drivers/input/joystick/turbografx.c b/drivers/input/joystick/turbografx.c index b154938e88a..5570fd5487c 100644 --- a/drivers/input/joystick/turbografx.c +++ b/drivers/input/joystick/turbografx.c @@ -37,6 +37,7 @@ #include <linux/module.h> #include <linux/moduleparam.h> #include <linux/init.h> +#include <linux/mutex.h> MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>"); MODULE_DESCRIPTION("TurboGraFX parallel port interface driver"); @@ -86,7 +87,7 @@ static struct tgfx { char phys[TGFX_MAX_DEVICES][32]; int sticks; int used; - struct semaphore sem; + struct mutex sem; } *tgfx_base[TGFX_MAX_PORTS]; /* @@ -128,7 +129,7 @@ static int tgfx_open(struct input_dev *dev) struct tgfx *tgfx = dev->private; int err; - err = down_interruptible(&tgfx->sem); + err = mutex_lock_interruptible(&tgfx->sem); if (err) return err; @@ -138,7 +139,7 @@ static int tgfx_open(struct input_dev *dev) mod_timer(&tgfx->timer, jiffies + TGFX_REFRESH_TIME); } - up(&tgfx->sem); + mutex_unlock(&tgfx->sem); return 0; } @@ -146,13 +147,13 @@ static void tgfx_close(struct input_dev *dev) { struct tgfx *tgfx = dev->private; - down(&tgfx->sem); + mutex_lock(&tgfx->sem); if (!--tgfx->used) { del_timer_sync(&tgfx->timer); parport_write_control(tgfx->pd->port, 0x00); parport_release(tgfx->pd); } - up(&tgfx->sem); + mutex_unlock(&tgfx->sem); } @@ -191,7 +192,7 @@ static struct tgfx __init *tgfx_probe(int parport, int *n_buttons, int n_devs) goto err_unreg_pardev; } - init_MUTEX(&tgfx->sem); + mutex_init(&tgfx->sem); tgfx->pd = pd; init_timer(&tgfx->timer); tgfx->timer.data = (long) tgfx; diff --git a/drivers/input/keyboard/Kconfig b/drivers/input/keyboard/Kconfig index 3b0ac3b43c5..a9dda56f62c 100644 --- a/drivers/input/keyboard/Kconfig +++ b/drivers/input/keyboard/Kconfig @@ -13,7 +13,7 @@ menuconfig INPUT_KEYBOARD if INPUT_KEYBOARD config KEYBOARD_ATKBD - tristate "AT keyboard" if !X86_PC + tristate "AT keyboard" if EMBEDDED || !X86_PC default y select SERIO select SERIO_LIBPS2 diff --git a/drivers/input/keyboard/atkbd.c b/drivers/input/keyboard/atkbd.c index ffacf6eca5f..fad04b66d26 100644 --- a/drivers/input/keyboard/atkbd.c +++ b/drivers/input/keyboard/atkbd.c @@ -27,6 +27,7 @@ #include <linux/serio.h> #include <linux/workqueue.h> #include <linux/libps2.h> +#include <linux/mutex.h> #define DRIVER_DESC "AT and PS/2 keyboard driver" @@ -216,7 +217,7 @@ struct atkbd { unsigned long time; struct work_struct event_work; - struct semaphore event_sem; + struct mutex event_mutex; unsigned long event_mask; }; @@ -302,19 +303,19 @@ static irqreturn_t atkbd_interrupt(struct serio *serio, unsigned char data, if (atkbd->translated) { if (atkbd->emul || - !(code == ATKBD_RET_EMUL0 || code == ATKBD_RET_EMUL1 || - code == ATKBD_RET_HANGUEL || code == ATKBD_RET_HANJA || - (code == ATKBD_RET_ERR && !atkbd->err_xl) || - (code == ATKBD_RET_BAT && !atkbd->bat_xl))) { + (code != ATKBD_RET_EMUL0 && code != ATKBD_RET_EMUL1 && + code != ATKBD_RET_HANGUEL && code != ATKBD_RET_HANJA && + (code != ATKBD_RET_ERR || atkbd->err_xl) && + (code != ATKBD_RET_BAT || atkbd->bat_xl))) { atkbd->release = code >> 7; code &= 0x7f; } if (!atkbd->emul) { if ((code & 0x7f) == (ATKBD_RET_BAT & 0x7f)) - atkbd->bat_xl = !atkbd->release; + atkbd->bat_xl = !(data >> 7); if ((code & 0x7f) == (ATKBD_RET_ERR & 0x7f)) - atkbd->err_xl = !atkbd->release; + atkbd->err_xl = !(data >> 7); } } @@ -449,7 +450,7 @@ static void atkbd_event_work(void *data) unsigned char param[2]; int i, j; - down(&atkbd->event_sem); + mutex_lock(&atkbd->event_mutex); if (test_and_clear_bit(ATKBD_LED_EVENT_BIT, &atkbd->event_mask)) { param[0] = (test_bit(LED_SCROLLL, dev->led) ? 1 : 0) @@ -480,7 +481,7 @@ static void atkbd_event_work(void *data) ps2_command(&atkbd->ps2dev, param, ATKBD_CMD_SETREP); } - up(&atkbd->event_sem); + mutex_unlock(&atkbd->event_mutex); } /* @@ -846,7 +847,7 @@ static int atkbd_connect(struct serio *serio, struct serio_driver *drv) atkbd->dev = dev; ps2_init(&atkbd->ps2dev, serio); INIT_WORK(&atkbd->event_work, atkbd_event_work, atkbd); - init_MUTEX(&atkbd->event_sem); + mutex_init(&atkbd->event_mutex); switch (serio->id.type) { @@ -862,9 +863,6 @@ static int atkbd_connect(struct serio *serio, struct serio_driver *drv) atkbd->softrepeat = atkbd_softrepeat; atkbd->scroll = atkbd_scroll; - if (!atkbd->write) - atkbd->softrepeat = 1; - if (atkbd->softrepeat) atkbd->softraw = 1; diff --git a/drivers/input/keyboard/corgikbd.c b/drivers/input/keyboard/corgikbd.c index e301ee4ca26..96c6bf77248 100644 --- a/drivers/input/keyboard/corgikbd.c +++ b/drivers/input/keyboard/corgikbd.c @@ -29,11 +29,11 @@ #define KB_COLS 12 #define KB_ROWMASK(r) (1 << (r)) #define SCANCODE(r,c) ( ((r)<<4) + (c) + 1 ) -/* zero code, 124 scancodes + 3 hinge combinations */ -#define NR_SCANCODES ( SCANCODE(KB_ROWS-1,KB_COLS-1) +1 +1 +3 ) -#define SCAN_INTERVAL (HZ/10) +/* zero code, 124 scancodes */ +#define NR_SCANCODES ( SCANCODE(KB_ROWS-1,KB_COLS-1) +1 +1 ) -#define HINGE_SCAN_INTERVAL (HZ/4) +#define SCAN_INTERVAL (50) /* ms */ +#define HINGE_SCAN_INTERVAL (250) /* ms */ #define CORGI_KEY_CALENDER KEY_F1 #define CORGI_KEY_ADDRESS KEY_F2 @@ -49,9 +49,6 @@ #define CORGI_KEY_MAIL KEY_F10 #define CORGI_KEY_OK KEY_F11 #define CORGI_KEY_MENU KEY_F12 -#define CORGI_HINGE_0 KEY_KP0 -#define CORGI_HINGE_1 KEY_KP1 -#define CORGI_HINGE_2 KEY_KP2 static unsigned char corgikbd_keycode[NR_SCANCODES] = { 0, /* 0 */ @@ -63,7 +60,6 @@ static unsigned char corgikbd_keycode[NR_SCANCODES] = { CORGI_KEY_MAIL, KEY_Z, KEY_X, KEY_MINUS, KEY_SPACE, KEY_COMMA, 0, KEY_UP, 0, 0, 0, CORGI_KEY_FN, 0, 0, 0, 0, /* 81-96 */ KEY_SYSRQ, CORGI_KEY_JAP1, CORGI_KEY_JAP2, CORGI_KEY_CANCEL, CORGI_KEY_OK, CORGI_KEY_MENU, KEY_LEFT, KEY_DOWN, KEY_RIGHT, 0, 0, 0, 0, 0, 0, 0, /* 97-112 */ CORGI_KEY_OFF, CORGI_KEY_EXOK, CORGI_KEY_EXCANCEL, CORGI_KEY_EXJOGDOWN, CORGI_KEY_EXJOGUP, 0, 0, 0, 0, 0, 0, 0, /* 113-124 */ - CORGI_HINGE_0, CORGI_HINGE_1, CORGI_HINGE_2 /* 125-127 */ }; @@ -187,7 +183,7 @@ static void corgikbd_scankeyboard(struct corgikbd *corgikbd_data, struct pt_regs /* if any keys are pressed, enable the timer */ if (num_pressed) - mod_timer(&corgikbd_data->timer, jiffies + SCAN_INTERVAL); + mod_timer(&corgikbd_data->timer, jiffies + msecs_to_jiffies(SCAN_INTERVAL)); spin_unlock_irqrestore(&corgikbd_data->lock, flags); } @@ -228,6 +224,7 @@ static void corgikbd_timer_callback(unsigned long data) * 0x0c - Keyboard and Screen Closed */ +#define READ_GPIO_BIT(x) (GPLR(x) & GPIO_bit(x)) #define HINGE_STABLE_COUNT 2 static int sharpsl_hinge_state; static int hinge_count; @@ -239,6 +236,7 @@ static void corgikbd_hinge_timer(unsigned long data) unsigned long flags; gprr = read_scoop_reg(&corgiscoop_device.dev, SCOOP_GPRR) & (CORGI_SCP_SWA | CORGI_SCP_SWB); + gprr |= (READ_GPIO_BIT(CORGI_GPIO_AK_INT) != 0); if (gprr != sharpsl_hinge_state) { hinge_count = 0; sharpsl_hinge_state = gprr; @@ -249,27 +247,38 @@ static void corgikbd_hinge_timer(unsigned long data) input_report_switch(corgikbd_data->input, SW_0, ((sharpsl_hinge_state & CORGI_SCP_SWA) != 0)); input_report_switch(corgikbd_data->input, SW_1, ((sharpsl_hinge_state & CORGI_SCP_SWB) != 0)); + input_report_switch(corgikbd_data->input, SW_2, (READ_GPIO_BIT(CORGI_GPIO_AK_INT) != 0)); input_sync(corgikbd_data->input); spin_unlock_irqrestore(&corgikbd_data->lock, flags); } } - mod_timer(&corgikbd_data->htimer, jiffies + HINGE_SCAN_INTERVAL); + mod_timer(&corgikbd_data->htimer, jiffies + msecs_to_jiffies(HINGE_SCAN_INTERVAL)); } #ifdef CONFIG_PM static int corgikbd_suspend(struct platform_device *dev, pm_message_t state) { + int i; struct corgikbd *corgikbd = platform_get_drvdata(dev); + corgikbd->suspended = 1; + /* strobe 0 is the power key so this can't be made an input for + powersaving therefore i = 1 */ + for (i = 1; i < CORGI_KEY_STROBE_NUM; i++) + pxa_gpio_mode(CORGI_GPIO_KEY_STROBE(i) | GPIO_IN); return 0; } static int corgikbd_resume(struct platform_device *dev) { + int i; struct corgikbd *corgikbd = platform_get_drvdata(dev); + for (i = 1; i < CORGI_KEY_STROBE_NUM; i++) + pxa_gpio_mode(CORGI_GPIO_KEY_STROBE(i) | GPIO_OUT | GPIO_DFLT_HIGH); + /* Upon resume, ignore the suspend key for a short while */ corgikbd->suspend_jiffies=jiffies; corgikbd->suspended = 0; @@ -333,10 +342,11 @@ static int __init corgikbd_probe(struct platform_device *pdev) clear_bit(0, input_dev->keybit); set_bit(SW_0, input_dev->swbit); set_bit(SW_1, input_dev->swbit); + set_bit(SW_2, input_dev->swbit); input_register_device(corgikbd->input); - mod_timer(&corgikbd->htimer, jiffies + HINGE_SCAN_INTERVAL); + mod_timer(&corgikbd->htimer, jiffies + msecs_to_jiffies(HINGE_SCAN_INTERVAL)); /* Setup sense interrupts - RisingEdge Detect, sense lines as inputs */ for (i = 0; i < CORGI_KEY_SENSE_NUM; i++) { @@ -351,6 +361,9 @@ static int __init corgikbd_probe(struct platform_device *pdev) for (i = 0; i < CORGI_KEY_STROBE_NUM; i++) pxa_gpio_mode(CORGI_GPIO_KEY_STROBE(i) | GPIO_OUT | GPIO_DFLT_HIGH); + /* Setup the headphone jack as an input */ + pxa_gpio_mode(CORGI_GPIO_AK_INT | GPIO_IN); + return 0; } diff --git a/drivers/input/keyboard/hil_kbd.c b/drivers/input/keyboard/hil_kbd.c index 0a90962c38e..1dca3cf42a5 100644 --- a/drivers/input/keyboard/hil_kbd.c +++ b/drivers/input/keyboard/hil_kbd.c @@ -66,7 +66,7 @@ static unsigned int hil_kbd_set3[HIL_KEYCODES_SET3_TBLSIZE] = static char hil_language[][16] = { HIL_LOCALE_MAP }; struct hil_kbd { - struct input_dev dev; + struct input_dev *dev; struct serio *serio; /* Input buffer and index for packets from HIL bus. */ @@ -86,7 +86,7 @@ struct hil_kbd { /* Process a complete packet after transfer from the HIL */ static void hil_kbd_process_record(struct hil_kbd *kbd) { - struct input_dev *dev = &kbd->dev; + struct input_dev *dev = kbd->dev; hil_packet *data = kbd->data; hil_packet p; int idx, i, cnt; @@ -240,8 +240,8 @@ static void hil_kbd_disconnect(struct serio *serio) return; } - input_unregister_device(&kbd->dev); serio_close(serio); + input_unregister_device(kbd->dev); kfree(kbd); } @@ -250,17 +250,22 @@ static int hil_kbd_connect(struct serio *serio, struct serio_driver *drv) struct hil_kbd *kbd; uint8_t did, *idd; int i; - - kbd = kmalloc(sizeof(*kbd), GFP_KERNEL); + + kbd = kzalloc(sizeof(*kbd), GFP_KERNEL); if (!kbd) return -ENOMEM; - memset(kbd, 0, sizeof(struct hil_kbd)); - if (serio_open(serio, drv)) goto bail0; + kbd->dev = input_allocate_device(); + if (!kbd->dev) + goto bail0; + + kbd->dev->private = kbd; + + if (serio_open(serio, drv)) + goto bail1; serio_set_drvdata(serio, kbd); kbd->serio = serio; - kbd->dev.private = kbd; init_MUTEX_LOCKED(&(kbd->sem)); @@ -302,38 +307,38 @@ static int hil_kbd_connect(struct serio *serio, struct serio_driver *drv) did, hil_language[did & HIL_IDD_DID_TYPE_KB_LANG_MASK]); break; default: - goto bail1; + goto bail2; } if(HIL_IDD_NUM_BUTTONS(idd) || HIL_IDD_NUM_AXES_PER_SET(*idd)) { printk(KERN_INFO PREFIX "keyboards only, no combo devices supported.\n"); - goto bail1; + goto bail2; } - kbd->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_REP); - kbd->dev.ledbit[0] = BIT(LED_NUML) | BIT(LED_CAPSL) | BIT(LED_SCROLLL); - kbd->dev.keycodemax = HIL_KEYCODES_SET1_TBLSIZE; - kbd->dev.keycodesize = sizeof(hil_kbd_set1[0]); - kbd->dev.keycode = hil_kbd_set1; - kbd->dev.name = strlen(kbd->rnm) ? kbd->rnm : HIL_GENERIC_NAME; - kbd->dev.phys = "hpkbd/input0"; /* XXX */ + kbd->dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REP); + kbd->dev->ledbit[0] = BIT(LED_NUML) | BIT(LED_CAPSL) | BIT(LED_SCROLLL); + kbd->dev->keycodemax = HIL_KEYCODES_SET1_TBLSIZE; + kbd->dev->keycodesize = sizeof(hil_kbd_set1[0]); + kbd->dev->keycode = hil_kbd_set1; + kbd->dev->name = strlen(kbd->rnm) ? kbd->rnm : HIL_GENERIC_NAME; + kbd->dev->phys = "hpkbd/input0"; /* XXX */ - kbd->dev.id.bustype = BUS_HIL; - kbd->dev.id.vendor = PCI_VENDOR_ID_HP; - kbd->dev.id.product = 0x0001; /* TODO: get from kbd->rsc */ - kbd->dev.id.version = 0x0100; /* TODO: get from kbd->rsc */ - kbd->dev.dev = &serio->dev; + kbd->dev->id.bustype = BUS_HIL; + kbd->dev->id.vendor = PCI_VENDOR_ID_HP; + kbd->dev->id.product = 0x0001; /* TODO: get from kbd->rsc */ + kbd->dev->id.version = 0x0100; /* TODO: get from kbd->rsc */ + kbd->dev->dev = &serio->dev; for (i = 0; i < 128; i++) { - set_bit(hil_kbd_set1[i], kbd->dev.keybit); - set_bit(hil_kbd_set3[i], kbd->dev.keybit); + set_bit(hil_kbd_set1[i], kbd->dev->keybit); + set_bit(hil_kbd_set3[i], kbd->dev->keybit); } - clear_bit(0, kbd->dev.keybit); + clear_bit(0, kbd->dev->keybit); - input_register_device(&kbd->dev); + input_register_device(kbd->dev); printk(KERN_INFO "input: %s, ID: %d\n", - kbd->dev.name, did); + kbd->dev->name, did); serio->write(serio, 0); serio->write(serio, 0); @@ -343,8 +348,10 @@ static int hil_kbd_connect(struct serio *serio, struct serio_driver *drv) up(&(kbd->sem)); return 0; - bail1: + bail2: serio_close(serio); + bail1: + input_free_device(kbd->dev); bail0: kfree(kbd); serio_set_drvdata(serio, NULL); diff --git a/drivers/input/keyboard/hilkbd.c b/drivers/input/keyboard/hilkbd.c index e95bc052e32..33edd030aa7 100644 --- a/drivers/input/keyboard/hilkbd.c +++ b/drivers/input/keyboard/hilkbd.c @@ -3,7 +3,7 @@ * * Copyright (C) 1998 Philip Blundell <philb@gnu.org> * Copyright (C) 1999 Matthew Wilcox <willy@bofh.ai> - * Copyright (C) 1999-2003 Helge Deller <deller@gmx.de> + * Copyright (C) 1999-2006 Helge Deller <deller@gmx.de> * * Very basic HP Human Interface Loop (HIL) driver. * This driver handles the keyboard on HP300 (m68k) and on some @@ -90,7 +90,7 @@ static unsigned int hphilkeyb_keycode[HIL_KEYCODES_SET1_TBLSIZE] = /* HIL structure */ static struct { - struct input_dev dev; + struct input_dev *dev; unsigned int curdev; @@ -117,7 +117,7 @@ static void poll_finished(void) down = (hil_dev.data[1] & 1) == 0; scode = hil_dev.data[1] >> 1; key = hphilkeyb_keycode[scode]; - input_report_key(&hil_dev.dev, key, down); + input_report_key(hil_dev.dev, key, down); break; } hil_dev.curdev = 0; @@ -207,9 +207,14 @@ hil_keyb_init(void) unsigned int i, kbid; wait_queue_head_t hil_wait; - if (hil_dev.dev.id.bustype) { + if (hil_dev.dev) { return -ENODEV; /* already initialized */ } + + hil_dev.dev = input_allocate_device(); + if (!hil_dev.dev) + return -ENOMEM; + hil_dev.dev->private = &hil_dev; #if defined(CONFIG_HP300) if (!hwreg_present((void *)(HILBASE + HIL_DATA))) @@ -247,28 +252,26 @@ hil_keyb_init(void) c = 0; hil_do(HIL_WRITEKBDSADR, &c, 1); - init_input_dev(&hil_dev.dev); - for (i = 0; i < HIL_KEYCODES_SET1_TBLSIZE; i++) if (hphilkeyb_keycode[i] != KEY_RESERVED) - set_bit(hphilkeyb_keycode[i], hil_dev.dev.keybit); - - hil_dev.dev.evbit[0] = BIT(EV_KEY) | BIT(EV_REP); - hil_dev.dev.ledbit[0] = BIT(LED_NUML) | BIT(LED_CAPSL) | BIT(LED_SCROLLL); - hil_dev.dev.keycodemax = HIL_KEYCODES_SET1_TBLSIZE; - hil_dev.dev.keycodesize = sizeof(hphilkeyb_keycode[0]); - hil_dev.dev.keycode = hphilkeyb_keycode; - hil_dev.dev.name = "HIL keyboard"; - hil_dev.dev.phys = "hpkbd/input0"; - - hil_dev.dev.id.bustype = BUS_HIL; - hil_dev.dev.id.vendor = PCI_VENDOR_ID_HP; - hil_dev.dev.id.product = 0x0001; - hil_dev.dev.id.version = 0x0010; - - input_register_device(&hil_dev.dev); + set_bit(hphilkeyb_keycode[i], hil_dev.dev->keybit); + + hil_dev.dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REP); + hil_dev.dev->ledbit[0] = BIT(LED_NUML) | BIT(LED_CAPSL) | BIT(LED_SCROLLL); + hil_dev.dev->keycodemax = HIL_KEYCODES_SET1_TBLSIZE; + hil_dev.dev->keycodesize = sizeof(hphilkeyb_keycode[0]); + hil_dev.dev->keycode = hphilkeyb_keycode; + hil_dev.dev->name = "HIL keyboard"; + hil_dev.dev->phys = "hpkbd/input0"; + + hil_dev.dev->id.bustype = BUS_HIL; + hil_dev.dev->id.vendor = PCI_VENDOR_ID_HP; + hil_dev.dev->id.product = 0x0001; + hil_dev.dev->id.version = 0x0010; + + input_register_device(hil_dev.dev); printk(KERN_INFO "input: %s, ID %d at 0x%08lx (irq %d) found and attached\n", - hil_dev.dev.name, kbid, HILBASE, HIL_IRQ); + hil_dev.dev->name, kbid, HILBASE, HIL_IRQ); return 0; } @@ -329,7 +332,9 @@ static void __exit hil_exit(void) /* Turn off interrupts */ hil_do(HIL_INTOFF, NULL, 0); - input_unregister_device(&hil_dev.dev); + input_unregister_device(hil_dev.dev); + + hil_dev.dev = NULL; #if defined(CONFIG_PARISC) unregister_parisc_driver(&hil_driver); diff --git a/drivers/input/keyboard/spitzkbd.c b/drivers/input/keyboard/spitzkbd.c index 83999d58312..bc61cf8cfc6 100644 --- a/drivers/input/keyboard/spitzkbd.c +++ b/drivers/input/keyboard/spitzkbd.c @@ -30,6 +30,7 @@ #define SCANCODE(r,c) (((r)<<4) + (c) + 1) #define NR_SCANCODES ((KB_ROWS<<4) + 1) +#define SCAN_INTERVAL (50) /* ms */ #define HINGE_SCAN_INTERVAL (150) /* ms */ #define SPITZ_KEY_CALENDER KEY_F1 @@ -230,7 +231,7 @@ static void spitzkbd_scankeyboard(struct spitzkbd *spitzkbd_data, struct pt_regs /* if any keys are pressed, enable the timer */ if (num_pressed) - mod_timer(&spitzkbd_data->timer, jiffies + msecs_to_jiffies(100)); + mod_timer(&spitzkbd_data->timer, jiffies + msecs_to_jiffies(SCAN_INTERVAL)); spin_unlock_irqrestore(&spitzkbd_data->lock, flags); } @@ -287,6 +288,7 @@ static void spitzkbd_hinge_timer(unsigned long data) unsigned long flags; state = GPLR(SPITZ_GPIO_SWA) & (GPIO_bit(SPITZ_GPIO_SWA)|GPIO_bit(SPITZ_GPIO_SWB)); + state |= (GPLR(SPITZ_GPIO_AK_INT) & GPIO_bit(SPITZ_GPIO_AK_INT)); if (state != sharpsl_hinge_state) { hinge_count = 0; sharpsl_hinge_state = state; @@ -299,6 +301,7 @@ static void spitzkbd_hinge_timer(unsigned long data) input_report_switch(spitzkbd_data->input, SW_0, ((GPLR(SPITZ_GPIO_SWA) & GPIO_bit(SPITZ_GPIO_SWA)) != 0)); input_report_switch(spitzkbd_data->input, SW_1, ((GPLR(SPITZ_GPIO_SWB) & GPIO_bit(SPITZ_GPIO_SWB)) != 0)); + input_report_switch(spitzkbd_data->input, SW_2, ((GPLR(SPITZ_GPIO_AK_INT) & GPIO_bit(SPITZ_GPIO_AK_INT)) != 0)); input_sync(spitzkbd_data->input); spin_unlock_irqrestore(&spitzkbd_data->lock, flags); @@ -397,6 +400,7 @@ static int __init spitzkbd_probe(struct platform_device *dev) clear_bit(0, input_dev->keybit); set_bit(SW_0, input_dev->swbit); set_bit(SW_1, input_dev->swbit); + set_bit(SW_2, input_dev->swbit); input_register_device(input_dev); @@ -432,6 +436,9 @@ static int __init spitzkbd_probe(struct platform_device *dev) request_irq(SPITZ_IRQ_GPIO_SWB, spitzkbd_hinge_isr, SA_INTERRUPT | SA_TRIGGER_RISING | SA_TRIGGER_FALLING, "Spitzkbd SWB", spitzkbd); + request_irq(SPITZ_IRQ_GPIO_AK_INT, spitzkbd_hinge_isr, + SA_INTERRUPT | SA_TRIGGER_RISING | SA_TRIGGER_FALLING, + "Spitzkbd HP", spitzkbd); printk(KERN_INFO "input: Spitz Keyboard Registered\n"); @@ -450,6 +457,7 @@ static int spitzkbd_remove(struct platform_device *dev) free_irq(SPITZ_IRQ_GPIO_ON_KEY, spitzkbd); free_irq(SPITZ_IRQ_GPIO_SWA, spitzkbd); free_irq(SPITZ_IRQ_GPIO_SWB, spitzkbd); + free_irq(SPITZ_IRQ_GPIO_AK_INT, spitzkbd); del_timer_sync(&spitzkbd->htimer); del_timer_sync(&spitzkbd->timer); diff --git a/drivers/input/misc/pcspkr.c b/drivers/input/misc/pcspkr.c index 1ef477f4469..afd322185bb 100644 --- a/drivers/input/misc/pcspkr.c +++ b/drivers/input/misc/pcspkr.c @@ -24,7 +24,6 @@ MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>"); MODULE_DESCRIPTION("PC Speaker beeper driver"); MODULE_LICENSE("GPL"); -static struct platform_device *pcspkr_platform_device; static DEFINE_SPINLOCK(i8253_beep_lock); static int pcspkr_event(struct input_dev *dev, unsigned int type, unsigned int code, int value) @@ -135,35 +134,11 @@ static struct platform_driver pcspkr_platform_driver = { static int __init pcspkr_init(void) { - int err; - - err = platform_driver_register(&pcspkr_platform_driver); - if (err) - return err; - - pcspkr_platform_device = platform_device_alloc("pcspkr", -1); - if (!pcspkr_platform_device) { - err = -ENOMEM; - goto err_unregister_driver; - } - - err = platform_device_add(pcspkr_platform_device); - if (err) - goto err_free_device; - - return 0; - - err_free_device: - platform_device_put(pcspkr_platform_device); - err_unregister_driver: - platform_driver_unregister(&pcspkr_platform_driver); - - return err; + return platform_driver_register(&pcspkr_platform_driver); } static void __exit pcspkr_exit(void) { - platform_device_unregister(pcspkr_platform_device); platform_driver_unregister(&pcspkr_platform_driver); } diff --git a/drivers/input/misc/uinput.c b/drivers/input/misc/uinput.c index 546ed9b4901..d723e9ad7c4 100644 --- a/drivers/input/misc/uinput.c +++ b/drivers/input/misc/uinput.c @@ -194,7 +194,7 @@ static int uinput_open(struct inode *inode, struct file *file) if (!newdev) return -ENOMEM; - init_MUTEX(&newdev->sem); + mutex_init(&newdev->mutex); spin_lock_init(&newdev->requests_lock); init_waitqueue_head(&newdev->requests_waitq); init_waitqueue_head(&newdev->waitq); @@ -340,7 +340,7 @@ static ssize_t uinput_write(struct file *file, const char __user *buffer, size_t struct uinput_device *udev = file->private_data; int retval; - retval = down_interruptible(&udev->sem); + retval = mutex_lock_interruptible(&udev->mutex); if (retval) return retval; @@ -348,7 +348,7 @@ static ssize_t uinput_write(struct file *file, const char __user *buffer, size_t uinput_inject_event(udev, buffer, count) : uinput_setup_device(udev, buffer, count); - up(&udev->sem); + mutex_unlock(&udev->mutex); return retval; } @@ -369,7 +369,7 @@ static ssize_t uinput_read(struct file *file, char __user *buffer, size_t count, if (retval) return retval; - retval = down_interruptible(&udev->sem); + retval = mutex_lock_interruptible(&udev->mutex); if (retval) return retval; @@ -388,7 +388,7 @@ static ssize_t uinput_read(struct file *file, char __user *buffer, size_t count, } out: - up(&udev->sem); + mutex_unlock(&udev->mutex); return retval; } @@ -439,7 +439,7 @@ static long uinput_ioctl(struct file *file, unsigned int cmd, unsigned long arg) udev = file->private_data; - retval = down_interruptible(&udev->sem); + retval = mutex_lock_interruptible(&udev->mutex); if (retval) return retval; @@ -589,7 +589,7 @@ static long uinput_ioctl(struct file *file, unsigned int cmd, unsigned long arg) } out: - up(&udev->sem); + mutex_unlock(&udev->mutex); return retval; } diff --git a/drivers/input/mouse/hil_ptr.c b/drivers/input/mouse/hil_ptr.c index c2bf2ed07dc..69f02178c52 100644 --- a/drivers/input/mouse/hil_ptr.c +++ b/drivers/input/mouse/hil_ptr.c @@ -55,7 +55,7 @@ MODULE_LICENSE("Dual BSD/GPL"); #define HIL_PTR_MAX_LENGTH 16 struct hil_ptr { - struct input_dev dev; + struct input_dev *dev; struct serio *serio; /* Input buffer and index for packets from HIL bus. */ @@ -79,7 +79,7 @@ struct hil_ptr { /* Process a complete packet after transfer from the HIL */ static void hil_ptr_process_record(struct hil_ptr *ptr) { - struct input_dev *dev = &ptr->dev; + struct input_dev *dev = ptr->dev; hil_packet *data = ptr->data; hil_packet p; int idx, i, cnt, laxis; @@ -148,12 +148,12 @@ static void hil_ptr_process_record(struct hil_ptr *ptr) if (absdev) { val = lo + (hi<<8); #ifdef TABLET_AUTOADJUST - if (val < ptr->dev.absmin[ABS_X + i]) - ptr->dev.absmin[ABS_X + i] = val; - if (val > ptr->dev.absmax[ABS_X + i]) - ptr->dev.absmax[ABS_X + i] = val; + if (val < dev->absmin[ABS_X + i]) + dev->absmin[ABS_X + i] = val; + if (val > dev->absmax[ABS_X + i]) + dev->absmax[ABS_X + i] = val; #endif - if (i%3) val = ptr->dev.absmax[ABS_X + i] - val; + if (i%3) val = dev->absmax[ABS_X + i] - val; input_report_abs(dev, ABS_X + i, val); } else { val = (int) (((int8_t)lo) | ((int8_t)hi<<8)); @@ -233,26 +233,32 @@ static void hil_ptr_disconnect(struct serio *serio) return; } - input_unregister_device(&ptr->dev); serio_close(serio); + input_unregister_device(ptr->dev); kfree(ptr); } static int hil_ptr_connect(struct serio *serio, struct serio_driver *driver) { - struct hil_ptr *ptr; - char *txt; - unsigned int i, naxsets, btntype; - uint8_t did, *idd; + struct hil_ptr *ptr; + char *txt; + unsigned int i, naxsets, btntype; + uint8_t did, *idd; - if (!(ptr = kmalloc(sizeof(struct hil_ptr), GFP_KERNEL))) return -ENOMEM; - memset(ptr, 0, sizeof(struct hil_ptr)); + if (!(ptr = kzalloc(sizeof(struct hil_ptr), GFP_KERNEL))) + return -ENOMEM; - if (serio_open(serio, driver)) goto bail0; + ptr->dev = input_allocate_device(); + if (!ptr->dev) + goto bail0; + + ptr->dev->private = ptr; + + if (serio_open(serio, driver)) + goto bail1; serio_set_drvdata(serio, ptr); ptr->serio = serio; - ptr->dev.private = ptr; init_MUTEX_LOCKED(&(ptr->sem)); @@ -283,25 +289,24 @@ static int hil_ptr_connect(struct serio *serio, struct serio_driver *driver) up(&(ptr->sem)); - init_input_dev(&ptr->dev); did = ptr->idd[0]; idd = ptr->idd + 1; txt = "unknown"; if ((did & HIL_IDD_DID_TYPE_MASK) == HIL_IDD_DID_TYPE_REL) { - ptr->dev.evbit[0] = BIT(EV_REL); + ptr->dev->evbit[0] = BIT(EV_REL); txt = "relative"; } if ((did & HIL_IDD_DID_TYPE_MASK) == HIL_IDD_DID_TYPE_ABS) { - ptr->dev.evbit[0] = BIT(EV_ABS); + ptr->dev->evbit[0] = BIT(EV_ABS); txt = "absolute"; } - if (!ptr->dev.evbit[0]) { - goto bail1; + if (!ptr->dev->evbit[0]) { + goto bail2; } ptr->nbtn = HIL_IDD_NUM_BUTTONS(idd); - if (ptr->nbtn) ptr->dev.evbit[0] |= BIT(EV_KEY); + if (ptr->nbtn) ptr->dev->evbit[0] |= BIT(EV_KEY); naxsets = HIL_IDD_NUM_AXSETS(*idd); ptr->naxes = HIL_IDD_NUM_AXES_PER_SET(*idd); @@ -325,7 +330,7 @@ static int hil_ptr_connect(struct serio *serio, struct serio_driver *driver) btntype = BTN_MOUSE; for (i = 0; i < ptr->nbtn; i++) { - set_bit(btntype | i, ptr->dev.keybit); + set_bit(btntype | i, ptr->dev->keybit); ptr->btnmap[i] = btntype | i; } @@ -337,50 +342,52 @@ static int hil_ptr_connect(struct serio *serio, struct serio_driver *driver) if ((did & HIL_IDD_DID_TYPE_MASK) == HIL_IDD_DID_TYPE_REL) { for (i = 0; i < ptr->naxes; i++) { - set_bit(REL_X + i, ptr->dev.relbit); + set_bit(REL_X + i, ptr->dev->relbit); } for (i = 3; (i < ptr->naxes + 3) && (naxsets > 1); i++) { - set_bit(REL_X + i, ptr->dev.relbit); + set_bit(REL_X + i, ptr->dev->relbit); } } else { for (i = 0; i < ptr->naxes; i++) { - set_bit(ABS_X + i, ptr->dev.absbit); - ptr->dev.absmin[ABS_X + i] = 0; - ptr->dev.absmax[ABS_X + i] = + set_bit(ABS_X + i, ptr->dev->absbit); + ptr->dev->absmin[ABS_X + i] = 0; + ptr->dev->absmax[ABS_X + i] = HIL_IDD_AXIS_MAX((ptr->idd + 1), i); } for (i = 3; (i < ptr->naxes + 3) && (naxsets > 1); i++) { - set_bit(ABS_X + i, ptr->dev.absbit); - ptr->dev.absmin[ABS_X + i] = 0; - ptr->dev.absmax[ABS_X + i] = + set_bit(ABS_X + i, ptr->dev->absbit); + ptr->dev->absmin[ABS_X + i] = 0; + ptr->dev->absmax[ABS_X + i] = HIL_IDD_AXIS_MAX((ptr->idd + 1), (i - 3)); } #ifdef TABLET_AUTOADJUST for (i = 0; i < ABS_MAX; i++) { - int diff = ptr->dev.absmax[ABS_X + i] / 10; - ptr->dev.absmin[ABS_X + i] += diff; - ptr->dev.absmax[ABS_X + i] -= diff; + int diff = ptr->dev->absmax[ABS_X + i] / 10; + ptr->dev->absmin[ABS_X + i] += diff; + ptr->dev->absmax[ABS_X + i] -= diff; } #endif } - ptr->dev.name = strlen(ptr->rnm) ? ptr->rnm : HIL_GENERIC_NAME; + ptr->dev->name = strlen(ptr->rnm) ? ptr->rnm : HIL_GENERIC_NAME; - ptr->dev.id.bustype = BUS_HIL; - ptr->dev.id.vendor = PCI_VENDOR_ID_HP; - ptr->dev.id.product = 0x0001; /* TODO: get from ptr->rsc */ - ptr->dev.id.version = 0x0100; /* TODO: get from ptr->rsc */ - ptr->dev.dev = &serio->dev; + ptr->dev->id.bustype = BUS_HIL; + ptr->dev->id.vendor = PCI_VENDOR_ID_HP; + ptr->dev->id.product = 0x0001; /* TODO: get from ptr->rsc */ + ptr->dev->id.version = 0x0100; /* TODO: get from ptr->rsc */ + ptr->dev->dev = &serio->dev; - input_register_device(&ptr->dev); + input_register_device(ptr->dev); printk(KERN_INFO "input: %s (%s), ID: %d\n", - ptr->dev.name, + ptr->dev->name, (btntype == BTN_MOUSE) ? "HIL mouse":"HIL tablet or touchpad", did); return 0; - bail1: + bail2: serio_close(serio); + bail1: + input_free_device(ptr->dev); bail0: kfree(ptr); serio_set_drvdata(serio, NULL); diff --git a/drivers/input/mouse/psmouse-base.c b/drivers/input/mouse/psmouse-base.c index ad621746767..32d70ed8f41 100644 --- a/drivers/input/mouse/psmouse-base.c +++ b/drivers/input/mouse/psmouse-base.c @@ -20,6 +20,8 @@ #include <linux/serio.h> #include <linux/init.h> #include <linux/libps2.h> +#include <linux/mutex.h> + #include "psmouse.h" #include "synaptics.h" #include "logips2pp.h" @@ -98,13 +100,13 @@ __obsolete_setup("psmouse_resetafter="); __obsolete_setup("psmouse_rate="); /* - * psmouse_sem protects all operations changing state of mouse + * psmouse_mutex protects all operations changing state of mouse * (connecting, disconnecting, changing rate or resolution via * sysfs). We could use a per-device semaphore but since there * rarely more than one PS/2 mouse connected and since semaphore * is taken in "slow" paths it is not worth it. */ -static DECLARE_MUTEX(psmouse_sem); +static DEFINE_MUTEX(psmouse_mutex); static struct workqueue_struct *kpsmoused_wq; @@ -868,7 +870,7 @@ static void psmouse_resync(void *p) int failed = 0, enabled = 0; int i; - down(&psmouse_sem); + mutex_lock(&psmouse_mutex); if (psmouse->state != PSMOUSE_RESYNCING) goto out; @@ -948,7 +950,7 @@ static void psmouse_resync(void *p) if (parent) psmouse_activate(parent); out: - up(&psmouse_sem); + mutex_unlock(&psmouse_mutex); } /* @@ -974,14 +976,14 @@ static void psmouse_disconnect(struct serio *serio) sysfs_remove_group(&serio->dev.kobj, &psmouse_attribute_group); - down(&psmouse_sem); + mutex_lock(&psmouse_mutex); psmouse_set_state(psmouse, PSMOUSE_CMD_MODE); /* make sure we don't have a resync in progress */ - up(&psmouse_sem); + mutex_unlock(&psmouse_mutex); flush_workqueue(kpsmoused_wq); - down(&psmouse_sem); + mutex_lock(&psmouse_mutex); if (serio->parent && serio->id.type == SERIO_PS_PSTHRU) { parent = serio_get_drvdata(serio->parent); @@ -1004,7 +1006,7 @@ static void psmouse_disconnect(struct serio *serio) if (parent) psmouse_activate(parent); - up(&psmouse_sem); + mutex_unlock(&psmouse_mutex); } static int psmouse_switch_protocol(struct psmouse *psmouse, struct psmouse_protocol *proto) @@ -1076,7 +1078,7 @@ static int psmouse_connect(struct serio *serio, struct serio_driver *drv) struct input_dev *input_dev; int retval = -ENOMEM; - down(&psmouse_sem); + mutex_lock(&psmouse_mutex); /* * If this is a pass-through port deactivate parent so the device @@ -1144,7 +1146,7 @@ out: if (parent) psmouse_activate(parent); - up(&psmouse_sem); + mutex_unlock(&psmouse_mutex); return retval; } @@ -1161,7 +1163,7 @@ static int psmouse_reconnect(struct serio *serio) return -1; } - down(&psmouse_sem); + mutex_lock(&psmouse_mutex); if (serio->parent && serio->id.type == SERIO_PS_PSTHRU) { parent = serio_get_drvdata(serio->parent); @@ -1195,7 +1197,7 @@ out: if (parent) psmouse_activate(parent); - up(&psmouse_sem); + mutex_unlock(&psmouse_mutex); return rc; } @@ -1273,7 +1275,7 @@ ssize_t psmouse_attr_set_helper(struct device *dev, struct device_attribute *dev goto out_unpin; } - retval = down_interruptible(&psmouse_sem); + retval = mutex_lock_interruptible(&psmouse_mutex); if (retval) goto out_unpin; @@ -1281,7 +1283,7 @@ ssize_t psmouse_attr_set_helper(struct device *dev, struct device_attribute *dev if (psmouse->state == PSMOUSE_IGNORE) { retval = -ENODEV; - goto out_up; + goto out_unlock; } if (serio->parent && serio->id.type == SERIO_PS_PSTHRU) { @@ -1299,8 +1301,8 @@ ssize_t psmouse_attr_set_helper(struct device *dev, struct device_attribute *dev if (parent) psmouse_activate(parent); - out_up: - up(&psmouse_sem); + out_unlock: + mutex_unlock(&psmouse_mutex); out_unpin: serio_unpin_driver(serio); return retval; @@ -1357,11 +1359,11 @@ static ssize_t psmouse_attr_set_protocol(struct psmouse *psmouse, void *data, co return -EIO; } - up(&psmouse_sem); + mutex_unlock(&psmouse_mutex); serio_unpin_driver(serio); serio_unregister_child_port(serio); serio_pin_driver_uninterruptible(serio); - down(&psmouse_sem); + mutex_lock(&psmouse_mutex); if (serio->drv != &psmouse_drv) { input_free_device(new_dev); diff --git a/drivers/input/mouse/synaptics.c b/drivers/input/mouse/synaptics.c index 2051bec2c39..ad5d0a85e96 100644 --- a/drivers/input/mouse/synaptics.c +++ b/drivers/input/mouse/synaptics.c @@ -247,14 +247,12 @@ static void synaptics_pt_create(struct psmouse *psmouse) { struct serio *serio; - serio = kmalloc(sizeof(struct serio), GFP_KERNEL); + serio = kzalloc(sizeof(struct serio), GFP_KERNEL); if (!serio) { printk(KERN_ERR "synaptics: not enough memory to allocate pass-through port\n"); return; } - memset(serio, 0, sizeof(struct serio)); - serio->id.type = SERIO_PS_PSTHRU; strlcpy(serio->name, "Synaptics pass-through", sizeof(serio->name)); strlcpy(serio->phys, "synaptics-pt/serio0", sizeof(serio->name)); @@ -605,14 +603,21 @@ static struct dmi_system_id toshiba_dmi_table[] = { .ident = "Toshiba Satellite", .matches = { DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"), - DMI_MATCH(DMI_PRODUCT_NAME , "Satellite"), + DMI_MATCH(DMI_PRODUCT_NAME, "Satellite"), }, }, { .ident = "Toshiba Dynabook", .matches = { DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"), - DMI_MATCH(DMI_PRODUCT_NAME , "dynabook"), + DMI_MATCH(DMI_PRODUCT_NAME, "dynabook"), + }, + }, + { + .ident = "Toshiba Portege M300", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"), + DMI_MATCH(DMI_PRODUCT_NAME, "PORTEGE M300"), }, }, { } @@ -623,10 +628,9 @@ int synaptics_init(struct psmouse *psmouse) { struct synaptics_data *priv; - psmouse->private = priv = kmalloc(sizeof(struct synaptics_data), GFP_KERNEL); + psmouse->private = priv = kzalloc(sizeof(struct synaptics_data), GFP_KERNEL); if (!priv) return -1; - memset(priv, 0, sizeof(struct synaptics_data)); if (synaptics_query_hardware(psmouse)) { printk(KERN_ERR "Unable to query Synaptics hardware.\n"); diff --git a/drivers/input/mousedev.c b/drivers/input/mousedev.c index 9abed18d2ec..b685a507955 100644 --- a/drivers/input/mousedev.c +++ b/drivers/input/mousedev.c @@ -412,9 +412,8 @@ static int mousedev_open(struct inode * inode, struct file * file) if (i >= MOUSEDEV_MINORS || !mousedev_table[i]) return -ENODEV; - if (!(list = kmalloc(sizeof(struct mousedev_list), GFP_KERNEL))) + if (!(list = kzalloc(sizeof(struct mousedev_list), GFP_KERNEL))) return -ENOMEM; - memset(list, 0, sizeof(struct mousedev_list)); spin_lock_init(&list->packet_lock); list->pos_x = xres / 2; @@ -626,9 +625,8 @@ static struct input_handle *mousedev_connect(struct input_handler *handler, stru return NULL; } - if (!(mousedev = kmalloc(sizeof(struct mousedev), GFP_KERNEL))) + if (!(mousedev = kzalloc(sizeof(struct mousedev), GFP_KERNEL))) return NULL; - memset(mousedev, 0, sizeof(struct mousedev)); INIT_LIST_HEAD(&mousedev->list); init_waitqueue_head(&mousedev->wait); diff --git a/drivers/input/power.c b/drivers/input/power.c index bfc5c63ebff..526e6070600 100644 --- a/drivers/input/power.c +++ b/drivers/input/power.c @@ -103,9 +103,8 @@ static struct input_handle *power_connect(struct input_handler *handler, { struct input_handle *handle; - if (!(handle = kmalloc(sizeof(struct input_handle), GFP_KERNEL))) + if (!(handle = kzalloc(sizeof(struct input_handle), GFP_KERNEL))) return NULL; - memset(handle, 0, sizeof(struct input_handle)); handle->dev = dev; handle->handler = handler; diff --git a/drivers/input/serio/gscps2.c b/drivers/input/serio/gscps2.c index a7b0de0f92b..c0b1e4becad 100644 --- a/drivers/input/serio/gscps2.c +++ b/drivers/input/serio/gscps2.c @@ -1,7 +1,7 @@ /* * drivers/input/serio/gscps2.c * - * Copyright (c) 2004 Helge Deller <deller@gmx.de> + * Copyright (c) 2004-2006 Helge Deller <deller@gmx.de> * Copyright (c) 2002 Laurent Canet <canetl@esiee.fr> * Copyright (c) 2002 Thibaut Varene <varenet@parisc-linux.org> * @@ -354,7 +354,7 @@ static int __init gscps2_probe(struct parisc_device *dev) memset(serio, 0, sizeof(struct serio)); ps2port->port = serio; ps2port->padev = dev; - ps2port->addr = ioremap(hpa, GSC_STATUS + 4); + ps2port->addr = ioremap_nocache(hpa, GSC_STATUS + 4); spin_lock_init(&ps2port->lock); gscps2_reset(ps2port); diff --git a/drivers/input/serio/hil_mlc.c b/drivers/input/serio/hil_mlc.c index ea499783fb1..bbbe15e2190 100644 --- a/drivers/input/serio/hil_mlc.c +++ b/drivers/input/serio/hil_mlc.c @@ -872,9 +872,8 @@ int hil_mlc_register(hil_mlc *mlc) { for (i = 0; i < HIL_MLC_DEVMEM; i++) { struct serio *mlc_serio; hil_mlc_copy_di_scratch(mlc, i); - mlc_serio = kmalloc(sizeof(*mlc_serio), GFP_KERNEL); + mlc_serio = kzalloc(sizeof(*mlc_serio), GFP_KERNEL); mlc->serio[i] = mlc_serio; - memset(mlc_serio, 0, sizeof(*mlc_serio)); mlc_serio->id = hil_mlc_serio_id; mlc_serio->write = hil_mlc_serio_write; mlc_serio->open = hil_mlc_serio_open; diff --git a/drivers/input/serio/i8042-x86ia64io.h b/drivers/input/serio/i8042-x86ia64io.h index a4c6f352272..f606e96bc2f 100644 --- a/drivers/input/serio/i8042-x86ia64io.h +++ b/drivers/input/serio/i8042-x86ia64io.h @@ -192,7 +192,9 @@ static struct dmi_system_id __initdata i8042_dmi_nomux_table[] = { #include <linux/pnp.h> static int i8042_pnp_kbd_registered; +static unsigned int i8042_pnp_kbd_devices; static int i8042_pnp_aux_registered; +static unsigned int i8042_pnp_aux_devices; static int i8042_pnp_command_reg; static int i8042_pnp_data_reg; @@ -219,6 +221,7 @@ static int i8042_pnp_kbd_probe(struct pnp_dev *dev, const struct pnp_device_id * strncat(i8042_pnp_kbd_name, pnp_dev_name(dev), sizeof(i8042_pnp_kbd_name)); } + i8042_pnp_kbd_devices++; return 0; } @@ -239,6 +242,7 @@ static int i8042_pnp_aux_probe(struct pnp_dev *dev, const struct pnp_device_id * strncat(i8042_pnp_aux_name, pnp_dev_name(dev), sizeof(i8042_pnp_aux_name)); } + i8042_pnp_aux_devices++; return 0; } @@ -287,21 +291,23 @@ static void i8042_pnp_exit(void) static int __init i8042_pnp_init(void) { - int result_kbd = 0, result_aux = 0; char kbd_irq_str[4] = { 0 }, aux_irq_str[4] = { 0 }; + int err; if (i8042_nopnp) { printk(KERN_INFO "i8042: PNP detection disabled\n"); return 0; } - if ((result_kbd = pnp_register_driver(&i8042_pnp_kbd_driver)) >= 0) + err = pnp_register_driver(&i8042_pnp_kbd_driver); + if (!err) i8042_pnp_kbd_registered = 1; - if ((result_aux = pnp_register_driver(&i8042_pnp_aux_driver)) >= 0) + err = pnp_register_driver(&i8042_pnp_aux_driver); + if (!err) i8042_pnp_aux_registered = 1; - if (result_kbd <= 0 && result_aux <= 0) { + if (!i8042_pnp_kbd_devices && !i8042_pnp_aux_devices) { i8042_pnp_exit(); #if defined(__ia64__) return -ENODEV; @@ -311,24 +317,24 @@ static int __init i8042_pnp_init(void) #endif } - if (result_kbd > 0) + if (i8042_pnp_kbd_devices) snprintf(kbd_irq_str, sizeof(kbd_irq_str), "%d", i8042_pnp_kbd_irq); - if (result_aux > 0) + if (i8042_pnp_aux_devices) snprintf(aux_irq_str, sizeof(aux_irq_str), "%d", i8042_pnp_aux_irq); printk(KERN_INFO "PNP: PS/2 Controller [%s%s%s] at %#x,%#x irq %s%s%s\n", - i8042_pnp_kbd_name, (result_kbd > 0 && result_aux > 0) ? "," : "", + i8042_pnp_kbd_name, (i8042_pnp_kbd_devices && i8042_pnp_aux_devices) ? "," : "", i8042_pnp_aux_name, i8042_pnp_data_reg, i8042_pnp_command_reg, - kbd_irq_str, (result_kbd > 0 && result_aux > 0) ? "," : "", + kbd_irq_str, (i8042_pnp_kbd_devices && i8042_pnp_aux_devices) ? "," : "", aux_irq_str); #if defined(__ia64__) - if (result_kbd <= 0) + if (!i8042_pnp_kbd_devices) i8042_nokbd = 1; - if (result_aux <= 0) + if (!i8042_pnp_aux_devices) i8042_noaux = 1; #endif diff --git a/drivers/input/serio/libps2.c b/drivers/input/serio/libps2.c index d4c990f7c85..79c97f94bcb 100644 --- a/drivers/input/serio/libps2.c +++ b/drivers/input/serio/libps2.c @@ -84,7 +84,7 @@ void ps2_drain(struct ps2dev *ps2dev, int maxbytes, int timeout) maxbytes = sizeof(ps2dev->cmdbuf); } - down(&ps2dev->cmd_sem); + mutex_lock(&ps2dev->cmd_mutex); serio_pause_rx(ps2dev->serio); ps2dev->flags = PS2_FLAG_CMD; @@ -94,7 +94,7 @@ void ps2_drain(struct ps2dev *ps2dev, int maxbytes, int timeout) wait_event_timeout(ps2dev->wait, !(ps2dev->flags & PS2_FLAG_CMD), msecs_to_jiffies(timeout)); - up(&ps2dev->cmd_sem); + mutex_unlock(&ps2dev->cmd_mutex); } /* @@ -177,7 +177,7 @@ int ps2_command(struct ps2dev *ps2dev, unsigned char *param, int command) return -1; } - down(&ps2dev->cmd_sem); + mutex_lock(&ps2dev->cmd_mutex); serio_pause_rx(ps2dev->serio); ps2dev->flags = command == PS2_CMD_GETID ? PS2_FLAG_WAITID : 0; @@ -229,7 +229,7 @@ int ps2_command(struct ps2dev *ps2dev, unsigned char *param, int command) ps2dev->flags = 0; serio_continue_rx(ps2dev->serio); - up(&ps2dev->cmd_sem); + mutex_unlock(&ps2dev->cmd_mutex); return rc; } @@ -281,7 +281,7 @@ int ps2_schedule_command(struct ps2dev *ps2dev, unsigned char *param, int comman void ps2_init(struct ps2dev *ps2dev, struct serio *serio) { - init_MUTEX(&ps2dev->cmd_sem); + mutex_init(&ps2dev->cmd_mutex); init_waitqueue_head(&ps2dev->wait); ps2dev->serio = serio; } diff --git a/drivers/input/serio/parkbd.c b/drivers/input/serio/parkbd.c index 1d15c281981..a5c1fb3a4a5 100644 --- a/drivers/input/serio/parkbd.c +++ b/drivers/input/serio/parkbd.c @@ -171,9 +171,8 @@ static struct serio * __init parkbd_allocate_serio(void) { struct serio *serio; - serio = kmalloc(sizeof(struct serio), GFP_KERNEL); + serio = kzalloc(sizeof(struct serio), GFP_KERNEL); if (serio) { - memset(serio, 0, sizeof(struct serio)); serio->id.type = parkbd_mode; serio->write = parkbd_write, strlcpy(serio->name, "PARKBD AT/XT keyboard adapter", sizeof(serio->name)); diff --git a/drivers/input/serio/rpckbd.c b/drivers/input/serio/rpckbd.c index a3bd11589bc..513d37fc1ac 100644 --- a/drivers/input/serio/rpckbd.c +++ b/drivers/input/serio/rpckbd.c @@ -111,11 +111,10 @@ static int __devinit rpckbd_probe(struct platform_device *dev) { struct serio *serio; - serio = kmalloc(sizeof(struct serio), GFP_KERNEL); + serio = kzalloc(sizeof(struct serio), GFP_KERNEL); if (!serio) return -ENOMEM; - memset(serio, 0, sizeof(struct serio)); serio->id.type = SERIO_8042; serio->write = rpckbd_write; serio->open = rpckbd_open; diff --git a/drivers/input/serio/serio.c b/drivers/input/serio/serio.c index 2f76813c3a6..6521034bc93 100644 --- a/drivers/input/serio/serio.c +++ b/drivers/input/serio/serio.c @@ -34,6 +34,7 @@ #include <linux/sched.h> #include <linux/slab.h> #include <linux/kthread.h> +#include <linux/mutex.h> MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>"); MODULE_DESCRIPTION("Serio abstraction core"); @@ -52,10 +53,10 @@ EXPORT_SYMBOL(serio_rescan); EXPORT_SYMBOL(serio_reconnect); /* - * serio_sem protects entire serio subsystem and is taken every time + * serio_mutex protects entire serio subsystem and is taken every time * serio port or driver registrered or unregistered. */ -static DECLARE_MUTEX(serio_sem); +static DEFINE_MUTEX(serio_mutex); static LIST_HEAD(serio_list); @@ -70,9 +71,9 @@ static int serio_connect_driver(struct serio *serio, struct serio_driver *drv) { int retval; - down(&serio->drv_sem); + mutex_lock(&serio->drv_mutex); retval = drv->connect(serio, drv); - up(&serio->drv_sem); + mutex_unlock(&serio->drv_mutex); return retval; } @@ -81,20 +82,20 @@ static int serio_reconnect_driver(struct serio *serio) { int retval = -1; - down(&serio->drv_sem); + mutex_lock(&serio->drv_mutex); if (serio->drv && serio->drv->reconnect) retval = serio->drv->reconnect(serio); - up(&serio->drv_sem); + mutex_unlock(&serio->drv_mutex); return retval; } static void serio_disconnect_driver(struct serio *serio) { - down(&serio->drv_sem); + mutex_lock(&serio->drv_mutex); if (serio->drv) serio->drv->disconnect(serio); - up(&serio->drv_sem); + mutex_unlock(&serio->drv_mutex); } static int serio_match_port(const struct serio_device_id *ids, struct serio *serio) @@ -195,6 +196,7 @@ static void serio_queue_event(void *object, struct module *owner, if ((event = kmalloc(sizeof(struct serio_event), GFP_ATOMIC))) { if (!try_module_get(owner)) { printk(KERN_WARNING "serio: Can't get module reference, dropping event %d\n", event_type); + kfree(event); goto out; } @@ -272,7 +274,7 @@ static void serio_handle_event(void) struct serio_event *event; struct serio_driver *serio_drv; - down(&serio_sem); + mutex_lock(&serio_mutex); /* * Note that we handle only one event here to give swsusp @@ -314,7 +316,7 @@ static void serio_handle_event(void) serio_free_event(event); } - up(&serio_sem); + mutex_unlock(&serio_mutex); } /* @@ -449,7 +451,7 @@ static ssize_t serio_rebind_driver(struct device *dev, struct device_attribute * struct device_driver *drv; int retval; - retval = down_interruptible(&serio_sem); + retval = mutex_lock_interruptible(&serio_mutex); if (retval) return retval; @@ -469,7 +471,7 @@ static ssize_t serio_rebind_driver(struct device *dev, struct device_attribute * retval = -EINVAL; } - up(&serio_sem); + mutex_unlock(&serio_mutex); return retval; } @@ -524,7 +526,7 @@ static void serio_init_port(struct serio *serio) __module_get(THIS_MODULE); spin_lock_init(&serio->lock); - init_MUTEX(&serio->drv_sem); + mutex_init(&serio->drv_mutex); device_initialize(&serio->dev); snprintf(serio->dev.bus_id, sizeof(serio->dev.bus_id), "serio%ld", (long)atomic_inc_return(&serio_no) - 1); @@ -661,10 +663,10 @@ void __serio_register_port(struct serio *serio, struct module *owner) */ void serio_unregister_port(struct serio *serio) { - down(&serio_sem); + mutex_lock(&serio_mutex); serio_disconnect_port(serio); serio_destroy_port(serio); - up(&serio_sem); + mutex_unlock(&serio_mutex); } /* @@ -672,17 +674,17 @@ void serio_unregister_port(struct serio *serio) */ void serio_unregister_child_port(struct serio *serio) { - down(&serio_sem); + mutex_lock(&serio_mutex); if (serio->child) { serio_disconnect_port(serio->child); serio_destroy_port(serio->child); } - up(&serio_sem); + mutex_unlock(&serio_mutex); } /* * Submits register request to kseriod for subsequent execution. - * Can be used when it is not obvious whether the serio_sem is + * Can be used when it is not obvious whether the serio_mutex is * taken or not and when delayed execution is feasible. */ void __serio_unregister_port_delayed(struct serio *serio, struct module *owner) @@ -765,7 +767,7 @@ void serio_unregister_driver(struct serio_driver *drv) { struct serio *serio; - down(&serio_sem); + mutex_lock(&serio_mutex); drv->manual_bind = 1; /* so serio_find_driver ignores it */ start_over: @@ -779,7 +781,7 @@ start_over: } driver_unregister(&drv->driver); - up(&serio_sem); + mutex_unlock(&serio_mutex); } static void serio_set_drv(struct serio *serio, struct serio_driver *drv) @@ -858,7 +860,7 @@ static int serio_resume(struct device *dev) return 0; } -/* called from serio_driver->connect/disconnect methods under serio_sem */ +/* called from serio_driver->connect/disconnect methods under serio_mutex */ int serio_open(struct serio *serio, struct serio_driver *drv) { serio_set_drv(serio, drv); @@ -870,7 +872,7 @@ int serio_open(struct serio *serio, struct serio_driver *drv) return 0; } -/* called from serio_driver->connect/disconnect methods under serio_sem */ +/* called from serio_driver->connect/disconnect methods under serio_mutex */ void serio_close(struct serio *serio) { if (serio->close) @@ -923,5 +925,5 @@ static void __exit serio_exit(void) kthread_stop(serio_task); } -module_init(serio_init); +subsys_initcall(serio_init); module_exit(serio_exit); diff --git a/drivers/input/serio/serio_raw.c b/drivers/input/serio/serio_raw.c index 47e08de18d0..5a2703b536d 100644 --- a/drivers/input/serio/serio_raw.c +++ b/drivers/input/serio/serio_raw.c @@ -19,6 +19,7 @@ #include <linux/devfs_fs_kernel.h> #include <linux/miscdevice.h> #include <linux/wait.h> +#include <linux/mutex.h> #define DRIVER_DESC "Raw serio driver" @@ -46,7 +47,7 @@ struct serio_raw_list { struct list_head node; }; -static DECLARE_MUTEX(serio_raw_sem); +static DEFINE_MUTEX(serio_raw_mutex); static LIST_HEAD(serio_raw_list); static unsigned int serio_raw_no; @@ -81,7 +82,7 @@ static int serio_raw_open(struct inode *inode, struct file *file) struct serio_raw_list *list; int retval = 0; - retval = down_interruptible(&serio_raw_sem); + retval = mutex_lock_interruptible(&serio_raw_mutex); if (retval) return retval; @@ -95,12 +96,11 @@ static int serio_raw_open(struct inode *inode, struct file *file) goto out; } - if (!(list = kmalloc(sizeof(struct serio_raw_list), GFP_KERNEL))) { + if (!(list = kzalloc(sizeof(struct serio_raw_list), GFP_KERNEL))) { retval = -ENOMEM; goto out; } - memset(list, 0, sizeof(struct serio_raw_list)); list->serio_raw = serio_raw; file->private_data = list; @@ -108,7 +108,7 @@ static int serio_raw_open(struct inode *inode, struct file *file) list_add_tail(&list->node, &serio_raw->list); out: - up(&serio_raw_sem); + mutex_unlock(&serio_raw_mutex); return retval; } @@ -130,12 +130,12 @@ static int serio_raw_release(struct inode *inode, struct file *file) struct serio_raw_list *list = file->private_data; struct serio_raw *serio_raw = list->serio_raw; - down(&serio_raw_sem); + mutex_lock(&serio_raw_mutex); serio_raw_fasync(-1, file, 0); serio_raw_cleanup(serio_raw); - up(&serio_raw_sem); + mutex_unlock(&serio_raw_mutex); return 0; } @@ -194,7 +194,7 @@ static ssize_t serio_raw_write(struct file *file, const char __user *buffer, siz int retval; unsigned char c; - retval = down_interruptible(&serio_raw_sem); + retval = mutex_lock_interruptible(&serio_raw_mutex); if (retval) return retval; @@ -219,7 +219,7 @@ static ssize_t serio_raw_write(struct file *file, const char __user *buffer, siz }; out: - up(&serio_raw_sem); + mutex_unlock(&serio_raw_mutex); return written; } @@ -275,14 +275,13 @@ static int serio_raw_connect(struct serio *serio, struct serio_driver *drv) struct serio_raw *serio_raw; int err; - if (!(serio_raw = kmalloc(sizeof(struct serio_raw), GFP_KERNEL))) { + if (!(serio_raw = kzalloc(sizeof(struct serio_raw), GFP_KERNEL))) { printk(KERN_ERR "serio_raw.c: can't allocate memory for a device\n"); return -ENOMEM; } - down(&serio_raw_sem); + mutex_lock(&serio_raw_mutex); - memset(serio_raw, 0, sizeof(struct serio_raw)); snprintf(serio_raw->name, sizeof(serio_raw->name), "serio_raw%d", serio_raw_no++); serio_raw->refcnt = 1; serio_raw->serio = serio; @@ -325,7 +324,7 @@ out_free: serio_set_drvdata(serio, NULL); kfree(serio_raw); out: - up(&serio_raw_sem); + mutex_unlock(&serio_raw_mutex); return err; } @@ -350,7 +349,7 @@ static void serio_raw_disconnect(struct serio *serio) { struct serio_raw *serio_raw; - down(&serio_raw_sem); + mutex_lock(&serio_raw_mutex); serio_raw = serio_get_drvdata(serio); @@ -361,7 +360,7 @@ static void serio_raw_disconnect(struct serio *serio) if (!serio_raw_cleanup(serio_raw)) wake_up_interruptible(&serio_raw->wait); - up(&serio_raw_sem); + mutex_unlock(&serio_raw_mutex); } static struct serio_device_id serio_raw_serio_ids[] = { diff --git a/drivers/input/tsdev.c b/drivers/input/tsdev.c index ca1547929d6..d678d144bbf 100644 --- a/drivers/input/tsdev.c +++ b/drivers/input/tsdev.c @@ -157,9 +157,8 @@ static int tsdev_open(struct inode *inode, struct file *file) if (i >= TSDEV_MINORS || !tsdev_table[i & TSDEV_MINOR_MASK]) return -ENODEV; - if (!(list = kmalloc(sizeof(struct tsdev_list), GFP_KERNEL))) + if (!(list = kzalloc(sizeof(struct tsdev_list), GFP_KERNEL))) return -ENOMEM; - memset(list, 0, sizeof(struct tsdev_list)); list->raw = (i >= TSDEV_MINORS/2) ? 1 : 0; @@ -379,9 +378,8 @@ static struct input_handle *tsdev_connect(struct input_handler *handler, return NULL; } - if (!(tsdev = kmalloc(sizeof(struct tsdev), GFP_KERNEL))) + if (!(tsdev = kzalloc(sizeof(struct tsdev), GFP_KERNEL))) return NULL; - memset(tsdev, 0, sizeof(struct tsdev)); INIT_LIST_HEAD(&tsdev->list); init_waitqueue_head(&tsdev->wait); diff --git a/drivers/isdn/hardware/avm/avm_cs.c b/drivers/isdn/hardware/avm/avm_cs.c index 2a2b03ff096..7bbfd85ab79 100644 --- a/drivers/isdn/hardware/avm/avm_cs.c +++ b/drivers/isdn/hardware/avm/avm_cs.c @@ -51,8 +51,8 @@ MODULE_LICENSE("GPL"); handler. */ -static void avmcs_config(dev_link_t *link); -static void avmcs_release(dev_link_t *link); +static int avmcs_config(struct pcmcia_device *link); +static void avmcs_release(struct pcmcia_device *link); /* The attach() and detach() entry points are used to create and destroy @@ -65,10 +65,10 @@ static void avmcs_detach(struct pcmcia_device *p_dev); /* A linked list of "instances" of the skeleton device. Each actual PCMCIA card corresponds to one device instance, and is described - by one dev_link_t structure (defined in ds.h). + by one struct pcmcia_device structure (defined in ds.h). You may not want to use a linked list for this -- for example, the - memory card driver uses an array of dev_link_t pointers, where minor + memory card driver uses an array of struct pcmcia_device pointers, where minor device numbers are used to derive the corresponding array index. */ @@ -78,7 +78,7 @@ static void avmcs_detach(struct pcmcia_device *p_dev); example, ethernet cards, modems). In other cases, there may be many actual or logical devices (SCSI adapters, memory cards with multiple partitions). The dev_node_t structures need to be kept - in a linked list starting at the 'dev' field of a dev_link_t + in a linked list starting at the 'dev' field of a struct pcmcia_device structure. We allocate them in the card's private data structure, because they generally can't be allocated dynamically. */ @@ -99,54 +99,38 @@ typedef struct local_info_t { ======================================================================*/ -static int avmcs_attach(struct pcmcia_device *p_dev) +static int avmcs_probe(struct pcmcia_device *p_dev) { - dev_link_t *link; local_info_t *local; - /* Initialize the dev_link_t structure */ - link = kmalloc(sizeof(struct dev_link_t), GFP_KERNEL); - if (!link) - goto err; - memset(link, 0, sizeof(struct dev_link_t)); - /* The io structure describes IO port mapping */ - link->io.NumPorts1 = 16; - link->io.Attributes1 = IO_DATA_PATH_WIDTH_8; - link->io.NumPorts2 = 0; + p_dev->io.NumPorts1 = 16; + p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_8; + p_dev->io.NumPorts2 = 0; /* Interrupt setup */ - link->irq.Attributes = IRQ_TYPE_EXCLUSIVE; - link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING|IRQ_FIRST_SHARED; + p_dev->irq.Attributes = IRQ_TYPE_EXCLUSIVE; + p_dev->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING|IRQ_FIRST_SHARED; + + p_dev->irq.IRQInfo1 = IRQ_LEVEL_ID; - link->irq.IRQInfo1 = IRQ_LEVEL_ID; - /* General socket configuration */ - link->conf.Attributes = CONF_ENABLE_IRQ; - link->conf.Vcc = 50; - link->conf.IntType = INT_MEMORY_AND_IO; - link->conf.ConfigIndex = 1; - link->conf.Present = PRESENT_OPTION; + p_dev->conf.Attributes = CONF_ENABLE_IRQ; + p_dev->conf.IntType = INT_MEMORY_AND_IO; + p_dev->conf.ConfigIndex = 1; + p_dev->conf.Present = PRESENT_OPTION; /* Allocate space for private device-specific data */ local = kmalloc(sizeof(local_info_t), GFP_KERNEL); if (!local) - goto err_kfree; + goto err; memset(local, 0, sizeof(local_info_t)); - link->priv = local; + p_dev->priv = local; - link->handle = p_dev; - p_dev->instance = link; + return avmcs_config(p_dev); - link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; - avmcs_config(link); - - return 0; - - err_kfree: - kfree(link); err: - return -EINVAL; + return -ENOMEM; } /* avmcs_attach */ /*====================================================================== @@ -158,15 +142,10 @@ static int avmcs_attach(struct pcmcia_device *p_dev) ======================================================================*/ -static void avmcs_detach(struct pcmcia_device *p_dev) +static void avmcs_detach(struct pcmcia_device *link) { - dev_link_t *link = dev_to_instance(p_dev); - - if (link->state & DEV_CONFIG) avmcs_release(link); - - kfree(link->priv); - kfree(link); + kfree(link->priv); } /* avmcs_detach */ /*====================================================================== @@ -177,7 +156,7 @@ static void avmcs_detach(struct pcmcia_device *p_dev) ======================================================================*/ -static int get_tuple(client_handle_t handle, tuple_t *tuple, +static int get_tuple(struct pcmcia_device *handle, tuple_t *tuple, cisparse_t *parse) { int i = pcmcia_get_tuple_data(handle, tuple); @@ -185,7 +164,7 @@ static int get_tuple(client_handle_t handle, tuple_t *tuple, return pcmcia_parse_tuple(handle, tuple, parse); } -static int first_tuple(client_handle_t handle, tuple_t *tuple, +static int first_tuple(struct pcmcia_device *handle, tuple_t *tuple, cisparse_t *parse) { int i = pcmcia_get_first_tuple(handle, tuple); @@ -193,7 +172,7 @@ static int first_tuple(client_handle_t handle, tuple_t *tuple, return get_tuple(handle, tuple, parse); } -static int next_tuple(client_handle_t handle, tuple_t *tuple, +static int next_tuple(struct pcmcia_device *handle, tuple_t *tuple, cisparse_t *parse) { int i = pcmcia_get_next_tuple(handle, tuple); @@ -201,9 +180,8 @@ static int next_tuple(client_handle_t handle, tuple_t *tuple, return get_tuple(handle, tuple, parse); } -static void avmcs_config(dev_link_t *link) +static int avmcs_config(struct pcmcia_device *link) { - client_handle_t handle; tuple_t tuple; cisparse_t parse; cistpl_cftable_entry_t *cf = &parse.cftable_entry; @@ -213,8 +191,7 @@ static void avmcs_config(dev_link_t *link) char devname[128]; int cardtype; int (*addcard)(unsigned int port, unsigned irq); - - handle = link->handle; + dev = link->priv; /* @@ -223,25 +200,21 @@ static void avmcs_config(dev_link_t *link) */ do { tuple.DesiredTuple = CISTPL_CONFIG; - i = pcmcia_get_first_tuple(handle, &tuple); + i = pcmcia_get_first_tuple(link, &tuple); if (i != CS_SUCCESS) break; tuple.TupleData = buf; tuple.TupleDataMax = 64; tuple.TupleOffset = 0; - i = pcmcia_get_tuple_data(handle, &tuple); + i = pcmcia_get_tuple_data(link, &tuple); if (i != CS_SUCCESS) break; - i = pcmcia_parse_tuple(handle, &tuple, &parse); + i = pcmcia_parse_tuple(link, &tuple, &parse); if (i != CS_SUCCESS) break; link->conf.ConfigBase = parse.config.base; } while (0); if (i != CS_SUCCESS) { - cs_error(link->handle, ParseTuple, i); - link->state &= ~DEV_CONFIG_PENDING; - return; + cs_error(link, ParseTuple, i); + return -ENODEV; } - - /* Configure card */ - link->state |= DEV_CONFIG; do { @@ -252,7 +225,7 @@ static void avmcs_config(dev_link_t *link) tuple.DesiredTuple = CISTPL_VERS_1; devname[0] = 0; - if( !first_tuple(handle, &tuple, &parse) && parse.version_1.ns > 1 ) { + if( !first_tuple(link, &tuple, &parse) && parse.version_1.ns > 1 ) { strlcpy(devname,parse.version_1.str + parse.version_1.ofs[1], sizeof(devname)); } @@ -263,7 +236,7 @@ static void avmcs_config(dev_link_t *link) tuple.TupleOffset = 0; tuple.TupleDataMax = 255; tuple.Attributes = 0; tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; - i = first_tuple(handle, &tuple, &parse); + i = first_tuple(link, &tuple, &parse); while (i == CS_SUCCESS) { if (cf->io.nwin > 0) { link->conf.ConfigIndex = cf->index; @@ -273,36 +246,36 @@ static void avmcs_config(dev_link_t *link) printk(KERN_INFO "avm_cs: testing i/o %#x-%#x\n", link->io.BasePort1, link->io.BasePort1+link->io.NumPorts1-1); - i = pcmcia_request_io(link->handle, &link->io); + i = pcmcia_request_io(link, &link->io); if (i == CS_SUCCESS) goto found_port; } - i = next_tuple(handle, &tuple, &parse); + i = next_tuple(link, &tuple, &parse); } found_port: if (i != CS_SUCCESS) { - cs_error(link->handle, RequestIO, i); + cs_error(link, RequestIO, i); break; } - + /* * allocate an interrupt line */ - i = pcmcia_request_irq(link->handle, &link->irq); + i = pcmcia_request_irq(link, &link->irq); if (i != CS_SUCCESS) { - cs_error(link->handle, RequestIRQ, i); - pcmcia_release_io(link->handle, &link->io); + cs_error(link, RequestIRQ, i); + /* undo */ + pcmcia_disable_device(link); break; } - + /* * configure the PCMCIA socket */ - i = pcmcia_request_configuration(link->handle, &link->conf); + i = pcmcia_request_configuration(link, &link->conf); if (i != CS_SUCCESS) { - cs_error(link->handle, RequestConfiguration, i); - pcmcia_release_io(link->handle, &link->io); - pcmcia_release_irq(link->handle, &link->irq); + cs_error(link, RequestConfiguration, i); + pcmcia_disable_device(link); break; } @@ -331,13 +304,12 @@ found_port: dev->node.major = 64; dev->node.minor = 0; - link->dev = &dev->node; - - link->state &= ~DEV_CONFIG_PENDING; + link->dev_node = &dev->node; + /* If any step failed, release any partially configured state */ if (i != 0) { avmcs_release(link); - return; + return -ENODEV; } @@ -351,9 +323,10 @@ found_port: printk(KERN_ERR "avm_cs: failed to add AVM-%s-Controller at i/o %#x, irq %d\n", dev->node.dev_name, link->io.BasePort1, link->irq.AssignedIRQ); avmcs_release(link); - return; + return -ENODEV; } dev->node.minor = i; + return 0; } /* avmcs_config */ @@ -365,56 +338,12 @@ found_port: ======================================================================*/ -static void avmcs_release(dev_link_t *link) +static void avmcs_release(struct pcmcia_device *link) { - b1pcmcia_delcard(link->io.BasePort1, link->irq.AssignedIRQ); - - /* Unlink the device chain */ - link->dev = NULL; - - /* Don't bother checking to see if these succeed or not */ - pcmcia_release_configuration(link->handle); - pcmcia_release_io(link->handle, &link->io); - pcmcia_release_irq(link->handle, &link->irq); - link->state &= ~DEV_CONFIG; + b1pcmcia_delcard(link->io.BasePort1, link->irq.AssignedIRQ); + pcmcia_disable_device(link); } /* avmcs_release */ -static int avmcs_suspend(struct pcmcia_device *dev) -{ - dev_link_t *link = dev_to_instance(dev); - - link->state |= DEV_SUSPEND; - if (link->state & DEV_CONFIG) - pcmcia_release_configuration(link->handle); - - return 0; -} - -static int avmcs_resume(struct pcmcia_device *dev) -{ - dev_link_t *link = dev_to_instance(dev); - - link->state &= ~DEV_SUSPEND; - if (link->state & DEV_CONFIG) - pcmcia_request_configuration(link->handle, &link->conf); - - return 0; -} - -/*====================================================================== - - The card status event handler. Mostly, this schedules other - stuff to run after an event is received. A CARD_REMOVAL event - also sets some flags to discourage the net drivers from trying - to talk to the card any more. - - When a CARD_REMOVAL event is received, we immediately set a flag - to block future accesses to this device. All the functions that - actually access the device should check this flag to make sure - the card is still present. - -======================================================================*/ - static struct pcmcia_device_id avmcs_ids[] = { PCMCIA_DEVICE_PROD_ID12("AVM", "ISDN-Controller B1", 0x95d42008, 0x845dc335), @@ -429,11 +358,9 @@ static struct pcmcia_driver avmcs_driver = { .drv = { .name = "avm_cs", }, - .probe = avmcs_attach, + .probe = avmcs_probe, .remove = avmcs_detach, .id_table = avmcs_ids, - .suspend= avmcs_suspend, - .resume = avmcs_resume, }; static int __init avmcs_init(void) diff --git a/drivers/isdn/hisax/avma1_cs.c b/drivers/isdn/hisax/avma1_cs.c index 969da40c424..ac28e3278ad 100644 --- a/drivers/isdn/hisax/avma1_cs.c +++ b/drivers/isdn/hisax/avma1_cs.c @@ -67,8 +67,8 @@ module_param(isdnprot, int, 0); handler. */ -static void avma1cs_config(dev_link_t *link); -static void avma1cs_release(dev_link_t *link); +static int avma1cs_config(struct pcmcia_device *link); +static void avma1cs_release(struct pcmcia_device *link); /* The attach() and detach() entry points are used to create and destroy @@ -82,10 +82,10 @@ static void avma1cs_detach(struct pcmcia_device *p_dev); /* A linked list of "instances" of the skeleton device. Each actual PCMCIA card corresponds to one device instance, and is described - by one dev_link_t structure (defined in ds.h). + by one struct pcmcia_device structure (defined in ds.h). You may not want to use a linked list for this -- for example, the - memory card driver uses an array of dev_link_t pointers, where minor + memory card driver uses an array of struct pcmcia_device pointers, where minor device numbers are used to derive the corresponding array index. */ @@ -95,7 +95,7 @@ static void avma1cs_detach(struct pcmcia_device *p_dev); example, ethernet cards, modems). In other cases, there may be many actual or logical devices (SCSI adapters, memory cards with multiple partitions). The dev_node_t structures need to be kept - in a linked list starting at the 'dev' field of a dev_link_t + in a linked list starting at the 'dev' field of a struct pcmcia_device structure. We allocate them in the card's private data structure, because they generally can't be allocated dynamically. */ @@ -116,55 +116,40 @@ typedef struct local_info_t { ======================================================================*/ -static int avma1cs_attach(struct pcmcia_device *p_dev) +static int avma1cs_probe(struct pcmcia_device *p_dev) { - dev_link_t *link; local_info_t *local; DEBUG(0, "avma1cs_attach()\n"); - /* Initialize the dev_link_t structure */ - link = kmalloc(sizeof(struct dev_link_t), GFP_KERNEL); - if (!link) - return -ENOMEM; - memset(link, 0, sizeof(struct dev_link_t)); - /* Allocate space for private device-specific data */ local = kmalloc(sizeof(local_info_t), GFP_KERNEL); - if (!local) { - kfree(link); + if (!local) return -ENOMEM; - } + memset(local, 0, sizeof(local_info_t)); - link->priv = local; + p_dev->priv = local; /* The io structure describes IO port mapping */ - link->io.NumPorts1 = 16; - link->io.Attributes1 = IO_DATA_PATH_WIDTH_8; - link->io.NumPorts2 = 16; - link->io.Attributes2 = IO_DATA_PATH_WIDTH_16; - link->io.IOAddrLines = 5; + p_dev->io.NumPorts1 = 16; + p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_8; + p_dev->io.NumPorts2 = 16; + p_dev->io.Attributes2 = IO_DATA_PATH_WIDTH_16; + p_dev->io.IOAddrLines = 5; /* Interrupt setup */ - link->irq.Attributes = IRQ_TYPE_EXCLUSIVE; - link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING|IRQ_FIRST_SHARED; + p_dev->irq.Attributes = IRQ_TYPE_EXCLUSIVE; + p_dev->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING|IRQ_FIRST_SHARED; - link->irq.IRQInfo1 = IRQ_LEVEL_ID; + p_dev->irq.IRQInfo1 = IRQ_LEVEL_ID; /* General socket configuration */ - link->conf.Attributes = CONF_ENABLE_IRQ; - link->conf.Vcc = 50; - link->conf.IntType = INT_MEMORY_AND_IO; - link->conf.ConfigIndex = 1; - link->conf.Present = PRESENT_OPTION; + p_dev->conf.Attributes = CONF_ENABLE_IRQ; + p_dev->conf.IntType = INT_MEMORY_AND_IO; + p_dev->conf.ConfigIndex = 1; + p_dev->conf.Present = PRESENT_OPTION; - link->handle = p_dev; - p_dev->instance = link; - - link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; - avma1cs_config(link); - - return 0; + return avma1cs_config(p_dev); } /* avma1cs_attach */ /*====================================================================== @@ -176,17 +161,11 @@ static int avma1cs_attach(struct pcmcia_device *p_dev) ======================================================================*/ -static void avma1cs_detach(struct pcmcia_device *p_dev) +static void avma1cs_detach(struct pcmcia_device *link) { - dev_link_t *link = dev_to_instance(p_dev); - - DEBUG(0, "avma1cs_detach(0x%p)\n", link); - - if (link->state & DEV_CONFIG) - avma1cs_release(link); - - kfree(link->priv); - kfree(link); + DEBUG(0, "avma1cs_detach(0x%p)\n", link); + avma1cs_release(link); + kfree(link->priv); } /* avma1cs_detach */ /*====================================================================== @@ -197,7 +176,7 @@ static void avma1cs_detach(struct pcmcia_device *p_dev) ======================================================================*/ -static int get_tuple(client_handle_t handle, tuple_t *tuple, +static int get_tuple(struct pcmcia_device *handle, tuple_t *tuple, cisparse_t *parse) { int i = pcmcia_get_tuple_data(handle, tuple); @@ -205,7 +184,7 @@ static int get_tuple(client_handle_t handle, tuple_t *tuple, return pcmcia_parse_tuple(handle, tuple, parse); } -static int first_tuple(client_handle_t handle, tuple_t *tuple, +static int first_tuple(struct pcmcia_device *handle, tuple_t *tuple, cisparse_t *parse) { int i = pcmcia_get_first_tuple(handle, tuple); @@ -213,7 +192,7 @@ static int first_tuple(client_handle_t handle, tuple_t *tuple, return get_tuple(handle, tuple, parse); } -static int next_tuple(client_handle_t handle, tuple_t *tuple, +static int next_tuple(struct pcmcia_device *handle, tuple_t *tuple, cisparse_t *parse) { int i = pcmcia_get_next_tuple(handle, tuple); @@ -221,9 +200,8 @@ static int next_tuple(client_handle_t handle, tuple_t *tuple, return get_tuple(handle, tuple, parse); } -static void avma1cs_config(dev_link_t *link) +static int avma1cs_config(struct pcmcia_device *link) { - client_handle_t handle; tuple_t tuple; cisparse_t parse; cistpl_cftable_entry_t *cf = &parse.cftable_entry; @@ -233,8 +211,7 @@ static void avma1cs_config(dev_link_t *link) char devname[128]; IsdnCard_t icard; int busy = 0; - - handle = link->handle; + dev = link->priv; DEBUG(0, "avma1cs_config(0x%p)\n", link); @@ -245,25 +222,21 @@ static void avma1cs_config(dev_link_t *link) */ do { tuple.DesiredTuple = CISTPL_CONFIG; - i = pcmcia_get_first_tuple(handle, &tuple); + i = pcmcia_get_first_tuple(link, &tuple); if (i != CS_SUCCESS) break; tuple.TupleData = buf; tuple.TupleDataMax = 64; tuple.TupleOffset = 0; - i = pcmcia_get_tuple_data(handle, &tuple); + i = pcmcia_get_tuple_data(link, &tuple); if (i != CS_SUCCESS) break; - i = pcmcia_parse_tuple(handle, &tuple, &parse); + i = pcmcia_parse_tuple(link, &tuple, &parse); if (i != CS_SUCCESS) break; link->conf.ConfigBase = parse.config.base; } while (0); if (i != CS_SUCCESS) { - cs_error(link->handle, ParseTuple, i); - link->state &= ~DEV_CONFIG_PENDING; - return; + cs_error(link, ParseTuple, i); + return -ENODEV; } - - /* Configure card */ - link->state |= DEV_CONFIG; do { @@ -274,7 +247,7 @@ static void avma1cs_config(dev_link_t *link) tuple.DesiredTuple = CISTPL_VERS_1; devname[0] = 0; - if( !first_tuple(handle, &tuple, &parse) && parse.version_1.ns > 1 ) { + if( !first_tuple(link, &tuple, &parse) && parse.version_1.ns > 1 ) { strlcpy(devname,parse.version_1.str + parse.version_1.ofs[1], sizeof(devname)); } @@ -285,7 +258,7 @@ static void avma1cs_config(dev_link_t *link) tuple.TupleOffset = 0; tuple.TupleDataMax = 255; tuple.Attributes = 0; tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; - i = first_tuple(handle, &tuple, &parse); + i = first_tuple(link, &tuple, &parse); while (i == CS_SUCCESS) { if (cf->io.nwin > 0) { link->conf.ConfigIndex = cf->index; @@ -295,36 +268,36 @@ static void avma1cs_config(dev_link_t *link) printk(KERN_INFO "avma1_cs: testing i/o %#x-%#x\n", link->io.BasePort1, link->io.BasePort1+link->io.NumPorts1 - 1); - i = pcmcia_request_io(link->handle, &link->io); + i = pcmcia_request_io(link, &link->io); if (i == CS_SUCCESS) goto found_port; } - i = next_tuple(handle, &tuple, &parse); + i = next_tuple(link, &tuple, &parse); } found_port: if (i != CS_SUCCESS) { - cs_error(link->handle, RequestIO, i); + cs_error(link, RequestIO, i); break; } /* * allocate an interrupt line */ - i = pcmcia_request_irq(link->handle, &link->irq); + i = pcmcia_request_irq(link, &link->irq); if (i != CS_SUCCESS) { - cs_error(link->handle, RequestIRQ, i); - pcmcia_release_io(link->handle, &link->io); + cs_error(link, RequestIRQ, i); + /* undo */ + pcmcia_disable_device(link); break; } - + /* * configure the PCMCIA socket */ - i = pcmcia_request_configuration(link->handle, &link->conf); + i = pcmcia_request_configuration(link, &link->conf); if (i != CS_SUCCESS) { - cs_error(link->handle, RequestConfiguration, i); - pcmcia_release_io(link->handle, &link->io); - pcmcia_release_irq(link->handle, &link->irq); + cs_error(link, RequestConfiguration, i); + pcmcia_disable_device(link); break; } @@ -336,13 +309,12 @@ found_port: strcpy(dev->node.dev_name, "A1"); dev->node.major = 45; dev->node.minor = 0; - link->dev = &dev->node; - - link->state &= ~DEV_CONFIG_PENDING; + link->dev_node = &dev->node; + /* If any step failed, release any partially configured state */ if (i != 0) { avma1cs_release(link); - return; + return -ENODEV; } printk(KERN_NOTICE "avma1_cs: checking at i/o %#x, irq %d\n", @@ -357,10 +329,11 @@ found_port: if (i < 0) { printk(KERN_ERR "avma1_cs: failed to initialize AVM A1 PCMCIA %d at i/o %#x\n", i, link->io.BasePort1); avma1cs_release(link); - return; + return -ENODEV; } dev->node.minor = i; + return 0; } /* avma1cs_config */ /*====================================================================== @@ -371,47 +344,18 @@ found_port: ======================================================================*/ -static void avma1cs_release(dev_link_t *link) +static void avma1cs_release(struct pcmcia_device *link) { - local_info_t *local = link->priv; + local_info_t *local = link->priv; - DEBUG(0, "avma1cs_release(0x%p)\n", link); + DEBUG(0, "avma1cs_release(0x%p)\n", link); - /* no unregister function with hisax */ - HiSax_closecard(local->node.minor); + /* now unregister function with hisax */ + HiSax_closecard(local->node.minor); - /* Unlink the device chain */ - link->dev = NULL; - - /* Don't bother checking to see if these succeed or not */ - pcmcia_release_configuration(link->handle); - pcmcia_release_io(link->handle, &link->io); - pcmcia_release_irq(link->handle, &link->irq); - link->state &= ~DEV_CONFIG; + pcmcia_disable_device(link); } /* avma1cs_release */ -static int avma1cs_suspend(struct pcmcia_device *dev) -{ - dev_link_t *link = dev_to_instance(dev); - - link->state |= DEV_SUSPEND; - if (link->state & DEV_CONFIG) - pcmcia_release_configuration(link->handle); - - return 0; -} - -static int avma1cs_resume(struct pcmcia_device *dev) -{ - dev_link_t *link = dev_to_instance(dev); - - link->state &= ~DEV_SUSPEND; - if (link->state & DEV_CONFIG) - pcmcia_request_configuration(link->handle, &link->conf); - - return 0; -} - static struct pcmcia_device_id avma1cs_ids[] = { PCMCIA_DEVICE_PROD_ID12("AVM", "ISDN A", 0x95d42008, 0xadc9d4bb), @@ -425,13 +369,11 @@ static struct pcmcia_driver avma1cs_driver = { .drv = { .name = "avma1_cs", }, - .probe = avma1cs_attach, + .probe = avma1cs_probe, .remove = avma1cs_detach, .id_table = avma1cs_ids, - .suspend = avma1cs_suspend, - .resume = avma1cs_resume, }; - + /*====================================================================*/ static int __init init_avma1_cs(void) diff --git a/drivers/isdn/hisax/elsa_cs.c b/drivers/isdn/hisax/elsa_cs.c index 062fb8f0739..e18e75be8ed 100644 --- a/drivers/isdn/hisax/elsa_cs.c +++ b/drivers/isdn/hisax/elsa_cs.c @@ -94,8 +94,8 @@ module_param(protocol, int, 0); handler. */ -static void elsa_cs_config(dev_link_t *link); -static void elsa_cs_release(dev_link_t *link); +static int elsa_cs_config(struct pcmcia_device *link); +static void elsa_cs_release(struct pcmcia_device *link); /* The attach() and detach() entry points are used to create and destroy @@ -111,7 +111,7 @@ static void elsa_cs_detach(struct pcmcia_device *p_dev); example, ethernet cards, modems). In other cases, there may be many actual or logical devices (SCSI adapters, memory cards with multiple partitions). The dev_node_t structures need to be kept - in a linked list starting at the 'dev' field of a dev_link_t + in a linked list starting at the 'dev' field of a struct pcmcia_device structure. We allocate them in the card's private data structure, because they generally shouldn't be allocated dynamically. In this case, we also provide a flag to indicate if a device is @@ -121,7 +121,7 @@ static void elsa_cs_detach(struct pcmcia_device *p_dev); */ typedef struct local_info_t { - dev_link_t link; + struct pcmcia_device *p_dev; dev_node_t node; int busy; int cardnr; @@ -139,9 +139,8 @@ typedef struct local_info_t { ======================================================================*/ -static int elsa_cs_attach(struct pcmcia_device *p_dev) +static int elsa_cs_probe(struct pcmcia_device *link) { - dev_link_t *link; local_info_t *local; DEBUG(0, "elsa_cs_attach()\n"); @@ -150,8 +149,11 @@ static int elsa_cs_attach(struct pcmcia_device *p_dev) local = kmalloc(sizeof(local_info_t), GFP_KERNEL); if (!local) return -ENOMEM; memset(local, 0, sizeof(local_info_t)); + + local->p_dev = link; + link->priv = local; + local->cardnr = -1; - link = &local->link; link->priv = local; /* Interrupt setup */ link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING|IRQ_FIRST_SHARED; @@ -170,16 +172,9 @@ static int elsa_cs_attach(struct pcmcia_device *p_dev) link->io.IOAddrLines = 3; link->conf.Attributes = CONF_ENABLE_IRQ; - link->conf.Vcc = 50; link->conf.IntType = INT_MEMORY_AND_IO; - link->handle = p_dev; - p_dev->instance = link; - - link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; - elsa_cs_config(link); - - return 0; + return elsa_cs_config(link); } /* elsa_cs_attach */ /*====================================================================== @@ -191,20 +186,16 @@ static int elsa_cs_attach(struct pcmcia_device *p_dev) ======================================================================*/ -static void elsa_cs_detach(struct pcmcia_device *p_dev) +static void elsa_cs_detach(struct pcmcia_device *link) { - dev_link_t *link = dev_to_instance(p_dev); - local_info_t *info = link->priv; + local_info_t *info = link->priv; - DEBUG(0, "elsa_cs_detach(0x%p)\n", link); + DEBUG(0, "elsa_cs_detach(0x%p)\n", link); - if (link->state & DEV_CONFIG) { - info->busy = 1; - elsa_cs_release(link); - } - - kfree(info); + info->busy = 1; + elsa_cs_release(link); + kfree(info); } /* elsa_cs_detach */ /*====================================================================== @@ -214,7 +205,7 @@ static void elsa_cs_detach(struct pcmcia_device *p_dev) device available to the system. ======================================================================*/ -static int get_tuple(client_handle_t handle, tuple_t *tuple, +static int get_tuple(struct pcmcia_device *handle, tuple_t *tuple, cisparse_t *parse) { int i = pcmcia_get_tuple_data(handle, tuple); @@ -222,7 +213,7 @@ static int get_tuple(client_handle_t handle, tuple_t *tuple, return pcmcia_parse_tuple(handle, tuple, parse); } -static int first_tuple(client_handle_t handle, tuple_t *tuple, +static int first_tuple(struct pcmcia_device *handle, tuple_t *tuple, cisparse_t *parse) { int i = pcmcia_get_first_tuple(handle, tuple); @@ -230,7 +221,7 @@ static int first_tuple(client_handle_t handle, tuple_t *tuple, return get_tuple(handle, tuple, parse); } -static int next_tuple(client_handle_t handle, tuple_t *tuple, +static int next_tuple(struct pcmcia_device *handle, tuple_t *tuple, cisparse_t *parse) { int i = pcmcia_get_next_tuple(handle, tuple); @@ -238,9 +229,8 @@ static int next_tuple(client_handle_t handle, tuple_t *tuple, return get_tuple(handle, tuple, parse); } -static void elsa_cs_config(dev_link_t *link) +static int elsa_cs_config(struct pcmcia_device *link) { - client_handle_t handle; tuple_t tuple; cisparse_t parse; local_info_t *dev; @@ -250,7 +240,6 @@ static void elsa_cs_config(dev_link_t *link) IsdnCard_t icard; DEBUG(0, "elsa_config(0x%p)\n", link); - handle = link->handle; dev = link->priv; /* @@ -262,7 +251,7 @@ static void elsa_cs_config(dev_link_t *link) tuple.TupleDataMax = 255; tuple.TupleOffset = 0; tuple.Attributes = 0; - i = first_tuple(handle, &tuple, &parse); + i = first_tuple(link, &tuple, &parse); if (i != CS_SUCCESS) { last_fn = ParseTuple; goto cs_failed; @@ -270,32 +259,29 @@ static void elsa_cs_config(dev_link_t *link) link->conf.ConfigBase = parse.config.base; link->conf.Present = parse.config.rmask[0]; - /* Configure card */ - link->state |= DEV_CONFIG; - tuple.TupleData = (cisdata_t *)buf; tuple.TupleOffset = 0; tuple.TupleDataMax = 255; tuple.Attributes = 0; tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; - i = first_tuple(handle, &tuple, &parse); + i = first_tuple(link, &tuple, &parse); while (i == CS_SUCCESS) { if ( (cf->io.nwin > 0) && cf->io.win[0].base) { printk(KERN_INFO "(elsa_cs: looks like the 96 model)\n"); link->conf.ConfigIndex = cf->index; link->io.BasePort1 = cf->io.win[0].base; - i = pcmcia_request_io(link->handle, &link->io); + i = pcmcia_request_io(link, &link->io); if (i == CS_SUCCESS) break; } else { printk(KERN_INFO "(elsa_cs: looks like the 97 model)\n"); link->conf.ConfigIndex = cf->index; for (i = 0, j = 0x2f0; j > 0x100; j -= 0x10) { link->io.BasePort1 = j; - i = pcmcia_request_io(link->handle, &link->io); + i = pcmcia_request_io(link, &link->io); if (i == CS_SUCCESS) break; } break; } - i = next_tuple(handle, &tuple, &parse); + i = next_tuple(link, &tuple, &parse); } if (i != CS_SUCCESS) { @@ -303,14 +289,14 @@ static void elsa_cs_config(dev_link_t *link) goto cs_failed; } - i = pcmcia_request_irq(link->handle, &link->irq); + i = pcmcia_request_irq(link, &link->irq); if (i != CS_SUCCESS) { link->irq.AssignedIRQ = 0; last_fn = RequestIRQ; goto cs_failed; } - i = pcmcia_request_configuration(link->handle, &link->conf); + i = pcmcia_request_configuration(link, &link->conf); if (i != CS_SUCCESS) { last_fn = RequestConfiguration; goto cs_failed; @@ -321,14 +307,11 @@ static void elsa_cs_config(dev_link_t *link) sprintf(dev->node.dev_name, "elsa"); dev->node.major = dev->node.minor = 0x0; - link->dev = &dev->node; + link->dev_node = &dev->node; /* Finally, report what we've done */ - printk(KERN_INFO "%s: index 0x%02x: Vcc %d.%d", - dev->node.dev_name, link->conf.ConfigIndex, - link->conf.Vcc/10, link->conf.Vcc%10); - if (link->conf.Vpp1) - printk(", Vpp %d.%d", link->conf.Vpp1/10, link->conf.Vpp1%10); + printk(KERN_INFO "%s: index 0x%02x: ", + dev->node.dev_name, link->conf.ConfigIndex); if (link->conf.Attributes & CONF_ENABLE_IRQ) printk(", irq %d", link->irq.AssignedIRQ); if (link->io.NumPorts1) @@ -339,8 +322,6 @@ static void elsa_cs_config(dev_link_t *link) link->io.BasePort2+link->io.NumPorts2-1); printk("\n"); - link->state &= ~DEV_CONFIG_PENDING; - icard.para[0] = link->irq.AssignedIRQ; icard.para[1] = link->io.BasePort1; icard.protocol = protocol; @@ -354,10 +335,11 @@ static void elsa_cs_config(dev_link_t *link) } else ((local_info_t*)link->priv)->cardnr = i; - return; + return 0; cs_failed: - cs_error(link->handle, last_fn, i); + cs_error(link, last_fn, i); elsa_cs_release(link); + return -ENODEV; } /* elsa_cs_config */ /*====================================================================== @@ -368,7 +350,7 @@ cs_failed: ======================================================================*/ -static void elsa_cs_release(dev_link_t *link) +static void elsa_cs_release(struct pcmcia_device *link) { local_info_t *local = link->priv; @@ -380,39 +362,23 @@ static void elsa_cs_release(dev_link_t *link) HiSax_closecard(local->cardnr); } } - /* Unlink the device chain */ - link->dev = NULL; - - /* Don't bother checking to see if these succeed or not */ - if (link->win) - pcmcia_release_window(link->win); - pcmcia_release_configuration(link->handle); - pcmcia_release_io(link->handle, &link->io); - pcmcia_release_irq(link->handle, &link->irq); - link->state &= ~DEV_CONFIG; + + pcmcia_disable_device(link); } /* elsa_cs_release */ -static int elsa_suspend(struct pcmcia_device *p_dev) +static int elsa_suspend(struct pcmcia_device *link) { - dev_link_t *link = dev_to_instance(p_dev); local_info_t *dev = link->priv; - link->state |= DEV_SUSPEND; dev->busy = 1; - if (link->state & DEV_CONFIG) - pcmcia_release_configuration(link->handle); return 0; } -static int elsa_resume(struct pcmcia_device *p_dev) +static int elsa_resume(struct pcmcia_device *link) { - dev_link_t *link = dev_to_instance(p_dev); local_info_t *dev = link->priv; - link->state &= ~DEV_SUSPEND; - if (link->state & DEV_CONFIG) - pcmcia_request_configuration(link->handle, &link->conf); dev->busy = 0; return 0; @@ -430,7 +396,7 @@ static struct pcmcia_driver elsa_cs_driver = { .drv = { .name = "elsa_cs", }, - .probe = elsa_cs_attach, + .probe = elsa_cs_probe, .remove = elsa_cs_detach, .id_table = elsa_ids, .suspend = elsa_suspend, diff --git a/drivers/isdn/hisax/sedlbauer_cs.c b/drivers/isdn/hisax/sedlbauer_cs.c index 6f5213a18a8..9bb18f3f782 100644 --- a/drivers/isdn/hisax/sedlbauer_cs.c +++ b/drivers/isdn/hisax/sedlbauer_cs.c @@ -95,8 +95,8 @@ module_param(protocol, int, 0); event handler. */ -static void sedlbauer_config(dev_link_t *link); -static void sedlbauer_release(dev_link_t *link); +static int sedlbauer_config(struct pcmcia_device *link); +static void sedlbauer_release(struct pcmcia_device *link); /* The attach() and detach() entry points are used to create and destroy @@ -119,7 +119,7 @@ static void sedlbauer_detach(struct pcmcia_device *p_dev); example, ethernet cards, modems). In other cases, there may be many actual or logical devices (SCSI adapters, memory cards with multiple partitions). The dev_node_t structures need to be kept - in a linked list starting at the 'dev' field of a dev_link_t + in a linked list starting at the 'dev' field of a struct pcmcia_device structure. We allocate them in the card's private data structure, because they generally shouldn't be allocated dynamically. @@ -130,7 +130,7 @@ static void sedlbauer_detach(struct pcmcia_device *p_dev); */ typedef struct local_info_t { - dev_link_t link; + struct pcmcia_device *p_dev; dev_node_t node; int stop; int cardnr; @@ -148,11 +148,10 @@ typedef struct local_info_t { ======================================================================*/ -static int sedlbauer_attach(struct pcmcia_device *p_dev) +static int sedlbauer_probe(struct pcmcia_device *link) { local_info_t *local; - dev_link_t *link; - + DEBUG(0, "sedlbauer_attach()\n"); /* Allocate space for private device-specific data */ @@ -160,8 +159,10 @@ static int sedlbauer_attach(struct pcmcia_device *p_dev) if (!local) return -ENOMEM; memset(local, 0, sizeof(local_info_t)); local->cardnr = -1; - link = &local->link; link->priv = local; - + + local->p_dev = link; + link->priv = local; + /* Interrupt setup */ link->irq.Attributes = IRQ_TYPE_EXCLUSIVE; link->irq.IRQInfo1 = IRQ_LEVEL_ID; @@ -182,18 +183,10 @@ static int sedlbauer_attach(struct pcmcia_device *p_dev) link->io.Attributes1 = IO_DATA_PATH_WIDTH_8; link->io.IOAddrLines = 3; - link->conf.Attributes = 0; - link->conf.Vcc = 50; link->conf.IntType = INT_MEMORY_AND_IO; - link->handle = p_dev; - p_dev->instance = link; - - link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; - sedlbauer_config(link); - - return 0; + return sedlbauer_config(link); } /* sedlbauer_attach */ /*====================================================================== @@ -205,19 +198,15 @@ static int sedlbauer_attach(struct pcmcia_device *p_dev) ======================================================================*/ -static void sedlbauer_detach(struct pcmcia_device *p_dev) +static void sedlbauer_detach(struct pcmcia_device *link) { - dev_link_t *link = dev_to_instance(p_dev); - - DEBUG(0, "sedlbauer_detach(0x%p)\n", link); + DEBUG(0, "sedlbauer_detach(0x%p)\n", link); - if (link->state & DEV_CONFIG) { - ((local_info_t *)link->priv)->stop = 1; - sedlbauer_release(link); - } + ((local_info_t *)link->priv)->stop = 1; + sedlbauer_release(link); - /* This points to the parent local_info_t struct */ - kfree(link->priv); + /* This points to the parent local_info_t struct */ + kfree(link->priv); } /* sedlbauer_detach */ /*====================================================================== @@ -230,9 +219,8 @@ static void sedlbauer_detach(struct pcmcia_device *p_dev) #define CS_CHECK(fn, ret) \ do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0) -static void sedlbauer_config(dev_link_t *link) +static int sedlbauer_config(struct pcmcia_device *link) { - client_handle_t handle = link->handle; local_info_t *dev = link->priv; tuple_t tuple; cisparse_t parse; @@ -254,18 +242,13 @@ static void sedlbauer_config(dev_link_t *link) tuple.TupleData = buf; tuple.TupleDataMax = sizeof(buf); tuple.TupleOffset = 0; - CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple)); - CS_CHECK(GetTupleData, pcmcia_get_tuple_data(handle, &tuple)); - CS_CHECK(ParseTuple, pcmcia_parse_tuple(handle, &tuple, &parse)); + CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); + CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple)); + CS_CHECK(ParseTuple, pcmcia_parse_tuple(link, &tuple, &parse)); link->conf.ConfigBase = parse.config.base; link->conf.Present = parse.config.rmask[0]; - - /* Configure card */ - link->state |= DEV_CONFIG; - /* Look up the current Vcc */ - CS_CHECK(GetConfigurationInfo, pcmcia_get_configuration_info(handle, &conf)); - link->conf.Vcc = conf.Vcc; + CS_CHECK(GetConfigurationInfo, pcmcia_get_configuration_info(link, &conf)); /* In this loop, we scan the CIS for configuration table entries, @@ -280,12 +263,12 @@ static void sedlbauer_config(dev_link_t *link) will only use the CIS to fill in implementation-defined details. */ tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; - CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple)); + CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); while (1) { cistpl_cftable_entry_t dflt = { 0 }; cistpl_cftable_entry_t *cfg = &(parse.cftable_entry); - if (pcmcia_get_tuple_data(handle, &tuple) != 0 || - pcmcia_parse_tuple(handle, &tuple, &parse) != 0) + if (pcmcia_get_tuple_data(link, &tuple) != 0 || + pcmcia_parse_tuple(link, &tuple, &parse) != 0) goto next_entry; if (cfg->flags & CISTPL_CFTABLE_DEFAULT) dflt = *cfg; @@ -309,10 +292,10 @@ static void sedlbauer_config(dev_link_t *link) } if (cfg->vpp1.present & (1<<CISTPL_POWER_VNOM)) - link->conf.Vpp1 = link->conf.Vpp2 = + link->conf.Vpp = cfg->vpp1.param[CISTPL_POWER_VNOM]/10000; else if (dflt.vpp1.present & (1<<CISTPL_POWER_VNOM)) - link->conf.Vpp1 = link->conf.Vpp2 = + link->conf.Vpp = dflt.vpp1.param[CISTPL_POWER_VNOM]/10000; /* Do we need to allocate an interrupt? */ @@ -339,13 +322,13 @@ static void sedlbauer_config(dev_link_t *link) link->io.NumPorts2 = io->win[1].len; } /* This reserves IO space but doesn't actually enable it */ - if (pcmcia_request_io(link->handle, &link->io) != 0) + if (pcmcia_request_io(link, &link->io) != 0) goto next_entry; } /* Now set up a common memory window, if needed. There is room - in the dev_link_t structure for one memory window handle, + in the struct pcmcia_device structure for one memory window handle, but if the base addresses need to be saved, or if multiple windows are needed, the info should go in the private data structure for this device. @@ -366,7 +349,7 @@ static void sedlbauer_config(dev_link_t *link) req.Size = 0x1000; */ req.AccessSpeed = 0; - if (pcmcia_request_window(&link->handle, &req, &link->win) != 0) + if (pcmcia_request_window(&link, &req, &link->win) != 0) goto next_entry; map.Page = 0; map.CardOffset = mem->win[0].card_addr; if (pcmcia_map_mem_page(link->win, &map) != 0) @@ -374,29 +357,25 @@ static void sedlbauer_config(dev_link_t *link) } /* If we got this far, we're cool! */ break; - + next_entry: -/* new in dummy.cs 2001/01/28 MN - if (link->io.NumPorts1) - pcmcia_release_io(link->handle, &link->io); -*/ - CS_CHECK(GetNextTuple, pcmcia_get_next_tuple(handle, &tuple)); + CS_CHECK(GetNextTuple, pcmcia_get_next_tuple(link, &tuple)); } - + /* Allocate an interrupt line. Note that this does not assign a handler to the interrupt, unless the 'Handler' member of the irq structure is initialized. */ if (link->conf.Attributes & CONF_ENABLE_IRQ) - CS_CHECK(RequestIRQ, pcmcia_request_irq(link->handle, &link->irq)); + CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq)); /* This actually configures the PCMCIA socket -- setting up the I/O windows and the interrupt mapping, and putting the card and host interface into "Memory and IO" mode. */ - CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link->handle, &link->conf)); + CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf)); /* At this point, the dev_node_t structure(s) need to be @@ -404,14 +383,13 @@ static void sedlbauer_config(dev_link_t *link) */ sprintf(dev->node.dev_name, "sedlbauer"); dev->node.major = dev->node.minor = 0; - link->dev = &dev->node; + link->dev_node = &dev->node; /* Finally, report what we've done */ - printk(KERN_INFO "%s: index 0x%02x: Vcc %d.%d", - dev->node.dev_name, link->conf.ConfigIndex, - link->conf.Vcc/10, link->conf.Vcc%10); - if (link->conf.Vpp1) - printk(", Vpp %d.%d", link->conf.Vpp1/10, link->conf.Vpp1%10); + printk(KERN_INFO "%s: index 0x%02x:", + dev->node.dev_name, link->conf.ConfigIndex); + if (link->conf.Vpp) + printk(", Vpp %d.%d", link->conf.Vpp/10, link->conf.Vpp%10); if (link->conf.Attributes & CONF_ENABLE_IRQ) printk(", irq %d", link->irq.AssignedIRQ); if (link->io.NumPorts1) @@ -424,8 +402,6 @@ static void sedlbauer_config(dev_link_t *link) printk(", mem 0x%06lx-0x%06lx", req.Base, req.Base+req.Size-1); printk("\n"); - - link->state &= ~DEV_CONFIG_PENDING; icard.para[0] = link->irq.AssignedIRQ; icard.para[1] = link->io.BasePort1; @@ -437,14 +413,16 @@ static void sedlbauer_config(dev_link_t *link) printk(KERN_ERR "sedlbauer_cs: failed to initialize SEDLBAUER PCMCIA %d at i/o %#x\n", last_ret, link->io.BasePort1); sedlbauer_release(link); + return -ENODEV; } else ((local_info_t*)link->priv)->cardnr = last_ret; - return; + return 0; cs_failed: - cs_error(link->handle, last_fn, last_ret); + cs_error(link, last_fn, last_ret); sedlbauer_release(link); + return -ENODEV; } /* sedlbauer_config */ @@ -456,7 +434,7 @@ cs_failed: ======================================================================*/ -static void sedlbauer_release(dev_link_t *link) +static void sedlbauer_release(struct pcmcia_device *link) { local_info_t *local = link->priv; DEBUG(0, "sedlbauer_release(0x%p)\n", link); @@ -467,46 +445,23 @@ static void sedlbauer_release(dev_link_t *link) HiSax_closecard(local->cardnr); } } - /* Unlink the device chain */ - link->dev = NULL; - /* - In a normal driver, additional code may be needed to release - other kernel data structures associated with this device. - */ - - /* Don't bother checking to see if these succeed or not */ - if (link->win) - pcmcia_release_window(link->win); - pcmcia_release_configuration(link->handle); - if (link->io.NumPorts1) - pcmcia_release_io(link->handle, &link->io); - if (link->irq.AssignedIRQ) - pcmcia_release_irq(link->handle, &link->irq); - link->state &= ~DEV_CONFIG; + pcmcia_disable_device(link); } /* sedlbauer_release */ -static int sedlbauer_suspend(struct pcmcia_device *p_dev) +static int sedlbauer_suspend(struct pcmcia_device *link) { - dev_link_t *link = dev_to_instance(p_dev); local_info_t *dev = link->priv; - link->state |= DEV_SUSPEND; dev->stop = 1; - if (link->state & DEV_CONFIG) - pcmcia_release_configuration(link->handle); return 0; } -static int sedlbauer_resume(struct pcmcia_device *p_dev) +static int sedlbauer_resume(struct pcmcia_device *link) { - dev_link_t *link = dev_to_instance(p_dev); local_info_t *dev = link->priv; - link->state &= ~DEV_SUSPEND; - if (link->state & DEV_CONFIG) - pcmcia_request_configuration(link->handle, &link->conf); dev->stop = 0; return 0; @@ -530,7 +485,7 @@ static struct pcmcia_driver sedlbauer_driver = { .drv = { .name = "sedlbauer_cs", }, - .probe = sedlbauer_attach, + .probe = sedlbauer_probe, .remove = sedlbauer_detach, .id_table = sedlbauer_ids, .suspend = sedlbauer_suspend, diff --git a/drivers/isdn/hisax/teles_cs.c b/drivers/isdn/hisax/teles_cs.c index 4e5c14c7240..afcc2aeadb3 100644 --- a/drivers/isdn/hisax/teles_cs.c +++ b/drivers/isdn/hisax/teles_cs.c @@ -75,8 +75,8 @@ module_param(protocol, int, 0); handler. */ -static void teles_cs_config(dev_link_t *link); -static void teles_cs_release(dev_link_t *link); +static int teles_cs_config(struct pcmcia_device *link); +static void teles_cs_release(struct pcmcia_device *link); /* The attach() and detach() entry points are used to create and destroy @@ -89,10 +89,10 @@ static void teles_detach(struct pcmcia_device *p_dev); /* A linked list of "instances" of the teles_cs device. Each actual PCMCIA card corresponds to one device instance, and is described - by one dev_link_t structure (defined in ds.h). + by one struct pcmcia_device structure (defined in ds.h). You may not want to use a linked list for this -- for example, the - memory card driver uses an array of dev_link_t pointers, where minor + memory card driver uses an array of struct pcmcia_device pointers, where minor device numbers are used to derive the corresponding array index. */ @@ -102,7 +102,7 @@ static void teles_detach(struct pcmcia_device *p_dev); example, ethernet cards, modems). In other cases, there may be many actual or logical devices (SCSI adapters, memory cards with multiple partitions). The dev_node_t structures need to be kept - in a linked list starting at the 'dev' field of a dev_link_t + in a linked list starting at the 'dev' field of a struct pcmcia_device structure. We allocate them in the card's private data structure, because they generally shouldn't be allocated dynamically. In this case, we also provide a flag to indicate if a device is @@ -112,7 +112,7 @@ static void teles_detach(struct pcmcia_device *p_dev); */ typedef struct local_info_t { - dev_link_t link; + struct pcmcia_device *p_dev; dev_node_t node; int busy; int cardnr; @@ -130,9 +130,8 @@ typedef struct local_info_t { ======================================================================*/ -static int teles_attach(struct pcmcia_device *p_dev) +static int teles_probe(struct pcmcia_device *link) { - dev_link_t *link; local_info_t *local; DEBUG(0, "teles_attach()\n"); @@ -142,7 +141,9 @@ static int teles_attach(struct pcmcia_device *p_dev) if (!local) return -ENOMEM; memset(local, 0, sizeof(local_info_t)); local->cardnr = -1; - link = &local->link; link->priv = local; + + local->p_dev = link; + link->priv = local; /* Interrupt setup */ link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING|IRQ_FIRST_SHARED; @@ -161,16 +162,9 @@ static int teles_attach(struct pcmcia_device *p_dev) link->io.IOAddrLines = 5; link->conf.Attributes = CONF_ENABLE_IRQ; - link->conf.Vcc = 50; link->conf.IntType = INT_MEMORY_AND_IO; - link->handle = p_dev; - p_dev->instance = link; - - link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; - teles_cs_config(link); - - return 0; + return teles_cs_config(link); } /* teles_attach */ /*====================================================================== @@ -182,20 +176,16 @@ static int teles_attach(struct pcmcia_device *p_dev) ======================================================================*/ -static void teles_detach(struct pcmcia_device *p_dev) +static void teles_detach(struct pcmcia_device *link) { - dev_link_t *link = dev_to_instance(p_dev); - local_info_t *info = link->priv; - - DEBUG(0, "teles_detach(0x%p)\n", link); + local_info_t *info = link->priv; - if (link->state & DEV_CONFIG) { - info->busy = 1; - teles_cs_release(link); - } + DEBUG(0, "teles_detach(0x%p)\n", link); - kfree(info); + info->busy = 1; + teles_cs_release(link); + kfree(info); } /* teles_detach */ /*====================================================================== @@ -205,7 +195,7 @@ static void teles_detach(struct pcmcia_device *p_dev) device available to the system. ======================================================================*/ -static int get_tuple(client_handle_t handle, tuple_t *tuple, +static int get_tuple(struct pcmcia_device *handle, tuple_t *tuple, cisparse_t *parse) { int i = pcmcia_get_tuple_data(handle, tuple); @@ -213,7 +203,7 @@ static int get_tuple(client_handle_t handle, tuple_t *tuple, return pcmcia_parse_tuple(handle, tuple, parse); } -static int first_tuple(client_handle_t handle, tuple_t *tuple, +static int first_tuple(struct pcmcia_device *handle, tuple_t *tuple, cisparse_t *parse) { int i = pcmcia_get_first_tuple(handle, tuple); @@ -221,7 +211,7 @@ static int first_tuple(client_handle_t handle, tuple_t *tuple, return get_tuple(handle, tuple, parse); } -static int next_tuple(client_handle_t handle, tuple_t *tuple, +static int next_tuple(struct pcmcia_device *handle, tuple_t *tuple, cisparse_t *parse) { int i = pcmcia_get_next_tuple(handle, tuple); @@ -229,9 +219,8 @@ static int next_tuple(client_handle_t handle, tuple_t *tuple, return get_tuple(handle, tuple, parse); } -static void teles_cs_config(dev_link_t *link) +static int teles_cs_config(struct pcmcia_device *link) { - client_handle_t handle; tuple_t tuple; cisparse_t parse; local_info_t *dev; @@ -241,7 +230,6 @@ static void teles_cs_config(dev_link_t *link) IsdnCard_t icard; DEBUG(0, "teles_config(0x%p)\n", link); - handle = link->handle; dev = link->priv; /* @@ -253,7 +241,7 @@ static void teles_cs_config(dev_link_t *link) tuple.TupleDataMax = 255; tuple.TupleOffset = 0; tuple.Attributes = 0; - i = first_tuple(handle, &tuple, &parse); + i = first_tuple(link, &tuple, &parse); if (i != CS_SUCCESS) { last_fn = ParseTuple; goto cs_failed; @@ -261,32 +249,29 @@ static void teles_cs_config(dev_link_t *link) link->conf.ConfigBase = parse.config.base; link->conf.Present = parse.config.rmask[0]; - /* Configure card */ - link->state |= DEV_CONFIG; - tuple.TupleData = (cisdata_t *)buf; tuple.TupleOffset = 0; tuple.TupleDataMax = 255; tuple.Attributes = 0; tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; - i = first_tuple(handle, &tuple, &parse); + i = first_tuple(link, &tuple, &parse); while (i == CS_SUCCESS) { if ( (cf->io.nwin > 0) && cf->io.win[0].base) { printk(KERN_INFO "(teles_cs: looks like the 96 model)\n"); link->conf.ConfigIndex = cf->index; link->io.BasePort1 = cf->io.win[0].base; - i = pcmcia_request_io(link->handle, &link->io); + i = pcmcia_request_io(link, &link->io); if (i == CS_SUCCESS) break; } else { printk(KERN_INFO "(teles_cs: looks like the 97 model)\n"); link->conf.ConfigIndex = cf->index; for (i = 0, j = 0x2f0; j > 0x100; j -= 0x10) { link->io.BasePort1 = j; - i = pcmcia_request_io(link->handle, &link->io); + i = pcmcia_request_io(link, &link->io); if (i == CS_SUCCESS) break; } break; } - i = next_tuple(handle, &tuple, &parse); + i = next_tuple(link, &tuple, &parse); } if (i != CS_SUCCESS) { @@ -294,14 +279,14 @@ static void teles_cs_config(dev_link_t *link) goto cs_failed; } - i = pcmcia_request_irq(link->handle, &link->irq); + i = pcmcia_request_irq(link, &link->irq); if (i != CS_SUCCESS) { link->irq.AssignedIRQ = 0; last_fn = RequestIRQ; goto cs_failed; } - i = pcmcia_request_configuration(link->handle, &link->conf); + i = pcmcia_request_configuration(link, &link->conf); if (i != CS_SUCCESS) { last_fn = RequestConfiguration; goto cs_failed; @@ -312,14 +297,11 @@ static void teles_cs_config(dev_link_t *link) sprintf(dev->node.dev_name, "teles"); dev->node.major = dev->node.minor = 0x0; - link->dev = &dev->node; + link->dev_node = &dev->node; /* Finally, report what we've done */ - printk(KERN_INFO "%s: index 0x%02x: Vcc %d.%d", - dev->node.dev_name, link->conf.ConfigIndex, - link->conf.Vcc/10, link->conf.Vcc%10); - if (link->conf.Vpp1) - printk(", Vpp %d.%d", link->conf.Vpp1/10, link->conf.Vpp1%10); + printk(KERN_INFO "%s: index 0x%02x:", + dev->node.dev_name, link->conf.ConfigIndex); if (link->conf.Attributes & CONF_ENABLE_IRQ) printk(", irq %d", link->irq.AssignedIRQ); if (link->io.NumPorts1) @@ -330,8 +312,6 @@ static void teles_cs_config(dev_link_t *link) link->io.BasePort2+link->io.NumPorts2-1); printk("\n"); - link->state &= ~DEV_CONFIG_PENDING; - icard.para[0] = link->irq.AssignedIRQ; icard.para[1] = link->io.BasePort1; icard.protocol = protocol; @@ -342,13 +322,16 @@ static void teles_cs_config(dev_link_t *link) printk(KERN_ERR "teles_cs: failed to initialize Teles PCMCIA %d at i/o %#x\n", i, link->io.BasePort1); teles_cs_release(link); - } else - ((local_info_t*)link->priv)->cardnr = i; + return -ENODEV; + } + + ((local_info_t*)link->priv)->cardnr = i; + return 0; - return; cs_failed: - cs_error(link->handle, last_fn, i); + cs_error(link, last_fn, i); teles_cs_release(link); + return -ENODEV; } /* teles_cs_config */ /*====================================================================== @@ -359,7 +342,7 @@ cs_failed: ======================================================================*/ -static void teles_cs_release(dev_link_t *link) +static void teles_cs_release(struct pcmcia_device *link) { local_info_t *local = link->priv; @@ -371,39 +354,23 @@ static void teles_cs_release(dev_link_t *link) HiSax_closecard(local->cardnr); } } - /* Unlink the device chain */ - link->dev = NULL; - - /* Don't bother checking to see if these succeed or not */ - if (link->win) - pcmcia_release_window(link->win); - pcmcia_release_configuration(link->handle); - pcmcia_release_io(link->handle, &link->io); - pcmcia_release_irq(link->handle, &link->irq); - link->state &= ~DEV_CONFIG; + + pcmcia_disable_device(link); } /* teles_cs_release */ -static int teles_suspend(struct pcmcia_device *p_dev) +static int teles_suspend(struct pcmcia_device *link) { - dev_link_t *link = dev_to_instance(p_dev); local_info_t *dev = link->priv; - link->state |= DEV_SUSPEND; dev->busy = 1; - if (link->state & DEV_CONFIG) - pcmcia_release_configuration(link->handle); return 0; } -static int teles_resume(struct pcmcia_device *p_dev) +static int teles_resume(struct pcmcia_device *link) { - dev_link_t *link = dev_to_instance(p_dev); local_info_t *dev = link->priv; - link->state &= ~DEV_SUSPEND; - if (link->state & DEV_CONFIG) - pcmcia_request_configuration(link->handle, &link->conf); dev->busy = 0; return 0; @@ -421,7 +388,7 @@ static struct pcmcia_driver teles_cs_driver = { .drv = { .name = "teles_cs", }, - .probe = teles_attach, + .probe = teles_probe, .remove = teles_detach, .id_table = teles_ids, .suspend = teles_suspend, diff --git a/drivers/isdn/sc/ioctl.c b/drivers/isdn/sc/ioctl.c index 94c9afb7017..f4f71226a07 100644 --- a/drivers/isdn/sc/ioctl.c +++ b/drivers/isdn/sc/ioctl.c @@ -46,7 +46,8 @@ int sc_ioctl(int card, scs_ioctl *data) pr_debug("%s: SCIOCRESET: ioctl received\n", sc_adapter[card]->devicename); sc_adapter[card]->StartOnReset = 0; - return (reset(card)); + kfree(rcvmsg); + return reset(card); } case SCIOCLOAD: @@ -183,7 +184,7 @@ int sc_ioctl(int card, scs_ioctl *data) sc_adapter[card]->devicename); spid = kmalloc(SCIOC_SPIDSIZE, GFP_KERNEL); - if(!spid) { + if (!spid) { kfree(rcvmsg); return -ENOMEM; } @@ -195,10 +196,10 @@ int sc_ioctl(int card, scs_ioctl *data) if (!status) { pr_debug("%s: SCIOCGETSPID: command successful\n", sc_adapter[card]->devicename); - } - else { + } else { pr_debug("%s: SCIOCGETSPID: command failed (status = %d)\n", sc_adapter[card]->devicename, status); + kfree(spid); kfree(rcvmsg); return status; } diff --git a/drivers/leds/Kconfig b/drivers/leds/Kconfig new file mode 100644 index 00000000000..2c4f20b7f02 --- /dev/null +++ b/drivers/leds/Kconfig @@ -0,0 +1,77 @@ + +menu "LED devices" + +config NEW_LEDS + bool "LED Support" + help + Say Y to enable Linux LED support. This is not related to standard + keyboard LEDs which are controlled via the input system. + +config LEDS_CLASS + tristate "LED Class Support" + depends NEW_LEDS + help + This option enables the led sysfs class in /sys/class/leds. You'll + need this to do anything useful with LEDs. If unsure, say N. + +config LEDS_TRIGGERS + bool "LED Trigger support" + depends NEW_LEDS + help + This option enables trigger support for the leds class. + These triggers allow kernel events to drive the LEDs and can + be configured via sysfs. If unsure, say Y. + +config LEDS_CORGI + tristate "LED Support for the Sharp SL-C7x0 series" + depends LEDS_CLASS && PXA_SHARP_C7xx + help + This option enables support for the LEDs on Sharp Zaurus + SL-C7x0 series (C700, C750, C760, C860). + +config LEDS_LOCOMO + tristate "LED Support for Locomo device" + depends LEDS_CLASS && SHARP_LOCOMO + help + This option enables support for the LEDs on Sharp Locomo. + Zaurus models SL-5500 and SL-5600. + +config LEDS_SPITZ + tristate "LED Support for the Sharp SL-Cxx00 series" + depends LEDS_CLASS && PXA_SHARP_Cxx00 + help + This option enables support for the LEDs on Sharp Zaurus + SL-Cxx00 series (C1000, C3000, C3100). + +config LEDS_IXP4XX + tristate "LED Support for GPIO connected LEDs on IXP4XX processors" + depends LEDS_CLASS && ARCH_IXP4XX + help + This option enables support for the LEDs connected to GPIO + outputs of the Intel IXP4XX processors. To be useful the + particular board must have LEDs and they must be connected + to the GPIO lines. If unsure, say Y. + +config LEDS_TOSA + tristate "LED Support for the Sharp SL-6000 series" + depends LEDS_CLASS && PXA_SHARPSL + help + This option enables support for the LEDs on Sharp Zaurus + SL-6000 series. + +config LEDS_TRIGGER_TIMER + tristate "LED Timer Trigger" + depends LEDS_TRIGGERS + help + This allows LEDs to be controlled by a programmable timer + via sysfs. If unsure, say Y. + +config LEDS_TRIGGER_IDE_DISK + bool "LED Timer Trigger" + depends LEDS_TRIGGERS && BLK_DEV_IDEDISK + help + This allows LEDs to be controlled by IDE disk activity. + If unsure, say Y. + +endmenu + diff --git a/drivers/leds/Makefile b/drivers/leds/Makefile new file mode 100644 index 00000000000..40699d3cabb --- /dev/null +++ b/drivers/leds/Makefile @@ -0,0 +1,16 @@ + +# LED Core +obj-$(CONFIG_NEW_LEDS) += led-core.o +obj-$(CONFIG_LEDS_CLASS) += led-class.o +obj-$(CONFIG_LEDS_TRIGGERS) += led-triggers.o + +# LED Platform Drivers +obj-$(CONFIG_LEDS_CORGI) += leds-corgi.o +obj-$(CONFIG_LEDS_LOCOMO) += leds-locomo.o +obj-$(CONFIG_LEDS_SPITZ) += leds-spitz.o +obj-$(CONFIG_LEDS_IXP4XX) += leds-ixp4xx-gpio.o +obj-$(CONFIG_LEDS_TOSA) += leds-tosa.o + +# LED Triggers +obj-$(CONFIG_LEDS_TRIGGER_TIMER) += ledtrig-timer.o +obj-$(CONFIG_LEDS_TRIGGER_IDE_DISK) += ledtrig-ide-disk.o diff --git a/drivers/leds/led-class.c b/drivers/leds/led-class.c new file mode 100644 index 00000000000..b0b5d05fadd --- /dev/null +++ b/drivers/leds/led-class.c @@ -0,0 +1,167 @@ +/* + * LED Class Core + * + * Copyright (C) 2005 John Lenz <lenz@cs.wisc.edu> + * Copyright (C) 2005-2006 Richard Purdie <rpurdie@openedhand.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include <linux/config.h> +#include <linux/module.h> +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/list.h> +#include <linux/spinlock.h> +#include <linux/device.h> +#include <linux/sysdev.h> +#include <linux/timer.h> +#include <linux/err.h> +#include <linux/leds.h> +#include "leds.h" + +static struct class *leds_class; + +static ssize_t led_brightness_show(struct class_device *dev, char *buf) +{ + struct led_classdev *led_cdev = class_get_devdata(dev); + ssize_t ret = 0; + + /* no lock needed for this */ + sprintf(buf, "%u\n", led_cdev->brightness); + ret = strlen(buf) + 1; + + return ret; +} + +static ssize_t led_brightness_store(struct class_device *dev, + const char *buf, size_t size) +{ + struct led_classdev *led_cdev = class_get_devdata(dev); + ssize_t ret = -EINVAL; + char *after; + unsigned long state = simple_strtoul(buf, &after, 10); + + if (after - buf > 0) { + ret = after - buf; + led_set_brightness(led_cdev, state); + } + + return ret; +} + +static CLASS_DEVICE_ATTR(brightness, 0644, led_brightness_show, + led_brightness_store); +#ifdef CONFIG_LEDS_TRIGGERS +static CLASS_DEVICE_ATTR(trigger, 0644, led_trigger_show, led_trigger_store); +#endif + +/** + * led_classdev_suspend - suspend an led_classdev. + * @led_cdev: the led_classdev to suspend. + */ +void led_classdev_suspend(struct led_classdev *led_cdev) +{ + led_cdev->flags |= LED_SUSPENDED; + led_cdev->brightness_set(led_cdev, 0); +} +EXPORT_SYMBOL_GPL(led_classdev_suspend); + +/** + * led_classdev_resume - resume an led_classdev. + * @led_cdev: the led_classdev to resume. + */ +void led_classdev_resume(struct led_classdev *led_cdev) +{ + led_cdev->brightness_set(led_cdev, led_cdev->brightness); + led_cdev->flags &= ~LED_SUSPENDED; +} +EXPORT_SYMBOL_GPL(led_classdev_resume); + +/** + * led_classdev_register - register a new object of led_classdev class. + * @dev: The device to register. + * @led_cdev: the led_classdev structure for this device. + */ +int led_classdev_register(struct device *parent, struct led_classdev *led_cdev) +{ + led_cdev->class_dev = class_device_create(leds_class, NULL, 0, + parent, "%s", led_cdev->name); + if (unlikely(IS_ERR(led_cdev->class_dev))) + return PTR_ERR(led_cdev->class_dev); + + class_set_devdata(led_cdev->class_dev, led_cdev); + + /* register the attributes */ + class_device_create_file(led_cdev->class_dev, + &class_device_attr_brightness); + + /* add to the list of leds */ + write_lock(&leds_list_lock); + list_add_tail(&led_cdev->node, &leds_list); + write_unlock(&leds_list_lock); + +#ifdef CONFIG_LEDS_TRIGGERS + rwlock_init(&led_cdev->trigger_lock); + + led_trigger_set_default(led_cdev); + + class_device_create_file(led_cdev->class_dev, + &class_device_attr_trigger); +#endif + + printk(KERN_INFO "Registered led device: %s\n", + led_cdev->class_dev->class_id); + + return 0; +} +EXPORT_SYMBOL_GPL(led_classdev_register); + +/** + * led_classdev_unregister - unregisters a object of led_properties class. + * @led_cdev: the led device to unreigister + * + * Unregisters a previously registered via led_classdev_register object. + */ +void led_classdev_unregister(struct led_classdev *led_cdev) +{ + class_device_remove_file(led_cdev->class_dev, + &class_device_attr_brightness); +#ifdef CONFIG_LEDS_TRIGGERS + class_device_remove_file(led_cdev->class_dev, + &class_device_attr_trigger); + write_lock(&led_cdev->trigger_lock); + if (led_cdev->trigger) + led_trigger_set(led_cdev, NULL); + write_unlock(&led_cdev->trigger_lock); +#endif + + class_device_unregister(led_cdev->class_dev); + + write_lock(&leds_list_lock); + list_del(&led_cdev->node); + write_unlock(&leds_list_lock); +} +EXPORT_SYMBOL_GPL(led_classdev_unregister); + +static int __init leds_init(void) +{ + leds_class = class_create(THIS_MODULE, "leds"); + if (IS_ERR(leds_class)) + return PTR_ERR(leds_class); + return 0; +} + +static void __exit leds_exit(void) +{ + class_destroy(leds_class); +} + +subsys_initcall(leds_init); +module_exit(leds_exit); + +MODULE_AUTHOR("John Lenz, Richard Purdie"); +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("LED Class Interface"); diff --git a/drivers/leds/led-core.c b/drivers/leds/led-core.c new file mode 100644 index 00000000000..fe6541326c7 --- /dev/null +++ b/drivers/leds/led-core.c @@ -0,0 +1,25 @@ +/* + * LED Class Core + * + * Copyright 2005-2006 Openedhand Ltd. + * + * Author: Richard Purdie <rpurdie@openedhand.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + */ + +#include <linux/kernel.h> +#include <linux/list.h> +#include <linux/module.h> +#include <linux/spinlock.h> +#include <linux/leds.h> +#include "leds.h" + +rwlock_t leds_list_lock = RW_LOCK_UNLOCKED; +LIST_HEAD(leds_list); + +EXPORT_SYMBOL_GPL(leds_list); +EXPORT_SYMBOL_GPL(leds_list_lock); diff --git a/drivers/leds/led-triggers.c b/drivers/leds/led-triggers.c new file mode 100644 index 00000000000..5e2cd8be119 --- /dev/null +++ b/drivers/leds/led-triggers.c @@ -0,0 +1,239 @@ +/* + * LED Triggers Core + * + * Copyright 2005-2006 Openedhand Ltd. + * + * Author: Richard Purdie <rpurdie@openedhand.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + */ + +#include <linux/config.h> +#include <linux/module.h> +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/list.h> +#include <linux/spinlock.h> +#include <linux/device.h> +#include <linux/sysdev.h> +#include <linux/timer.h> +#include <linux/leds.h> +#include "leds.h" + +/* + * Nests outside led_cdev->trigger_lock + */ +static rwlock_t triggers_list_lock = RW_LOCK_UNLOCKED; +static LIST_HEAD(trigger_list); + +ssize_t led_trigger_store(struct class_device *dev, const char *buf, + size_t count) +{ + struct led_classdev *led_cdev = class_get_devdata(dev); + char trigger_name[TRIG_NAME_MAX]; + struct led_trigger *trig; + size_t len; + + trigger_name[sizeof(trigger_name) - 1] = '\0'; + strncpy(trigger_name, buf, sizeof(trigger_name) - 1); + len = strlen(trigger_name); + + if (len && trigger_name[len - 1] == '\n') + trigger_name[len - 1] = '\0'; + + if (!strcmp(trigger_name, "none")) { + write_lock(&led_cdev->trigger_lock); + led_trigger_set(led_cdev, NULL); + write_unlock(&led_cdev->trigger_lock); + return count; + } + + read_lock(&triggers_list_lock); + list_for_each_entry(trig, &trigger_list, next_trig) { + if (!strcmp(trigger_name, trig->name)) { + write_lock(&led_cdev->trigger_lock); + led_trigger_set(led_cdev, trig); + write_unlock(&led_cdev->trigger_lock); + + read_unlock(&triggers_list_lock); + return count; + } + } + read_unlock(&triggers_list_lock); + + return -EINVAL; +} + + +ssize_t led_trigger_show(struct class_device *dev, char *buf) +{ + struct led_classdev *led_cdev = class_get_devdata(dev); + struct led_trigger *trig; + int len = 0; + + read_lock(&triggers_list_lock); + read_lock(&led_cdev->trigger_lock); + + if (!led_cdev->trigger) + len += sprintf(buf+len, "[none] "); + else + len += sprintf(buf+len, "none "); + + list_for_each_entry(trig, &trigger_list, next_trig) { + if (led_cdev->trigger && !strcmp(led_cdev->trigger->name, + trig->name)) + len += sprintf(buf+len, "[%s] ", trig->name); + else + len += sprintf(buf+len, "%s ", trig->name); + } + read_unlock(&led_cdev->trigger_lock); + read_unlock(&triggers_list_lock); + + len += sprintf(len+buf, "\n"); + return len; +} + +void led_trigger_event(struct led_trigger *trigger, + enum led_brightness brightness) +{ + struct list_head *entry; + + if (!trigger) + return; + + read_lock(&trigger->leddev_list_lock); + list_for_each(entry, &trigger->led_cdevs) { + struct led_classdev *led_cdev; + + led_cdev = list_entry(entry, struct led_classdev, trig_list); + led_set_brightness(led_cdev, brightness); + } + read_unlock(&trigger->leddev_list_lock); +} + +/* Caller must ensure led_cdev->trigger_lock held */ +void led_trigger_set(struct led_classdev *led_cdev, struct led_trigger *trigger) +{ + unsigned long flags; + + /* Remove any existing trigger */ + if (led_cdev->trigger) { + write_lock_irqsave(&led_cdev->trigger->leddev_list_lock, flags); + list_del(&led_cdev->trig_list); + write_unlock_irqrestore(&led_cdev->trigger->leddev_list_lock, flags); + if (led_cdev->trigger->deactivate) + led_cdev->trigger->deactivate(led_cdev); + } + if (trigger) { + write_lock_irqsave(&trigger->leddev_list_lock, flags); + list_add_tail(&led_cdev->trig_list, &trigger->led_cdevs); + write_unlock_irqrestore(&trigger->leddev_list_lock, flags); + if (trigger->activate) + trigger->activate(led_cdev); + } + led_cdev->trigger = trigger; +} + +void led_trigger_set_default(struct led_classdev *led_cdev) +{ + struct led_trigger *trig; + + if (!led_cdev->default_trigger) + return; + + read_lock(&triggers_list_lock); + write_lock(&led_cdev->trigger_lock); + list_for_each_entry(trig, &trigger_list, next_trig) { + if (!strcmp(led_cdev->default_trigger, trig->name)) + led_trigger_set(led_cdev, trig); + } + write_unlock(&led_cdev->trigger_lock); + read_unlock(&triggers_list_lock); +} + +int led_trigger_register(struct led_trigger *trigger) +{ + struct led_classdev *led_cdev; + + rwlock_init(&trigger->leddev_list_lock); + INIT_LIST_HEAD(&trigger->led_cdevs); + + /* Add to the list of led triggers */ + write_lock(&triggers_list_lock); + list_add_tail(&trigger->next_trig, &trigger_list); + write_unlock(&triggers_list_lock); + + /* Register with any LEDs that have this as a default trigger */ + read_lock(&leds_list_lock); + list_for_each_entry(led_cdev, &leds_list, node) { + write_lock(&led_cdev->trigger_lock); + if (!led_cdev->trigger && led_cdev->default_trigger && + !strcmp(led_cdev->default_trigger, trigger->name)) + led_trigger_set(led_cdev, trigger); + write_unlock(&led_cdev->trigger_lock); + } + read_unlock(&leds_list_lock); + + return 0; +} + +void led_trigger_register_simple(const char *name, struct led_trigger **tp) +{ + struct led_trigger *trigger; + + trigger = kzalloc(sizeof(struct led_trigger), GFP_KERNEL); + + if (trigger) { + trigger->name = name; + led_trigger_register(trigger); + } + *tp = trigger; +} + +void led_trigger_unregister(struct led_trigger *trigger) +{ + struct led_classdev *led_cdev; + + /* Remove from the list of led triggers */ + write_lock(&triggers_list_lock); + list_del(&trigger->next_trig); + write_unlock(&triggers_list_lock); + + /* Remove anyone actively using this trigger */ + read_lock(&leds_list_lock); + list_for_each_entry(led_cdev, &leds_list, node) { + write_lock(&led_cdev->trigger_lock); + if (led_cdev->trigger == trigger) + led_trigger_set(led_cdev, NULL); + write_unlock(&led_cdev->trigger_lock); + } + read_unlock(&leds_list_lock); +} + +void led_trigger_unregister_simple(struct led_trigger *trigger) +{ + led_trigger_unregister(trigger); + kfree(trigger); +} + +/* Used by LED Class */ +EXPORT_SYMBOL_GPL(led_trigger_set); +EXPORT_SYMBOL_GPL(led_trigger_set_default); +EXPORT_SYMBOL_GPL(led_trigger_show); +EXPORT_SYMBOL_GPL(led_trigger_store); + +/* LED Trigger Interface */ +EXPORT_SYMBOL_GPL(led_trigger_register); +EXPORT_SYMBOL_GPL(led_trigger_unregister); + +/* Simple LED Tigger Interface */ +EXPORT_SYMBOL_GPL(led_trigger_register_simple); +EXPORT_SYMBOL_GPL(led_trigger_unregister_simple); +EXPORT_SYMBOL_GPL(led_trigger_event); + +MODULE_AUTHOR("Richard Purdie"); +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("LED Triggers Core"); diff --git a/drivers/leds/leds-corgi.c b/drivers/leds/leds-corgi.c new file mode 100644 index 00000000000..bb7d84df012 --- /dev/null +++ b/drivers/leds/leds-corgi.c @@ -0,0 +1,121 @@ +/* + * LED Triggers Core + * + * Copyright 2005-2006 Openedhand Ltd. + * + * Author: Richard Purdie <rpurdie@openedhand.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + */ + +#include <linux/config.h> +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/platform_device.h> +#include <linux/leds.h> +#include <asm/mach-types.h> +#include <asm/arch/corgi.h> +#include <asm/arch/hardware.h> +#include <asm/arch/pxa-regs.h> +#include <asm/hardware/scoop.h> + +static void corgiled_amber_set(struct led_classdev *led_cdev, enum led_brightness value) +{ + if (value) + GPSR0 = GPIO_bit(CORGI_GPIO_LED_ORANGE); + else + GPCR0 = GPIO_bit(CORGI_GPIO_LED_ORANGE); +} + +static void corgiled_green_set(struct led_classdev *led_cdev, enum led_brightness value) +{ + if (value) + set_scoop_gpio(&corgiscoop_device.dev, CORGI_SCP_LED_GREEN); + else + reset_scoop_gpio(&corgiscoop_device.dev, CORGI_SCP_LED_GREEN); +} + +static struct led_classdev corgi_amber_led = { + .name = "corgi:amber", + .default_trigger = "sharpsl-charge", + .brightness_set = corgiled_amber_set, +}; + +static struct led_classdev corgi_green_led = { + .name = "corgi:green", + .default_trigger = "nand-disk", + .brightness_set = corgiled_green_set, +}; + +#ifdef CONFIG_PM +static int corgiled_suspend(struct platform_device *dev, pm_message_t state) +{ +#ifdef CONFIG_LEDS_TRIGGERS + if (corgi_amber_led.trigger && strcmp(corgi_amber_led.trigger->name, "sharpsl-charge")) +#endif + led_classdev_suspend(&corgi_amber_led); + led_classdev_suspend(&corgi_green_led); + return 0; +} + +static int corgiled_resume(struct platform_device *dev) +{ + led_classdev_resume(&corgi_amber_led); + led_classdev_resume(&corgi_green_led); + return 0; +} +#endif + +static int corgiled_probe(struct platform_device *pdev) +{ + int ret; + + ret = led_classdev_register(&pdev->dev, &corgi_amber_led); + if (ret < 0) + return ret; + + ret = led_classdev_register(&pdev->dev, &corgi_green_led); + if (ret < 0) + led_classdev_unregister(&corgi_amber_led); + + return ret; +} + +static int corgiled_remove(struct platform_device *pdev) +{ + led_classdev_unregister(&corgi_amber_led); + led_classdev_unregister(&corgi_green_led); + return 0; +} + +static struct platform_driver corgiled_driver = { + .probe = corgiled_probe, + .remove = corgiled_remove, +#ifdef CONFIG_PM + .suspend = corgiled_suspend, + .resume = corgiled_resume, +#endif + .driver = { + .name = "corgi-led", + }, +}; + +static int __init corgiled_init(void) +{ + return platform_driver_register(&corgiled_driver); +} + +static void __exit corgiled_exit(void) +{ + platform_driver_unregister(&corgiled_driver); +} + +module_init(corgiled_init); +module_exit(corgiled_exit); + +MODULE_AUTHOR("Richard Purdie <rpurdie@openedhand.com>"); +MODULE_DESCRIPTION("Corgi LED driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/leds/leds-ixp4xx-gpio.c b/drivers/leds/leds-ixp4xx-gpio.c new file mode 100644 index 00000000000..30ced150e4c --- /dev/null +++ b/drivers/leds/leds-ixp4xx-gpio.c @@ -0,0 +1,215 @@ +/* + * IXP4XX GPIO driver LED driver + * + * Author: John Bowler <jbowler@acm.org> + * + * Copyright (c) 2006 John Bowler + * + * Permission is hereby granted, free of charge, to any + * person obtaining a copy of this software and associated + * documentation files (the "Software"), to deal in the + * Software without restriction, including without + * limitation the rights to use, copy, modify, merge, + * publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the + * following conditions: + * + * The above copyright notice and this permission notice + * shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF + * ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED + * TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT + * SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + */ + +#include <linux/config.h> +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/platform_device.h> +#include <linux/spinlock.h> +#include <linux/leds.h> +#include <asm/arch/hardware.h> + +extern spinlock_t gpio_lock; + +/* Up to 16 gpio lines are possible. */ +#define GPIO_MAX 16 +static struct ixp4xxgpioled_device { + struct led_classdev ancestor; + int flags; +} ixp4xxgpioled_devices[GPIO_MAX]; + +void ixp4xxgpioled_brightness_set(struct led_classdev *pled, + enum led_brightness value) +{ + const struct ixp4xxgpioled_device *const ixp4xx_dev = + container_of(pled, struct ixp4xxgpioled_device, ancestor); + const u32 gpio_pin = ixp4xx_dev - ixp4xxgpioled_devices; + + if (gpio_pin < GPIO_MAX && ixp4xx_dev->ancestor.name != 0) { + /* Set or clear the 'gpio_pin' bit according to the style + * and the required setting (value > 0 == on) + */ + const int gpio_value = + (value > 0) == (ixp4xx_dev->flags != IXP4XX_GPIO_LOW) ? + IXP4XX_GPIO_HIGH : IXP4XX_GPIO_LOW; + + { + unsigned long flags; + spin_lock_irqsave(&gpio_lock, flags); + gpio_line_set(gpio_pin, gpio_value); + spin_unlock_irqrestore(&gpio_lock, flags); + } + } +} + +/* LEDs are described in resources, the following iterates over the valid + * LED resources. + */ +#define for_all_leds(i, pdev) \ + for (i=0; i<pdev->num_resources; ++i) \ + if (pdev->resource[i].start < GPIO_MAX && \ + pdev->resource[i].name != 0) + +/* The following applies 'operation' to each LED from the given platform, + * the function always returns 0 to allow tail call elimination. + */ +static int apply_to_all_leds(struct platform_device *pdev, + void (*operation)(struct led_classdev *pled)) +{ + int i; + + for_all_leds(i, pdev) + operation(&ixp4xxgpioled_devices[pdev->resource[i].start].ancestor); + return 0; +} + +#ifdef CONFIG_PM +static int ixp4xxgpioled_suspend(struct platform_device *pdev, + pm_message_t state) +{ + return apply_to_all_leds(pdev, led_classdev_suspend); +} + +static int ixp4xxgpioled_resume(struct platform_device *pdev) +{ + return apply_to_all_leds(pdev, led_classdev_resume); +} +#endif + +static void ixp4xxgpioled_remove_one_led(struct led_classdev *pled) +{ + led_classdev_unregister(pled); + pled->name = 0; +} + +static int ixp4xxgpioled_remove(struct platform_device *pdev) +{ + return apply_to_all_leds(pdev, ixp4xxgpioled_remove_one_led); +} + +static int ixp4xxgpioled_probe(struct platform_device *pdev) +{ + /* The board level has to tell the driver where the + * LEDs are connected - there is no way to find out + * electrically. It must also say whether the GPIO + * lines are active high or active low. + * + * To do this read the num_resources (the number of + * LEDs) and the struct resource (the data for each + * LED). The name comes from the resource, and it + * isn't copied. + */ + int i; + + for_all_leds(i, pdev) { + const u8 gpio_pin = pdev->resource[i].start; + int rc; + + if (ixp4xxgpioled_devices[gpio_pin].ancestor.name == 0) { + unsigned long flags; + + spin_lock_irqsave(&gpio_lock, flags); + gpio_line_config(gpio_pin, IXP4XX_GPIO_OUT); + /* The config can, apparently, reset the state, + * I suspect the gpio line may be an input and + * the config may cause the line to be latched, + * so the setting depends on how the LED is + * connected to the line (which affects how it + * floats if not driven). + */ + gpio_line_set(gpio_pin, IXP4XX_GPIO_HIGH); + spin_unlock_irqrestore(&gpio_lock, flags); + + ixp4xxgpioled_devices[gpio_pin].flags = + pdev->resource[i].flags & IORESOURCE_BITS; + + ixp4xxgpioled_devices[gpio_pin].ancestor.name = + pdev->resource[i].name; + + /* This is how a board manufacturer makes the LED + * come on on reset - the GPIO line will be high, so + * make the LED light when the line is low... + */ + if (ixp4xxgpioled_devices[gpio_pin].flags != IXP4XX_GPIO_LOW) + ixp4xxgpioled_devices[gpio_pin].ancestor.brightness = 100; + else + ixp4xxgpioled_devices[gpio_pin].ancestor.brightness = 0; + + ixp4xxgpioled_devices[gpio_pin].ancestor.flags = 0; + + ixp4xxgpioled_devices[gpio_pin].ancestor.brightness_set = + ixp4xxgpioled_brightness_set; + + ixp4xxgpioled_devices[gpio_pin].ancestor.default_trigger = 0; + } + + rc = led_classdev_register(&pdev->dev, + &ixp4xxgpioled_devices[gpio_pin].ancestor); + if (rc < 0) { + ixp4xxgpioled_devices[gpio_pin].ancestor.name = 0; + ixp4xxgpioled_remove(pdev); + return rc; + } + } + + return 0; +} + +static struct platform_driver ixp4xxgpioled_driver = { + .probe = ixp4xxgpioled_probe, + .remove = ixp4xxgpioled_remove, +#ifdef CONFIG_PM + .suspend = ixp4xxgpioled_suspend, + .resume = ixp4xxgpioled_resume, +#endif + .driver = { + .name = "IXP4XX-GPIO-LED", + }, +}; + +static int __init ixp4xxgpioled_init(void) +{ + return platform_driver_register(&ixp4xxgpioled_driver); +} + +static void __exit ixp4xxgpioled_exit(void) +{ + platform_driver_unregister(&ixp4xxgpioled_driver); +} + +module_init(ixp4xxgpioled_init); +module_exit(ixp4xxgpioled_exit); + +MODULE_AUTHOR("John Bowler <jbowler@acm.org>"); +MODULE_DESCRIPTION("IXP4XX GPIO LED driver"); +MODULE_LICENSE("Dual MIT/GPL"); diff --git a/drivers/leds/leds-locomo.c b/drivers/leds/leds-locomo.c new file mode 100644 index 00000000000..749a86c2adb --- /dev/null +++ b/drivers/leds/leds-locomo.c @@ -0,0 +1,95 @@ +/* + * linux/drivers/leds/locomo.c + * + * Copyright (C) 2005 John Lenz <lenz@cs.wisc.edu> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include <linux/config.h> +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/device.h> +#include <linux/leds.h> + +#include <asm/hardware.h> +#include <asm/hardware/locomo.h> + +static void locomoled_brightness_set(struct led_classdev *led_cdev, + enum led_brightness value, int offset) +{ + struct locomo_dev *locomo_dev = LOCOMO_DEV(led_cdev->class_dev->dev); + unsigned long flags; + + local_irq_save(flags); + if (value) + locomo_writel(LOCOMO_LPT_TOFH, locomo_dev->mapbase + offset); + else + locomo_writel(LOCOMO_LPT_TOFL, locomo_dev->mapbase + offset); + local_irq_restore(flags); +} + +static void locomoled_brightness_set0(struct led_classdev *led_cdev, + enum led_brightness value) +{ + locomoled_brightness_set(led_cdev, value, LOCOMO_LPT0); +} + +static void locomoled_brightness_set1(struct led_classdev *led_cdev, + enum led_brightness value) +{ + locomoled_brightness_set(led_cdev, value, LOCOMO_LPT1); +} + +static struct led_classdev locomo_led0 = { + .name = "locomo:amber", + .brightness_set = locomoled_brightness_set0, +}; + +static struct led_classdev locomo_led1 = { + .name = "locomo:green", + .brightness_set = locomoled_brightness_set1, +}; + +static int locomoled_probe(struct locomo_dev *ldev) +{ + int ret; + + ret = led_classdev_register(&ldev->dev, &locomo_led0); + if (ret < 0) + return ret; + + ret = led_classdev_register(&ldev->dev, &locomo_led1); + if (ret < 0) + led_classdev_unregister(&locomo_led0); + + return ret; +} + +static int locomoled_remove(struct locomo_dev *dev) +{ + led_classdev_unregister(&locomo_led0); + led_classdev_unregister(&locomo_led1); + return 0; +} + +static struct locomo_driver locomoled_driver = { + .drv = { + .name = "locomoled" + }, + .devid = LOCOMO_DEVID_LED, + .probe = locomoled_probe, + .remove = locomoled_remove, +}; + +static int __init locomoled_init(void) +{ + return locomo_driver_register(&locomoled_driver); +} +module_init(locomoled_init); + +MODULE_AUTHOR("John Lenz <lenz@cs.wisc.edu>"); +MODULE_DESCRIPTION("Locomo LED driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/leds/leds-spitz.c b/drivers/leds/leds-spitz.c new file mode 100644 index 00000000000..65bbef4a5e0 --- /dev/null +++ b/drivers/leds/leds-spitz.c @@ -0,0 +1,125 @@ +/* + * LED Triggers Core + * + * Copyright 2005-2006 Openedhand Ltd. + * + * Author: Richard Purdie <rpurdie@openedhand.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + */ + +#include <linux/config.h> +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/platform_device.h> +#include <linux/leds.h> +#include <asm/hardware/scoop.h> +#include <asm/mach-types.h> +#include <asm/arch/hardware.h> +#include <asm/arch/pxa-regs.h> +#include <asm/arch/spitz.h> + +static void spitzled_amber_set(struct led_classdev *led_cdev, enum led_brightness value) +{ + if (value) + set_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_LED_ORANGE); + else + reset_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_LED_ORANGE); +} + +static void spitzled_green_set(struct led_classdev *led_cdev, enum led_brightness value) +{ + if (value) + set_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_LED_GREEN); + else + reset_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_LED_GREEN); +} + +static struct led_classdev spitz_amber_led = { + .name = "spitz:amber", + .default_trigger = "sharpsl-charge", + .brightness_set = spitzled_amber_set, +}; + +static struct led_classdev spitz_green_led = { + .name = "spitz:green", + .default_trigger = "ide-disk", + .brightness_set = spitzled_green_set, +}; + +#ifdef CONFIG_PM +static int spitzled_suspend(struct platform_device *dev, pm_message_t state) +{ +#ifdef CONFIG_LEDS_TRIGGERS + if (spitz_amber_led.trigger && strcmp(spitz_amber_led.trigger->name, "sharpsl-charge")) +#endif + led_classdev_suspend(&spitz_amber_led); + led_classdev_suspend(&spitz_green_led); + return 0; +} + +static int spitzled_resume(struct platform_device *dev) +{ + led_classdev_resume(&spitz_amber_led); + led_classdev_resume(&spitz_green_led); + return 0; +} +#endif + +static int spitzled_probe(struct platform_device *pdev) +{ + int ret; + + if (machine_is_akita()) + spitz_green_led.default_trigger = "nand-disk"; + + ret = led_classdev_register(&pdev->dev, &spitz_amber_led); + if (ret < 0) + return ret; + + ret = led_classdev_register(&pdev->dev, &spitz_green_led); + if (ret < 0) + led_classdev_unregister(&spitz_amber_led); + + return ret; +} + +static int spitzled_remove(struct platform_device *pdev) +{ + led_classdev_unregister(&spitz_amber_led); + led_classdev_unregister(&spitz_green_led); + + return 0; +} + +static struct platform_driver spitzled_driver = { + .probe = spitzled_probe, + .remove = spitzled_remove, +#ifdef CONFIG_PM + .suspend = spitzled_suspend, + .resume = spitzled_resume, +#endif + .driver = { + .name = "spitz-led", + }, +}; + +static int __init spitzled_init(void) +{ + return platform_driver_register(&spitzled_driver); +} + +static void __exit spitzled_exit(void) +{ + platform_driver_unregister(&spitzled_driver); +} + +module_init(spitzled_init); +module_exit(spitzled_exit); + +MODULE_AUTHOR("Richard Purdie <rpurdie@openedhand.com>"); +MODULE_DESCRIPTION("Spitz LED driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/leds/leds-tosa.c b/drivers/leds/leds-tosa.c new file mode 100644 index 00000000000..c9e8cc1ec48 --- /dev/null +++ b/drivers/leds/leds-tosa.c @@ -0,0 +1,131 @@ +/* + * LED Triggers Core + * + * Copyright 2005 Dirk Opfer + * + * Author: Dirk Opfer <Dirk@Opfer-Online.de> + * based on spitz.c + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + */ + +#include <linux/config.h> +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/platform_device.h> +#include <linux/leds.h> +#include <asm/hardware/scoop.h> +#include <asm/mach-types.h> +#include <asm/arch/hardware.h> +#include <asm/arch/pxa-regs.h> +#include <asm/arch/tosa.h> + +static void tosaled_amber_set(struct led_classdev *led_cdev, + enum led_brightness value) +{ + if (value) + set_scoop_gpio(&tosascoop_jc_device.dev, + TOSA_SCOOP_JC_CHRG_ERR_LED); + else + reset_scoop_gpio(&tosascoop_jc_device.dev, + TOSA_SCOOP_JC_CHRG_ERR_LED); +} + +static void tosaled_green_set(struct led_classdev *led_cdev, + enum led_brightness value) +{ + if (value) + set_scoop_gpio(&tosascoop_jc_device.dev, + TOSA_SCOOP_JC_NOTE_LED); + else + reset_scoop_gpio(&tosascoop_jc_device.dev, + TOSA_SCOOP_JC_NOTE_LED); +} + +static struct led_classdev tosa_amber_led = { + .name = "tosa:amber", + .default_trigger = "sharpsl-charge", + .brightness_set = tosaled_amber_set, +}; + +static struct led_classdev tosa_green_led = { + .name = "tosa:green", + .default_trigger = "nand-disk", + .brightness_set = tosaled_green_set, +}; + +#ifdef CONFIG_PM +static int tosaled_suspend(struct platform_device *dev, pm_message_t state) +{ +#ifdef CONFIG_LEDS_TRIGGERS + if (tosa_amber_led.trigger && strcmp(tosa_amber_led.trigger->name, + "sharpsl-charge")) +#endif + led_classdev_suspend(&tosa_amber_led); + led_classdev_suspend(&tosa_green_led); + return 0; +} + +static int tosaled_resume(struct platform_device *dev) +{ + led_classdev_resume(&tosa_amber_led); + led_classdev_resume(&tosa_green_led); + return 0; +} +#else +#define tosaled_suspend NULL +#define tosaled_resume NULL +#endif + +static int tosaled_probe(struct platform_device *pdev) +{ + int ret; + + ret = led_classdev_register(&pdev->dev, &tosa_amber_led); + if (ret < 0) + return ret; + + ret = led_classdev_register(&pdev->dev, &tosa_green_led); + if (ret < 0) + led_classdev_unregister(&tosa_amber_led); + + return ret; +} + +static int tosaled_remove(struct platform_device *pdev) +{ + led_classdev_unregister(&tosa_amber_led); + led_classdev_unregister(&tosa_green_led); + + return 0; +} + +static struct platform_driver tosaled_driver = { + .probe = tosaled_probe, + .remove = tosaled_remove, + .suspend = tosaled_suspend, + .resume = tosaled_resume, + .driver = { + .name = "tosa-led", + }, +}; + +static int __init tosaled_init(void) +{ + return platform_driver_register(&tosaled_driver); +} + +static void __exit tosaled_exit(void) +{ + platform_driver_unregister(&tosaled_driver); +} + +module_init(tosaled_init); +module_exit(tosaled_exit); + +MODULE_AUTHOR("Dirk Opfer <Dirk@Opfer-Online.de>"); +MODULE_DESCRIPTION("Tosa LED driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/leds/leds.h b/drivers/leds/leds.h new file mode 100644 index 00000000000..a715c4ed93f --- /dev/null +++ b/drivers/leds/leds.h @@ -0,0 +1,44 @@ +/* + * LED Core + * + * Copyright 2005 Openedhand Ltd. + * + * Author: Richard Purdie <rpurdie@openedhand.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + */ +#ifndef __LEDS_H_INCLUDED +#define __LEDS_H_INCLUDED + +#include <linux/leds.h> + +static inline void led_set_brightness(struct led_classdev *led_cdev, + enum led_brightness value) +{ + if (value > LED_FULL) + value = LED_FULL; + led_cdev->brightness = value; + if (!(led_cdev->flags & LED_SUSPENDED)) + led_cdev->brightness_set(led_cdev, value); +} + +extern rwlock_t leds_list_lock; +extern struct list_head leds_list; + +#ifdef CONFIG_LEDS_TRIGGERS +void led_trigger_set_default(struct led_classdev *led_cdev); +void led_trigger_set(struct led_classdev *led_cdev, + struct led_trigger *trigger); +#else +#define led_trigger_set_default(x) do {} while(0) +#define led_trigger_set(x, y) do {} while(0) +#endif + +ssize_t led_trigger_store(struct class_device *dev, const char *buf, + size_t count); +ssize_t led_trigger_show(struct class_device *dev, char *buf); + +#endif /* __LEDS_H_INCLUDED */ diff --git a/drivers/leds/ledtrig-ide-disk.c b/drivers/leds/ledtrig-ide-disk.c new file mode 100644 index 00000000000..fa651886ab4 --- /dev/null +++ b/drivers/leds/ledtrig-ide-disk.c @@ -0,0 +1,62 @@ +/* + * LED IDE-Disk Activity Trigger + * + * Copyright 2006 Openedhand Ltd. + * + * Author: Richard Purdie <rpurdie@openedhand.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + */ + +#include <linux/module.h> +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/timer.h> +#include <linux/leds.h> + +static void ledtrig_ide_timerfunc(unsigned long data); + +DEFINE_LED_TRIGGER(ledtrig_ide); +static DEFINE_TIMER(ledtrig_ide_timer, ledtrig_ide_timerfunc, 0, 0); +static int ide_activity; +static int ide_lastactivity; + +void ledtrig_ide_activity(void) +{ + ide_activity++; + if (!timer_pending(&ledtrig_ide_timer)) + mod_timer(&ledtrig_ide_timer, jiffies + msecs_to_jiffies(10)); +} +EXPORT_SYMBOL(ledtrig_ide_activity); + +static void ledtrig_ide_timerfunc(unsigned long data) +{ + if (ide_lastactivity != ide_activity) { + ide_lastactivity = ide_activity; + led_trigger_event(ledtrig_ide, LED_FULL); + mod_timer(&ledtrig_ide_timer, jiffies + msecs_to_jiffies(10)); + } else { + led_trigger_event(ledtrig_ide, LED_OFF); + } +} + +static int __init ledtrig_ide_init(void) +{ + led_trigger_register_simple("ide-disk", &ledtrig_ide); + return 0; +} + +static void __exit ledtrig_ide_exit(void) +{ + led_trigger_unregister_simple(ledtrig_ide); +} + +module_init(ledtrig_ide_init); +module_exit(ledtrig_ide_exit); + +MODULE_AUTHOR("Richard Purdie <rpurdie@openedhand.com>"); +MODULE_DESCRIPTION("LED IDE Disk Activity Trigger"); +MODULE_LICENSE("GPL"); diff --git a/drivers/leds/ledtrig-timer.c b/drivers/leds/ledtrig-timer.c new file mode 100644 index 00000000000..f484b5d6dbf --- /dev/null +++ b/drivers/leds/ledtrig-timer.c @@ -0,0 +1,170 @@ +/* + * LED Kernel Timer Trigger + * + * Copyright 2005-2006 Openedhand Ltd. + * + * Author: Richard Purdie <rpurdie@openedhand.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + */ + +#include <linux/config.h> +#include <linux/module.h> +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/list.h> +#include <linux/spinlock.h> +#include <linux/device.h> +#include <linux/sysdev.h> +#include <linux/timer.h> +#include <linux/leds.h> +#include "leds.h" + +struct timer_trig_data { + unsigned long delay_on; /* milliseconds on */ + unsigned long delay_off; /* milliseconds off */ + struct timer_list timer; +}; + +static void led_timer_function(unsigned long data) +{ + struct led_classdev *led_cdev = (struct led_classdev *) data; + struct timer_trig_data *timer_data = led_cdev->trigger_data; + unsigned long brightness = LED_OFF; + unsigned long delay = timer_data->delay_off; + + if (!timer_data->delay_on || !timer_data->delay_off) { + led_set_brightness(led_cdev, LED_OFF); + return; + } + + if (!led_cdev->brightness) { + brightness = LED_FULL; + delay = timer_data->delay_on; + } + + led_set_brightness(led_cdev, brightness); + + mod_timer(&timer_data->timer, jiffies + msecs_to_jiffies(delay)); +} + +static ssize_t led_delay_on_show(struct class_device *dev, char *buf) +{ + struct led_classdev *led_cdev = class_get_devdata(dev); + struct timer_trig_data *timer_data = led_cdev->trigger_data; + + sprintf(buf, "%lu\n", timer_data->delay_on); + + return strlen(buf) + 1; +} + +static ssize_t led_delay_on_store(struct class_device *dev, const char *buf, + size_t size) +{ + struct led_classdev *led_cdev = class_get_devdata(dev); + struct timer_trig_data *timer_data = led_cdev->trigger_data; + int ret = -EINVAL; + char *after; + unsigned long state = simple_strtoul(buf, &after, 10); + + if (after - buf > 0) { + timer_data->delay_on = state; + mod_timer(&timer_data->timer, jiffies + 1); + ret = after - buf; + } + + return ret; +} + +static ssize_t led_delay_off_show(struct class_device *dev, char *buf) +{ + struct led_classdev *led_cdev = class_get_devdata(dev); + struct timer_trig_data *timer_data = led_cdev->trigger_data; + + sprintf(buf, "%lu\n", timer_data->delay_off); + + return strlen(buf) + 1; +} + +static ssize_t led_delay_off_store(struct class_device *dev, const char *buf, + size_t size) +{ + struct led_classdev *led_cdev = class_get_devdata(dev); + struct timer_trig_data *timer_data = led_cdev->trigger_data; + int ret = -EINVAL; + char *after; + unsigned long state = simple_strtoul(buf, &after, 10); + + if (after - buf > 0) { + timer_data->delay_off = state; + mod_timer(&timer_data->timer, jiffies + 1); + ret = after - buf; + } + + return ret; +} + +static CLASS_DEVICE_ATTR(delay_on, 0644, led_delay_on_show, + led_delay_on_store); +static CLASS_DEVICE_ATTR(delay_off, 0644, led_delay_off_show, + led_delay_off_store); + +static void timer_trig_activate(struct led_classdev *led_cdev) +{ + struct timer_trig_data *timer_data; + + timer_data = kzalloc(sizeof(struct timer_trig_data), GFP_KERNEL); + if (!timer_data) + return; + + led_cdev->trigger_data = timer_data; + + init_timer(&timer_data->timer); + timer_data->timer.function = led_timer_function; + timer_data->timer.data = (unsigned long) led_cdev; + + class_device_create_file(led_cdev->class_dev, + &class_device_attr_delay_on); + class_device_create_file(led_cdev->class_dev, + &class_device_attr_delay_off); +} + +static void timer_trig_deactivate(struct led_classdev *led_cdev) +{ + struct timer_trig_data *timer_data = led_cdev->trigger_data; + + if (timer_data) { + class_device_remove_file(led_cdev->class_dev, + &class_device_attr_delay_on); + class_device_remove_file(led_cdev->class_dev, + &class_device_attr_delay_off); + del_timer_sync(&timer_data->timer); + kfree(timer_data); + } +} + +static struct led_trigger timer_led_trigger = { + .name = "timer", + .activate = timer_trig_activate, + .deactivate = timer_trig_deactivate, +}; + +static int __init timer_trig_init(void) +{ + return led_trigger_register(&timer_led_trigger); +} + +static void __exit timer_trig_exit(void) +{ + led_trigger_unregister(&timer_led_trigger); +} + +module_init(timer_trig_init); +module_exit(timer_trig_exit); + +MODULE_AUTHOR("Richard Purdie <rpurdie@openedhand.com>"); +MODULE_DESCRIPTION("Timer LED trigger"); +MODULE_LICENSE("GPL"); diff --git a/drivers/md/md.c b/drivers/md/md.c index 039e071c100..1ed5152db45 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c @@ -215,13 +215,11 @@ static void mddev_put(mddev_t *mddev) return; if (!mddev->raid_disks && list_empty(&mddev->disks)) { list_del(&mddev->all_mddevs); - /* that blocks */ + spin_unlock(&all_mddevs_lock); blk_cleanup_queue(mddev->queue); - /* that also blocks */ kobject_unregister(&mddev->kobj); - /* result blows... */ - } - spin_unlock(&all_mddevs_lock); + } else + spin_unlock(&all_mddevs_lock); } static mddev_t * mddev_find(dev_t unit) diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c index 3cb0872a845..9b374c91db6 100644 --- a/drivers/md/raid1.c +++ b/drivers/md/raid1.c @@ -1135,8 +1135,19 @@ static int end_sync_write(struct bio *bio, unsigned int bytes_done, int error) mirror = i; break; } - if (!uptodate) + if (!uptodate) { + int sync_blocks = 0; + sector_t s = r1_bio->sector; + long sectors_to_go = r1_bio->sectors; + /* make sure these bits doesn't get cleared. */ + do { + bitmap_end_sync(mddev->bitmap, r1_bio->sector, + &sync_blocks, 1); + s += sync_blocks; + sectors_to_go -= sync_blocks; + } while (sectors_to_go > 0); md_error(mddev, conf->mirrors[mirror].rdev); + } update_head_pos(mirror, r1_bio); diff --git a/drivers/md/raid6main.c b/drivers/md/raid6main.c index 6df4930fdde..ab64b37e499 100644 --- a/drivers/md/raid6main.c +++ b/drivers/md/raid6main.c @@ -2151,6 +2151,8 @@ static int run(mddev_t *mddev) } /* Ok, everything is just fine now */ + sysfs_create_group(&mddev->kobj, &raid6_attrs_group); + mddev->array_size = mddev->size * (mddev->raid_disks - 2); mddev->queue->unplug_fn = raid6_unplug_device; diff --git a/drivers/media/video/cpia_pp.c b/drivers/media/video/cpia_pp.c index 3021f21aae3..0b00e6027df 100644 --- a/drivers/media/video/cpia_pp.c +++ b/drivers/media/video/cpia_pp.c @@ -873,7 +873,7 @@ static int __init cpia_pp_setup(char *str) parport_nr[parport_ptr++] = PPCPIA_PARPORT_NONE; } - return 0; + return 1; } __setup("cpia_pp=", cpia_pp_setup); diff --git a/drivers/mmc/Kconfig b/drivers/mmc/Kconfig index 3f5d77f633f..7cc162e8978 100644 --- a/drivers/mmc/Kconfig +++ b/drivers/mmc/Kconfig @@ -60,6 +60,17 @@ config MMC_SDHCI If unsure, say N. +config MMC_OMAP + tristate "TI OMAP Multimedia Card Interface support" + depends on ARCH_OMAP && MMC + select TPS65010 if MACH_OMAP_H2 + help + This selects the TI OMAP Multimedia card Interface. + If you have an OMAP board with a Multimedia Card slot, + say Y or M here. + + If unsure, say N. + config MMC_WBSD tristate "Winbond W83L51xD SD/MMC Card Interface support" depends on MMC && ISA_DMA_API diff --git a/drivers/mmc/Makefile b/drivers/mmc/Makefile index 769d545284a..c7c34aadfc9 100644 --- a/drivers/mmc/Makefile +++ b/drivers/mmc/Makefile @@ -20,5 +20,10 @@ obj-$(CONFIG_MMC_PXA) += pxamci.o obj-$(CONFIG_MMC_SDHCI) += sdhci.o obj-$(CONFIG_MMC_WBSD) += wbsd.o obj-$(CONFIG_MMC_AU1X) += au1xmmc.o +obj-$(CONFIG_MMC_OMAP) += omap.o mmc_core-y := mmc.o mmc_queue.o mmc_sysfs.o + +ifeq ($(CONFIG_MMC_DEBUG),y) +EXTRA_CFLAGS += -DDEBUG +endif diff --git a/drivers/mmc/au1xmmc.c b/drivers/mmc/au1xmmc.c index 85e89c77bde..c0326bbc5f2 100644 --- a/drivers/mmc/au1xmmc.c +++ b/drivers/mmc/au1xmmc.c @@ -56,12 +56,11 @@ #define DRIVER_NAME "au1xxx-mmc" /* Set this to enable special debugging macros */ -/* #define MMC_DEBUG */ -#ifdef MMC_DEBUG -#define DEBUG(fmt, idx, args...) printk("au1xx(%d): DEBUG: " fmt, idx, ##args) +#ifdef DEBUG +#define DBG(fmt, idx, args...) printk("au1xx(%d): DEBUG: " fmt, idx, ##args) #else -#define DEBUG(fmt, idx, args...) +#define DBG(fmt, idx, args...) #endif const struct { @@ -424,18 +423,18 @@ static void au1xmmc_receive_pio(struct au1xmmc_host *host) break; if (status & SD_STATUS_RC) { - DEBUG("RX CRC Error [%d + %d].\n", host->id, + DBG("RX CRC Error [%d + %d].\n", host->id, host->pio.len, count); break; } if (status & SD_STATUS_RO) { - DEBUG("RX Overrun [%d + %d]\n", host->id, + DBG("RX Overrun [%d + %d]\n", host->id, host->pio.len, count); break; } else if (status & SD_STATUS_RU) { - DEBUG("RX Underrun [%d + %d]\n", host->id, + DBG("RX Underrun [%d + %d]\n", host->id, host->pio.len, count); break; } @@ -721,7 +720,7 @@ static void au1xmmc_set_ios(struct mmc_host* mmc, struct mmc_ios* ios) { struct au1xmmc_host *host = mmc_priv(mmc); - DEBUG("set_ios (power=%u, clock=%uHz, vdd=%u, mode=%u)\n", + DBG("set_ios (power=%u, clock=%uHz, vdd=%u, mode=%u)\n", host->id, ios->power_mode, ios->clock, ios->vdd, ios->bus_mode); @@ -810,7 +809,7 @@ static irqreturn_t au1xmmc_irq(int irq, void *dev_id, struct pt_regs *regs) au1xmmc_receive_pio(host); } else if (status & 0x203FBC70) { - DEBUG("Unhandled status %8.8x\n", host->id, status); + DBG("Unhandled status %8.8x\n", host->id, status); handled = 0; } @@ -839,7 +838,7 @@ static void au1xmmc_poll_event(unsigned long arg) if (host->mrq != NULL) { u32 status = au_readl(HOST_STATUS(host)); - DEBUG("PENDING - %8.8x\n", host->id, status); + DBG("PENDING - %8.8x\n", host->id, status); } mod_timer(&host->timer, jiffies + AU1XMMC_DETECT_TIMEOUT); diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c index 1888060c5e0..da6ddd910fc 100644 --- a/drivers/mmc/mmc.c +++ b/drivers/mmc/mmc.c @@ -27,12 +27,6 @@ #include "mmc.h" -#ifdef CONFIG_MMC_DEBUG -#define DBG(x...) printk(KERN_DEBUG x) -#else -#define DBG(x...) do { } while (0) -#endif - #define CMD_RETRIES 3 /* @@ -77,8 +71,9 @@ void mmc_request_done(struct mmc_host *host, struct mmc_request *mrq) { struct mmc_command *cmd = mrq->cmd; int err = mrq->cmd->error; - DBG("MMC: req done (%02x): %d: %08x %08x %08x %08x\n", cmd->opcode, - err, cmd->resp[0], cmd->resp[1], cmd->resp[2], cmd->resp[3]); + pr_debug("MMC: req done (%02x): %d: %08x %08x %08x %08x\n", + cmd->opcode, err, cmd->resp[0], cmd->resp[1], + cmd->resp[2], cmd->resp[3]); if (err && cmd->retries) { cmd->retries--; @@ -102,8 +97,8 @@ EXPORT_SYMBOL(mmc_request_done); void mmc_start_request(struct mmc_host *host, struct mmc_request *mrq) { - DBG("MMC: starting cmd %02x arg %08x flags %08x\n", - mrq->cmd->opcode, mrq->cmd->arg, mrq->cmd->flags); + pr_debug("MMC: starting cmd %02x arg %08x flags %08x\n", + mrq->cmd->opcode, mrq->cmd->arg, mrq->cmd->flags); WARN_ON(host->card_busy == NULL); @@ -976,8 +971,8 @@ static unsigned int mmc_calculate_clock(struct mmc_host *host) if (!mmc_card_dead(card) && max_dtr > card->csd.max_dtr) max_dtr = card->csd.max_dtr; - DBG("MMC: selected %d.%03dMHz transfer rate\n", - max_dtr / 1000000, (max_dtr / 1000) % 1000); + pr_debug("MMC: selected %d.%03dMHz transfer rate\n", + max_dtr / 1000000, (max_dtr / 1000) % 1000); return max_dtr; } diff --git a/drivers/mmc/mmci.c b/drivers/mmc/mmci.c index 9fef29d978b..df7e861e2fc 100644 --- a/drivers/mmc/mmci.c +++ b/drivers/mmc/mmci.c @@ -33,12 +33,8 @@ #define DRIVER_NAME "mmci-pl18x" -#ifdef CONFIG_MMC_DEBUG #define DBG(host,fmt,args...) \ pr_debug("%s: %s: " fmt, mmc_hostname(host->mmc), __func__ , args) -#else -#define DBG(host,fmt,args...) do { } while (0) -#endif static unsigned int fmax = 515633; diff --git a/drivers/mmc/omap.c b/drivers/mmc/omap.c new file mode 100644 index 00000000000..becb3c68c34 --- /dev/null +++ b/drivers/mmc/omap.c @@ -0,0 +1,1226 @@ +/* + * linux/drivers/media/mmc/omap.c + * + * Copyright (C) 2004 Nokia Corporation + * Written by Tuukka Tikkanen and Juha Yrjölä<juha.yrjola@nokia.com> + * Misc hacks here and there by Tony Lindgren <tony@atomide.com> + * Other hacks (DMA, SD, etc) by David Brownell + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include <linux/config.h> +#include <linux/module.h> +#include <linux/moduleparam.h> +#include <linux/init.h> +#include <linux/ioport.h> +#include <linux/platform_device.h> +#include <linux/interrupt.h> +#include <linux/dma-mapping.h> +#include <linux/delay.h> +#include <linux/spinlock.h> +#include <linux/timer.h> +#include <linux/mmc/host.h> +#include <linux/mmc/protocol.h> +#include <linux/mmc/card.h> +#include <linux/clk.h> + +#include <asm/io.h> +#include <asm/irq.h> +#include <asm/scatterlist.h> +#include <asm/mach-types.h> + +#include <asm/arch/board.h> +#include <asm/arch/gpio.h> +#include <asm/arch/dma.h> +#include <asm/arch/mux.h> +#include <asm/arch/fpga.h> +#include <asm/arch/tps65010.h> + +#include "omap.h" + +#define DRIVER_NAME "mmci-omap" +#define RSP_TYPE(x) ((x) & ~(MMC_RSP_BUSY|MMC_RSP_OPCODE)) + +/* Specifies how often in millisecs to poll for card status changes + * when the cover switch is open */ +#define OMAP_MMC_SWITCH_POLL_DELAY 500 + +static int mmc_omap_enable_poll = 1; + +struct mmc_omap_host { + int initialized; + int suspended; + struct mmc_request * mrq; + struct mmc_command * cmd; + struct mmc_data * data; + struct mmc_host * mmc; + struct device * dev; + unsigned char id; /* 16xx chips have 2 MMC blocks */ + struct clk * iclk; + struct clk * fclk; + void __iomem *base; + int irq; + unsigned char bus_mode; + unsigned char hw_bus_mode; + + unsigned int sg_len; + int sg_idx; + u16 * buffer; + u32 buffer_bytes_left; + u32 total_bytes_left; + + unsigned use_dma:1; + unsigned brs_received:1, dma_done:1; + unsigned dma_is_read:1; + unsigned dma_in_use:1; + int dma_ch; + spinlock_t dma_lock; + struct timer_list dma_timer; + unsigned dma_len; + + short power_pin; + short wp_pin; + + int switch_pin; + struct work_struct switch_work; + struct timer_list switch_timer; + int switch_last_state; +}; + +static inline int +mmc_omap_cover_is_open(struct mmc_omap_host *host) +{ + if (host->switch_pin < 0) + return 0; + return omap_get_gpio_datain(host->switch_pin); +} + +static ssize_t +mmc_omap_show_cover_switch(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct mmc_omap_host *host = dev_get_drvdata(dev); + + return sprintf(buf, "%s\n", mmc_omap_cover_is_open(host) ? "open" : + "closed"); +} + +static DEVICE_ATTR(cover_switch, S_IRUGO, mmc_omap_show_cover_switch, NULL); + +static ssize_t +mmc_omap_show_enable_poll(struct device *dev, + struct device_attribute *attr, char *buf) +{ + return snprintf(buf, PAGE_SIZE, "%d\n", mmc_omap_enable_poll); +} + +static ssize_t +mmc_omap_store_enable_poll(struct device *dev, + struct device_attribute *attr, const char *buf, + size_t size) +{ + int enable_poll; + + if (sscanf(buf, "%10d", &enable_poll) != 1) + return -EINVAL; + + if (enable_poll != mmc_omap_enable_poll) { + struct mmc_omap_host *host = dev_get_drvdata(dev); + + mmc_omap_enable_poll = enable_poll; + if (enable_poll && host->switch_pin >= 0) + schedule_work(&host->switch_work); + } + return size; +} + +static DEVICE_ATTR(enable_poll, 0664, + mmc_omap_show_enable_poll, mmc_omap_store_enable_poll); + +static void +mmc_omap_start_command(struct mmc_omap_host *host, struct mmc_command *cmd) +{ + u32 cmdreg; + u32 resptype; + u32 cmdtype; + + host->cmd = cmd; + + resptype = 0; + cmdtype = 0; + + /* Our hardware needs to know exact type */ + switch (RSP_TYPE(mmc_resp_type(cmd))) { + case RSP_TYPE(MMC_RSP_R1): + /* resp 1, resp 1b */ + resptype = 1; + break; + case RSP_TYPE(MMC_RSP_R2): + resptype = 2; + break; + case RSP_TYPE(MMC_RSP_R3): + resptype = 3; + break; + default: + break; + } + + if (mmc_cmd_type(cmd) == MMC_CMD_ADTC) { + cmdtype = OMAP_MMC_CMDTYPE_ADTC; + } else if (mmc_cmd_type(cmd) == MMC_CMD_BC) { + cmdtype = OMAP_MMC_CMDTYPE_BC; + } else if (mmc_cmd_type(cmd) == MMC_CMD_BCR) { + cmdtype = OMAP_MMC_CMDTYPE_BCR; + } else { + cmdtype = OMAP_MMC_CMDTYPE_AC; + } + + cmdreg = cmd->opcode | (resptype << 8) | (cmdtype << 12); + + if (host->bus_mode == MMC_BUSMODE_OPENDRAIN) + cmdreg |= 1 << 6; + + if (cmd->flags & MMC_RSP_BUSY) + cmdreg |= 1 << 11; + + if (host->data && !(host->data->flags & MMC_DATA_WRITE)) + cmdreg |= 1 << 15; + + clk_enable(host->fclk); + + OMAP_MMC_WRITE(host->base, CTO, 200); + OMAP_MMC_WRITE(host->base, ARGL, cmd->arg & 0xffff); + OMAP_MMC_WRITE(host->base, ARGH, cmd->arg >> 16); + OMAP_MMC_WRITE(host->base, IE, + OMAP_MMC_STAT_A_EMPTY | OMAP_MMC_STAT_A_FULL | + OMAP_MMC_STAT_CMD_CRC | OMAP_MMC_STAT_CMD_TOUT | + OMAP_MMC_STAT_DATA_CRC | OMAP_MMC_STAT_DATA_TOUT | + OMAP_MMC_STAT_END_OF_CMD | OMAP_MMC_STAT_CARD_ERR | + OMAP_MMC_STAT_END_OF_DATA); + OMAP_MMC_WRITE(host->base, CMD, cmdreg); +} + +static void +mmc_omap_xfer_done(struct mmc_omap_host *host, struct mmc_data *data) +{ + if (host->dma_in_use) { + enum dma_data_direction dma_data_dir; + + BUG_ON(host->dma_ch < 0); + if (data->error != MMC_ERR_NONE) + omap_stop_dma(host->dma_ch); + /* Release DMA channel lazily */ + mod_timer(&host->dma_timer, jiffies + HZ); + if (data->flags & MMC_DATA_WRITE) + dma_data_dir = DMA_TO_DEVICE; + else + dma_data_dir = DMA_FROM_DEVICE; + dma_unmap_sg(mmc_dev(host->mmc), data->sg, host->sg_len, + dma_data_dir); + } + host->data = NULL; + host->sg_len = 0; + clk_disable(host->fclk); + + /* NOTE: MMC layer will sometimes poll-wait CMD13 next, issuing + * dozens of requests until the card finishes writing data. + * It'd be cheaper to just wait till an EOFB interrupt arrives... + */ + + if (!data->stop) { + host->mrq = NULL; + mmc_request_done(host->mmc, data->mrq); + return; + } + + mmc_omap_start_command(host, data->stop); +} + +static void +mmc_omap_end_of_data(struct mmc_omap_host *host, struct mmc_data *data) +{ + unsigned long flags; + int done; + + if (!host->dma_in_use) { + mmc_omap_xfer_done(host, data); + return; + } + done = 0; + spin_lock_irqsave(&host->dma_lock, flags); + if (host->dma_done) + done = 1; + else + host->brs_received = 1; + spin_unlock_irqrestore(&host->dma_lock, flags); + if (done) + mmc_omap_xfer_done(host, data); +} + +static void +mmc_omap_dma_timer(unsigned long data) +{ + struct mmc_omap_host *host = (struct mmc_omap_host *) data; + + BUG_ON(host->dma_ch < 0); + omap_free_dma(host->dma_ch); + host->dma_ch = -1; +} + +static void +mmc_omap_dma_done(struct mmc_omap_host *host, struct mmc_data *data) +{ + unsigned long flags; + int done; + + done = 0; + spin_lock_irqsave(&host->dma_lock, flags); + if (host->brs_received) + done = 1; + else + host->dma_done = 1; + spin_unlock_irqrestore(&host->dma_lock, flags); + if (done) + mmc_omap_xfer_done(host, data); +} + +static void +mmc_omap_cmd_done(struct mmc_omap_host *host, struct mmc_command *cmd) +{ + host->cmd = NULL; + + if (cmd->flags & MMC_RSP_PRESENT) { + if (cmd->flags & MMC_RSP_136) { + /* response type 2 */ + cmd->resp[3] = + OMAP_MMC_READ(host->base, RSP0) | + (OMAP_MMC_READ(host->base, RSP1) << 16); + cmd->resp[2] = + OMAP_MMC_READ(host->base, RSP2) | + (OMAP_MMC_READ(host->base, RSP3) << 16); + cmd->resp[1] = + OMAP_MMC_READ(host->base, RSP4) | + (OMAP_MMC_READ(host->base, RSP5) << 16); + cmd->resp[0] = + OMAP_MMC_READ(host->base, RSP6) | + (OMAP_MMC_READ(host->base, RSP7) << 16); + } else { + /* response types 1, 1b, 3, 4, 5, 6 */ + cmd->resp[0] = + OMAP_MMC_READ(host->base, RSP6) | + (OMAP_MMC_READ(host->base, RSP7) << 16); + } + } + + if (host->data == NULL || cmd->error != MMC_ERR_NONE) { + host->mrq = NULL; + clk_disable(host->fclk); + mmc_request_done(host->mmc, cmd->mrq); + } +} + +/* PIO only */ +static void +mmc_omap_sg_to_buf(struct mmc_omap_host *host) +{ + struct scatterlist *sg; + + sg = host->data->sg + host->sg_idx; + host->buffer_bytes_left = sg->length; + host->buffer = page_address(sg->page) + sg->offset; + if (host->buffer_bytes_left > host->total_bytes_left) + host->buffer_bytes_left = host->total_bytes_left; +} + +/* PIO only */ +static void +mmc_omap_xfer_data(struct mmc_omap_host *host, int write) +{ + int n; + void __iomem *reg; + u16 *p; + + if (host->buffer_bytes_left == 0) { + host->sg_idx++; + BUG_ON(host->sg_idx == host->sg_len); + mmc_omap_sg_to_buf(host); + } + n = 64; + if (n > host->buffer_bytes_left) + n = host->buffer_bytes_left; + host->buffer_bytes_left -= n; + host->total_bytes_left -= n; + host->data->bytes_xfered += n; + + if (write) { + __raw_writesw(host->base + OMAP_MMC_REG_DATA, host->buffer, n); + } else { + __raw_readsw(host->base + OMAP_MMC_REG_DATA, host->buffer, n); + } +} + +static inline void mmc_omap_report_irq(u16 status) +{ + static const char *mmc_omap_status_bits[] = { + "EOC", "CD", "CB", "BRS", "EOFB", "DTO", "DCRC", "CTO", + "CCRC", "CRW", "AF", "AE", "OCRB", "CIRQ", "CERR" + }; + int i, c = 0; + + for (i = 0; i < ARRAY_SIZE(mmc_omap_status_bits); i++) + if (status & (1 << i)) { + if (c) + printk(" "); + printk("%s", mmc_omap_status_bits[i]); + c++; + } +} + +static irqreturn_t mmc_omap_irq(int irq, void *dev_id, struct pt_regs *regs) +{ + struct mmc_omap_host * host = (struct mmc_omap_host *)dev_id; + u16 status; + int end_command; + int end_transfer; + int transfer_error; + + if (host->cmd == NULL && host->data == NULL) { + status = OMAP_MMC_READ(host->base, STAT); + dev_info(mmc_dev(host->mmc),"spurious irq 0x%04x\n", status); + if (status != 0) { + OMAP_MMC_WRITE(host->base, STAT, status); + OMAP_MMC_WRITE(host->base, IE, 0); + } + return IRQ_HANDLED; + } + + end_command = 0; + end_transfer = 0; + transfer_error = 0; + + while ((status = OMAP_MMC_READ(host->base, STAT)) != 0) { + OMAP_MMC_WRITE(host->base, STAT, status); +#ifdef CONFIG_MMC_DEBUG + dev_dbg(mmc_dev(host->mmc), "MMC IRQ %04x (CMD %d): ", + status, host->cmd != NULL ? host->cmd->opcode : -1); + mmc_omap_report_irq(status); + printk("\n"); +#endif + if (host->total_bytes_left) { + if ((status & OMAP_MMC_STAT_A_FULL) || + (status & OMAP_MMC_STAT_END_OF_DATA)) + mmc_omap_xfer_data(host, 0); + if (status & OMAP_MMC_STAT_A_EMPTY) + mmc_omap_xfer_data(host, 1); + } + + if (status & OMAP_MMC_STAT_END_OF_DATA) { + end_transfer = 1; + } + + if (status & OMAP_MMC_STAT_DATA_TOUT) { + dev_dbg(mmc_dev(host->mmc), "data timeout\n"); + if (host->data) { + host->data->error |= MMC_ERR_TIMEOUT; + transfer_error = 1; + } + } + + if (status & OMAP_MMC_STAT_DATA_CRC) { + if (host->data) { + host->data->error |= MMC_ERR_BADCRC; + dev_dbg(mmc_dev(host->mmc), + "data CRC error, bytes left %d\n", + host->total_bytes_left); + transfer_error = 1; + } else { + dev_dbg(mmc_dev(host->mmc), "data CRC error\n"); + } + } + + if (status & OMAP_MMC_STAT_CMD_TOUT) { + /* Timeouts are routine with some commands */ + if (host->cmd) { + if (host->cmd->opcode != MMC_ALL_SEND_CID && + host->cmd->opcode != + MMC_SEND_OP_COND && + host->cmd->opcode != + MMC_APP_CMD && + !mmc_omap_cover_is_open(host)) + dev_err(mmc_dev(host->mmc), + "command timeout, CMD %d\n", + host->cmd->opcode); + host->cmd->error = MMC_ERR_TIMEOUT; + end_command = 1; + } + } + + if (status & OMAP_MMC_STAT_CMD_CRC) { + if (host->cmd) { + dev_err(mmc_dev(host->mmc), + "command CRC error (CMD%d, arg 0x%08x)\n", + host->cmd->opcode, host->cmd->arg); + host->cmd->error = MMC_ERR_BADCRC; + end_command = 1; + } else + dev_err(mmc_dev(host->mmc), + "command CRC error without cmd?\n"); + } + + if (status & OMAP_MMC_STAT_CARD_ERR) { + if (host->cmd && host->cmd->opcode == MMC_STOP_TRANSMISSION) { + u32 response = OMAP_MMC_READ(host->base, RSP6) + | (OMAP_MMC_READ(host->base, RSP7) << 16); + /* STOP sometimes sets must-ignore bits */ + if (!(response & (R1_CC_ERROR + | R1_ILLEGAL_COMMAND + | R1_COM_CRC_ERROR))) { + end_command = 1; + continue; + } + } + + dev_dbg(mmc_dev(host->mmc), "card status error (CMD%d)\n", + host->cmd->opcode); + if (host->cmd) { + host->cmd->error = MMC_ERR_FAILED; + end_command = 1; + } + if (host->data) { + host->data->error = MMC_ERR_FAILED; + transfer_error = 1; + } + } + + /* + * NOTE: On 1610 the END_OF_CMD may come too early when + * starting a write + */ + if ((status & OMAP_MMC_STAT_END_OF_CMD) && + (!(status & OMAP_MMC_STAT_A_EMPTY))) { + end_command = 1; + } + } + + if (end_command) { + mmc_omap_cmd_done(host, host->cmd); + } + if (transfer_error) + mmc_omap_xfer_done(host, host->data); + else if (end_transfer) + mmc_omap_end_of_data(host, host->data); + + return IRQ_HANDLED; +} + +static irqreturn_t mmc_omap_switch_irq(int irq, void *dev_id, struct pt_regs *regs) +{ + struct mmc_omap_host *host = (struct mmc_omap_host *) dev_id; + + schedule_work(&host->switch_work); + + return IRQ_HANDLED; +} + +static void mmc_omap_switch_timer(unsigned long arg) +{ + struct mmc_omap_host *host = (struct mmc_omap_host *) arg; + + schedule_work(&host->switch_work); +} + +/* FIXME: Handle card insertion and removal properly. Maybe use a mask + * for MMC state? */ +static void mmc_omap_switch_callback(unsigned long data, u8 mmc_mask) +{ +} + +static void mmc_omap_switch_handler(void *data) +{ + struct mmc_omap_host *host = (struct mmc_omap_host *) data; + struct mmc_card *card; + static int complained = 0; + int cards = 0, cover_open; + + if (host->switch_pin == -1) + return; + cover_open = mmc_omap_cover_is_open(host); + if (cover_open != host->switch_last_state) { + kobject_uevent(&host->dev->kobj, KOBJ_CHANGE); + host->switch_last_state = cover_open; + } + mmc_detect_change(host->mmc, 0); + list_for_each_entry(card, &host->mmc->cards, node) { + if (mmc_card_present(card)) + cards++; + } + if (mmc_omap_cover_is_open(host)) { + if (!complained) { + dev_info(mmc_dev(host->mmc), "cover is open"); + complained = 1; + } + if (mmc_omap_enable_poll) + mod_timer(&host->switch_timer, jiffies + + msecs_to_jiffies(OMAP_MMC_SWITCH_POLL_DELAY)); + } else { + complained = 0; + } +} + +/* Prepare to transfer the next segment of a scatterlist */ +static void +mmc_omap_prepare_dma(struct mmc_omap_host *host, struct mmc_data *data) +{ + int dma_ch = host->dma_ch; + unsigned long data_addr; + u16 buf, frame; + u32 count; + struct scatterlist *sg = &data->sg[host->sg_idx]; + int src_port = 0; + int dst_port = 0; + int sync_dev = 0; + + data_addr = io_v2p((u32) host->base) + OMAP_MMC_REG_DATA; + frame = 1 << data->blksz_bits; + count = sg_dma_len(sg); + + if ((data->blocks == 1) && (count > (1 << data->blksz_bits))) + count = frame; + + host->dma_len = count; + + /* FIFO is 16x2 bytes on 15xx, and 32x2 bytes on 16xx and 24xx. + * Use 16 or 32 word frames when the blocksize is at least that large. + * Blocksize is usually 512 bytes; but not for some SD reads. + */ + if (cpu_is_omap15xx() && frame > 32) + frame = 32; + else if (frame > 64) + frame = 64; + count /= frame; + frame >>= 1; + + if (!(data->flags & MMC_DATA_WRITE)) { + buf = 0x800f | ((frame - 1) << 8); + + if (cpu_class_is_omap1()) { + src_port = OMAP_DMA_PORT_TIPB; + dst_port = OMAP_DMA_PORT_EMIFF; + } + if (cpu_is_omap24xx()) + sync_dev = OMAP24XX_DMA_MMC1_RX; + + omap_set_dma_src_params(dma_ch, src_port, + OMAP_DMA_AMODE_CONSTANT, + data_addr, 0, 0); + omap_set_dma_dest_params(dma_ch, dst_port, + OMAP_DMA_AMODE_POST_INC, + sg_dma_address(sg), 0, 0); + omap_set_dma_dest_data_pack(dma_ch, 1); + omap_set_dma_dest_burst_mode(dma_ch, OMAP_DMA_DATA_BURST_4); + } else { + buf = 0x0f80 | ((frame - 1) << 0); + + if (cpu_class_is_omap1()) { + src_port = OMAP_DMA_PORT_EMIFF; + dst_port = OMAP_DMA_PORT_TIPB; + } + if (cpu_is_omap24xx()) + sync_dev = OMAP24XX_DMA_MMC1_TX; + + omap_set_dma_dest_params(dma_ch, dst_port, + OMAP_DMA_AMODE_CONSTANT, + data_addr, 0, 0); + omap_set_dma_src_params(dma_ch, src_port, + OMAP_DMA_AMODE_POST_INC, + sg_dma_address(sg), 0, 0); + omap_set_dma_src_data_pack(dma_ch, 1); + omap_set_dma_src_burst_mode(dma_ch, OMAP_DMA_DATA_BURST_4); + } + + /* Max limit for DMA frame count is 0xffff */ + if (unlikely(count > 0xffff)) + BUG(); + + OMAP_MMC_WRITE(host->base, BUF, buf); + omap_set_dma_transfer_params(dma_ch, OMAP_DMA_DATA_TYPE_S16, + frame, count, OMAP_DMA_SYNC_FRAME, + sync_dev, 0); +} + +/* A scatterlist segment completed */ +static void mmc_omap_dma_cb(int lch, u16 ch_status, void *data) +{ + struct mmc_omap_host *host = (struct mmc_omap_host *) data; + struct mmc_data *mmcdat = host->data; + + if (unlikely(host->dma_ch < 0)) { + dev_err(mmc_dev(host->mmc), "DMA callback while DMA not + enabled\n"); + return; + } + /* FIXME: We really should do something to _handle_ the errors */ + if (ch_status & OMAP_DMA_TOUT_IRQ) { + dev_err(mmc_dev(host->mmc),"DMA timeout\n"); + return; + } + if (ch_status & OMAP_DMA_DROP_IRQ) { + dev_err(mmc_dev(host->mmc), "DMA sync error\n"); + return; + } + if (!(ch_status & OMAP_DMA_BLOCK_IRQ)) { + return; + } + mmcdat->bytes_xfered += host->dma_len; + host->sg_idx++; + if (host->sg_idx < host->sg_len) { + mmc_omap_prepare_dma(host, host->data); + omap_start_dma(host->dma_ch); + } else + mmc_omap_dma_done(host, host->data); +} + +static int mmc_omap_get_dma_channel(struct mmc_omap_host *host, struct mmc_data *data) +{ + const char *dev_name; + int sync_dev, dma_ch, is_read, r; + + is_read = !(data->flags & MMC_DATA_WRITE); + del_timer_sync(&host->dma_timer); + if (host->dma_ch >= 0) { + if (is_read == host->dma_is_read) + return 0; + omap_free_dma(host->dma_ch); + host->dma_ch = -1; + } + + if (is_read) { + if (host->id == 1) { + sync_dev = OMAP_DMA_MMC_RX; + dev_name = "MMC1 read"; + } else { + sync_dev = OMAP_DMA_MMC2_RX; + dev_name = "MMC2 read"; + } + } else { + if (host->id == 1) { + sync_dev = OMAP_DMA_MMC_TX; + dev_name = "MMC1 write"; + } else { + sync_dev = OMAP_DMA_MMC2_TX; + dev_name = "MMC2 write"; + } + } + r = omap_request_dma(sync_dev, dev_name, mmc_omap_dma_cb, + host, &dma_ch); + if (r != 0) { + dev_dbg(mmc_dev(host->mmc), "omap_request_dma() failed with %d\n", r); + return r; + } + host->dma_ch = dma_ch; + host->dma_is_read = is_read; + + return 0; +} + +static inline void set_cmd_timeout(struct mmc_omap_host *host, struct mmc_request *req) +{ + u16 reg; + + reg = OMAP_MMC_READ(host->base, SDIO); + reg &= ~(1 << 5); + OMAP_MMC_WRITE(host->base, SDIO, reg); + /* Set maximum timeout */ + OMAP_MMC_WRITE(host->base, CTO, 0xff); +} + +static inline void set_data_timeout(struct mmc_omap_host *host, struct mmc_request *req) +{ + int timeout; + u16 reg; + + /* Convert ns to clock cycles by assuming 20MHz frequency + * 1 cycle at 20MHz = 500 ns + */ + timeout = req->data->timeout_clks + req->data->timeout_ns / 500; + + /* Check if we need to use timeout multiplier register */ + reg = OMAP_MMC_READ(host->base, SDIO); + if (timeout > 0xffff) { + reg |= (1 << 5); + timeout /= 1024; + } else + reg &= ~(1 << 5); + OMAP_MMC_WRITE(host->base, SDIO, reg); + OMAP_MMC_WRITE(host->base, DTO, timeout); +} + +static void +mmc_omap_prepare_data(struct mmc_omap_host *host, struct mmc_request *req) +{ + struct mmc_data *data = req->data; + int i, use_dma, block_size; + unsigned sg_len; + + host->data = data; + if (data == NULL) { + OMAP_MMC_WRITE(host->base, BLEN, 0); + OMAP_MMC_WRITE(host->base, NBLK, 0); + OMAP_MMC_WRITE(host->base, BUF, 0); + host->dma_in_use = 0; + set_cmd_timeout(host, req); + return; + } + + + block_size = 1 << data->blksz_bits; + + OMAP_MMC_WRITE(host->base, NBLK, data->blocks - 1); + OMAP_MMC_WRITE(host->base, BLEN, block_size - 1); + set_data_timeout(host, req); + + /* cope with calling layer confusion; it issues "single + * block" writes using multi-block scatterlists. + */ + sg_len = (data->blocks == 1) ? 1 : data->sg_len; + + /* Only do DMA for entire blocks */ + use_dma = host->use_dma; + if (use_dma) { + for (i = 0; i < sg_len; i++) { + if ((data->sg[i].length % block_size) != 0) { + use_dma = 0; + break; + } + } + } + + host->sg_idx = 0; + if (use_dma) { + if (mmc_omap_get_dma_channel(host, data) == 0) { + enum dma_data_direction dma_data_dir; + + if (data->flags & MMC_DATA_WRITE) + dma_data_dir = DMA_TO_DEVICE; + else + dma_data_dir = DMA_FROM_DEVICE; + + host->sg_len = dma_map_sg(mmc_dev(host->mmc), data->sg, + sg_len, dma_data_dir); + host->total_bytes_left = 0; + mmc_omap_prepare_dma(host, req->data); + host->brs_received = 0; + host->dma_done = 0; + host->dma_in_use = 1; + } else + use_dma = 0; + } + + /* Revert to PIO? */ + if (!use_dma) { + OMAP_MMC_WRITE(host->base, BUF, 0x1f1f); + host->total_bytes_left = data->blocks * block_size; + host->sg_len = sg_len; + mmc_omap_sg_to_buf(host); + host->dma_in_use = 0; + } +} + +static void mmc_omap_request(struct mmc_host *mmc, struct mmc_request *req) +{ + struct mmc_omap_host *host = mmc_priv(mmc); + + WARN_ON(host->mrq != NULL); + + host->mrq = req; + + /* only touch fifo AFTER the controller readies it */ + mmc_omap_prepare_data(host, req); + mmc_omap_start_command(host, req->cmd); + if (host->dma_in_use) + omap_start_dma(host->dma_ch); +} + +static void innovator_fpga_socket_power(int on) +{ +#if defined(CONFIG_MACH_OMAP_INNOVATOR) && defined(CONFIG_ARCH_OMAP15XX) + + if (on) { + fpga_write(fpga_read(OMAP1510_FPGA_POWER) | (1 << 3), + OMAP1510_FPGA_POWER); + } else { + fpga_write(fpga_read(OMAP1510_FPGA_POWER) & ~(1 << 3), + OMAP1510_FPGA_POWER); + } +#endif +} + +/* + * Turn the socket power on/off. Innovator uses FPGA, most boards + * probably use GPIO. + */ +static void mmc_omap_power(struct mmc_omap_host *host, int on) +{ + if (on) { + if (machine_is_omap_innovator()) + innovator_fpga_socket_power(1); + else if (machine_is_omap_h2()) + tps65010_set_gpio_out_value(GPIO3, HIGH); + else if (machine_is_omap_h3()) + /* GPIO 4 of TPS65010 sends SD_EN signal */ + tps65010_set_gpio_out_value(GPIO4, HIGH); + else if (cpu_is_omap24xx()) { + u16 reg = OMAP_MMC_READ(host->base, CON); + OMAP_MMC_WRITE(host->base, CON, reg | (1 << 11)); + } else + if (host->power_pin >= 0) + omap_set_gpio_dataout(host->power_pin, 1); + } else { + if (machine_is_omap_innovator()) + innovator_fpga_socket_power(0); + else if (machine_is_omap_h2()) + tps65010_set_gpio_out_value(GPIO3, LOW); + else if (machine_is_omap_h3()) + tps65010_set_gpio_out_value(GPIO4, LOW); + else if (cpu_is_omap24xx()) { + u16 reg = OMAP_MMC_READ(host->base, CON); + OMAP_MMC_WRITE(host->base, CON, reg & ~(1 << 11)); + } else + if (host->power_pin >= 0) + omap_set_gpio_dataout(host->power_pin, 0); + } +} + +static void mmc_omap_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) +{ + struct mmc_omap_host *host = mmc_priv(mmc); + int dsor; + int realclock, i; + + realclock = ios->clock; + + if (ios->clock == 0) + dsor = 0; + else { + int func_clk_rate = clk_get_rate(host->fclk); + + dsor = func_clk_rate / realclock; + if (dsor < 1) + dsor = 1; + + if (func_clk_rate / dsor > realclock) + dsor++; + + if (dsor > 250) + dsor = 250; + dsor++; + + if (ios->bus_width == MMC_BUS_WIDTH_4) + dsor |= 1 << 15; + } + + switch (ios->power_mode) { + case MMC_POWER_OFF: + mmc_omap_power(host, 0); + break; + case MMC_POWER_UP: + case MMC_POWER_ON: + mmc_omap_power(host, 1); + dsor |= 1<<11; + break; + } + + host->bus_mode = ios->bus_mode; + host->hw_bus_mode = host->bus_mode; + + clk_enable(host->fclk); + + /* On insanely high arm_per frequencies something sometimes + * goes somehow out of sync, and the POW bit is not being set, + * which results in the while loop below getting stuck. + * Writing to the CON register twice seems to do the trick. */ + for (i = 0; i < 2; i++) + OMAP_MMC_WRITE(host->base, CON, dsor); + if (ios->power_mode == MMC_POWER_UP) { + /* Send clock cycles, poll completion */ + OMAP_MMC_WRITE(host->base, IE, 0); + OMAP_MMC_WRITE(host->base, STAT, 0xffff); + OMAP_MMC_WRITE(host->base, CMD, 1<<7); + while (0 == (OMAP_MMC_READ(host->base, STAT) & 1)); + OMAP_MMC_WRITE(host->base, STAT, 1); + } + clk_disable(host->fclk); +} + +static int mmc_omap_get_ro(struct mmc_host *mmc) +{ + struct mmc_omap_host *host = mmc_priv(mmc); + + return host->wp_pin && omap_get_gpio_datain(host->wp_pin); +} + +static struct mmc_host_ops mmc_omap_ops = { + .request = mmc_omap_request, + .set_ios = mmc_omap_set_ios, + .get_ro = mmc_omap_get_ro, +}; + +static int __init mmc_omap_probe(struct platform_device *pdev) +{ + struct omap_mmc_conf *minfo = pdev->dev.platform_data; + struct mmc_host *mmc; + struct mmc_omap_host *host = NULL; + int ret = 0; + + if (platform_get_resource(pdev, IORESOURCE_MEM, 0) || + platform_get_irq(pdev, IORESOURCE_IRQ, 0)) { + dev_err(&pdev->dev, "mmc_omap_probe: invalid resource type\n"); + return -ENODEV; + } + + if (!request_mem_region(pdev->resource[0].start, + pdev->resource[0].end - pdev->resource[0].start + 1, + pdev->name)) { + dev_dbg(&pdev->dev, "request_mem_region failed\n"); + return -EBUSY; + } + + mmc = mmc_alloc_host(sizeof(struct mmc_omap_host), &pdev->dev); + if (!mmc) { + ret = -ENOMEM; + goto out; + } + + host = mmc_priv(mmc); + host->mmc = mmc; + + spin_lock_init(&host->dma_lock); + init_timer(&host->dma_timer); + host->dma_timer.function = mmc_omap_dma_timer; + host->dma_timer.data = (unsigned long) host; + + host->id = pdev->id; + + if (cpu_is_omap24xx()) { + host->iclk = clk_get(&pdev->dev, "mmc_ick"); + if (IS_ERR(host->iclk)) + goto out; + clk_enable(host->iclk); + } + + if (!cpu_is_omap24xx()) + host->fclk = clk_get(&pdev->dev, "mmc_ck"); + else + host->fclk = clk_get(&pdev->dev, "mmc_fck"); + + if (IS_ERR(host->fclk)) { + ret = PTR_ERR(host->fclk); + goto out; + } + + /* REVISIT: + * Also, use minfo->cover to decide how to manage + * the card detect sensing. + */ + host->power_pin = minfo->power_pin; + host->switch_pin = minfo->switch_pin; + host->wp_pin = minfo->wp_pin; + host->use_dma = 1; + host->dma_ch = -1; + + host->irq = pdev->resource[1].start; + host->base = ioremap(pdev->res.start, SZ_4K); + if (!host->base) { + ret = -ENOMEM; + goto out; + } + + if (minfo->wire4) + mmc->caps |= MMC_CAP_4_BIT_DATA; + + mmc->ops = &mmc_omap_ops; + mmc->f_min = 400000; + mmc->f_max = 24000000; + mmc->ocr_avail = MMC_VDD_32_33|MMC_VDD_33_34; + + /* Use scatterlist DMA to reduce per-transfer costs. + * NOTE max_seg_size assumption that small blocks aren't + * normally used (except e.g. for reading SD registers). + */ + mmc->max_phys_segs = 32; + mmc->max_hw_segs = 32; + mmc->max_sectors = 256; /* NBLK max 11-bits, OMAP also limited by DMA */ + mmc->max_seg_size = mmc->max_sectors * 512; + + if (host->power_pin >= 0) { + if ((ret = omap_request_gpio(host->power_pin)) != 0) { + dev_err(mmc_dev(host->mmc), "Unable to get GPIO + pin for MMC power\n"); + goto out; + } + omap_set_gpio_direction(host->power_pin, 0); + } + + ret = request_irq(host->irq, mmc_omap_irq, 0, DRIVER_NAME, host); + if (ret) + goto out; + + host->dev = &pdev->dev; + platform_set_drvdata(pdev, host); + + mmc_add_host(mmc); + + if (host->switch_pin >= 0) { + INIT_WORK(&host->switch_work, mmc_omap_switch_handler, host); + init_timer(&host->switch_timer); + host->switch_timer.function = mmc_omap_switch_timer; + host->switch_timer.data = (unsigned long) host; + if (omap_request_gpio(host->switch_pin) != 0) { + dev_warn(mmc_dev(host->mmc), "Unable to get GPIO pin for MMC cover switch\n"); + host->switch_pin = -1; + goto no_switch; + } + + omap_set_gpio_direction(host->switch_pin, 1); + ret = request_irq(OMAP_GPIO_IRQ(host->switch_pin), + mmc_omap_switch_irq, SA_TRIGGER_RISING, DRIVER_NAME, host); + if (ret) { + dev_warn(mmc_dev(host->mmc), "Unable to get IRQ for MMC cover switch\n"); + omap_free_gpio(host->switch_pin); + host->switch_pin = -1; + goto no_switch; + } + ret = device_create_file(&pdev->dev, &dev_attr_cover_switch); + if (ret == 0) { + ret = device_create_file(&pdev->dev, &dev_attr_enable_poll); + if (ret != 0) + device_remove_file(&pdev->dev, &dev_attr_cover_switch); + } + if (ret) { + dev_wan(mmc_dev(host->mmc), "Unable to create sysfs attributes\n"); + free_irq(OMAP_GPIO_IRQ(host->switch_pin), host); + omap_free_gpio(host->switch_pin); + host->switch_pin = -1; + goto no_switch; + } + if (mmc_omap_enable_poll && mmc_omap_cover_is_open(host)) + schedule_work(&host->switch_work); + } + +no_switch: + return 0; + +out: + /* FIXME: Free other resources too. */ + if (host) { + if (host->iclk && !IS_ERR(host->iclk)) + clk_put(host->iclk); + if (host->fclk && !IS_ERR(host->fclk)) + clk_put(host->fclk); + mmc_free_host(host->mmc); + } + return ret; +} + +static int mmc_omap_remove(struct platform_device *pdev) +{ + struct mmc_omap_host *host = platform_get_drvdata(pdev); + + platform_set_drvdata(pdev, NULL); + + if (host) { + mmc_remove_host(host->mmc); + free_irq(host->irq, host); + + if (host->power_pin >= 0) + omap_free_gpio(host->power_pin); + if (host->switch_pin >= 0) { + device_remove_file(&pdev->dev, &dev_attr_enable_poll); + device_remove_file(&pdev->dev, &dev_attr_cover_switch); + free_irq(OMAP_GPIO_IRQ(host->switch_pin), host); + omap_free_gpio(host->switch_pin); + host->switch_pin = -1; + del_timer_sync(&host->switch_timer); + flush_scheduled_work(); + } + if (host->iclk && !IS_ERR(host->iclk)) + clk_put(host->iclk); + if (host->fclk && !IS_ERR(host->fclk)) + clk_put(host->fclk); + mmc_free_host(host->mmc); + } + + release_mem_region(pdev->resource[0].start, + pdev->resource[0].end - pdev->resource[0].start + 1); + + return 0; +} + +#ifdef CONFIG_PM +static int mmc_omap_suspend(struct platform_device *pdev, pm_message_t mesg) +{ + int ret = 0; + struct mmc_omap_host *host = platform_get_drvdata(pdev); + + if (host && host->suspended) + return 0; + + if (host) { + ret = mmc_suspend_host(host->mmc, mesg); + if (ret == 0) + host->suspended = 1; + } + return ret; +} + +static int mmc_omap_resume(struct platform_device *pdev) +{ + int ret = 0; + struct mmc_omap_host *host = platform_get_drvdata(pdev); + + if (host && !host->suspended) + return 0; + + if (host) { + ret = mmc_resume_host(host->mmc); + if (ret == 0) + host->suspended = 0; + } + + return ret; +} +#else +#define mmc_omap_suspend NULL +#define mmc_omap_resume NULL +#endif + +static struct platform_driver mmc_omap_driver = { + .probe = mmc_omap_probe, + .remove = mmc_omap_remove, + .suspend = mmc_omap_suspend, + .resume = mmc_omap_resume, + .driver = { + .name = DRIVER_NAME, + }, +}; + +static int __init mmc_omap_init(void) +{ + return platform_driver_register(&mmc_omap_driver); +} + +static void __exit mmc_omap_exit(void) +{ + platform_driver_unregister(&mmc_omap_driver); +} + +module_init(mmc_omap_init); +module_exit(mmc_omap_exit); + +MODULE_DESCRIPTION("OMAP Multimedia Card driver"); +MODULE_LICENSE("GPL"); +MODULE_ALIAS(DRIVER_NAME); +MODULE_AUTHOR("Juha Yrjölä"); diff --git a/drivers/mmc/omap.h b/drivers/mmc/omap.h new file mode 100644 index 00000000000..c954d355a5e --- /dev/null +++ b/drivers/mmc/omap.h @@ -0,0 +1,55 @@ +#ifndef DRIVERS_MEDIA_MMC_OMAP_H +#define DRIVERS_MEDIA_MMC_OMAP_H + +#define OMAP_MMC_REG_CMD 0x00 +#define OMAP_MMC_REG_ARGL 0x04 +#define OMAP_MMC_REG_ARGH 0x08 +#define OMAP_MMC_REG_CON 0x0c +#define OMAP_MMC_REG_STAT 0x10 +#define OMAP_MMC_REG_IE 0x14 +#define OMAP_MMC_REG_CTO 0x18 +#define OMAP_MMC_REG_DTO 0x1c +#define OMAP_MMC_REG_DATA 0x20 +#define OMAP_MMC_REG_BLEN 0x24 +#define OMAP_MMC_REG_NBLK 0x28 +#define OMAP_MMC_REG_BUF 0x2c +#define OMAP_MMC_REG_SDIO 0x34 +#define OMAP_MMC_REG_REV 0x3c +#define OMAP_MMC_REG_RSP0 0x40 +#define OMAP_MMC_REG_RSP1 0x44 +#define OMAP_MMC_REG_RSP2 0x48 +#define OMAP_MMC_REG_RSP3 0x4c +#define OMAP_MMC_REG_RSP4 0x50 +#define OMAP_MMC_REG_RSP5 0x54 +#define OMAP_MMC_REG_RSP6 0x58 +#define OMAP_MMC_REG_RSP7 0x5c +#define OMAP_MMC_REG_IOSR 0x60 +#define OMAP_MMC_REG_SYSC 0x64 +#define OMAP_MMC_REG_SYSS 0x68 + +#define OMAP_MMC_STAT_CARD_ERR (1 << 14) +#define OMAP_MMC_STAT_CARD_IRQ (1 << 13) +#define OMAP_MMC_STAT_OCR_BUSY (1 << 12) +#define OMAP_MMC_STAT_A_EMPTY (1 << 11) +#define OMAP_MMC_STAT_A_FULL (1 << 10) +#define OMAP_MMC_STAT_CMD_CRC (1 << 8) +#define OMAP_MMC_STAT_CMD_TOUT (1 << 7) +#define OMAP_MMC_STAT_DATA_CRC (1 << 6) +#define OMAP_MMC_STAT_DATA_TOUT (1 << 5) +#define OMAP_MMC_STAT_END_BUSY (1 << 4) +#define OMAP_MMC_STAT_END_OF_DATA (1 << 3) +#define OMAP_MMC_STAT_CARD_BUSY (1 << 2) +#define OMAP_MMC_STAT_END_OF_CMD (1 << 0) + +#define OMAP_MMC_READ(base, reg) __raw_readw((base) + OMAP_MMC_REG_##reg) +#define OMAP_MMC_WRITE(base, reg, val) __raw_writew((val), (base) + OMAP_MMC_REG_##reg) + +/* + * Command types + */ +#define OMAP_MMC_CMDTYPE_BC 0 +#define OMAP_MMC_CMDTYPE_BCR 1 +#define OMAP_MMC_CMDTYPE_AC 2 +#define OMAP_MMC_CMDTYPE_ADTC 3 + +#endif diff --git a/drivers/mmc/pxamci.c b/drivers/mmc/pxamci.c index c32fad1ce51..eb9a8826e9b 100644 --- a/drivers/mmc/pxamci.c +++ b/drivers/mmc/pxamci.c @@ -37,12 +37,6 @@ #include "pxamci.h" -#ifdef CONFIG_MMC_DEBUG -#define DBG(x...) printk(KERN_DEBUG x) -#else -#define DBG(x...) do { } while (0) -#endif - #define DRIVER_NAME "pxa2xx-mci" #define NR_SG 1 @@ -206,7 +200,7 @@ static void pxamci_start_cmd(struct pxamci_host *host, struct mmc_command *cmd, static void pxamci_finish_request(struct pxamci_host *host, struct mmc_request *mrq) { - DBG("PXAMCI: request done\n"); + pr_debug("PXAMCI: request done\n"); host->mrq = NULL; host->cmd = NULL; host->data = NULL; @@ -252,7 +246,7 @@ static int pxamci_cmd_done(struct pxamci_host *host, unsigned int stat) if ((cmd->resp[0] & 0x80000000) == 0) cmd->error = MMC_ERR_BADCRC; } else { - DBG("ignoring CRC from command %d - *risky*\n",cmd->opcode); + pr_debug("ignoring CRC from command %d - *risky*\n",cmd->opcode); } #else cmd->error = MMC_ERR_BADCRC; @@ -317,12 +311,12 @@ static irqreturn_t pxamci_irq(int irq, void *devid, struct pt_regs *regs) ireg = readl(host->base + MMC_I_REG); - DBG("PXAMCI: irq %08x\n", ireg); + pr_debug("PXAMCI: irq %08x\n", ireg); if (ireg) { unsigned stat = readl(host->base + MMC_STAT); - DBG("PXAMCI: stat %08x\n", stat); + pr_debug("PXAMCI: stat %08x\n", stat); if (ireg & END_CMD_RES) handled |= pxamci_cmd_done(host, stat); @@ -376,9 +370,9 @@ static void pxamci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) { struct pxamci_host *host = mmc_priv(mmc); - DBG("pxamci_set_ios: clock %u power %u vdd %u.%02u\n", - ios->clock, ios->power_mode, ios->vdd / 100, - ios->vdd % 100); + pr_debug("pxamci_set_ios: clock %u power %u vdd %u.%02u\n", + ios->clock, ios->power_mode, ios->vdd / 100, + ios->vdd % 100); if (ios->clock) { unsigned int clk = CLOCKRATE / ios->clock; @@ -405,8 +399,8 @@ static void pxamci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) host->cmdat |= CMDAT_INIT; } - DBG("pxamci_set_ios: clkrt = %x cmdat = %x\n", - host->clkrt, host->cmdat); + pr_debug("pxamci_set_ios: clkrt = %x cmdat = %x\n", + host->clkrt, host->cmdat); } static struct mmc_host_ops pxamci_ops = { diff --git a/drivers/mmc/sdhci.c b/drivers/mmc/sdhci.c index 8b811d94371..bdbfca05002 100644 --- a/drivers/mmc/sdhci.c +++ b/drivers/mmc/sdhci.c @@ -31,12 +31,8 @@ #define BUGMAIL "<sdhci-devel@list.drzeus.cx>" -#ifdef CONFIG_MMC_DEBUG #define DBG(f, x...) \ - printk(KERN_DEBUG DRIVER_NAME " [%s()]: " f, __func__,## x) -#else -#define DBG(f, x...) do { } while (0) -#endif + pr_debug(DRIVER_NAME " [%s()]: " f, __func__,## x) static const struct pci_device_id pci_ids[] __devinitdata = { /* handle any SD host controller */ diff --git a/drivers/mmc/wbsd.c b/drivers/mmc/wbsd.c index 3be397d436f..511f7b0b31d 100644 --- a/drivers/mmc/wbsd.c +++ b/drivers/mmc/wbsd.c @@ -44,15 +44,10 @@ #define DRIVER_NAME "wbsd" #define DRIVER_VERSION "1.5" -#ifdef CONFIG_MMC_DEBUG #define DBG(x...) \ - printk(KERN_DEBUG DRIVER_NAME ": " x) + pr_debug(DRIVER_NAME ": " x) #define DBGF(f, x...) \ - printk(KERN_DEBUG DRIVER_NAME " [%s()]: " f, __func__ , ##x) -#else -#define DBG(x...) do { } while (0) -#define DBGF(x...) do { } while (0) -#endif + pr_debug(DRIVER_NAME " [%s()]: " f, __func__ , ##x) /* * Device resources diff --git a/drivers/mtd/chips/amd_flash.c b/drivers/mtd/chips/amd_flash.c index fdb91b6f1d9..57115618c49 100644 --- a/drivers/mtd/chips/amd_flash.c +++ b/drivers/mtd/chips/amd_flash.c @@ -664,7 +664,7 @@ static struct mtd_info *amd_flash_probe(struct map_info *map) printk("%s: Probing for AMD compatible flash...\n", map->name); if ((table_pos[0] = probe_new_chip(mtd, 0, NULL, &temp, table, - sizeof(table)/sizeof(table[0]))) + ARRAY_SIZE(table))) == -1) { printk(KERN_WARNING "%s: Found no AMD compatible device at location zero\n", @@ -696,7 +696,7 @@ static struct mtd_info *amd_flash_probe(struct map_info *map) base += (1 << temp.chipshift)) { int numchips = temp.numchips; table_pos[numchips] = probe_new_chip(mtd, base, chips, - &temp, table, sizeof(table)/sizeof(table[0])); + &temp, table, ARRAY_SIZE(table)); } mtd->eraseregions = kmalloc(sizeof(struct mtd_erase_region_info) * diff --git a/drivers/mtd/chips/jedec_probe.c b/drivers/mtd/chips/jedec_probe.c index edb306c03c0..517ea33e726 100644 --- a/drivers/mtd/chips/jedec_probe.c +++ b/drivers/mtd/chips/jedec_probe.c @@ -34,6 +34,7 @@ #define MANUFACTURER_MACRONIX 0x00C2 #define MANUFACTURER_NEC 0x0010 #define MANUFACTURER_PMC 0x009D +#define MANUFACTURER_SHARP 0x00b0 #define MANUFACTURER_SST 0x00BF #define MANUFACTURER_ST 0x0020 #define MANUFACTURER_TOSHIBA 0x0098 @@ -124,6 +125,9 @@ #define PM49FL004 0x006E #define PM49FL008 0x006A +/* Sharp */ +#define LH28F640BF 0x00b0 + /* ST - www.st.com */ #define M29W800DT 0x00D7 #define M29W800DB 0x005B @@ -1267,6 +1271,19 @@ static const struct amd_flash_info jedec_table[] = { .regions = { ERASEINFO( 0x01000, 256 ) } + }, { + .mfr_id = MANUFACTURER_SHARP, + .dev_id = LH28F640BF, + .name = "LH28F640BF", + .uaddr = { + [0] = MTD_UADDR_UNNECESSARY, /* x8 */ + }, + .DevSize = SIZE_4MiB, + .CmdSet = P_ID_INTEL_STD, + .NumEraseRegions= 1, + .regions = { + ERASEINFO(0x40000,16), + } }, { .mfr_id = MANUFACTURER_SST, .dev_id = SST39LF512, @@ -2035,7 +2052,7 @@ static int jedec_probe_chip(struct map_info *map, __u32 base, DEBUG(MTD_DEBUG_LEVEL3, "Search for id:(%02x %02x) interleave(%d) type(%d)\n", cfi->mfr, cfi->id, cfi_interleave(cfi), cfi->device_type); - for (i=0; i<sizeof(jedec_table)/sizeof(jedec_table[0]); i++) { + for (i = 0; i < ARRAY_SIZE(jedec_table); i++) { if ( jedec_match( base, map, cfi, &jedec_table[i] ) ) { DEBUG( MTD_DEBUG_LEVEL3, "MTD %s(): matched device 0x%x,0x%x unlock_addrs: 0x%.4x 0x%.4x\n", diff --git a/drivers/mtd/chips/sharp.c b/drivers/mtd/chips/sharp.c index 36f61a6a766..3cc0b23c586 100644 --- a/drivers/mtd/chips/sharp.c +++ b/drivers/mtd/chips/sharp.c @@ -64,7 +64,7 @@ #undef AUTOUNLOCK /* automatically unlocks blocks before erasing */ -struct mtd_info *sharp_probe(struct map_info *); +static struct mtd_info *sharp_probe(struct map_info *); static int sharp_probe_map(struct map_info *map,struct mtd_info *mtd); @@ -96,7 +96,6 @@ struct sharp_info{ struct flchip chips[1]; }; -struct mtd_info *sharp_probe(struct map_info *map); static void sharp_destroy(struct mtd_info *mtd); static struct mtd_chip_driver sharp_chipdrv = { @@ -107,7 +106,7 @@ static struct mtd_chip_driver sharp_chipdrv = { }; -struct mtd_info *sharp_probe(struct map_info *map) +static struct mtd_info *sharp_probe(struct map_info *map) { struct mtd_info *mtd = NULL; struct sharp_info *sharp = NULL; @@ -581,7 +580,7 @@ static void sharp_destroy(struct mtd_info *mtd) } -int __init sharp_probe_init(void) +static int __init sharp_probe_init(void) { printk("MTD Sharp chip driver <ds@lineo.com>\n"); diff --git a/drivers/mtd/cmdlinepart.c b/drivers/mtd/cmdlinepart.c index 6b8bb2e4dcf..a7a7bfe3387 100644 --- a/drivers/mtd/cmdlinepart.c +++ b/drivers/mtd/cmdlinepart.c @@ -42,7 +42,8 @@ /* special size referring to all the remaining space in a partition */ -#define SIZE_REMAINING 0xffffffff +#define SIZE_REMAINING UINT_MAX +#define OFFSET_CONTINUOUS UINT_MAX struct cmdline_mtd_partition { struct cmdline_mtd_partition *next; @@ -75,7 +76,7 @@ static struct mtd_partition * newpart(char *s, { struct mtd_partition *parts; unsigned long size; - unsigned long offset = 0; + unsigned long offset = OFFSET_CONTINUOUS; char *name; int name_len; unsigned char *extra_mem; @@ -314,7 +315,7 @@ static int parse_cmdline_partitions(struct mtd_info *master, { for(i = 0, offset = 0; i < part->num_parts; i++) { - if (!part->parts[i].offset) + if (part->parts[i].offset == OFFSET_CONTINUOUS) part->parts[i].offset = offset; else offset = part->parts[i].offset; diff --git a/drivers/mtd/devices/blkmtd.c b/drivers/mtd/devices/blkmtd.c index 04f864d238d..79f2e1f23eb 100644 --- a/drivers/mtd/devices/blkmtd.c +++ b/drivers/mtd/devices/blkmtd.c @@ -28,8 +28,9 @@ #include <linux/pagemap.h> #include <linux/list.h> #include <linux/init.h> +#include <linux/mount.h> #include <linux/mtd/mtd.h> - +#include <linux/mutex.h> #define err(format, arg...) printk(KERN_ERR "blkmtd: " format "\n" , ## arg) #define info(format, arg...) printk(KERN_INFO "blkmtd: " format "\n" , ## arg) @@ -46,7 +47,7 @@ struct blkmtd_dev { struct list_head list; struct block_device *blkdev; struct mtd_info mtd_info; - struct semaphore wrbuf_mutex; + struct mutex wrbuf_mutex; }; @@ -268,7 +269,7 @@ static int write_pages(struct blkmtd_dev *dev, const u_char *buf, loff_t to, if(end_len) pagecnt++; - down(&dev->wrbuf_mutex); + mutex_lock(&dev->wrbuf_mutex); DEBUG(3, "blkmtd: write: start_len = %zd len = %zd end_len = %zd pagecnt = %d\n", start_len, len, end_len, pagecnt); @@ -376,7 +377,7 @@ static int write_pages(struct blkmtd_dev *dev, const u_char *buf, loff_t to, blkmtd_write_out(bio); DEBUG(2, "blkmtd: write: end, retlen = %zd, err = %d\n", *retlen, err); - up(&dev->wrbuf_mutex); + mutex_unlock(&dev->wrbuf_mutex); if(retlen) *retlen = thislen; @@ -614,8 +615,6 @@ static struct mtd_erase_region_info *calc_erase_regions( } -extern dev_t __init name_to_dev_t(const char *line); - static struct blkmtd_dev *add_device(char *devname, int readonly, int erase_size) { struct block_device *bdev; @@ -659,7 +658,7 @@ static struct blkmtd_dev *add_device(char *devname, int readonly, int erase_size memset(dev, 0, sizeof(struct blkmtd_dev)); dev->blkdev = bdev; if(!readonly) { - init_MUTEX(&dev->wrbuf_mutex); + mutex_init(&dev->wrbuf_mutex); } dev->mtd_info.size = dev->blkdev->bd_inode->i_size & PAGE_MASK; diff --git a/drivers/mtd/devices/block2mtd.c b/drivers/mtd/devices/block2mtd.c index 7ff403b2a0a..4160b8334c5 100644 --- a/drivers/mtd/devices/block2mtd.c +++ b/drivers/mtd/devices/block2mtd.c @@ -18,6 +18,7 @@ #include <linux/init.h> #include <linux/mtd/mtd.h> #include <linux/buffer_head.h> +#include <linux/mutex.h> #define VERSION "$Revision: 1.30 $" @@ -31,7 +32,7 @@ struct block2mtd_dev { struct list_head list; struct block_device *blkdev; struct mtd_info mtd; - struct semaphore write_mutex; + struct mutex write_mutex; }; @@ -134,9 +135,9 @@ static int block2mtd_erase(struct mtd_info *mtd, struct erase_info *instr) int err; instr->state = MTD_ERASING; - down(&dev->write_mutex); + mutex_lock(&dev->write_mutex); err = _block2mtd_erase(dev, from, len); - up(&dev->write_mutex); + mutex_unlock(&dev->write_mutex); if (err) { ERROR("erase failed err = %d", err); instr->state = MTD_ERASE_FAILED; @@ -249,9 +250,9 @@ static int block2mtd_write(struct mtd_info *mtd, loff_t to, size_t len, if (to + len > mtd->size) len = mtd->size - to; - down(&dev->write_mutex); + mutex_lock(&dev->write_mutex); err = _block2mtd_write(dev, buf, to, len, retlen); - up(&dev->write_mutex); + mutex_unlock(&dev->write_mutex); if (err > 0) err = 0; return err; @@ -310,7 +311,7 @@ static struct block2mtd_dev *add_device(char *devname, int erase_size) goto devinit_err; } - init_MUTEX(&dev->write_mutex); + mutex_init(&dev->write_mutex); /* Setup the MTD structure */ /* make the name contain the block device in */ diff --git a/drivers/mtd/devices/doc2000.c b/drivers/mtd/devices/doc2000.c index e4345cf744a..23e7a5c7d2c 100644 --- a/drivers/mtd/devices/doc2000.c +++ b/drivers/mtd/devices/doc2000.c @@ -20,6 +20,7 @@ #include <linux/init.h> #include <linux/types.h> #include <linux/bitops.h> +#include <linux/mutex.h> #include <linux/mtd/mtd.h> #include <linux/mtd/nand.h> @@ -605,7 +606,7 @@ static void DoC2k_init(struct mtd_info *mtd) this->curfloor = -1; this->curchip = -1; - init_MUTEX(&this->lock); + mutex_init(&this->lock); /* Ident all the chips present. */ DoC_ScanChips(this, maxchips); @@ -645,7 +646,7 @@ static int doc_read_ecc(struct mtd_info *mtd, loff_t from, size_t len, if (from >= this->totlen) return -EINVAL; - down(&this->lock); + mutex_lock(&this->lock); *retlen = 0; while (left) { @@ -774,7 +775,7 @@ static int doc_read_ecc(struct mtd_info *mtd, loff_t from, size_t len, buf += len; } - up(&this->lock); + mutex_unlock(&this->lock); return ret; } @@ -803,7 +804,7 @@ static int doc_write_ecc(struct mtd_info *mtd, loff_t to, size_t len, if (to >= this->totlen) return -EINVAL; - down(&this->lock); + mutex_lock(&this->lock); *retlen = 0; while (left) { @@ -873,7 +874,7 @@ static int doc_write_ecc(struct mtd_info *mtd, loff_t to, size_t len, printk(KERN_ERR "Error programming flash\n"); /* Error in programming */ *retlen = 0; - up(&this->lock); + mutex_unlock(&this->lock); return -EIO; } @@ -935,7 +936,7 @@ static int doc_write_ecc(struct mtd_info *mtd, loff_t to, size_t len, printk(KERN_ERR "Error programming flash\n"); /* Error in programming */ *retlen = 0; - up(&this->lock); + mutex_unlock(&this->lock); return -EIO; } @@ -956,7 +957,7 @@ static int doc_write_ecc(struct mtd_info *mtd, loff_t to, size_t len, ret = doc_write_oob_nolock(mtd, to, 8, &dummy, x); if (ret) { - up(&this->lock); + mutex_unlock(&this->lock); return ret; } } @@ -966,7 +967,7 @@ static int doc_write_ecc(struct mtd_info *mtd, loff_t to, size_t len, buf += len; } - up(&this->lock); + mutex_unlock(&this->lock); return 0; } @@ -975,13 +976,13 @@ static int doc_writev_ecc(struct mtd_info *mtd, const struct kvec *vecs, u_char *eccbuf, struct nand_oobinfo *oobsel) { static char static_buf[512]; - static DECLARE_MUTEX(writev_buf_sem); + static DEFINE_MUTEX(writev_buf_mutex); size_t totretlen = 0; size_t thisvecofs = 0; int ret= 0; - down(&writev_buf_sem); + mutex_lock(&writev_buf_mutex); while(count) { size_t thislen, thisretlen; @@ -1024,7 +1025,7 @@ static int doc_writev_ecc(struct mtd_info *mtd, const struct kvec *vecs, to += thislen; } - up(&writev_buf_sem); + mutex_unlock(&writev_buf_mutex); *retlen = totretlen; return ret; } @@ -1037,7 +1038,7 @@ static int doc_read_oob(struct mtd_info *mtd, loff_t ofs, size_t len, int len256 = 0, ret; struct Nand *mychip; - down(&this->lock); + mutex_lock(&this->lock); mychip = &this->chips[ofs >> this->chipshift]; @@ -1083,7 +1084,7 @@ static int doc_read_oob(struct mtd_info *mtd, loff_t ofs, size_t len, ret = DoC_WaitReady(this); - up(&this->lock); + mutex_unlock(&this->lock); return ret; } @@ -1197,10 +1198,10 @@ static int doc_write_oob(struct mtd_info *mtd, loff_t ofs, size_t len, struct DiskOnChip *this = mtd->priv; int ret; - down(&this->lock); + mutex_lock(&this->lock); ret = doc_write_oob_nolock(mtd, ofs, len, retlen, buf); - up(&this->lock); + mutex_unlock(&this->lock); return ret; } @@ -1214,10 +1215,10 @@ static int doc_erase(struct mtd_info *mtd, struct erase_info *instr) struct Nand *mychip; int status; - down(&this->lock); + mutex_lock(&this->lock); if (ofs & (mtd->erasesize-1) || len & (mtd->erasesize-1)) { - up(&this->lock); + mutex_unlock(&this->lock); return -EINVAL; } @@ -1265,7 +1266,7 @@ static int doc_erase(struct mtd_info *mtd, struct erase_info *instr) callback: mtd_erase_callback(instr); - up(&this->lock); + mutex_unlock(&this->lock); return 0; } diff --git a/drivers/mtd/devices/lart.c b/drivers/mtd/devices/lart.c index 1e876fcb040..29b0ddaa324 100644 --- a/drivers/mtd/devices/lart.c +++ b/drivers/mtd/devices/lart.c @@ -581,8 +581,6 @@ static int flash_write (struct mtd_info *mtd,loff_t to,size_t len,size_t *retlen /***************************************************************************************************/ -#define NB_OF(x) (sizeof (x) / sizeof (x[0])) - static struct mtd_info mtd; static struct mtd_erase_region_info erase_regions[] = { @@ -640,7 +638,7 @@ int __init lart_flash_init (void) mtd.flags = MTD_CAP_NORFLASH; mtd.size = FLASH_BLOCKSIZE_PARAM * FLASH_NUMBLOCKS_16m_PARAM + FLASH_BLOCKSIZE_MAIN * FLASH_NUMBLOCKS_16m_MAIN; mtd.erasesize = FLASH_BLOCKSIZE_MAIN; - mtd.numeraseregions = NB_OF (erase_regions); + mtd.numeraseregions = ARRAY_SIZE(erase_regions); mtd.eraseregions = erase_regions; mtd.erase = flash_erase; mtd.read = flash_read; @@ -670,9 +668,9 @@ int __init lart_flash_init (void) result,mtd.eraseregions[result].numblocks); #ifdef HAVE_PARTITIONS - printk ("\npartitions = %d\n",NB_OF (lart_partitions)); + printk ("\npartitions = %d\n", ARRAY_SIZE(lart_partitions)); - for (result = 0; result < NB_OF (lart_partitions); result++) + for (result = 0; result < ARRAY_SIZE(lart_partitions); result++) printk (KERN_DEBUG "\n\n" "lart_partitions[%d].name = %s\n" @@ -687,7 +685,7 @@ int __init lart_flash_init (void) #ifndef HAVE_PARTITIONS result = add_mtd_device (&mtd); #else - result = add_mtd_partitions (&mtd,lart_partitions,NB_OF (lart_partitions)); + result = add_mtd_partitions (&mtd,lart_partitions, ARRAY_SIZE(lart_partitions)); #endif return (result); diff --git a/drivers/mtd/devices/m25p80.c b/drivers/mtd/devices/m25p80.c index d5f24089be7..04e65d5dae0 100644 --- a/drivers/mtd/devices/m25p80.c +++ b/drivers/mtd/devices/m25p80.c @@ -186,7 +186,7 @@ static int m25p80_erase(struct mtd_info *mtd, struct erase_info *instr) struct m25p *flash = mtd_to_m25p(mtd); u32 addr,len; - DEBUG(MTD_DEBUG_LEVEL2, "%s: %s %s 0x%08x, len %zd\n", + DEBUG(MTD_DEBUG_LEVEL2, "%s: %s %s 0x%08x, len %d\n", flash->spi->dev.bus_id, __FUNCTION__, "at", (u32)instr->addr, instr->len); diff --git a/drivers/mtd/devices/ms02-nv.c b/drivers/mtd/devices/ms02-nv.c index 0ff2e437824..485f663493d 100644 --- a/drivers/mtd/devices/ms02-nv.c +++ b/drivers/mtd/devices/ms02-nv.c @@ -308,7 +308,7 @@ static int __init ms02nv_init(void) break; } - for (i = 0; i < (sizeof(ms02nv_addrs) / sizeof(*ms02nv_addrs)); i++) + for (i = 0; i < ARRAY_SIZE(ms02nv_addrs); i++) if (!ms02nv_init_one(ms02nv_addrs[i] << stride)) count++; diff --git a/drivers/mtd/inftlcore.c b/drivers/mtd/inftlcore.c index 8a544890173..a3b92479719 100644 --- a/drivers/mtd/inftlcore.c +++ b/drivers/mtd/inftlcore.c @@ -47,9 +47,6 @@ */ #define MAX_LOOPS 10000 -extern void INFTL_dumptables(struct INFTLrecord *inftl); -extern void INFTL_dumpVUchains(struct INFTLrecord *inftl); - static void inftl_add_mtd(struct mtd_blktrans_ops *tr, struct mtd_info *mtd) { struct INFTLrecord *inftl; @@ -132,7 +129,7 @@ static void inftl_add_mtd(struct mtd_blktrans_ops *tr, struct mtd_info *mtd) return; } #ifdef PSYCHO_DEBUG - printk(KERN_INFO "INFTL: Found new nftl%c\n", nftl->mbd.devnum + 'a'); + printk(KERN_INFO "INFTL: Found new inftl%c\n", inftl->mbd.devnum + 'a'); #endif return; } @@ -885,8 +882,6 @@ static struct mtd_blktrans_ops inftl_tr = { .owner = THIS_MODULE, }; -extern char inftlmountrev[]; - static int __init init_inftl(void) { printk(KERN_INFO "INFTL: inftlcore.c $Revision: 1.19 $, " diff --git a/drivers/mtd/maps/alchemy-flash.c b/drivers/mtd/maps/alchemy-flash.c index a57791a6ce4..b933a2a27b1 100644 --- a/drivers/mtd/maps/alchemy-flash.c +++ b/drivers/mtd/maps/alchemy-flash.c @@ -126,8 +126,6 @@ static struct mtd_partition alchemy_partitions[] = { } }; -#define NB_OF(x) (sizeof(x)/sizeof(x[0])) - static struct mtd_info *mymtd; int __init alchemy_mtd_init(void) @@ -154,7 +152,7 @@ int __init alchemy_mtd_init(void) * Static partition definition selection */ parts = alchemy_partitions; - nb_parts = NB_OF(alchemy_partitions); + nb_parts = ARRAY_SIZE(alchemy_partitions); alchemy_map.size = window_size; /* diff --git a/drivers/mtd/maps/cfi_flagadm.c b/drivers/mtd/maps/cfi_flagadm.c index 6a8c0415bde..fd0f0d3187d 100644 --- a/drivers/mtd/maps/cfi_flagadm.c +++ b/drivers/mtd/maps/cfi_flagadm.c @@ -86,7 +86,7 @@ struct mtd_partition flagadm_parts[] = { } }; -#define PARTITION_COUNT (sizeof(flagadm_parts)/sizeof(struct mtd_partition)) +#define PARTITION_COUNT ARRAY_SIZE(flagadm_parts) static struct mtd_info *mymtd; diff --git a/drivers/mtd/maps/dbox2-flash.c b/drivers/mtd/maps/dbox2-flash.c index 49d90542fc7..652813cd6c2 100644 --- a/drivers/mtd/maps/dbox2-flash.c +++ b/drivers/mtd/maps/dbox2-flash.c @@ -57,7 +57,7 @@ static struct mtd_partition partition_info[]= { } }; -#define NUM_PARTITIONS (sizeof(partition_info) / sizeof(partition_info[0])) +#define NUM_PARTITIONS ARRAY_SIZE(partition_info) #define WINDOW_ADDR 0x10000000 #define WINDOW_SIZE 0x800000 diff --git a/drivers/mtd/maps/dilnetpc.c b/drivers/mtd/maps/dilnetpc.c index efb22169264..c299d10b33e 100644 --- a/drivers/mtd/maps/dilnetpc.c +++ b/drivers/mtd/maps/dilnetpc.c @@ -300,7 +300,7 @@ static struct mtd_partition partition_info[]= }, }; -#define NUM_PARTITIONS (sizeof(partition_info)/sizeof(partition_info[0])) +#define NUM_PARTITIONS ARRAY_SIZE(partition_info) static struct mtd_info *mymtd; static struct mtd_info *lowlvl_parts[NUM_PARTITIONS]; @@ -345,7 +345,7 @@ static struct mtd_partition higlvl_partition_info[]= }, }; -#define NUM_HIGHLVL_PARTITIONS (sizeof(higlvl_partition_info)/sizeof(partition_info[0])) +#define NUM_HIGHLVL_PARTITIONS ARRAY_SIZE(higlvl_partition_info) static int dnp_adnp_probe(void) diff --git a/drivers/mtd/maps/dmv182.c b/drivers/mtd/maps/dmv182.c index b993ac01a9a..2bb3c0f0f97 100644 --- a/drivers/mtd/maps/dmv182.c +++ b/drivers/mtd/maps/dmv182.c @@ -99,7 +99,7 @@ static struct mtd_info *this_mtd; static int __init init_svme182(void) { struct mtd_partition *partitions; - int num_parts = sizeof(svme182_partitions) / sizeof(struct mtd_partition); + int num_parts = ARRAY_SIZE(svme182_partitions); partitions = svme182_partitions; diff --git a/drivers/mtd/maps/h720x-flash.c b/drivers/mtd/maps/h720x-flash.c index 31909482110..0667101ccbe 100644 --- a/drivers/mtd/maps/h720x-flash.c +++ b/drivers/mtd/maps/h720x-flash.c @@ -59,7 +59,7 @@ static struct mtd_partition h720x_partitions[] = { } }; -#define NUM_PARTITIONS (sizeof(h720x_partitions)/sizeof(h720x_partitions[0])) +#define NUM_PARTITIONS ARRAY_SIZE(h720x_partitions) static int nr_mtd_parts; static struct mtd_partition *mtd_parts; diff --git a/drivers/mtd/maps/netsc520.c b/drivers/mtd/maps/netsc520.c index 33060a31572..ed215470158 100644 --- a/drivers/mtd/maps/netsc520.c +++ b/drivers/mtd/maps/netsc520.c @@ -76,7 +76,7 @@ static struct mtd_partition partition_info[]={ .size = 0x80000 }, }; -#define NUM_PARTITIONS (sizeof(partition_info)/sizeof(partition_info[0])) +#define NUM_PARTITIONS ARRAY_SIZE(partition_info) #define WINDOW_SIZE 0x00100000 #define WINDOW_ADDR 0x00200000 @@ -88,7 +88,7 @@ static struct map_info netsc520_map = { .phys = WINDOW_ADDR, }; -#define NUM_FLASH_BANKS (sizeof(netsc520_map)/sizeof(struct map_info)) +#define NUM_FLASH_BANKS ARRAY_SIZE(netsc520_map) static struct mtd_info *mymtd; diff --git a/drivers/mtd/maps/nettel.c b/drivers/mtd/maps/nettel.c index 632eb2aa968..54a3102ab19 100644 --- a/drivers/mtd/maps/nettel.c +++ b/drivers/mtd/maps/nettel.c @@ -128,8 +128,7 @@ static struct mtd_partition nettel_amd_partitions[] = { } }; -#define NUM_AMD_PARTITIONS \ - (sizeof(nettel_amd_partitions)/sizeof(nettel_amd_partitions[0])) +#define NUM_AMD_PARTITIONS ARRAY_SIZE(nettel_amd_partitions) /****************************************************************************/ diff --git a/drivers/mtd/maps/ocotea.c b/drivers/mtd/maps/ocotea.c index c223514ca2e..a21fcd195ab 100644 --- a/drivers/mtd/maps/ocotea.c +++ b/drivers/mtd/maps/ocotea.c @@ -58,8 +58,6 @@ static struct mtd_partition ocotea_large_partitions[] = { } }; -#define NB_OF(x) (sizeof(x)/sizeof(x[0])) - int __init init_ocotea(void) { u8 fpga0_reg; @@ -97,7 +95,7 @@ int __init init_ocotea(void) if (flash) { flash->owner = THIS_MODULE; add_mtd_partitions(flash, ocotea_small_partitions, - NB_OF(ocotea_small_partitions)); + ARRAY_SIZE(ocotea_small_partitions)); } else { printk("map probe failed for flash\n"); return -ENXIO; @@ -118,7 +116,7 @@ int __init init_ocotea(void) if (flash) { flash->owner = THIS_MODULE; add_mtd_partitions(flash, ocotea_large_partitions, - NB_OF(ocotea_large_partitions)); + ARRAY_SIZE(ocotea_large_partitions)); } else { printk("map probe failed for flash\n"); return -ENXIO; diff --git a/drivers/mtd/maps/pci.c b/drivers/mtd/maps/pci.c index 21822c2edbe..d2ab1bae9c3 100644 --- a/drivers/mtd/maps/pci.c +++ b/drivers/mtd/maps/pci.c @@ -334,9 +334,6 @@ mtd_pci_probe(struct pci_dev *dev, const struct pci_device_id *id) return 0; release: - if (mtd) - map_destroy(mtd); - if (map) { map->exit(dev, map); kfree(map); diff --git a/drivers/mtd/maps/pcmciamtd.c b/drivers/mtd/maps/pcmciamtd.c index f988c817e19..d27f4129afd 100644 --- a/drivers/mtd/maps/pcmciamtd.c +++ b/drivers/mtd/maps/pcmciamtd.c @@ -54,7 +54,7 @@ static const int debug = 0; #define MAX_PCMCIA_ADDR 0x4000000 struct pcmciamtd_dev { - dev_link_t link; /* PCMCIA link */ + struct pcmcia_device *p_dev; dev_node_t node; /* device node */ caddr_t win_base; /* ioremapped address of PCMCIA window */ unsigned int win_size; /* size of window */ @@ -111,8 +111,8 @@ static caddr_t remap_window(struct map_info *map, unsigned long to) memreq_t mrq; int ret; - if(!(dev->link.state & DEV_PRESENT)) { - DEBUG(1, "device removed state = 0x%4.4X", dev->link.state); + if (!pcmcia_dev_present(dev->p_dev)) { + DEBUG(1, "device removed"); return 0; } @@ -122,7 +122,7 @@ static caddr_t remap_window(struct map_info *map, unsigned long to) dev->offset, mrq.CardOffset); mrq.Page = 0; if( (ret = pcmcia_map_mem_page(win, &mrq)) != CS_SUCCESS) { - cs_error(dev->link.handle, MapMemPage, ret); + cs_error(dev->p_dev, MapMemPage, ret); return NULL; } dev->offset = mrq.CardOffset; @@ -238,7 +238,7 @@ static void pcmcia_copy_to_remap(struct map_info *map, unsigned long to, const v /* read/write{8,16} copy_{from,to} routines with direct access */ -#define DEV_REMOVED(x) (!(*(u_int *)x->map_priv_1 & DEV_PRESENT)) +#define DEV_REMOVED(x) (!(pcmcia_dev_present(((struct pcmciamtd_dev *)map->map_priv_1)->p_dev))) static map_word pcmcia_read8(struct map_info *map, unsigned long ofs) { @@ -319,7 +319,7 @@ static void pcmcia_copy_to(struct map_info *map, unsigned long to, const void *f static void pcmciamtd_set_vpp(struct map_info *map, int on) { struct pcmciamtd_dev *dev = (struct pcmciamtd_dev *)map->map_priv_1; - dev_link_t *link = &dev->link; + struct pcmcia_device *link = dev->p_dev; modconf_t mod; int ret; @@ -328,9 +328,9 @@ static void pcmciamtd_set_vpp(struct map_info *map, int on) mod.Vpp1 = mod.Vpp2 = on ? dev->vpp : 0; DEBUG(2, "dev = %p on = %d vpp = %d\n", dev, on, dev->vpp); - ret = pcmcia_modify_configuration(link->handle, &mod); + ret = pcmcia_modify_configuration(link, &mod); if(ret != CS_SUCCESS) { - cs_error(link->handle, ModifyConfiguration, ret); + cs_error(link, ModifyConfiguration, ret); } } @@ -340,7 +340,7 @@ static void pcmciamtd_set_vpp(struct map_info *map, int on) * still open, this will be postponed until it is closed. */ -static void pcmciamtd_release(dev_link_t *link) +static void pcmciamtd_release(struct pcmcia_device *link) { struct pcmciamtd_dev *dev = link->priv; @@ -353,12 +353,11 @@ static void pcmciamtd_release(dev_link_t *link) } pcmcia_release_window(link->win); } - pcmcia_release_configuration(link->handle); - link->state &= ~DEV_CONFIG; + pcmcia_disable_device(link); } -static void card_settings(struct pcmciamtd_dev *dev, dev_link_t *link, int *new_name) +static void card_settings(struct pcmciamtd_dev *dev, struct pcmcia_device *link, int *new_name) { int rc; tuple_t tuple; @@ -371,16 +370,16 @@ static void card_settings(struct pcmciamtd_dev *dev, dev_link_t *link, int *new_ tuple.TupleOffset = 0; tuple.DesiredTuple = RETURN_FIRST_TUPLE; - rc = pcmcia_get_first_tuple(link->handle, &tuple); + rc = pcmcia_get_first_tuple(link, &tuple); while(rc == CS_SUCCESS) { - rc = pcmcia_get_tuple_data(link->handle, &tuple); + rc = pcmcia_get_tuple_data(link, &tuple); if(rc != CS_SUCCESS) { - cs_error(link->handle, GetTupleData, rc); + cs_error(link, GetTupleData, rc); break; } - rc = pcmcia_parse_tuple(link->handle, &tuple, &parse); + rc = pcmcia_parse_tuple(link, &tuple, &parse); if(rc != CS_SUCCESS) { - cs_error(link->handle, ParseTuple, rc); + cs_error(link, ParseTuple, rc); break; } @@ -451,7 +450,7 @@ static void card_settings(struct pcmciamtd_dev *dev, dev_link_t *link, int *new_ DEBUG(2, "Unknown tuple code %d", tuple.TupleCode); } - rc = pcmcia_get_next_tuple(link->handle, &tuple); + rc = pcmcia_get_next_tuple(link, &tuple); } if(!dev->pcmcia_map.size) dev->pcmcia_map.size = MAX_PCMCIA_ADDR; @@ -488,7 +487,7 @@ static void card_settings(struct pcmciamtd_dev *dev, dev_link_t *link, int *new_ #define CS_CHECK(fn, ret) \ do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0) -static void pcmciamtd_config(dev_link_t *link) +static int pcmciamtd_config(struct pcmcia_device *link) { struct pcmciamtd_dev *dev = link->priv; struct mtd_info *mtd = NULL; @@ -504,13 +503,10 @@ static void pcmciamtd_config(dev_link_t *link) DEBUG(3, "link=0x%p", link); - /* Configure card */ - link->state |= DEV_CONFIG; - DEBUG(2, "Validating CIS"); - ret = pcmcia_validate_cis(link->handle, &cisinfo); + ret = pcmcia_validate_cis(link, &cisinfo); if(ret != CS_SUCCESS) { - cs_error(link->handle, GetTupleData, ret); + cs_error(link, GetTupleData, ret); } else { DEBUG(2, "ValidateCIS found %d chains", cisinfo.Chains); } @@ -538,7 +534,7 @@ static void pcmciamtd_config(dev_link_t *link) req.Attributes |= (dev->pcmcia_map.bankwidth == 1) ? WIN_DATA_WIDTH_8 : WIN_DATA_WIDTH_16; req.Base = 0; req.AccessSpeed = mem_speed; - link->win = (window_handle_t)link->handle; + link->win = (window_handle_t)link; req.Size = (force_size) ? force_size << 20 : MAX_PCMCIA_ADDR; dev->win_size = 0; @@ -546,7 +542,7 @@ static void pcmciamtd_config(dev_link_t *link) int ret; DEBUG(2, "requesting window with size = %dKiB memspeed = %d", req.Size >> 10, req.AccessSpeed); - ret = pcmcia_request_window(&link->handle, &req, &link->win); + ret = pcmcia_request_window(&link, &req, &link->win); DEBUG(2, "ret = %d dev->win_size = %d", ret, dev->win_size); if(ret) { req.Size >>= 1; @@ -562,19 +558,19 @@ static void pcmciamtd_config(dev_link_t *link) if(!dev->win_size) { err("Cant allocate memory window"); pcmciamtd_release(link); - return; + return -ENODEV; } DEBUG(1, "Allocated a window of %dKiB", dev->win_size >> 10); /* Get write protect status */ - CS_CHECK(GetStatus, pcmcia_get_status(link->handle, &status)); + CS_CHECK(GetStatus, pcmcia_get_status(link, &status)); DEBUG(2, "status value: 0x%x window handle = 0x%8.8lx", status.CardState, (unsigned long)link->win); dev->win_base = ioremap(req.Base, req.Size); if(!dev->win_base) { err("ioremap(%lu, %u) failed", req.Base, req.Size); pcmciamtd_release(link); - return; + return -ENODEV; } DEBUG(1, "mapped window dev = %p req.base = 0x%lx base = %p size = 0x%x", dev, req.Base, dev->win_base, req.Size); @@ -584,17 +580,14 @@ static void pcmciamtd_config(dev_link_t *link) dev->pcmcia_map.map_priv_2 = (unsigned long)link->win; DEBUG(2, "Getting configuration"); - CS_CHECK(GetConfigurationInfo, pcmcia_get_configuration_info(link->handle, &t)); + CS_CHECK(GetConfigurationInfo, pcmcia_get_configuration_info(link, &t)); DEBUG(2, "Vcc = %d Vpp1 = %d Vpp2 = %d", t.Vcc, t.Vpp1, t.Vpp2); dev->vpp = (vpp) ? vpp : t.Vpp1; link->conf.Attributes = 0; - link->conf.Vcc = t.Vcc; if(setvpp == 2) { - link->conf.Vpp1 = dev->vpp; - link->conf.Vpp2 = dev->vpp; + link->conf.Vpp = dev->vpp; } else { - link->conf.Vpp1 = 0; - link->conf.Vpp2 = 0; + link->conf.Vpp = 0; } link->conf.IntType = INT_MEMORY; @@ -606,9 +599,10 @@ static void pcmciamtd_config(dev_link_t *link) link->conf.ConfigIndex = 0; link->conf.Present = t.Present; DEBUG(2, "Setting Configuration"); - ret = pcmcia_request_configuration(link->handle, &link->conf); + ret = pcmcia_request_configuration(link, &link->conf); if(ret != CS_SUCCESS) { - cs_error(link->handle, RequestConfiguration, ret); + cs_error(link, RequestConfiguration, ret); + return -ENODEV; } if(mem_type == 1) { @@ -616,7 +610,7 @@ static void pcmciamtd_config(dev_link_t *link) } else if(mem_type == 2) { mtd = do_map_probe("map_rom", &dev->pcmcia_map); } else { - for(i = 0; i < sizeof(probes) / sizeof(char *); i++) { + for(i = 0; i < ARRAY_SIZE(probes); i++) { DEBUG(1, "Trying %s", probes[i]); mtd = do_map_probe(probes[i], &dev->pcmcia_map); if(mtd) @@ -629,7 +623,7 @@ static void pcmciamtd_config(dev_link_t *link) if(!mtd) { DEBUG(1, "Cant find an MTD"); pcmciamtd_release(link); - return; + return -ENODEV; } dev->mtd_info = mtd; @@ -654,7 +648,6 @@ static void pcmciamtd_config(dev_link_t *link) use the faster non-remapping read/write functions */ if(mtd->size <= dev->win_size) { DEBUG(1, "Using non remapping memory functions"); - dev->pcmcia_map.map_priv_1 = (unsigned long)&(dev->link.state); dev->pcmcia_map.map_priv_2 = (unsigned long)dev->win_base; if (dev->pcmcia_map.bankwidth == 1) { dev->pcmcia_map.read = pcmcia_read8; @@ -672,19 +665,18 @@ static void pcmciamtd_config(dev_link_t *link) dev->mtd_info = NULL; err("Couldnt register MTD device"); pcmciamtd_release(link); - return; + return -ENODEV; } snprintf(dev->node.dev_name, sizeof(dev->node.dev_name), "mtd%d", mtd->index); info("mtd%d: %s", mtd->index, mtd->name); - link->state &= ~DEV_CONFIG_PENDING; - link->dev = &dev->node; - return; + link->dev_node = &dev->node; + return 0; cs_failed: - cs_error(link->handle, last_fn, last_ret); + cs_error(link, last_fn, last_ret); err("CS Error, exiting"); pcmciamtd_release(link); - return; + return -ENODEV; } @@ -713,21 +705,18 @@ static int pcmciamtd_resume(struct pcmcia_device *dev) * when the device is released. */ -static void pcmciamtd_detach(struct pcmcia_device *p_dev) +static void pcmciamtd_detach(struct pcmcia_device *link) { - dev_link_t *link = dev_to_instance(p_dev); + struct pcmciamtd_dev *dev = link->priv; DEBUG(3, "link=0x%p", link); - if(link->state & DEV_CONFIG) { - struct pcmciamtd_dev *dev = link->priv; - if(dev->mtd_info) { - del_mtd_device(dev->mtd_info); - info("mtd%d: Removed", dev->mtd_info->index); - } - - pcmciamtd_release(link); + if(dev->mtd_info) { + del_mtd_device(dev->mtd_info); + info("mtd%d: Removed", dev->mtd_info->index); } + + pcmciamtd_release(link); } @@ -736,10 +725,9 @@ static void pcmciamtd_detach(struct pcmcia_device *p_dev) * with Card Services. */ -static int pcmciamtd_attach(struct pcmcia_device *p_dev) +static int pcmciamtd_probe(struct pcmcia_device *link) { struct pcmciamtd_dev *dev; - dev_link_t *link; /* Create new memory card device */ dev = kmalloc(sizeof(*dev), GFP_KERNEL); @@ -747,20 +735,13 @@ static int pcmciamtd_attach(struct pcmcia_device *p_dev) DEBUG(1, "dev=0x%p", dev); memset(dev, 0, sizeof(*dev)); - link = &dev->link; + dev->p_dev = link; link->priv = dev; link->conf.Attributes = 0; link->conf.IntType = INT_MEMORY; - link->next = NULL; - link->handle = p_dev; - p_dev->instance = link; - - link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; - pcmciamtd_config(link); - - return 0; + return pcmciamtd_config(link); } static struct pcmcia_device_id pcmciamtd_ids[] = { @@ -794,7 +775,7 @@ static struct pcmcia_driver pcmciamtd_driver = { .drv = { .name = "pcmciamtd" }, - .probe = pcmciamtd_attach, + .probe = pcmciamtd_probe, .remove = pcmciamtd_detach, .owner = THIS_MODULE, .id_table = pcmciamtd_ids, diff --git a/drivers/mtd/maps/redwood.c b/drivers/mtd/maps/redwood.c index 5b76ed88618..50b14033613 100644 --- a/drivers/mtd/maps/redwood.c +++ b/drivers/mtd/maps/redwood.c @@ -121,8 +121,7 @@ struct map_info redwood_flash_map = { }; -#define NUM_REDWOOD_FLASH_PARTITIONS \ - (sizeof(redwood_flash_partitions)/sizeof(redwood_flash_partitions[0])) +#define NUM_REDWOOD_FLASH_PARTITIONS ARRAY_SIZE(redwood_flash_partitions) static struct mtd_info *redwood_mtd; diff --git a/drivers/mtd/maps/sbc8240.c b/drivers/mtd/maps/sbc8240.c index 225cdd9ba5b..350286dc1d2 100644 --- a/drivers/mtd/maps/sbc8240.c +++ b/drivers/mtd/maps/sbc8240.c @@ -66,7 +66,7 @@ static struct map_info sbc8240_map[2] = { } }; -#define NUM_FLASH_BANKS (sizeof(sbc8240_map) / sizeof(struct map_info)) +#define NUM_FLASH_BANKS ARRAY_SIZE(sbc8240_map) /* * The following defines the partition layout of SBC8240 boards. @@ -125,8 +125,6 @@ static struct mtd_partition sbc8240_fs_partitions [] = { } }; -#define NB_OF(x) (sizeof (x) / sizeof (x[0])) - /* trivial struct to describe partition information */ struct mtd_part_def { @@ -190,10 +188,10 @@ int __init init_sbc8240_mtd (void) #ifdef CONFIG_MTD_PARTITIONS sbc8240_part_banks[0].mtd_part = sbc8240_uboot_partitions; sbc8240_part_banks[0].type = "static image"; - sbc8240_part_banks[0].nums = NB_OF(sbc8240_uboot_partitions); + sbc8240_part_banks[0].nums = ARRAY_SIZE(sbc8240_uboot_partitions); sbc8240_part_banks[1].mtd_part = sbc8240_fs_partitions; sbc8240_part_banks[1].type = "static file system"; - sbc8240_part_banks[1].nums = NB_OF(sbc8240_fs_partitions); + sbc8240_part_banks[1].nums = ARRAY_SIZE(sbc8240_fs_partitions); for (i = 0; i < NUM_FLASH_BANKS; i++) { diff --git a/drivers/mtd/maps/sc520cdp.c b/drivers/mtd/maps/sc520cdp.c index ed92afadd8a..e8c130e1efd 100644 --- a/drivers/mtd/maps/sc520cdp.c +++ b/drivers/mtd/maps/sc520cdp.c @@ -107,7 +107,7 @@ static struct map_info sc520cdp_map[] = { }, }; -#define NUM_FLASH_BANKS (sizeof(sc520cdp_map)/sizeof(struct map_info)) +#define NUM_FLASH_BANKS ARRAY_SIZE(sc520cdp_map) static struct mtd_info *mymtd[NUM_FLASH_BANKS]; static struct mtd_info *merged_mtd; diff --git a/drivers/mtd/maps/scx200_docflash.c b/drivers/mtd/maps/scx200_docflash.c index 2c91dff8bb6..28b8a571a91 100644 --- a/drivers/mtd/maps/scx200_docflash.c +++ b/drivers/mtd/maps/scx200_docflash.c @@ -70,7 +70,7 @@ static struct mtd_partition partition_info[] = { .size = 0x80000 }, }; -#define NUM_PARTITIONS (sizeof(partition_info)/sizeof(partition_info[0])) +#define NUM_PARTITIONS ARRAY_SIZE(partition_info) #endif diff --git a/drivers/mtd/maps/sharpsl-flash.c b/drivers/mtd/maps/sharpsl-flash.c index 999f4bb3d84..12fe53c0d2f 100644 --- a/drivers/mtd/maps/sharpsl-flash.c +++ b/drivers/mtd/maps/sharpsl-flash.c @@ -49,8 +49,6 @@ static struct mtd_partition sharpsl_partitions[1] = { } }; -#define NB_OF(x) (sizeof(x)/sizeof(x[0])) - int __init init_sharpsl(void) { struct mtd_partition *parts; @@ -92,7 +90,7 @@ int __init init_sharpsl(void) } parts = sharpsl_partitions; - nb_parts = NB_OF(sharpsl_partitions); + nb_parts = ARRAY_SIZE(sharpsl_partitions); printk(KERN_NOTICE "Using %s partision definition\n", part_type); add_mtd_partitions(mymtd, parts, nb_parts); diff --git a/drivers/mtd/maps/ts5500_flash.c b/drivers/mtd/maps/ts5500_flash.c index 4b372bcb17f..a7422c20056 100644 --- a/drivers/mtd/maps/ts5500_flash.c +++ b/drivers/mtd/maps/ts5500_flash.c @@ -64,7 +64,7 @@ static struct mtd_partition ts5500_partitions[] = { } }; -#define NUM_PARTITIONS (sizeof(ts5500_partitions)/sizeof(struct mtd_partition)) +#define NUM_PARTITIONS ARRAY_SIZE(ts5500_partitions) static struct mtd_info *mymtd; diff --git a/drivers/mtd/maps/uclinux.c b/drivers/mtd/maps/uclinux.c index 79d92808b76..f7264dc2ac9 100644 --- a/drivers/mtd/maps/uclinux.c +++ b/drivers/mtd/maps/uclinux.c @@ -37,7 +37,7 @@ struct mtd_partition uclinux_romfs[] = { { .name = "ROMfs" } }; -#define NUM_PARTITIONS (sizeof(uclinux_romfs) / sizeof(uclinux_romfs[0])) +#define NUM_PARTITIONS ARRAY_SIZE(uclinux_romfs) /****************************************************************************/ diff --git a/drivers/mtd/maps/vmax301.c b/drivers/mtd/maps/vmax301.c index e0063941c0d..b3e48739543 100644 --- a/drivers/mtd/maps/vmax301.c +++ b/drivers/mtd/maps/vmax301.c @@ -182,7 +182,7 @@ int __init init_vmax301(void) } } - if (!vmax_mtd[1] && !vmax_mtd[2]) { + if (!vmax_mtd[0] && !vmax_mtd[1]) { iounmap((void *)iomapadr); return -ENXIO; } diff --git a/drivers/mtd/mtd_blkdevs.c b/drivers/mtd/mtd_blkdevs.c index 840dd66ce2d..458d3c8ae1e 100644 --- a/drivers/mtd/mtd_blkdevs.c +++ b/drivers/mtd/mtd_blkdevs.c @@ -19,12 +19,12 @@ #include <linux/spinlock.h> #include <linux/hdreg.h> #include <linux/init.h> -#include <asm/semaphore.h> +#include <linux/mutex.h> #include <asm/uaccess.h> static LIST_HEAD(blktrans_majors); -extern struct semaphore mtd_table_mutex; +extern struct mutex mtd_table_mutex; extern struct mtd_info *mtd_table[]; struct mtd_blkcore_priv { @@ -122,9 +122,9 @@ static int mtd_blktrans_thread(void *arg) spin_unlock_irq(rq->queue_lock); - down(&dev->sem); + mutex_lock(&dev->lock); res = do_blktrans_request(tr, dev, req); - up(&dev->sem); + mutex_unlock(&dev->lock); spin_lock_irq(rq->queue_lock); @@ -235,8 +235,8 @@ int add_mtd_blktrans_dev(struct mtd_blktrans_dev *new) int last_devnum = -1; struct gendisk *gd; - if (!down_trylock(&mtd_table_mutex)) { - up(&mtd_table_mutex); + if (!!mutex_trylock(&mtd_table_mutex)) { + mutex_unlock(&mtd_table_mutex); BUG(); } @@ -267,7 +267,7 @@ int add_mtd_blktrans_dev(struct mtd_blktrans_dev *new) return -EBUSY; } - init_MUTEX(&new->sem); + mutex_init(&new->lock); list_add_tail(&new->list, &tr->devs); added: if (!tr->writesect) @@ -313,8 +313,8 @@ int add_mtd_blktrans_dev(struct mtd_blktrans_dev *new) int del_mtd_blktrans_dev(struct mtd_blktrans_dev *old) { - if (!down_trylock(&mtd_table_mutex)) { - up(&mtd_table_mutex); + if (!!mutex_trylock(&mtd_table_mutex)) { + mutex_unlock(&mtd_table_mutex); BUG(); } @@ -378,14 +378,14 @@ int register_mtd_blktrans(struct mtd_blktrans_ops *tr) memset(tr->blkcore_priv, 0, sizeof(*tr->blkcore_priv)); - down(&mtd_table_mutex); + mutex_lock(&mtd_table_mutex); ret = register_blkdev(tr->major, tr->name); if (ret) { printk(KERN_WARNING "Unable to register %s block device on major %d: %d\n", tr->name, tr->major, ret); kfree(tr->blkcore_priv); - up(&mtd_table_mutex); + mutex_unlock(&mtd_table_mutex); return ret; } spin_lock_init(&tr->blkcore_priv->queue_lock); @@ -396,7 +396,7 @@ int register_mtd_blktrans(struct mtd_blktrans_ops *tr) if (!tr->blkcore_priv->rq) { unregister_blkdev(tr->major, tr->name); kfree(tr->blkcore_priv); - up(&mtd_table_mutex); + mutex_unlock(&mtd_table_mutex); return -ENOMEM; } @@ -407,7 +407,7 @@ int register_mtd_blktrans(struct mtd_blktrans_ops *tr) blk_cleanup_queue(tr->blkcore_priv->rq); unregister_blkdev(tr->major, tr->name); kfree(tr->blkcore_priv); - up(&mtd_table_mutex); + mutex_unlock(&mtd_table_mutex); return ret; } @@ -419,7 +419,7 @@ int register_mtd_blktrans(struct mtd_blktrans_ops *tr) tr->add_mtd(tr, mtd_table[i]); } - up(&mtd_table_mutex); + mutex_unlock(&mtd_table_mutex); return 0; } @@ -428,7 +428,7 @@ int deregister_mtd_blktrans(struct mtd_blktrans_ops *tr) { struct list_head *this, *next; - down(&mtd_table_mutex); + mutex_lock(&mtd_table_mutex); /* Clean up the kernel thread */ tr->blkcore_priv->exiting = 1; @@ -446,7 +446,7 @@ int deregister_mtd_blktrans(struct mtd_blktrans_ops *tr) blk_cleanup_queue(tr->blkcore_priv->rq); unregister_blkdev(tr->major, tr->name); - up(&mtd_table_mutex); + mutex_unlock(&mtd_table_mutex); kfree(tr->blkcore_priv); diff --git a/drivers/mtd/mtdblock.c b/drivers/mtd/mtdblock.c index e84756644fd..2cef280e388 100644 --- a/drivers/mtd/mtdblock.c +++ b/drivers/mtd/mtdblock.c @@ -19,11 +19,13 @@ #include <linux/mtd/mtd.h> #include <linux/mtd/blktrans.h> +#include <linux/mutex.h> + static struct mtdblk_dev { struct mtd_info *mtd; int count; - struct semaphore cache_sem; + struct mutex cache_mutex; unsigned char *cache_data; unsigned long cache_offset; unsigned int cache_size; @@ -284,7 +286,7 @@ static int mtdblock_open(struct mtd_blktrans_dev *mbd) mtdblk->count = 1; mtdblk->mtd = mtd; - init_MUTEX (&mtdblk->cache_sem); + mutex_init(&mtdblk->cache_mutex); mtdblk->cache_state = STATE_EMPTY; if ((mtdblk->mtd->flags & MTD_CAP_RAM) != MTD_CAP_RAM && mtdblk->mtd->erasesize) { @@ -306,9 +308,9 @@ static int mtdblock_release(struct mtd_blktrans_dev *mbd) DEBUG(MTD_DEBUG_LEVEL1, "mtdblock_release\n"); - down(&mtdblk->cache_sem); + mutex_lock(&mtdblk->cache_mutex); write_cached_data(mtdblk); - up(&mtdblk->cache_sem); + mutex_unlock(&mtdblk->cache_mutex); if (!--mtdblk->count) { /* It was the last usage. Free the device */ @@ -327,9 +329,9 @@ static int mtdblock_flush(struct mtd_blktrans_dev *dev) { struct mtdblk_dev *mtdblk = mtdblks[dev->devnum]; - down(&mtdblk->cache_sem); + mutex_lock(&mtdblk->cache_mutex); write_cached_data(mtdblk); - up(&mtdblk->cache_sem); + mutex_unlock(&mtdblk->cache_mutex); if (mtdblk->mtd->sync) mtdblk->mtd->sync(mtdblk->mtd); diff --git a/drivers/mtd/mtdcore.c b/drivers/mtd/mtdcore.c index dade02ab068..9905870f56e 100644 --- a/drivers/mtd/mtdcore.c +++ b/drivers/mtd/mtdcore.c @@ -19,15 +19,13 @@ #include <linux/ioctl.h> #include <linux/init.h> #include <linux/mtd/compatmac.h> -#ifdef CONFIG_PROC_FS #include <linux/proc_fs.h> -#endif #include <linux/mtd/mtd.h> /* These are exported solely for the purpose of mtd_blkdevs.c. You should not use them for _anything_ else */ -DECLARE_MUTEX(mtd_table_mutex); +DEFINE_MUTEX(mtd_table_mutex); struct mtd_info *mtd_table[MAX_MTD_DEVICES]; EXPORT_SYMBOL_GPL(mtd_table_mutex); @@ -49,7 +47,7 @@ int add_mtd_device(struct mtd_info *mtd) { int i; - down(&mtd_table_mutex); + mutex_lock(&mtd_table_mutex); for (i=0; i < MAX_MTD_DEVICES; i++) if (!mtd_table[i]) { @@ -67,7 +65,7 @@ int add_mtd_device(struct mtd_info *mtd) not->add(mtd); } - up(&mtd_table_mutex); + mutex_unlock(&mtd_table_mutex); /* We _know_ we aren't being removed, because our caller is still holding us here. So none of this try_ nonsense, and no bitching about it @@ -76,7 +74,7 @@ int add_mtd_device(struct mtd_info *mtd) return 0; } - up(&mtd_table_mutex); + mutex_unlock(&mtd_table_mutex); return 1; } @@ -94,7 +92,7 @@ int del_mtd_device (struct mtd_info *mtd) { int ret; - down(&mtd_table_mutex); + mutex_lock(&mtd_table_mutex); if (mtd_table[mtd->index] != mtd) { ret = -ENODEV; @@ -118,7 +116,7 @@ int del_mtd_device (struct mtd_info *mtd) ret = 0; } - up(&mtd_table_mutex); + mutex_unlock(&mtd_table_mutex); return ret; } @@ -135,7 +133,7 @@ void register_mtd_user (struct mtd_notifier *new) { int i; - down(&mtd_table_mutex); + mutex_lock(&mtd_table_mutex); list_add(&new->list, &mtd_notifiers); @@ -145,7 +143,7 @@ void register_mtd_user (struct mtd_notifier *new) if (mtd_table[i]) new->add(mtd_table[i]); - up(&mtd_table_mutex); + mutex_unlock(&mtd_table_mutex); } /** @@ -162,7 +160,7 @@ int unregister_mtd_user (struct mtd_notifier *old) { int i; - down(&mtd_table_mutex); + mutex_lock(&mtd_table_mutex); module_put(THIS_MODULE); @@ -171,7 +169,7 @@ int unregister_mtd_user (struct mtd_notifier *old) old->remove(mtd_table[i]); list_del(&old->list); - up(&mtd_table_mutex); + mutex_unlock(&mtd_table_mutex); return 0; } @@ -193,7 +191,7 @@ struct mtd_info *get_mtd_device(struct mtd_info *mtd, int num) struct mtd_info *ret = NULL; int i; - down(&mtd_table_mutex); + mutex_lock(&mtd_table_mutex); if (num == -1) { for (i=0; i< MAX_MTD_DEVICES; i++) @@ -211,7 +209,7 @@ struct mtd_info *get_mtd_device(struct mtd_info *mtd, int num) if (ret) ret->usecount++; - up(&mtd_table_mutex); + mutex_unlock(&mtd_table_mutex); return ret; } @@ -219,9 +217,9 @@ void put_mtd_device(struct mtd_info *mtd) { int c; - down(&mtd_table_mutex); + mutex_lock(&mtd_table_mutex); c = --mtd->usecount; - up(&mtd_table_mutex); + mutex_unlock(&mtd_table_mutex); BUG_ON(c < 0); module_put(mtd->owner); @@ -296,10 +294,11 @@ EXPORT_SYMBOL(unregister_mtd_user); EXPORT_SYMBOL(default_mtd_writev); EXPORT_SYMBOL(default_mtd_readv); +#ifdef CONFIG_PROC_FS + /*====================================================================*/ /* Support for /proc/mtd */ -#ifdef CONFIG_PROC_FS static struct proc_dir_entry *proc_mtd; static inline int mtd_proc_info (char *buf, int i) @@ -319,7 +318,7 @@ static int mtd_read_proc (char *page, char **start, off_t off, int count, int len, l, i; off_t begin = 0; - down(&mtd_table_mutex); + mutex_lock(&mtd_table_mutex); len = sprintf(page, "dev: size erasesize name\n"); for (i=0; i< MAX_MTD_DEVICES; i++) { @@ -337,38 +336,34 @@ static int mtd_read_proc (char *page, char **start, off_t off, int count, *eof = 1; done: - up(&mtd_table_mutex); + mutex_unlock(&mtd_table_mutex); if (off >= len+begin) return 0; *start = page + (off-begin); return ((count < begin+len-off) ? count : begin+len-off); } -#endif /* CONFIG_PROC_FS */ - /*====================================================================*/ /* Init code */ static int __init init_mtd(void) { -#ifdef CONFIG_PROC_FS if ((proc_mtd = create_proc_entry( "mtd", 0, NULL ))) proc_mtd->read_proc = mtd_read_proc; -#endif return 0; } static void __exit cleanup_mtd(void) { -#ifdef CONFIG_PROC_FS if (proc_mtd) remove_proc_entry( "mtd", NULL); -#endif } module_init(init_mtd); module_exit(cleanup_mtd); +#endif /* CONFIG_PROC_FS */ + MODULE_LICENSE("GPL"); MODULE_AUTHOR("David Woodhouse <dwmw2@infradead.org>"); diff --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig index 1fc4c134d93..cfe288a6e85 100644 --- a/drivers/mtd/nand/Kconfig +++ b/drivers/mtd/nand/Kconfig @@ -178,17 +178,16 @@ config MTD_NAND_DISKONCHIP_BBTWRITE Even if you leave this disabled, you can enable BBT writes at module load time (assuming you build diskonchip as a module) with the module parameter "inftl_bbt_write=1". - - config MTD_NAND_SHARPSL - bool "Support for NAND Flash on Sharp SL Series (C7xx + others)" - depends on MTD_NAND && ARCH_PXA - - config MTD_NAND_NANDSIM - bool "Support for NAND Flash Simulator" - depends on MTD_NAND && MTD_PARTITIONS +config MTD_NAND_SHARPSL + tristate "Support for NAND Flash on Sharp SL Series (C7xx + others)" + depends on MTD_NAND && ARCH_PXA + +config MTD_NAND_NANDSIM + tristate "Support for NAND Flash Simulator" + depends on MTD_NAND && MTD_PARTITIONS help The simulator may simulate verious NAND flash chips for the MTD nand layer. - + endmenu diff --git a/drivers/mtd/nand/au1550nd.c b/drivers/mtd/nand/au1550nd.c index 201e1362da1..bde3550910a 100644 --- a/drivers/mtd/nand/au1550nd.c +++ b/drivers/mtd/nand/au1550nd.c @@ -55,8 +55,6 @@ static const struct mtd_partition partition_info[] = { .size = MTDPART_SIZ_FULL } }; -#define NB_OF(x) (sizeof(x)/sizeof(x[0])) - /** * au_read_byte - read one byte from the chip @@ -462,7 +460,7 @@ int __init au1xxx_nand_init (void) } /* Register the partitions */ - add_mtd_partitions(au1550_mtd, partition_info, NB_OF(partition_info)); + add_mtd_partitions(au1550_mtd, partition_info, ARRAY_SIZE(partition_info)); return 0; diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c index 5d222460b42..95e96fa1fce 100644 --- a/drivers/mtd/nand/nand_base.c +++ b/drivers/mtd/nand/nand_base.c @@ -80,6 +80,7 @@ #include <linux/mtd/compatmac.h> #include <linux/interrupt.h> #include <linux/bitops.h> +#include <linux/leds.h> #include <asm/io.h> #ifdef CONFIG_MTD_PARTITIONS @@ -515,6 +516,8 @@ static int nand_block_checkbad (struct mtd_info *mtd, loff_t ofs, int getchip, i return nand_isbad_bbt (mtd, ofs, allowbbt); } +DEFINE_LED_TRIGGER(nand_led_trigger); + /* * Wait for the ready pin, after a command * The timeout is catched later. @@ -524,12 +527,14 @@ static void nand_wait_ready(struct mtd_info *mtd) struct nand_chip *this = mtd->priv; unsigned long timeo = jiffies + 2; + led_trigger_event(nand_led_trigger, LED_FULL); /* wait until command is processed or timeout occures */ do { if (this->dev_ready(mtd)) - return; + break; touch_softlockup_watchdog(); } while (time_before(jiffies, timeo)); + led_trigger_event(nand_led_trigger, LED_OFF); } /** @@ -817,6 +822,8 @@ static int nand_wait(struct mtd_info *mtd, struct nand_chip *this, int state) else timeo += (HZ * 20) / 1000; + led_trigger_event(nand_led_trigger, LED_FULL); + /* Apply this short delay always to ensure that we do wait tWB in * any case on any machine. */ ndelay (100); @@ -840,6 +847,8 @@ static int nand_wait(struct mtd_info *mtd, struct nand_chip *this, int state) } cond_resched(); } + led_trigger_event(nand_led_trigger, LED_OFF); + status = (int) this->read_byte(mtd); return status; } @@ -2724,6 +2733,21 @@ void nand_release (struct mtd_info *mtd) EXPORT_SYMBOL_GPL (nand_scan); EXPORT_SYMBOL_GPL (nand_release); + +static int __init nand_base_init(void) +{ + led_trigger_register_simple("nand-disk", &nand_led_trigger); + return 0; +} + +static void __exit nand_base_exit(void) +{ + led_trigger_unregister_simple(nand_led_trigger); +} + +module_init(nand_base_init); +module_exit(nand_base_exit); + MODULE_LICENSE ("GPL"); MODULE_AUTHOR ("Steven J. Hill <sjhill@realitydiluted.com>, Thomas Gleixner <tglx@linutronix.de>"); MODULE_DESCRIPTION ("Generic NAND flash driver code"); diff --git a/drivers/mtd/redboot.c b/drivers/mtd/redboot.c index 8815c8dbef2..c077d2ec9cd 100644 --- a/drivers/mtd/redboot.c +++ b/drivers/mtd/redboot.c @@ -85,10 +85,6 @@ static int parse_redboot_partitions(struct mtd_info *master, numslots = (master->erasesize / sizeof(struct fis_image_desc)); for (i = 0; i < numslots; i++) { - if (buf[i].name[0] == 0xff) { - i = numslots; - break; - } if (!memcmp(buf[i].name, "FIS directory", 14)) { /* This is apparently the FIS directory entry for the * FIS directory itself. The FIS directory size is @@ -128,7 +124,7 @@ static int parse_redboot_partitions(struct mtd_info *master, struct fis_list *new_fl, **prev; if (buf[i].name[0] == 0xff) - break; + continue; if (!redboot_checksum(&buf[i])) break; diff --git a/drivers/net/3c59x.c b/drivers/net/3c59x.c index 70f63891b19..274b0138d44 100644 --- a/drivers/net/3c59x.c +++ b/drivers/net/3c59x.c @@ -788,7 +788,7 @@ struct vortex_private { int options; /* User-settable misc. driver options. */ unsigned int media_override:4, /* Passed-in media type. */ default_media:4, /* Read from the EEPROM/Wn3_Config. */ - full_duplex:1, force_fd:1, autoselect:1, + full_duplex:1, autoselect:1, bus_master:1, /* Vortex can only do a fragment bus-m. */ full_bus_master_tx:1, full_bus_master_rx:2, /* Boomerang */ flow_ctrl:1, /* Use 802.3x flow control (PAUSE only) */ @@ -1633,12 +1633,6 @@ vortex_set_duplex(struct net_device *dev) ((vp->full_duplex && vp->flow_ctrl && vp->partner_flow_ctrl) ? 0x100 : 0), ioaddr + Wn3_MAC_Ctrl); - - issue_and_wait(dev, TxReset); - /* - * Don't reset the PHY - that upsets autonegotiation during DHCP operations. - */ - issue_and_wait(dev, RxReset|0x04); } static void vortex_check_media(struct net_device *dev, unsigned int init) @@ -1663,7 +1657,7 @@ vortex_up(struct net_device *dev) struct vortex_private *vp = netdev_priv(dev); void __iomem *ioaddr = vp->ioaddr; unsigned int config; - int i; + int i, mii_reg1, mii_reg5; if (VORTEX_PCI(vp)) { pci_set_power_state(VORTEX_PCI(vp), PCI_D0); /* Go active */ @@ -1723,14 +1717,23 @@ vortex_up(struct net_device *dev) printk(KERN_DEBUG "vortex_up(): writing 0x%x to InternalConfig\n", config); iowrite32(config, ioaddr + Wn3_Config); - netif_carrier_off(dev); if (dev->if_port == XCVR_MII || dev->if_port == XCVR_NWAY) { EL3WINDOW(4); + mii_reg1 = mdio_read(dev, vp->phys[0], MII_BMSR); + mii_reg5 = mdio_read(dev, vp->phys[0], MII_LPA); + vp->partner_flow_ctrl = ((mii_reg5 & 0x0400) != 0); + vortex_check_media(dev, 1); } else vortex_set_duplex(dev); + issue_and_wait(dev, TxReset); + /* + * Don't reset the PHY - that upsets autonegotiation during DHCP operations. + */ + issue_and_wait(dev, RxReset|0x04); + iowrite16(SetStatusEnb | 0x00, ioaddr + EL3_CMD); @@ -2083,16 +2086,14 @@ vortex_error(struct net_device *dev, int status) } if (tx_status & 0x14) vp->stats.tx_fifo_errors++; if (tx_status & 0x38) vp->stats.tx_aborted_errors++; + if (tx_status & 0x08) vp->xstats.tx_max_collisions++; iowrite8(0, ioaddr + TxStatus); if (tx_status & 0x30) { /* txJabber or txUnderrun */ do_tx_reset = 1; - } else if (tx_status & 0x08) { /* maxCollisions */ - vp->xstats.tx_max_collisions++; - if (vp->drv_flags & MAX_COLLISION_RESET) { - do_tx_reset = 1; - reset_mask = 0x0108; /* Reset interface logic, but not download logic */ - } - } else { /* Merely re-enable the transmitter. */ + } else if ((tx_status & 0x08) && (vp->drv_flags & MAX_COLLISION_RESET)) { /* maxCollisions */ + do_tx_reset = 1; + reset_mask = 0x0108; /* Reset interface logic, but not download logic */ + } else { /* Merely re-enable the transmitter. */ iowrite16(TxEnable, ioaddr + EL3_CMD); } } diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index e20b849a22e..bdaaad8f212 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig @@ -2313,13 +2313,11 @@ config S2IO_NAPI endmenu -if !UML source "drivers/net/tokenring/Kconfig" source "drivers/net/wireless/Kconfig" source "drivers/net/pcmcia/Kconfig" -endif source "drivers/net/wan/Kconfig" diff --git a/drivers/net/arcnet/com90xx.c b/drivers/net/arcnet/com90xx.c index 43150b2bd13..0d45553ff75 100644 --- a/drivers/net/arcnet/com90xx.c +++ b/drivers/net/arcnet/com90xx.c @@ -125,11 +125,11 @@ static void __init com90xx_probe(void) if (!io && !irq && !shmem && !*device && com90xx_skip_probe) return; - shmems = kzalloc(((0x10000-0xa0000) / 0x800) * sizeof(unsigned long), + shmems = kzalloc(((0x100000-0xa0000) / 0x800) * sizeof(unsigned long), GFP_KERNEL); if (!shmems) return; - iomem = kzalloc(((0x10000-0xa0000) / 0x800) * sizeof(void __iomem *), + iomem = kzalloc(((0x100000-0xa0000) / 0x800) * sizeof(void __iomem *), GFP_KERNEL); if (!iomem) { kfree(shmems); diff --git a/drivers/net/ibmveth.c b/drivers/net/ibmveth.c index ceb98fd398a..52d01027d9e 100644 --- a/drivers/net/ibmveth.c +++ b/drivers/net/ibmveth.c @@ -235,7 +235,7 @@ static void ibmveth_replenish_buffer_pool(struct ibmveth_adapter *adapter, struc lpar_rc = h_add_logical_lan_buffer(adapter->vdev->unit_address, desc.desc); - if(lpar_rc != H_Success) { + if(lpar_rc != H_SUCCESS) { pool->free_map[free_index] = index; pool->skbuff[index] = NULL; pool->consumer_index--; @@ -373,7 +373,7 @@ static void ibmveth_rxq_recycle_buffer(struct ibmveth_adapter *adapter) lpar_rc = h_add_logical_lan_buffer(adapter->vdev->unit_address, desc.desc); - if(lpar_rc != H_Success) { + if(lpar_rc != H_SUCCESS) { ibmveth_debug_printk("h_add_logical_lan_buffer failed during recycle rc=%ld", lpar_rc); ibmveth_remove_buffer_from_pool(adapter, adapter->rx_queue.queue_addr[adapter->rx_queue.index].correlator); } @@ -511,7 +511,7 @@ static int ibmveth_open(struct net_device *netdev) adapter->filter_list_dma, mac_address); - if(lpar_rc != H_Success) { + if(lpar_rc != H_SUCCESS) { ibmveth_error_printk("h_register_logical_lan failed with %ld\n", lpar_rc); ibmveth_error_printk("buffer TCE:0x%lx filter TCE:0x%lx rxq desc:0x%lx MAC:0x%lx\n", adapter->buffer_list_dma, @@ -527,7 +527,7 @@ static int ibmveth_open(struct net_device *netdev) ibmveth_error_printk("unable to request irq 0x%x, rc %d\n", netdev->irq, rc); do { rc = h_free_logical_lan(adapter->vdev->unit_address); - } while (H_isLongBusy(rc) || (rc == H_Busy)); + } while (H_IS_LONG_BUSY(rc) || (rc == H_BUSY)); ibmveth_cleanup(adapter); return rc; @@ -556,9 +556,9 @@ static int ibmveth_close(struct net_device *netdev) do { lpar_rc = h_free_logical_lan(adapter->vdev->unit_address); - } while (H_isLongBusy(lpar_rc) || (lpar_rc == H_Busy)); + } while (H_IS_LONG_BUSY(lpar_rc) || (lpar_rc == H_BUSY)); - if(lpar_rc != H_Success) + if(lpar_rc != H_SUCCESS) { ibmveth_error_printk("h_free_logical_lan failed with %lx, continuing with close\n", lpar_rc); @@ -693,9 +693,9 @@ static int ibmveth_start_xmit(struct sk_buff *skb, struct net_device *netdev) desc[4].desc, desc[5].desc, correlator); - } while ((lpar_rc == H_Busy) && (retry_count--)); + } while ((lpar_rc == H_BUSY) && (retry_count--)); - if(lpar_rc != H_Success && lpar_rc != H_Dropped) { + if(lpar_rc != H_SUCCESS && lpar_rc != H_DROPPED) { int i; ibmveth_error_printk("tx: h_send_logical_lan failed with rc=%ld\n", lpar_rc); for(i = 0; i < 6; i++) { @@ -786,14 +786,14 @@ static int ibmveth_poll(struct net_device *netdev, int *budget) /* we think we are done - reenable interrupts, then check once more to make sure we are done */ lpar_rc = h_vio_signal(adapter->vdev->unit_address, VIO_IRQ_ENABLE); - ibmveth_assert(lpar_rc == H_Success); + ibmveth_assert(lpar_rc == H_SUCCESS); netif_rx_complete(netdev); if(ibmveth_rxq_pending_buffer(adapter) && netif_rx_reschedule(netdev, frames_processed)) { lpar_rc = h_vio_signal(adapter->vdev->unit_address, VIO_IRQ_DISABLE); - ibmveth_assert(lpar_rc == H_Success); + ibmveth_assert(lpar_rc == H_SUCCESS); more_work = 1; goto restart_poll; } @@ -813,7 +813,7 @@ static irqreturn_t ibmveth_interrupt(int irq, void *dev_instance, struct pt_regs if(netif_rx_schedule_prep(netdev)) { lpar_rc = h_vio_signal(adapter->vdev->unit_address, VIO_IRQ_DISABLE); - ibmveth_assert(lpar_rc == H_Success); + ibmveth_assert(lpar_rc == H_SUCCESS); __netif_rx_schedule(netdev); } return IRQ_HANDLED; @@ -835,7 +835,7 @@ static void ibmveth_set_multicast_list(struct net_device *netdev) IbmVethMcastEnableRecv | IbmVethMcastDisableFiltering, 0); - if(lpar_rc != H_Success) { + if(lpar_rc != H_SUCCESS) { ibmveth_error_printk("h_multicast_ctrl rc=%ld when entering promisc mode\n", lpar_rc); } } else { @@ -847,7 +847,7 @@ static void ibmveth_set_multicast_list(struct net_device *netdev) IbmVethMcastDisableFiltering | IbmVethMcastClearFilterTable, 0); - if(lpar_rc != H_Success) { + if(lpar_rc != H_SUCCESS) { ibmveth_error_printk("h_multicast_ctrl rc=%ld when attempting to clear filter table\n", lpar_rc); } /* add the addresses to the filter table */ @@ -858,7 +858,7 @@ static void ibmveth_set_multicast_list(struct net_device *netdev) lpar_rc = h_multicast_ctrl(adapter->vdev->unit_address, IbmVethMcastAddFilter, mcast_addr); - if(lpar_rc != H_Success) { + if(lpar_rc != H_SUCCESS) { ibmveth_error_printk("h_multicast_ctrl rc=%ld when adding an entry to the filter table\n", lpar_rc); } } @@ -867,7 +867,7 @@ static void ibmveth_set_multicast_list(struct net_device *netdev) lpar_rc = h_multicast_ctrl(adapter->vdev->unit_address, IbmVethMcastEnableFiltering, 0); - if(lpar_rc != H_Success) { + if(lpar_rc != H_SUCCESS) { ibmveth_error_printk("h_multicast_ctrl rc=%ld when enabling filtering\n", lpar_rc); } } diff --git a/drivers/net/netconsole.c b/drivers/net/netconsole.c index edd1b5306b1..75b35ad760d 100644 --- a/drivers/net/netconsole.c +++ b/drivers/net/netconsole.c @@ -94,7 +94,7 @@ static struct console netconsole = { static int option_setup(char *opt) { configured = !netpoll_parse_options(&np, opt); - return 0; + return 1; } __setup("netconsole=", option_setup); diff --git a/drivers/net/pcmcia/3c574_cs.c b/drivers/net/pcmcia/3c574_cs.c index ce90becb8bd..fab93360f01 100644 --- a/drivers/net/pcmcia/3c574_cs.c +++ b/drivers/net/pcmcia/3c574_cs.c @@ -204,7 +204,7 @@ enum Window4 { /* Window 4: Xcvr/media bits. */ #define MEDIA_TP 0x00C0 /* Enable link beat and jabber for 10baseT. */ struct el3_private { - dev_link_t link; + struct pcmcia_device *p_dev; dev_node_t node; struct net_device_stats stats; u16 advertising, partner; /* NWay media advertisement */ @@ -225,8 +225,8 @@ static char mii_preamble_required = 0; /* Index of functions. */ -static void tc574_config(dev_link_t *link); -static void tc574_release(dev_link_t *link); +static int tc574_config(struct pcmcia_device *link); +static void tc574_release(struct pcmcia_device *link); static void mdio_sync(kio_addr_t ioaddr, int bits); static int mdio_read(kio_addr_t ioaddr, int phy_id, int location); @@ -256,10 +256,9 @@ static void tc574_detach(struct pcmcia_device *p_dev); with Card Services. */ -static int tc574_attach(struct pcmcia_device *p_dev) +static int tc574_probe(struct pcmcia_device *link) { struct el3_private *lp; - dev_link_t *link; struct net_device *dev; DEBUG(0, "3c574_attach()\n"); @@ -269,8 +268,8 @@ static int tc574_attach(struct pcmcia_device *p_dev) if (!dev) return -ENOMEM; lp = netdev_priv(dev); - link = &lp->link; link->priv = dev; + lp->p_dev = link; spin_lock_init(&lp->window_lock); link->io.NumPorts1 = 32; @@ -280,7 +279,6 @@ static int tc574_attach(struct pcmcia_device *p_dev) link->irq.Handler = &el3_interrupt; link->irq.Instance = dev; link->conf.Attributes = CONF_ENABLE_IRQ; - link->conf.Vcc = 50; link->conf.IntType = INT_MEMORY_AND_IO; link->conf.ConfigIndex = 1; link->conf.Present = PRESENT_OPTION; @@ -298,13 +296,7 @@ static int tc574_attach(struct pcmcia_device *p_dev) dev->watchdog_timeo = TX_TIMEOUT; #endif - link->handle = p_dev; - p_dev->instance = link; - - link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; - tc574_config(link); - - return 0; + return tc574_config(link); } /* tc574_attach */ /* @@ -316,18 +308,16 @@ static int tc574_attach(struct pcmcia_device *p_dev) */ -static void tc574_detach(struct pcmcia_device *p_dev) +static void tc574_detach(struct pcmcia_device *link) { - dev_link_t *link = dev_to_instance(p_dev); struct net_device *dev = link->priv; DEBUG(0, "3c574_detach(0x%p)\n", link); - if (link->dev) + if (link->dev_node) unregister_netdev(dev); - if (link->state & DEV_CONFIG) - tc574_release(link); + tc574_release(link); free_netdev(dev); } /* tc574_detach */ @@ -343,9 +333,8 @@ static void tc574_detach(struct pcmcia_device *p_dev) static const char *ram_split[] = {"5:3", "3:1", "1:1", "3:5"}; -static void tc574_config(dev_link_t *link) +static int tc574_config(struct pcmcia_device *link) { - client_handle_t handle = link->handle; struct net_device *dev = link->priv; struct el3_private *lp = netdev_priv(dev); tuple_t tuple; @@ -363,30 +352,27 @@ static void tc574_config(dev_link_t *link) tuple.Attributes = 0; tuple.DesiredTuple = CISTPL_CONFIG; - CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple)); + CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); tuple.TupleData = (cisdata_t *)buf; tuple.TupleDataMax = 64; tuple.TupleOffset = 0; - CS_CHECK(GetTupleData, pcmcia_get_tuple_data(handle, &tuple)); - CS_CHECK(ParseTuple, pcmcia_parse_tuple(handle, &tuple, &parse)); + CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple)); + CS_CHECK(ParseTuple, pcmcia_parse_tuple(link, &tuple, &parse)); link->conf.ConfigBase = parse.config.base; link->conf.Present = parse.config.rmask[0]; - /* Configure card */ - link->state |= DEV_CONFIG; - link->io.IOAddrLines = 16; for (i = j = 0; j < 0x400; j += 0x20) { link->io.BasePort1 = j ^ 0x300; - i = pcmcia_request_io(link->handle, &link->io); + i = pcmcia_request_io(link, &link->io); if (i == CS_SUCCESS) break; } if (i != CS_SUCCESS) { - cs_error(link->handle, RequestIO, i); + cs_error(link, RequestIO, i); goto failed; } - CS_CHECK(RequestIRQ, pcmcia_request_irq(link->handle, &link->irq)); - CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link->handle, &link->conf)); + CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq)); + CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf)); dev->irq = link->irq.AssignedIRQ; dev->base_addr = link->io.BasePort1; @@ -397,8 +383,8 @@ static void tc574_config(dev_link_t *link) the hardware address. The future products may include a modem chip and put the address in the CIS. */ tuple.DesiredTuple = 0x88; - if (pcmcia_get_first_tuple(handle, &tuple) == CS_SUCCESS) { - pcmcia_get_tuple_data(handle, &tuple); + if (pcmcia_get_first_tuple(link, &tuple) == CS_SUCCESS) { + pcmcia_get_tuple_data(link, &tuple); for (i = 0; i < 3; i++) phys_addr[i] = htons(buf[i]); } else { @@ -412,9 +398,9 @@ static void tc574_config(dev_link_t *link) } } tuple.DesiredTuple = CISTPL_VERS_1; - if (pcmcia_get_first_tuple(handle, &tuple) == CS_SUCCESS && - pcmcia_get_tuple_data(handle, &tuple) == CS_SUCCESS && - pcmcia_parse_tuple(handle, &tuple, &parse) == CS_SUCCESS) { + if (pcmcia_get_first_tuple(link, &tuple) == CS_SUCCESS && + pcmcia_get_tuple_data(link, &tuple) == CS_SUCCESS && + pcmcia_parse_tuple(link, &tuple, &parse) == CS_SUCCESS) { cardname = parse.version_1.str + parse.version_1.ofs[1]; } else cardname = "3Com 3c574"; @@ -473,13 +459,12 @@ static void tc574_config(dev_link_t *link) } } - link->state &= ~DEV_CONFIG_PENDING; - link->dev = &lp->node; - SET_NETDEV_DEV(dev, &handle_to_dev(handle)); + link->dev_node = &lp->node; + SET_NETDEV_DEV(dev, &handle_to_dev(link)); if (register_netdev(dev) != 0) { printk(KERN_NOTICE "3c574_cs: register_netdev() failed\n"); - link->dev = NULL; + link->dev_node = NULL; goto failed; } @@ -493,13 +478,13 @@ static void tc574_config(dev_link_t *link) 8 << config.u.ram_size, ram_split[config.u.ram_split], config.u.autoselect ? "autoselect " : ""); - return; + return 0; cs_failed: - cs_error(link->handle, last_fn, last_ret); + cs_error(link, last_fn, last_ret); failed: tc574_release(link); - return; + return -ENODEV; } /* tc574_config */ @@ -509,44 +494,28 @@ failed: still open, this will be postponed until it is closed. */ -static void tc574_release(dev_link_t *link) +static void tc574_release(struct pcmcia_device *link) { - DEBUG(0, "3c574_release(0x%p)\n", link); - - pcmcia_release_configuration(link->handle); - pcmcia_release_io(link->handle, &link->io); - pcmcia_release_irq(link->handle, &link->irq); - - link->state &= ~DEV_CONFIG; + pcmcia_disable_device(link); } -static int tc574_suspend(struct pcmcia_device *p_dev) +static int tc574_suspend(struct pcmcia_device *link) { - dev_link_t *link = dev_to_instance(p_dev); struct net_device *dev = link->priv; - link->state |= DEV_SUSPEND; - if (link->state & DEV_CONFIG) { - if (link->open) - netif_device_detach(dev); - pcmcia_release_configuration(link->handle); - } + if (link->open) + netif_device_detach(dev); return 0; } -static int tc574_resume(struct pcmcia_device *p_dev) +static int tc574_resume(struct pcmcia_device *link) { - dev_link_t *link = dev_to_instance(p_dev); struct net_device *dev = link->priv; - link->state &= ~DEV_SUSPEND; - if (link->state & DEV_CONFIG) { - pcmcia_request_configuration(link->handle, &link->conf); - if (link->open) { - tc574_reset(dev); - netif_device_attach(dev); - } + if (link->open) { + tc574_reset(dev); + netif_device_attach(dev); } return 0; @@ -757,9 +726,9 @@ static void tc574_reset(struct net_device *dev) static int el3_open(struct net_device *dev) { struct el3_private *lp = netdev_priv(dev); - dev_link_t *link = &lp->link; + struct pcmcia_device *link = lp->p_dev; - if (!DEV_OK(link)) + if (!pcmcia_dev_present(link)) return -ENODEV; link->open++; @@ -1203,11 +1172,11 @@ static int el3_close(struct net_device *dev) { kio_addr_t ioaddr = dev->base_addr; struct el3_private *lp = netdev_priv(dev); - dev_link_t *link = &lp->link; + struct pcmcia_device *link = lp->p_dev; DEBUG(2, "%s: shutting down ethercard.\n", dev->name); - if (DEV_OK(link)) { + if (pcmcia_dev_present(link)) { unsigned long flags; /* Turn off statistics ASAP. We update lp->stats below. */ @@ -1246,7 +1215,7 @@ static struct pcmcia_driver tc574_driver = { .drv = { .name = "3c574_cs", }, - .probe = tc574_attach, + .probe = tc574_probe, .remove = tc574_detach, .id_table = tc574_ids, .suspend = tc574_suspend, diff --git a/drivers/net/pcmcia/3c589_cs.c b/drivers/net/pcmcia/3c589_cs.c index 3dba50849da..875a0fe251e 100644 --- a/drivers/net/pcmcia/3c589_cs.c +++ b/drivers/net/pcmcia/3c589_cs.c @@ -105,7 +105,7 @@ enum RxFilter { #define TX_TIMEOUT ((400*HZ)/1000) struct el3_private { - dev_link_t link; + struct pcmcia_device *p_dev; dev_node_t node; struct net_device_stats stats; /* For transceiver monitoring */ @@ -142,8 +142,8 @@ DRV_NAME ".c " DRV_VERSION " 2001/10/13 00:08:50 (David Hinds)"; /*====================================================================*/ -static void tc589_config(dev_link_t *link); -static void tc589_release(dev_link_t *link); +static int tc589_config(struct pcmcia_device *link); +static void tc589_release(struct pcmcia_device *link); static u16 read_eeprom(kio_addr_t ioaddr, int index); static void tc589_reset(struct net_device *dev); @@ -170,10 +170,9 @@ static void tc589_detach(struct pcmcia_device *p_dev); ======================================================================*/ -static int tc589_attach(struct pcmcia_device *p_dev) +static int tc589_probe(struct pcmcia_device *link) { struct el3_private *lp; - dev_link_t *link; struct net_device *dev; DEBUG(0, "3c589_attach()\n"); @@ -183,8 +182,8 @@ static int tc589_attach(struct pcmcia_device *p_dev) if (!dev) return -ENOMEM; lp = netdev_priv(dev); - link = &lp->link; link->priv = dev; + lp->p_dev = link; spin_lock_init(&lp->lock); link->io.NumPorts1 = 16; @@ -194,7 +193,6 @@ static int tc589_attach(struct pcmcia_device *p_dev) link->irq.Handler = &el3_interrupt; link->irq.Instance = dev; link->conf.Attributes = CONF_ENABLE_IRQ; - link->conf.Vcc = 50; link->conf.IntType = INT_MEMORY_AND_IO; link->conf.ConfigIndex = 1; link->conf.Present = PRESENT_OPTION; @@ -213,13 +211,7 @@ static int tc589_attach(struct pcmcia_device *p_dev) #endif SET_ETHTOOL_OPS(dev, &netdev_ethtool_ops); - link->handle = p_dev; - p_dev->instance = link; - - link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; - tc589_config(link); - - return 0; + return tc589_config(link); } /* tc589_attach */ /*====================================================================== @@ -231,18 +223,16 @@ static int tc589_attach(struct pcmcia_device *p_dev) ======================================================================*/ -static void tc589_detach(struct pcmcia_device *p_dev) +static void tc589_detach(struct pcmcia_device *link) { - dev_link_t *link = dev_to_instance(p_dev); struct net_device *dev = link->priv; DEBUG(0, "3c589_detach(0x%p)\n", link); - if (link->dev) + if (link->dev_node) unregister_netdev(dev); - if (link->state & DEV_CONFIG) - tc589_release(link); + tc589_release(link); free_netdev(dev); } /* tc589_detach */ @@ -258,9 +248,8 @@ static void tc589_detach(struct pcmcia_device *p_dev) #define CS_CHECK(fn, ret) \ do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0) -static void tc589_config(dev_link_t *link) +static int tc589_config(struct pcmcia_device *link) { - client_handle_t handle = link->handle; struct net_device *dev = link->priv; struct el3_private *lp = netdev_priv(dev); tuple_t tuple; @@ -275,43 +264,40 @@ static void tc589_config(dev_link_t *link) phys_addr = (u16 *)dev->dev_addr; tuple.Attributes = 0; tuple.DesiredTuple = CISTPL_CONFIG; - CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple)); + CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); tuple.TupleData = (cisdata_t *)buf; tuple.TupleDataMax = sizeof(buf); tuple.TupleOffset = 0; - CS_CHECK(GetTupleData, pcmcia_get_tuple_data(handle, &tuple)); - CS_CHECK(ParseTuple, pcmcia_parse_tuple(handle, &tuple, &parse)); + CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple)); + CS_CHECK(ParseTuple, pcmcia_parse_tuple(link, &tuple, &parse)); link->conf.ConfigBase = parse.config.base; link->conf.Present = parse.config.rmask[0]; /* Is this a 3c562? */ tuple.DesiredTuple = CISTPL_MANFID; tuple.Attributes = TUPLE_RETURN_COMMON; - if ((pcmcia_get_first_tuple(handle, &tuple) == CS_SUCCESS) && - (pcmcia_get_tuple_data(handle, &tuple) == CS_SUCCESS)) { + if ((pcmcia_get_first_tuple(link, &tuple) == CS_SUCCESS) && + (pcmcia_get_tuple_data(link, &tuple) == CS_SUCCESS)) { if (le16_to_cpu(buf[0]) != MANFID_3COM) printk(KERN_INFO "3c589_cs: hmmm, is this really a " "3Com card??\n"); multi = (le16_to_cpu(buf[1]) == PRODID_3COM_3C562); } - - /* Configure card */ - link->state |= DEV_CONFIG; /* For the 3c562, the base address must be xx00-xx7f */ link->io.IOAddrLines = 16; for (i = j = 0; j < 0x400; j += 0x10) { if (multi && (j & 0x80)) continue; link->io.BasePort1 = j ^ 0x300; - i = pcmcia_request_io(link->handle, &link->io); + i = pcmcia_request_io(link, &link->io); if (i == CS_SUCCESS) break; } if (i != CS_SUCCESS) { - cs_error(link->handle, RequestIO, i); + cs_error(link, RequestIO, i); goto failed; } - CS_CHECK(RequestIRQ, pcmcia_request_irq(link->handle, &link->irq)); - CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link->handle, &link->conf)); + CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq)); + CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf)); dev->irq = link->irq.AssignedIRQ; dev->base_addr = link->io.BasePort1; @@ -321,8 +307,8 @@ static void tc589_config(dev_link_t *link) /* The 3c589 has an extra EEPROM for configuration info, including the hardware address. The 3c562 puts the address in the CIS. */ tuple.DesiredTuple = 0x88; - if (pcmcia_get_first_tuple(handle, &tuple) == CS_SUCCESS) { - pcmcia_get_tuple_data(handle, &tuple); + if (pcmcia_get_first_tuple(link, &tuple) == CS_SUCCESS) { + pcmcia_get_tuple_data(link, &tuple); for (i = 0; i < 3; i++) phys_addr[i] = htons(buf[i]); } else { @@ -346,13 +332,12 @@ static void tc589_config(dev_link_t *link) else printk(KERN_ERR "3c589_cs: invalid if_port requested\n"); - link->dev = &lp->node; - link->state &= ~DEV_CONFIG_PENDING; - SET_NETDEV_DEV(dev, &handle_to_dev(handle)); + link->dev_node = &lp->node; + SET_NETDEV_DEV(dev, &handle_to_dev(link)); if (register_netdev(dev) != 0) { printk(KERN_ERR "3c589_cs: register_netdev() failed\n"); - link->dev = NULL; + link->dev_node = NULL; goto failed; } @@ -366,14 +351,13 @@ static void tc589_config(dev_link_t *link) printk(KERN_INFO " %dK FIFO split %s Rx:Tx, %s xcvr\n", (fifo & 7) ? 32 : 8, ram_split[(fifo >> 16) & 3], if_names[dev->if_port]); - return; + return 0; cs_failed: - cs_error(link->handle, last_fn, last_ret); + cs_error(link, last_fn, last_ret); failed: tc589_release(link); - return; - + return -ENODEV; } /* tc589_config */ /*====================================================================== @@ -384,44 +368,28 @@ failed: ======================================================================*/ -static void tc589_release(dev_link_t *link) +static void tc589_release(struct pcmcia_device *link) { - DEBUG(0, "3c589_release(0x%p)\n", link); - - pcmcia_release_configuration(link->handle); - pcmcia_release_io(link->handle, &link->io); - pcmcia_release_irq(link->handle, &link->irq); - - link->state &= ~DEV_CONFIG; + pcmcia_disable_device(link); } -static int tc589_suspend(struct pcmcia_device *p_dev) +static int tc589_suspend(struct pcmcia_device *link) { - dev_link_t *link = dev_to_instance(p_dev); struct net_device *dev = link->priv; - link->state |= DEV_SUSPEND; - if (link->state & DEV_CONFIG) { - if (link->open) - netif_device_detach(dev); - pcmcia_release_configuration(link->handle); - } + if (link->open) + netif_device_detach(dev); return 0; } -static int tc589_resume(struct pcmcia_device *p_dev) +static int tc589_resume(struct pcmcia_device *link) { - dev_link_t *link = dev_to_instance(p_dev); struct net_device *dev = link->priv; - link->state &= ~DEV_SUSPEND; - if (link->state & DEV_CONFIG) { - pcmcia_request_configuration(link->handle, &link->conf); - if (link->open) { - tc589_reset(dev); - netif_device_attach(dev); - } + if (link->open) { + tc589_reset(dev); + netif_device_attach(dev); } return 0; @@ -587,9 +555,9 @@ static int el3_config(struct net_device *dev, struct ifmap *map) static int el3_open(struct net_device *dev) { struct el3_private *lp = netdev_priv(dev); - dev_link_t *link = &lp->link; + struct pcmcia_device *link = lp->p_dev; - if (!DEV_OK(link)) + if (!pcmcia_dev_present(link)) return -ENODEV; link->open++; @@ -848,9 +816,9 @@ static struct net_device_stats *el3_get_stats(struct net_device *dev) { struct el3_private *lp = netdev_priv(dev); unsigned long flags; - dev_link_t *link = &lp->link; + struct pcmcia_device *link = lp->p_dev; - if (DEV_OK(link)) { + if (pcmcia_dev_present(link)) { spin_lock_irqsave(&lp->lock, flags); update_stats(dev); spin_unlock_irqrestore(&lp->lock, flags); @@ -950,11 +918,11 @@ static int el3_rx(struct net_device *dev) static void set_multicast_list(struct net_device *dev) { struct el3_private *lp = netdev_priv(dev); - dev_link_t *link = &lp->link; + struct pcmcia_device *link = lp->p_dev; kio_addr_t ioaddr = dev->base_addr; u16 opts = SetRxFilter | RxStation | RxBroadcast; - if (!(DEV_OK(link))) return; + if (!pcmcia_dev_present(link)) return; if (dev->flags & IFF_PROMISC) opts |= RxMulticast | RxProm; else if (dev->mc_count || (dev->flags & IFF_ALLMULTI)) @@ -965,12 +933,12 @@ static void set_multicast_list(struct net_device *dev) static int el3_close(struct net_device *dev) { struct el3_private *lp = netdev_priv(dev); - dev_link_t *link = &lp->link; + struct pcmcia_device *link = lp->p_dev; kio_addr_t ioaddr = dev->base_addr; DEBUG(1, "%s: shutting down ethercard.\n", dev->name); - if (DEV_OK(link)) { + if (pcmcia_dev_present(link)) { /* Turn off statistics ASAP. We update lp->stats below. */ outw(StatsDisable, ioaddr + EL3_CMD); @@ -1020,7 +988,7 @@ static struct pcmcia_driver tc589_driver = { .drv = { .name = "3c589_cs", }, - .probe = tc589_attach, + .probe = tc589_probe, .remove = tc589_detach, .id_table = tc589_ids, .suspend = tc589_suspend, diff --git a/drivers/net/pcmcia/axnet_cs.c b/drivers/net/pcmcia/axnet_cs.c index 1cc94b2d76c..56233afcb2b 100644 --- a/drivers/net/pcmcia/axnet_cs.c +++ b/drivers/net/pcmcia/axnet_cs.c @@ -86,8 +86,8 @@ static char *version = /*====================================================================*/ -static void axnet_config(dev_link_t *link); -static void axnet_release(dev_link_t *link); +static int axnet_config(struct pcmcia_device *link); +static void axnet_release(struct pcmcia_device *link); static int axnet_open(struct net_device *dev); static int axnet_close(struct net_device *dev); static int axnet_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); @@ -117,7 +117,7 @@ static irqreturn_t ax_interrupt(int irq, void *dev_id, struct pt_regs *regs); /*====================================================================*/ typedef struct axnet_dev_t { - dev_link_t link; + struct pcmcia_device *p_dev; dev_node_t node; caddr_t base; struct timer_list watchdog; @@ -142,10 +142,9 @@ static inline axnet_dev_t *PRIV(struct net_device *dev) ======================================================================*/ -static int axnet_attach(struct pcmcia_device *p_dev) +static int axnet_probe(struct pcmcia_device *link) { axnet_dev_t *info; - dev_link_t *link; struct net_device *dev; DEBUG(0, "axnet_attach()\n"); @@ -157,7 +156,7 @@ static int axnet_attach(struct pcmcia_device *p_dev) return -ENOMEM; info = PRIV(dev); - link = &info->link; + info->p_dev = link; link->priv = dev; link->irq.Attributes = IRQ_TYPE_EXCLUSIVE; link->irq.IRQInfo1 = IRQ_LEVEL_ID; @@ -169,13 +168,7 @@ static int axnet_attach(struct pcmcia_device *p_dev) dev->do_ioctl = &axnet_ioctl; SET_ETHTOOL_OPS(dev, &netdev_ethtool_ops); - link->handle = p_dev; - p_dev->instance = link; - - link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; - axnet_config(link); - - return 0; + return axnet_config(link); } /* axnet_attach */ /*====================================================================== @@ -187,18 +180,16 @@ static int axnet_attach(struct pcmcia_device *p_dev) ======================================================================*/ -static void axnet_detach(struct pcmcia_device *p_dev) +static void axnet_detach(struct pcmcia_device *link) { - dev_link_t *link = dev_to_instance(p_dev); struct net_device *dev = link->priv; DEBUG(0, "axnet_detach(0x%p)\n", link); - if (link->dev) + if (link->dev_node) unregister_netdev(dev); - if (link->state & DEV_CONFIG) - axnet_release(link); + axnet_release(link); free_netdev(dev); } /* axnet_detach */ @@ -209,7 +200,7 @@ static void axnet_detach(struct pcmcia_device *p_dev) ======================================================================*/ -static int get_prom(dev_link_t *link) +static int get_prom(struct pcmcia_device *link) { struct net_device *dev = link->priv; kio_addr_t ioaddr = dev->base_addr; @@ -263,7 +254,7 @@ static int get_prom(dev_link_t *link) #define CS_CHECK(fn, ret) \ do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0) -static int try_io_port(dev_link_t *link) +static int try_io_port(struct pcmcia_device *link) { int j, ret; if (link->io.NumPorts1 == 32) { @@ -284,25 +275,23 @@ static int try_io_port(dev_link_t *link) for (j = 0; j < 0x400; j += 0x20) { link->io.BasePort1 = j ^ 0x300; link->io.BasePort2 = (j ^ 0x300) + 0x10; - ret = pcmcia_request_io(link->handle, &link->io); + ret = pcmcia_request_io(link, &link->io); if (ret == CS_SUCCESS) return ret; } return ret; } else { - return pcmcia_request_io(link->handle, &link->io); + return pcmcia_request_io(link, &link->io); } } -static void axnet_config(dev_link_t *link) +static int axnet_config(struct pcmcia_device *link) { - client_handle_t handle = link->handle; struct net_device *dev = link->priv; axnet_dev_t *info = PRIV(dev); tuple_t tuple; cisparse_t parse; int i, j, last_ret, last_fn; u_short buf[64]; - config_info_t conf; DEBUG(0, "axnet_config(0x%p)\n", link); @@ -311,29 +300,22 @@ static void axnet_config(dev_link_t *link) tuple.TupleDataMax = sizeof(buf); tuple.TupleOffset = 0; tuple.DesiredTuple = CISTPL_CONFIG; - CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple)); - CS_CHECK(GetTupleData, pcmcia_get_tuple_data(handle, &tuple)); - CS_CHECK(ParseTuple, pcmcia_parse_tuple(handle, &tuple, &parse)); + CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); + CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple)); + CS_CHECK(ParseTuple, pcmcia_parse_tuple(link, &tuple, &parse)); link->conf.ConfigBase = parse.config.base; /* don't trust the CIS on this; Linksys got it wrong */ link->conf.Present = 0x63; - /* Configure card */ - link->state |= DEV_CONFIG; - - /* Look up current Vcc */ - CS_CHECK(GetConfigurationInfo, pcmcia_get_configuration_info(handle, &conf)); - link->conf.Vcc = conf.Vcc; - tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; tuple.Attributes = 0; - CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple)); + CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); while (last_ret == CS_SUCCESS) { cistpl_cftable_entry_t *cfg = &(parse.cftable_entry); cistpl_io_t *io = &(parse.cftable_entry.io); - if (pcmcia_get_tuple_data(handle, &tuple) != 0 || - pcmcia_parse_tuple(handle, &tuple, &parse) != 0 || + if (pcmcia_get_tuple_data(link, &tuple) != 0 || + pcmcia_parse_tuple(link, &tuple, &parse) != 0 || cfg->index == 0 || cfg->io.nwin == 0) goto next_entry; @@ -355,21 +337,21 @@ static void axnet_config(dev_link_t *link) if (last_ret == CS_SUCCESS) break; } next_entry: - last_ret = pcmcia_get_next_tuple(handle, &tuple); + last_ret = pcmcia_get_next_tuple(link, &tuple); } if (last_ret != CS_SUCCESS) { - cs_error(handle, RequestIO, last_ret); + cs_error(link, RequestIO, last_ret); goto failed; } - CS_CHECK(RequestIRQ, pcmcia_request_irq(handle, &link->irq)); + CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq)); if (link->io.NumPorts2 == 8) { link->conf.Attributes |= CONF_ENABLE_SPKR; link->conf.Status = CCSR_AUDIO_ENA; } - CS_CHECK(RequestConfiguration, pcmcia_request_configuration(handle, &link->conf)); + CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf)); dev->irq = link->irq.AssignedIRQ; dev->base_addr = link->io.BasePort1; @@ -406,7 +388,7 @@ static void axnet_config(dev_link_t *link) Bit 2 of CCSR is active low. */ if (i == 32) { conf_reg_t reg = { 0, CS_WRITE, CISREG_CCSR, 0x04 }; - pcmcia_access_configuration_register(link->handle, ®); + pcmcia_access_configuration_register(link, ®); for (i = 0; i < 32; i++) { j = mdio_read(dev->base_addr + AXNET_MII_EEP, i, 1); if ((j != 0) && (j != 0xffff)) break; @@ -414,13 +396,12 @@ static void axnet_config(dev_link_t *link) } info->phy_id = (i < 32) ? i : -1; - link->dev = &info->node; - link->state &= ~DEV_CONFIG_PENDING; - SET_NETDEV_DEV(dev, &handle_to_dev(handle)); + link->dev_node = &info->node; + SET_NETDEV_DEV(dev, &handle_to_dev(link)); if (register_netdev(dev) != 0) { printk(KERN_NOTICE "axnet_cs: register_netdev() failed\n"); - link->dev = NULL; + link->dev_node = NULL; goto failed; } @@ -436,14 +417,13 @@ static void axnet_config(dev_link_t *link) } else { printk(KERN_NOTICE " No MII transceivers found!\n"); } - return; + return 0; cs_failed: - cs_error(link->handle, last_fn, last_ret); + cs_error(link, last_fn, last_ret); failed: axnet_release(link); - link->state &= ~DEV_CONFIG_PENDING; - return; + return -ENODEV; } /* axnet_config */ /*====================================================================== @@ -454,45 +434,29 @@ failed: ======================================================================*/ -static void axnet_release(dev_link_t *link) +static void axnet_release(struct pcmcia_device *link) { - DEBUG(0, "axnet_release(0x%p)\n", link); - - pcmcia_release_configuration(link->handle); - pcmcia_release_io(link->handle, &link->io); - pcmcia_release_irq(link->handle, &link->irq); - - link->state &= ~DEV_CONFIG; + pcmcia_disable_device(link); } -static int axnet_suspend(struct pcmcia_device *p_dev) +static int axnet_suspend(struct pcmcia_device *link) { - dev_link_t *link = dev_to_instance(p_dev); struct net_device *dev = link->priv; - link->state |= DEV_SUSPEND; - if (link->state & DEV_CONFIG) { - if (link->open) - netif_device_detach(dev); - pcmcia_release_configuration(link->handle); - } + if (link->open) + netif_device_detach(dev); return 0; } -static int axnet_resume(struct pcmcia_device *p_dev) +static int axnet_resume(struct pcmcia_device *link) { - dev_link_t *link = dev_to_instance(p_dev); struct net_device *dev = link->priv; - link->state &= ~DEV_SUSPEND; - if (link->state & DEV_CONFIG) { - pcmcia_request_configuration(link->handle, &link->conf); - if (link->open) { - axnet_reset_8390(dev); - AX88190_init(dev, 1); - netif_device_attach(dev); - } + if (link->open) { + axnet_reset_8390(dev); + AX88190_init(dev, 1); + netif_device_attach(dev); } return 0; @@ -562,11 +526,11 @@ static void mdio_write(kio_addr_t addr, int phy_id, int loc, int value) static int axnet_open(struct net_device *dev) { axnet_dev_t *info = PRIV(dev); - dev_link_t *link = &info->link; + struct pcmcia_device *link = info->p_dev; DEBUG(2, "axnet_open('%s')\n", dev->name); - if (!DEV_OK(link)) + if (!pcmcia_dev_present(link)) return -ENODEV; link->open++; @@ -588,7 +552,7 @@ static int axnet_open(struct net_device *dev) static int axnet_close(struct net_device *dev) { axnet_dev_t *info = PRIV(dev); - dev_link_t *link = &info->link; + struct pcmcia_device *link = info->p_dev; DEBUG(2, "axnet_close('%s')\n", dev->name); @@ -833,7 +797,7 @@ static struct pcmcia_driver axnet_cs_driver = { .drv = { .name = "axnet_cs", }, - .probe = axnet_attach, + .probe = axnet_probe, .remove = axnet_detach, .id_table = axnet_ids, .suspend = axnet_suspend, diff --git a/drivers/net/pcmcia/com20020_cs.c b/drivers/net/pcmcia/com20020_cs.c index 2827a48ea37..441de824ab6 100644 --- a/drivers/net/pcmcia/com20020_cs.c +++ b/drivers/net/pcmcia/com20020_cs.c @@ -118,8 +118,8 @@ MODULE_LICENSE("GPL"); /*====================================================================*/ -static void com20020_config(dev_link_t *link); -static void com20020_release(dev_link_t *link); +static int com20020_config(struct pcmcia_device *link); +static void com20020_release(struct pcmcia_device *link); static void com20020_detach(struct pcmcia_device *p_dev); @@ -138,9 +138,8 @@ typedef struct com20020_dev_t { ======================================================================*/ -static int com20020_attach(struct pcmcia_device *p_dev) +static int com20020_probe(struct pcmcia_device *p_dev) { - dev_link_t *link; com20020_dev_t *info; struct net_device *dev; struct arcnet_local *lp; @@ -148,10 +147,6 @@ static int com20020_attach(struct pcmcia_device *p_dev) DEBUG(0, "com20020_attach()\n"); /* Create new network device */ - link = kmalloc(sizeof(struct dev_link_t), GFP_KERNEL); - if (!link) - return -ENOMEM; - info = kmalloc(sizeof(struct com20020_dev_t), GFP_KERNEL); if (!info) goto fail_alloc_info; @@ -161,7 +156,6 @@ static int com20020_attach(struct pcmcia_device *p_dev) goto fail_alloc_dev; memset(info, 0, sizeof(struct com20020_dev_t)); - memset(link, 0, sizeof(struct dev_link_t)); lp = dev->priv; lp->timeout = timeout; lp->backplane = backplane; @@ -172,28 +166,23 @@ static int com20020_attach(struct pcmcia_device *p_dev) /* fill in our module parameters as defaults */ dev->dev_addr[0] = node; - link->io.Attributes1 = IO_DATA_PATH_WIDTH_8; - link->io.NumPorts1 = 16; - link->io.IOAddrLines = 16; - link->irq.Attributes = IRQ_TYPE_EXCLUSIVE; - link->irq.IRQInfo1 = IRQ_LEVEL_ID; - link->conf.Attributes = CONF_ENABLE_IRQ; - link->conf.Vcc = 50; - link->conf.IntType = INT_MEMORY_AND_IO; - link->conf.Present = PRESENT_OPTION; - - link->irq.Instance = info->dev = dev; - link->priv = info; + p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_8; + p_dev->io.NumPorts1 = 16; + p_dev->io.IOAddrLines = 16; + p_dev->irq.Attributes = IRQ_TYPE_EXCLUSIVE; + p_dev->irq.IRQInfo1 = IRQ_LEVEL_ID; + p_dev->conf.Attributes = CONF_ENABLE_IRQ; + p_dev->conf.IntType = INT_MEMORY_AND_IO; + p_dev->conf.Present = PRESENT_OPTION; - link->state |= DEV_PRESENT; - com20020_config(link); + p_dev->irq.Instance = info->dev = dev; + p_dev->priv = info; - return 0; + return com20020_config(p_dev); fail_alloc_dev: kfree(info); fail_alloc_info: - kfree(link); return -ENOMEM; } /* com20020_attach */ @@ -206,9 +195,8 @@ fail_alloc_info: ======================================================================*/ -static void com20020_detach(struct pcmcia_device *p_dev) +static void com20020_detach(struct pcmcia_device *link) { - dev_link_t *link = dev_to_instance(p_dev); struct com20020_dev_t *info = link->priv; struct net_device *dev = info->dev; @@ -216,7 +204,7 @@ static void com20020_detach(struct pcmcia_device *p_dev) DEBUG(0, "com20020_detach(0x%p)\n", link); - if (link->dev) { + if (link->dev_node) { DEBUG(1,"unregister...\n"); unregister_netdev(dev); @@ -229,8 +217,7 @@ static void com20020_detach(struct pcmcia_device *p_dev) free_irq(dev->irq, dev); } - if (link->state & DEV_CONFIG) - com20020_release(link); + com20020_release(link); /* Unlink device structure, free bits */ DEBUG(1,"unlinking...\n"); @@ -245,8 +232,6 @@ static void com20020_detach(struct pcmcia_device *p_dev) DEBUG(1,"kfree2...\n"); kfree(info); } - DEBUG(1,"kfree3...\n"); - kfree(link); } /* com20020_detach */ @@ -261,10 +246,9 @@ static void com20020_detach(struct pcmcia_device *p_dev) #define CS_CHECK(fn, ret) \ do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0) -static void com20020_config(dev_link_t *link) +static int com20020_config(struct pcmcia_device *link) { struct arcnet_local *lp; - client_handle_t handle; tuple_t tuple; cisparse_t parse; com20020_dev_t *info; @@ -273,7 +257,6 @@ static void com20020_config(dev_link_t *link) u_char buf[64]; int ioaddr; - handle = link->handle; info = link->priv; dev = info->dev; @@ -286,14 +269,11 @@ static void com20020_config(dev_link_t *link) tuple.TupleDataMax = 64; tuple.TupleOffset = 0; tuple.DesiredTuple = CISTPL_CONFIG; - CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple)); - CS_CHECK(GetTupleData, pcmcia_get_tuple_data(handle, &tuple)); - CS_CHECK(ParseTuple, pcmcia_parse_tuple(handle, &tuple, &parse)); + CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); + CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple)); + CS_CHECK(ParseTuple, pcmcia_parse_tuple(link, &tuple, &parse)); link->conf.ConfigBase = parse.config.base; - /* Configure card */ - link->state |= DEV_CONFIG; - DEBUG(1,"arcnet: baseport1 is %Xh\n", link->io.BasePort1); i = !CS_SUCCESS; if (!link->io.BasePort1) @@ -301,13 +281,13 @@ static void com20020_config(dev_link_t *link) for (ioaddr = 0x100; ioaddr < 0x400; ioaddr += 0x10) { link->io.BasePort1 = ioaddr; - i = pcmcia_request_io(link->handle, &link->io); + i = pcmcia_request_io(link, &link->io); if (i == CS_SUCCESS) break; } } else - i = pcmcia_request_io(link->handle, &link->io); + i = pcmcia_request_io(link, &link->io); if (i != CS_SUCCESS) { @@ -321,7 +301,7 @@ static void com20020_config(dev_link_t *link) DEBUG(1,"arcnet: request IRQ %d (%Xh/%Xh)\n", link->irq.AssignedIRQ, link->irq.IRQInfo1, link->irq.IRQInfo2); - i = pcmcia_request_irq(link->handle, &link->irq); + i = pcmcia_request_irq(link, &link->irq); if (i != CS_SUCCESS) { DEBUG(1,"arcnet: requestIRQ failed totally!\n"); @@ -330,7 +310,7 @@ static void com20020_config(dev_link_t *link) dev->irq = link->irq.AssignedIRQ; - CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link->handle, &link->conf)); + CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf)); if (com20020_check(dev)) { @@ -342,15 +322,14 @@ static void com20020_config(dev_link_t *link) lp->card_name = "PCMCIA COM20020"; lp->card_flags = ARC_CAN_10MBIT; /* pretend all of them can 10Mbit */ - link->dev = &info->node; - link->state &= ~DEV_CONFIG_PENDING; - SET_NETDEV_DEV(dev, &handle_to_dev(handle)); + link->dev_node = &info->node; + SET_NETDEV_DEV(dev, &handle_to_dev(link)); i = com20020_found(dev, 0); /* calls register_netdev */ if (i != 0) { DEBUG(1,KERN_NOTICE "com20020_cs: com20020_found() failed\n"); - link->dev = NULL; + link->dev_node = NULL; goto failed; } @@ -358,13 +337,14 @@ static void com20020_config(dev_link_t *link) DEBUG(1,KERN_INFO "%s: port %#3lx, irq %d\n", dev->name, dev->base_addr, dev->irq); - return; + return 0; cs_failed: - cs_error(link->handle, last_fn, last_ret); + cs_error(link, last_fn, last_ret); failed: DEBUG(1,"com20020_config failed...\n"); com20020_release(link); + return -ENODEV; } /* com20020_config */ /*====================================================================== @@ -375,52 +355,33 @@ failed: ======================================================================*/ -static void com20020_release(dev_link_t *link) +static void com20020_release(struct pcmcia_device *link) { - - DEBUG(1,"release...\n"); - - DEBUG(0, "com20020_release(0x%p)\n", link); - - pcmcia_release_configuration(link->handle); - pcmcia_release_io(link->handle, &link->io); - pcmcia_release_irq(link->handle, &link->irq); - - link->state &= ~(DEV_CONFIG | DEV_RELEASE_PENDING); + DEBUG(0, "com20020_release(0x%p)\n", link); + pcmcia_disable_device(link); } -static int com20020_suspend(struct pcmcia_device *p_dev) +static int com20020_suspend(struct pcmcia_device *link) { - dev_link_t *link = dev_to_instance(p_dev); com20020_dev_t *info = link->priv; struct net_device *dev = info->dev; - link->state |= DEV_SUSPEND; - if (link->state & DEV_CONFIG) { - if (link->open) { - netif_device_detach(dev); - } - pcmcia_release_configuration(link->handle); - } + if (link->open) + netif_device_detach(dev); return 0; } -static int com20020_resume(struct pcmcia_device *p_dev) +static int com20020_resume(struct pcmcia_device *link) { - dev_link_t *link = dev_to_instance(p_dev); com20020_dev_t *info = link->priv; struct net_device *dev = info->dev; - link->state &= ~DEV_SUSPEND; - if (link->state & DEV_CONFIG) { - pcmcia_request_configuration(link->handle, &link->conf); - if (link->open) { - int ioaddr = dev->base_addr; - struct arcnet_local *lp = dev->priv; - ARCRESET; - } - } + if (link->open) { + int ioaddr = dev->base_addr; + struct arcnet_local *lp = dev->priv; + ARCRESET; + } return 0; } @@ -436,7 +397,7 @@ static struct pcmcia_driver com20020_cs_driver = { .drv = { .name = "com20020_cs", }, - .probe = com20020_attach, + .probe = com20020_probe, .remove = com20020_detach, .id_table = com20020_ids, .suspend = com20020_suspend, diff --git a/drivers/net/pcmcia/fmvj18x_cs.c b/drivers/net/pcmcia/fmvj18x_cs.c index b7ac14ba887..09b11761cdf 100644 --- a/drivers/net/pcmcia/fmvj18x_cs.c +++ b/drivers/net/pcmcia/fmvj18x_cs.c @@ -84,10 +84,10 @@ static char *version = DRV_NAME ".c " DRV_VERSION " 2002/03/23"; /* PCMCIA event handlers */ -static void fmvj18x_config(dev_link_t *link); -static int fmvj18x_get_hwinfo(dev_link_t *link, u_char *node_id); -static int fmvj18x_setup_mfc(dev_link_t *link); -static void fmvj18x_release(dev_link_t *link); +static int fmvj18x_config(struct pcmcia_device *link); +static int fmvj18x_get_hwinfo(struct pcmcia_device *link, u_char *node_id); +static int fmvj18x_setup_mfc(struct pcmcia_device *link); +static void fmvj18x_release(struct pcmcia_device *link); static void fmvj18x_detach(struct pcmcia_device *p_dev); /* @@ -116,7 +116,7 @@ typedef enum { MBH10302, MBH10304, TDK, CONTEC, LA501, UNGERMANN, driver specific data structure */ typedef struct local_info_t { - dev_link_t link; + struct pcmcia_device *p_dev; dev_node_t node; struct net_device_stats stats; long open_time; @@ -228,10 +228,9 @@ typedef struct local_info_t { #define BANK_1U 0x24 /* bank 1 (CONFIG_1) */ #define BANK_2U 0x28 /* bank 2 (CONFIG_1) */ -static int fmvj18x_attach(struct pcmcia_device *p_dev) +static int fmvj18x_probe(struct pcmcia_device *link) { local_info_t *lp; - dev_link_t *link; struct net_device *dev; DEBUG(0, "fmvj18x_attach()\n"); @@ -241,8 +240,8 @@ static int fmvj18x_attach(struct pcmcia_device *p_dev) if (!dev) return -ENOMEM; lp = netdev_priv(dev); - link = &lp->link; link->priv = dev; + lp->p_dev = link; /* The io structure describes IO port mapping */ link->io.NumPorts1 = 32; @@ -257,7 +256,6 @@ static int fmvj18x_attach(struct pcmcia_device *p_dev) /* General socket configuration */ link->conf.Attributes = CONF_ENABLE_IRQ; - link->conf.Vcc = 50; link->conf.IntType = INT_MEMORY_AND_IO; /* The FMVJ18x specific entries in the device structure. */ @@ -274,29 +272,21 @@ static int fmvj18x_attach(struct pcmcia_device *p_dev) #endif SET_ETHTOOL_OPS(dev, &netdev_ethtool_ops); - link->handle = p_dev; - p_dev->instance = link; - - link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; - fmvj18x_config(link); - - return 0; + return fmvj18x_config(link); } /* fmvj18x_attach */ /*====================================================================*/ -static void fmvj18x_detach(struct pcmcia_device *p_dev) +static void fmvj18x_detach(struct pcmcia_device *link) { - dev_link_t *link = dev_to_instance(p_dev); struct net_device *dev = link->priv; DEBUG(0, "fmvj18x_detach(0x%p)\n", link); - if (link->dev) + if (link->dev_node) unregister_netdev(dev); - if (link->state & DEV_CONFIG) - fmvj18x_release(link); + fmvj18x_release(link); free_netdev(dev); } /* fmvj18x_detach */ @@ -306,7 +296,7 @@ static void fmvj18x_detach(struct pcmcia_device *p_dev) #define CS_CHECK(fn, ret) \ do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0) -static int mfc_try_io_port(dev_link_t *link) +static int mfc_try_io_port(struct pcmcia_device *link) { int i, ret; static const kio_addr_t serial_base[5] = { 0x3f8, 0x2f8, 0x3e8, 0x2e8, 0x0 }; @@ -318,13 +308,13 @@ static int mfc_try_io_port(dev_link_t *link) link->io.NumPorts2 = 0; printk(KERN_NOTICE "fmvj18x_cs: out of resource for serial\n"); } - ret = pcmcia_request_io(link->handle, &link->io); + ret = pcmcia_request_io(link, &link->io); if (ret == CS_SUCCESS) return ret; } return ret; } -static int ungermann_try_io_port(dev_link_t *link) +static int ungermann_try_io_port(struct pcmcia_device *link) { int ret; kio_addr_t ioaddr; @@ -334,7 +324,7 @@ static int ungermann_try_io_port(dev_link_t *link) */ for (ioaddr = 0x300; ioaddr < 0x3e0; ioaddr += 0x20) { link->io.BasePort1 = ioaddr; - ret = pcmcia_request_io(link->handle, &link->io); + ret = pcmcia_request_io(link, &link->io); if (ret == CS_SUCCESS) { /* calculate ConfigIndex value */ link->conf.ConfigIndex = @@ -345,9 +335,8 @@ static int ungermann_try_io_port(dev_link_t *link) return ret; /* RequestIO failed */ } -static void fmvj18x_config(dev_link_t *link) +static int fmvj18x_config(struct pcmcia_device *link) { - client_handle_t handle = link->handle; struct net_device *dev = link->priv; local_info_t *lp = netdev_priv(dev); tuple_t tuple; @@ -366,42 +355,34 @@ static void fmvj18x_config(dev_link_t *link) registers. */ tuple.DesiredTuple = CISTPL_CONFIG; - CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple)); + CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); tuple.TupleData = (u_char *)buf; tuple.TupleDataMax = 64; tuple.TupleOffset = 0; - CS_CHECK(GetTupleData, pcmcia_get_tuple_data(handle, &tuple)); - CS_CHECK(ParseTuple, pcmcia_parse_tuple(handle, &tuple, &parse)); - - /* Configure card */ - link->state |= DEV_CONFIG; + CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple)); + CS_CHECK(ParseTuple, pcmcia_parse_tuple(link, &tuple, &parse)); link->conf.ConfigBase = parse.config.base; link->conf.Present = parse.config.rmask[0]; tuple.DesiredTuple = CISTPL_FUNCE; tuple.TupleOffset = 0; - if (pcmcia_get_first_tuple(handle, &tuple) == CS_SUCCESS) { + if (pcmcia_get_first_tuple(link, &tuple) == CS_SUCCESS) { /* Yes, I have CISTPL_FUNCE. Let's check CISTPL_MANFID */ tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; - CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple)); - CS_CHECK(GetTupleData, pcmcia_get_tuple_data(handle, &tuple)); - CS_CHECK(ParseTuple, pcmcia_parse_tuple(handle, &tuple, &parse)); + CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); + CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple)); + CS_CHECK(ParseTuple, pcmcia_parse_tuple(link, &tuple, &parse)); link->conf.ConfigIndex = parse.cftable_entry.index; tuple.DesiredTuple = CISTPL_MANFID; - if (pcmcia_get_first_tuple(handle, &tuple) == CS_SUCCESS) - CS_CHECK(GetTupleData, pcmcia_get_tuple_data(handle, &tuple)); + if (pcmcia_get_first_tuple(link, &tuple) == CS_SUCCESS) + CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple)); else buf[0] = 0xffff; switch (le16_to_cpu(buf[0])) { case MANFID_TDK: cardtype = TDK; - if (le16_to_cpu(buf[1]) == PRODID_TDK_CF010) { - cs_status_t status; - pcmcia_get_status(handle, &status); - if (status.CardState & CS_EVENT_3VCARD) - link->conf.Vcc = 33; /* inserted in 3.3V slot */ - } else if (le16_to_cpu(buf[1]) == PRODID_TDK_GN3410 + if (le16_to_cpu(buf[1]) == PRODID_TDK_GN3410 || le16_to_cpu(buf[1]) == PRODID_TDK_NP9610 || le16_to_cpu(buf[1]) == PRODID_TDK_MN3200) { /* MultiFunction Card */ @@ -429,8 +410,8 @@ static void fmvj18x_config(dev_link_t *link) } else { /* old type card */ tuple.DesiredTuple = CISTPL_MANFID; - if (pcmcia_get_first_tuple(handle, &tuple) == CS_SUCCESS) - CS_CHECK(GetTupleData, pcmcia_get_tuple_data(handle, &tuple)); + if (pcmcia_get_first_tuple(link, &tuple) == CS_SUCCESS) + CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple)); else buf[0] = 0xffff; switch (le16_to_cpu(buf[0])) { @@ -461,10 +442,10 @@ static void fmvj18x_config(dev_link_t *link) ret = ungermann_try_io_port(link); if (ret != CS_SUCCESS) goto cs_failed; } else { - CS_CHECK(RequestIO, pcmcia_request_io(link->handle, &link->io)); + CS_CHECK(RequestIO, pcmcia_request_io(link, &link->io)); } - CS_CHECK(RequestIRQ, pcmcia_request_irq(link->handle, &link->irq)); - CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link->handle, &link->conf)); + CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq)); + CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf)); dev->irq = link->irq.AssignedIRQ; dev->base_addr = link->io.BasePort1; @@ -493,17 +474,17 @@ static void fmvj18x_config(dev_link_t *link) case CONTEC: tuple.DesiredTuple = CISTPL_FUNCE; tuple.TupleOffset = 0; - CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple)); + CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); tuple.TupleOffset = 0; - CS_CHECK(GetTupleData, pcmcia_get_tuple_data(handle, &tuple)); + CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple)); if (cardtype == MBH10304) { /* MBH10304's CIS_FUNCE is corrupted */ node_id = &(tuple.TupleData[5]); card_name = "FMV-J182"; } else { while (tuple.TupleData[0] != CISTPL_FUNCE_LAN_NODE_ID ) { - CS_CHECK(GetNextTuple, pcmcia_get_next_tuple(handle, &tuple)); - CS_CHECK(GetTupleData, pcmcia_get_tuple_data(handle, &tuple)); + CS_CHECK(GetNextTuple, pcmcia_get_next_tuple(link, &tuple)); + CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple)); } node_id = &(tuple.TupleData[2]); if( cardtype == TDK ) { @@ -545,13 +526,12 @@ static void fmvj18x_config(dev_link_t *link) } lp->cardtype = cardtype; - link->dev = &lp->node; - link->state &= ~DEV_CONFIG_PENDING; - SET_NETDEV_DEV(dev, &handle_to_dev(handle)); + link->dev_node = &lp->node; + SET_NETDEV_DEV(dev, &handle_to_dev(link)); if (register_netdev(dev) != 0) { printk(KERN_NOTICE "fmvj18x_cs: register_netdev() failed\n"); - link->dev = NULL; + link->dev_node = NULL; goto failed; } @@ -564,19 +544,18 @@ static void fmvj18x_config(dev_link_t *link) for (i = 0; i < 6; i++) printk("%02X%s", dev->dev_addr[i], ((i<5) ? ":" : "\n")); - return; + return 0; cs_failed: /* All Card Services errors end up here */ - cs_error(link->handle, last_fn, last_ret); + cs_error(link, last_fn, last_ret); failed: fmvj18x_release(link); - link->state &= ~DEV_CONFIG_PENDING; - + return -ENODEV; } /* fmvj18x_config */ /*====================================================================*/ -static int fmvj18x_get_hwinfo(dev_link_t *link, u_char *node_id) +static int fmvj18x_get_hwinfo(struct pcmcia_device *link, u_char *node_id) { win_req_t req; memreq_t mem; @@ -587,9 +566,9 @@ static int fmvj18x_get_hwinfo(dev_link_t *link, u_char *node_id) req.Attributes = WIN_DATA_WIDTH_8|WIN_MEMORY_TYPE_AM|WIN_ENABLE; req.Base = 0; req.Size = 0; req.AccessSpeed = 0; - i = pcmcia_request_window(&link->handle, &req, &link->win); + i = pcmcia_request_window(&link, &req, &link->win); if (i != CS_SUCCESS) { - cs_error(link->handle, RequestWindow, i); + cs_error(link, RequestWindow, i); return -1; } @@ -623,13 +602,13 @@ static int fmvj18x_get_hwinfo(dev_link_t *link, u_char *node_id) iounmap(base); j = pcmcia_release_window(link->win); if (j != CS_SUCCESS) - cs_error(link->handle, ReleaseWindow, j); + cs_error(link, ReleaseWindow, j); return (i != 0x200) ? 0 : -1; } /* fmvj18x_get_hwinfo */ /*====================================================================*/ -static int fmvj18x_setup_mfc(dev_link_t *link) +static int fmvj18x_setup_mfc(struct pcmcia_device *link) { win_req_t req; memreq_t mem; @@ -642,9 +621,9 @@ static int fmvj18x_setup_mfc(dev_link_t *link) req.Attributes = WIN_DATA_WIDTH_8|WIN_MEMORY_TYPE_AM|WIN_ENABLE; req.Base = 0; req.Size = 0; req.AccessSpeed = 0; - i = pcmcia_request_window(&link->handle, &req, &link->win); + i = pcmcia_request_window(&link, &req, &link->win); if (i != CS_SUCCESS) { - cs_error(link->handle, RequestWindow, i); + cs_error(link, RequestWindow, i); return -1; } @@ -666,54 +645,35 @@ static int fmvj18x_setup_mfc(dev_link_t *link) iounmap(base); j = pcmcia_release_window(link->win); if (j != CS_SUCCESS) - cs_error(link->handle, ReleaseWindow, j); + cs_error(link, ReleaseWindow, j); return 0; } /*====================================================================*/ -static void fmvj18x_release(dev_link_t *link) +static void fmvj18x_release(struct pcmcia_device *link) { - - DEBUG(0, "fmvj18x_release(0x%p)\n", link); - - /* Don't bother checking to see if these succeed or not */ - pcmcia_release_window(link->win); - pcmcia_release_configuration(link->handle); - pcmcia_release_io(link->handle, &link->io); - pcmcia_release_irq(link->handle, &link->irq); - - link->state &= ~DEV_CONFIG; + DEBUG(0, "fmvj18x_release(0x%p)\n", link); + pcmcia_disable_device(link); } -static int fmvj18x_suspend(struct pcmcia_device *p_dev) +static int fmvj18x_suspend(struct pcmcia_device *link) { - dev_link_t *link = dev_to_instance(p_dev); struct net_device *dev = link->priv; - link->state |= DEV_SUSPEND; - if (link->state & DEV_CONFIG) { - if (link->open) - netif_device_detach(dev); - pcmcia_release_configuration(link->handle); - } - + if (link->open) + netif_device_detach(dev); return 0; } -static int fmvj18x_resume(struct pcmcia_device *p_dev) +static int fmvj18x_resume(struct pcmcia_device *link) { - dev_link_t *link = dev_to_instance(p_dev); struct net_device *dev = link->priv; - link->state &= ~DEV_SUSPEND; - if (link->state & DEV_CONFIG) { - pcmcia_request_configuration(link->handle, &link->conf); - if (link->open) { - fjn_reset(dev); - netif_device_attach(dev); - } + if (link->open) { + fjn_reset(dev); + netif_device_attach(dev); } return 0; @@ -751,7 +711,7 @@ static struct pcmcia_driver fmvj18x_cs_driver = { .drv = { .name = "fmvj18x_cs", }, - .probe = fmvj18x_attach, + .probe = fmvj18x_probe, .remove = fmvj18x_detach, .id_table = fmvj18x_ids, .suspend = fmvj18x_suspend, @@ -1148,11 +1108,11 @@ static int fjn_config(struct net_device *dev, struct ifmap *map){ static int fjn_open(struct net_device *dev) { struct local_info_t *lp = netdev_priv(dev); - dev_link_t *link = &lp->link; + struct pcmcia_device *link = lp->p_dev; DEBUG(4, "fjn_open('%s').\n", dev->name); - if (!DEV_OK(link)) + if (!pcmcia_dev_present(link)) return -ENODEV; link->open++; @@ -1173,7 +1133,7 @@ static int fjn_open(struct net_device *dev) static int fjn_close(struct net_device *dev) { struct local_info_t *lp = netdev_priv(dev); - dev_link_t *link = &lp->link; + struct pcmcia_device *link = lp->p_dev; kio_addr_t ioaddr = dev->base_addr; DEBUG(4, "fjn_close('%s').\n", dev->name); diff --git a/drivers/net/pcmcia/ibmtr_cs.c b/drivers/net/pcmcia/ibmtr_cs.c index b9c7e39576f..b8fe70b8564 100644 --- a/drivers/net/pcmcia/ibmtr_cs.c +++ b/drivers/net/pcmcia/ibmtr_cs.c @@ -105,15 +105,15 @@ MODULE_LICENSE("GPL"); /*====================================================================*/ -static void ibmtr_config(dev_link_t *link); +static int ibmtr_config(struct pcmcia_device *link); static void ibmtr_hw_setup(struct net_device *dev, u_int mmiobase); -static void ibmtr_release(dev_link_t *link); +static void ibmtr_release(struct pcmcia_device *link); static void ibmtr_detach(struct pcmcia_device *p_dev); /*====================================================================*/ typedef struct ibmtr_dev_t { - dev_link_t link; + struct pcmcia_device *p_dev; struct net_device *dev; dev_node_t node; window_handle_t sram_win_handle; @@ -138,12 +138,11 @@ static struct ethtool_ops netdev_ethtool_ops = { ======================================================================*/ -static int ibmtr_attach(struct pcmcia_device *p_dev) +static int ibmtr_attach(struct pcmcia_device *link) { ibmtr_dev_t *info; - dev_link_t *link; struct net_device *dev; - + DEBUG(0, "ibmtr_attach()\n"); /* Create new token-ring device */ @@ -156,7 +155,7 @@ static int ibmtr_attach(struct pcmcia_device *p_dev) return -ENOMEM; } - link = &info->link; + info->p_dev = link; link->priv = info; info->ti = netdev_priv(dev); @@ -167,21 +166,14 @@ static int ibmtr_attach(struct pcmcia_device *p_dev) link->irq.IRQInfo1 = IRQ_LEVEL_ID; link->irq.Handler = &tok_interrupt; link->conf.Attributes = CONF_ENABLE_IRQ; - link->conf.Vcc = 50; link->conf.IntType = INT_MEMORY_AND_IO; link->conf.Present = PRESENT_OPTION; link->irq.Instance = info->dev = dev; - - SET_ETHTOOL_OPS(dev, &netdev_ethtool_ops); - - link->handle = p_dev; - p_dev->instance = link; - link->state |= DEV_PRESENT; - ibmtr_config(link); + SET_ETHTOOL_OPS(dev, &netdev_ethtool_ops); - return 0; + return ibmtr_config(link); } /* ibmtr_attach */ /*====================================================================== @@ -193,23 +185,22 @@ static int ibmtr_attach(struct pcmcia_device *p_dev) ======================================================================*/ -static void ibmtr_detach(struct pcmcia_device *p_dev) +static void ibmtr_detach(struct pcmcia_device *link) { - dev_link_t *link = dev_to_instance(p_dev); struct ibmtr_dev_t *info = link->priv; struct net_device *dev = info->dev; DEBUG(0, "ibmtr_detach(0x%p)\n", link); - if (link->dev) + if (link->dev_node) unregister_netdev(dev); { struct tok_info *ti = netdev_priv(dev); del_timer_sync(&(ti->tr_timer)); } - if (link->state & DEV_CONFIG) - ibmtr_release(link); + + ibmtr_release(link); free_netdev(dev); kfree(info); @@ -226,9 +217,8 @@ static void ibmtr_detach(struct pcmcia_device *p_dev) #define CS_CHECK(fn, ret) \ do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0) -static void ibmtr_config(dev_link_t *link) +static int ibmtr_config(struct pcmcia_device *link) { - client_handle_t handle = link->handle; ibmtr_dev_t *info = link->priv; struct net_device *dev = info->dev; struct tok_info *ti = netdev_priv(dev); @@ -246,29 +236,25 @@ static void ibmtr_config(dev_link_t *link) tuple.TupleDataMax = 64; tuple.TupleOffset = 0; tuple.DesiredTuple = CISTPL_CONFIG; - CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple)); - CS_CHECK(GetTupleData, pcmcia_get_tuple_data(handle, &tuple)); - CS_CHECK(ParseTuple, pcmcia_parse_tuple(handle, &tuple, &parse)); + CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); + CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple)); + CS_CHECK(ParseTuple, pcmcia_parse_tuple(link, &tuple, &parse)); link->conf.ConfigBase = parse.config.base; - - /* Configure card */ - link->state |= DEV_CONFIG; - link->conf.ConfigIndex = 0x61; /* Determine if this is PRIMARY or ALTERNATE. */ /* Try PRIMARY card at 0xA20-0xA23 */ link->io.BasePort1 = 0xA20; - i = pcmcia_request_io(link->handle, &link->io); + i = pcmcia_request_io(link, &link->io); if (i != CS_SUCCESS) { /* Couldn't get 0xA20-0xA23. Try ALTERNATE at 0xA24-0xA27. */ link->io.BasePort1 = 0xA24; - CS_CHECK(RequestIO, pcmcia_request_io(link->handle, &link->io)); + CS_CHECK(RequestIO, pcmcia_request_io(link, &link->io)); } dev->base_addr = link->io.BasePort1; - CS_CHECK(RequestIRQ, pcmcia_request_irq(link->handle, &link->irq)); + CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq)); dev->irq = link->irq.AssignedIRQ; ti->irq = link->irq.AssignedIRQ; ti->global_int_enable=GLOBAL_INT_ENABLE+((dev->irq==9) ? 2 : dev->irq); @@ -279,7 +265,7 @@ static void ibmtr_config(dev_link_t *link) req.Base = 0; req.Size = 0x2000; req.AccessSpeed = 250; - CS_CHECK(RequestWindow, pcmcia_request_window(&link->handle, &req, &link->win)); + CS_CHECK(RequestWindow, pcmcia_request_window(&link, &req, &link->win)); mem.CardOffset = mmiobase; mem.Page = 0; @@ -292,7 +278,7 @@ static void ibmtr_config(dev_link_t *link) req.Base = 0; req.Size = sramsize * 1024; req.AccessSpeed = 250; - CS_CHECK(RequestWindow, pcmcia_request_window(&link->handle, &req, &info->sram_win_handle)); + CS_CHECK(RequestWindow, pcmcia_request_window(&link, &req, &info->sram_win_handle)); mem.CardOffset = srambase; mem.Page = 0; @@ -302,21 +288,20 @@ static void ibmtr_config(dev_link_t *link) ti->sram_virt = ioremap(req.Base, req.Size); ti->sram_phys = req.Base; - CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link->handle, &link->conf)); + CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf)); /* Set up the Token-Ring Controller Configuration Register and turn on the card. Check the "Local Area Network Credit Card Adapters Technical Reference" SC30-3585 for this info. */ ibmtr_hw_setup(dev, mmiobase); - link->dev = &info->node; - link->state &= ~DEV_CONFIG_PENDING; - SET_NETDEV_DEV(dev, &handle_to_dev(handle)); + link->dev_node = &info->node; + SET_NETDEV_DEV(dev, &handle_to_dev(link)); i = ibmtr_probe_card(dev); if (i != 0) { printk(KERN_NOTICE "ibmtr_cs: register_netdev() failed\n"); - link->dev = NULL; + link->dev_node = NULL; goto failed; } @@ -330,12 +315,13 @@ static void ibmtr_config(dev_link_t *link) for (i = 0; i < TR_ALEN; i++) printk("%02X", dev->dev_addr[i]); printk("\n"); - return; + return 0; cs_failed: - cs_error(link->handle, last_fn, last_ret); + cs_error(link, last_fn, last_ret); failed: ibmtr_release(link); + return -ENODEV; } /* ibmtr_config */ /*====================================================================== @@ -346,56 +332,41 @@ failed: ======================================================================*/ -static void ibmtr_release(dev_link_t *link) +static void ibmtr_release(struct pcmcia_device *link) { - ibmtr_dev_t *info = link->priv; - struct net_device *dev = info->dev; - - DEBUG(0, "ibmtr_release(0x%p)\n", link); + ibmtr_dev_t *info = link->priv; + struct net_device *dev = info->dev; - pcmcia_release_configuration(link->handle); - pcmcia_release_io(link->handle, &link->io); - pcmcia_release_irq(link->handle, &link->irq); - if (link->win) { - struct tok_info *ti = netdev_priv(dev); - iounmap(ti->mmio); - pcmcia_release_window(link->win); - pcmcia_release_window(info->sram_win_handle); - } + DEBUG(0, "ibmtr_release(0x%p)\n", link); - link->state &= ~DEV_CONFIG; + if (link->win) { + struct tok_info *ti = netdev_priv(dev); + iounmap(ti->mmio); + pcmcia_release_window(info->sram_win_handle); + } + pcmcia_disable_device(link); } -static int ibmtr_suspend(struct pcmcia_device *p_dev) +static int ibmtr_suspend(struct pcmcia_device *link) { - dev_link_t *link = dev_to_instance(p_dev); ibmtr_dev_t *info = link->priv; struct net_device *dev = info->dev; - link->state |= DEV_SUSPEND; - if (link->state & DEV_CONFIG) { - if (link->open) - netif_device_detach(dev); - pcmcia_release_configuration(link->handle); - } + if (link->open) + netif_device_detach(dev); return 0; } -static int ibmtr_resume(struct pcmcia_device *p_dev) +static int ibmtr_resume(struct pcmcia_device *link) { - dev_link_t *link = dev_to_instance(p_dev); ibmtr_dev_t *info = link->priv; struct net_device *dev = info->dev; - link->state &= ~DEV_SUSPEND; - if (link->state & DEV_CONFIG) { - pcmcia_request_configuration(link->handle, &link->conf); - if (link->open) { - ibmtr_probe(dev); /* really? */ - netif_device_attach(dev); - } - } + if (link->open) { + ibmtr_probe(dev); /* really? */ + netif_device_attach(dev); + } return 0; } diff --git a/drivers/net/pcmcia/nmclan_cs.c b/drivers/net/pcmcia/nmclan_cs.c index 787176c57fd..4260c2128f4 100644 --- a/drivers/net/pcmcia/nmclan_cs.c +++ b/drivers/net/pcmcia/nmclan_cs.c @@ -362,7 +362,7 @@ typedef struct _mace_statistics { } mace_statistics; typedef struct _mace_private { - dev_link_t link; + struct pcmcia_device *p_dev; dev_node_t node; struct net_device_stats linux_stats; /* Linux statistics counters */ mace_statistics mace_stats; /* MACE chip statistics counters */ @@ -417,8 +417,8 @@ INT_MODULE_PARM(pc_debug, PCMCIA_DEBUG); Function Prototypes ---------------------------------------------------------------------------- */ -static void nmclan_config(dev_link_t *link); -static void nmclan_release(dev_link_t *link); +static int nmclan_config(struct pcmcia_device *link); +static void nmclan_release(struct pcmcia_device *link); static void nmclan_reset(struct net_device *dev); static int mace_config(struct net_device *dev, struct ifmap *map); @@ -443,10 +443,9 @@ nmclan_attach Services. ---------------------------------------------------------------------------- */ -static int nmclan_attach(struct pcmcia_device *p_dev) +static int nmclan_probe(struct pcmcia_device *link) { mace_private *lp; - dev_link_t *link; struct net_device *dev; DEBUG(0, "nmclan_attach()\n"); @@ -457,7 +456,7 @@ static int nmclan_attach(struct pcmcia_device *p_dev) if (!dev) return -ENOMEM; lp = netdev_priv(dev); - link = &lp->link; + lp->p_dev = link; link->priv = dev; spin_lock_init(&lp->bank_lock); @@ -469,7 +468,6 @@ static int nmclan_attach(struct pcmcia_device *p_dev) link->irq.Handler = &mace_interrupt; link->irq.Instance = dev; link->conf.Attributes = CONF_ENABLE_IRQ; - link->conf.Vcc = 50; link->conf.IntType = INT_MEMORY_AND_IO; link->conf.ConfigIndex = 1; link->conf.Present = PRESENT_OPTION; @@ -489,13 +487,7 @@ static int nmclan_attach(struct pcmcia_device *p_dev) dev->watchdog_timeo = TX_TIMEOUT; #endif - link->handle = p_dev; - p_dev->instance = link; - - link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; - nmclan_config(link); - - return 0; + return nmclan_config(link); } /* nmclan_attach */ /* ---------------------------------------------------------------------------- @@ -506,18 +498,16 @@ nmclan_detach when the device is released. ---------------------------------------------------------------------------- */ -static void nmclan_detach(struct pcmcia_device *p_dev) +static void nmclan_detach(struct pcmcia_device *link) { - dev_link_t *link = dev_to_instance(p_dev); struct net_device *dev = link->priv; DEBUG(0, "nmclan_detach(0x%p)\n", link); - if (link->dev) + if (link->dev_node) unregister_netdev(dev); - if (link->state & DEV_CONFIG) - nmclan_release(link); + nmclan_release(link); free_netdev(dev); } /* nmclan_detach */ @@ -661,9 +651,8 @@ nmclan_config #define CS_CHECK(fn, ret) \ do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0) -static void nmclan_config(dev_link_t *link) +static int nmclan_config(struct pcmcia_device *link) { - client_handle_t handle = link->handle; struct net_device *dev = link->priv; mace_private *lp = netdev_priv(dev); tuple_t tuple; @@ -679,17 +668,14 @@ static void nmclan_config(dev_link_t *link) tuple.TupleDataMax = 64; tuple.TupleOffset = 0; tuple.DesiredTuple = CISTPL_CONFIG; - CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple)); - CS_CHECK(GetTupleData, pcmcia_get_tuple_data(handle, &tuple)); - CS_CHECK(ParseTuple, pcmcia_parse_tuple(handle, &tuple, &parse)); + CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); + CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple)); + CS_CHECK(ParseTuple, pcmcia_parse_tuple(link, &tuple, &parse)); link->conf.ConfigBase = parse.config.base; - /* Configure card */ - link->state |= DEV_CONFIG; - - CS_CHECK(RequestIO, pcmcia_request_io(handle, &link->io)); - CS_CHECK(RequestIRQ, pcmcia_request_irq(handle, &link->irq)); - CS_CHECK(RequestConfiguration, pcmcia_request_configuration(handle, &link->conf)); + CS_CHECK(RequestIO, pcmcia_request_io(link, &link->io)); + CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq)); + CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf)); dev->irq = link->irq.AssignedIRQ; dev->base_addr = link->io.BasePort1; @@ -700,8 +686,8 @@ static void nmclan_config(dev_link_t *link) tuple.TupleData = buf; tuple.TupleDataMax = 64; tuple.TupleOffset = 0; - CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple)); - CS_CHECK(GetTupleData, pcmcia_get_tuple_data(handle, &tuple)); + CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); + CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple)); memcpy(dev->dev_addr, tuple.TupleData, ETHER_ADDR_LEN); /* Verify configuration by reading the MACE ID. */ @@ -716,8 +702,7 @@ static void nmclan_config(dev_link_t *link) } else { printk(KERN_NOTICE "nmclan_cs: mace id not found: %x %x should" " be 0x40 0x?9\n", sig[0], sig[1]); - link->state &= ~DEV_CONFIG_PENDING; - return; + return -ENODEV; } } @@ -730,14 +715,13 @@ static void nmclan_config(dev_link_t *link) else printk(KERN_NOTICE "nmclan_cs: invalid if_port requested\n"); - link->dev = &lp->node; - link->state &= ~DEV_CONFIG_PENDING; - SET_NETDEV_DEV(dev, &handle_to_dev(handle)); + link->dev_node = &lp->node; + SET_NETDEV_DEV(dev, &handle_to_dev(link)); i = register_netdev(dev); if (i != 0) { printk(KERN_NOTICE "nmclan_cs: register_netdev() failed\n"); - link->dev = NULL; + link->dev_node = NULL; goto failed; } @@ -747,14 +731,13 @@ static void nmclan_config(dev_link_t *link) dev->name, dev->base_addr, dev->irq, if_names[dev->if_port]); for (i = 0; i < 6; i++) printk("%02X%s", dev->dev_addr[i], ((i<5) ? ":" : "\n")); - return; + return 0; cs_failed: - cs_error(link->handle, last_fn, last_ret); + cs_error(link, last_fn, last_ret); failed: - nmclan_release(link); - return; - + nmclan_release(link); + return -ENODEV; } /* nmclan_config */ /* ---------------------------------------------------------------------------- @@ -763,46 +746,29 @@ nmclan_release net device, and release the PCMCIA configuration. If the device is still open, this will be postponed until it is closed. ---------------------------------------------------------------------------- */ -static void nmclan_release(dev_link_t *link) +static void nmclan_release(struct pcmcia_device *link) { - - DEBUG(0, "nmclan_release(0x%p)\n", link); - - pcmcia_release_configuration(link->handle); - pcmcia_release_io(link->handle, &link->io); - pcmcia_release_irq(link->handle, &link->irq); - - link->state &= ~DEV_CONFIG; + DEBUG(0, "nmclan_release(0x%p)\n", link); + pcmcia_disable_device(link); } -static int nmclan_suspend(struct pcmcia_device *p_dev) +static int nmclan_suspend(struct pcmcia_device *link) { - dev_link_t *link = dev_to_instance(p_dev); struct net_device *dev = link->priv; - link->state |= DEV_SUSPEND; - if (link->state & DEV_CONFIG) { - if (link->open) - netif_device_detach(dev); - pcmcia_release_configuration(link->handle); - } - + if (link->open) + netif_device_detach(dev); return 0; } -static int nmclan_resume(struct pcmcia_device *p_dev) +static int nmclan_resume(struct pcmcia_device *link) { - dev_link_t *link = dev_to_instance(p_dev); struct net_device *dev = link->priv; - link->state &= ~DEV_SUSPEND; - if (link->state & DEV_CONFIG) { - pcmcia_request_configuration(link->handle, &link->conf); - if (link->open) { - nmclan_reset(dev); - netif_device_attach(dev); - } + if (link->open) { + nmclan_reset(dev); + netif_device_attach(dev); } return 0; @@ -818,7 +784,7 @@ static void nmclan_reset(struct net_device *dev) mace_private *lp = netdev_priv(dev); #if RESET_XILINX - dev_link_t *link = &lp->link; + struct pcmcia_device *link = &lp->link; conf_reg_t reg; u_long OrigCorValue; @@ -827,7 +793,7 @@ static void nmclan_reset(struct net_device *dev) reg.Action = CS_READ; reg.Offset = CISREG_COR; reg.Value = 0; - pcmcia_access_configuration_register(link->handle, ®); + pcmcia_access_configuration_register(link, ®); OrigCorValue = reg.Value; /* Reset Xilinx */ @@ -836,12 +802,12 @@ static void nmclan_reset(struct net_device *dev) DEBUG(1, "nmclan_reset: OrigCorValue=0x%lX, resetting...\n", OrigCorValue); reg.Value = COR_SOFT_RESET; - pcmcia_access_configuration_register(link->handle, ®); + pcmcia_access_configuration_register(link, ®); /* Need to wait for 20 ms for PCMCIA to finish reset. */ /* Restore original COR configuration index */ reg.Value = COR_LEVEL_REQ | (OrigCorValue & COR_CONFIG_MASK); - pcmcia_access_configuration_register(link->handle, ®); + pcmcia_access_configuration_register(link, ®); /* Xilinx is now completely reset along with the MACE chip. */ lp->tx_free_frames=AM2150_MAX_TX_FRAMES; @@ -885,9 +851,9 @@ static int mace_open(struct net_device *dev) { kio_addr_t ioaddr = dev->base_addr; mace_private *lp = netdev_priv(dev); - dev_link_t *link = &lp->link; + struct pcmcia_device *link = lp->p_dev; - if (!DEV_OK(link)) + if (!pcmcia_dev_present(link)) return -ENODEV; link->open++; @@ -908,7 +874,7 @@ static int mace_close(struct net_device *dev) { kio_addr_t ioaddr = dev->base_addr; mace_private *lp = netdev_priv(dev); - dev_link_t *link = &lp->link; + struct pcmcia_device *link = lp->p_dev; DEBUG(2, "%s: shutting down ethercard.\n", dev->name); @@ -963,12 +929,12 @@ mace_start_xmit static void mace_tx_timeout(struct net_device *dev) { mace_private *lp = netdev_priv(dev); - dev_link_t *link = &lp->link; + struct pcmcia_device *link = lp->p_dev; printk(KERN_NOTICE "%s: transmit timed out -- ", dev->name); #if RESET_ON_TIMEOUT printk("resetting card\n"); - pcmcia_reset_card(link->handle, NULL); + pcmcia_reset_card(link, NULL); #else /* #if RESET_ON_TIMEOUT */ printk("NOT resetting card\n"); #endif /* #if RESET_ON_TIMEOUT */ @@ -1635,7 +1601,7 @@ static struct pcmcia_driver nmclan_cs_driver = { .drv = { .name = "nmclan_cs", }, - .probe = nmclan_attach, + .probe = nmclan_probe, .remove = nmclan_detach, .id_table = nmclan_ids, .suspend = nmclan_suspend, diff --git a/drivers/net/pcmcia/pcnet_cs.c b/drivers/net/pcmcia/pcnet_cs.c index b46e5f703ef..506e777c5f0 100644 --- a/drivers/net/pcmcia/pcnet_cs.c +++ b/drivers/net/pcmcia/pcnet_cs.c @@ -103,8 +103,8 @@ module_param_array(hw_addr, int, NULL, 0); /*====================================================================*/ static void mii_phy_probe(struct net_device *dev); -static void pcnet_config(dev_link_t *link); -static void pcnet_release(dev_link_t *link); +static int pcnet_config(struct pcmcia_device *link); +static void pcnet_release(struct pcmcia_device *link); static int pcnet_open(struct net_device *dev); static int pcnet_close(struct net_device *dev); static int ei_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); @@ -113,9 +113,9 @@ static irqreturn_t ei_irq_wrapper(int irq, void *dev_id, struct pt_regs *regs); static void ei_watchdog(u_long arg); static void pcnet_reset_8390(struct net_device *dev); static int set_config(struct net_device *dev, struct ifmap *map); -static int setup_shmem_window(dev_link_t *link, int start_pg, +static int setup_shmem_window(struct pcmcia_device *link, int start_pg, int stop_pg, int cm_offset); -static int setup_dma_config(dev_link_t *link, int start_pg, +static int setup_dma_config(struct pcmcia_device *link, int start_pg, int stop_pg); static void pcnet_detach(struct pcmcia_device *p_dev); @@ -214,7 +214,7 @@ static hw_info_t dl10019_info = { 0, 0, 0, 0, IS_DL10019|HAS_MII }; static hw_info_t dl10022_info = { 0, 0, 0, 0, IS_DL10022|HAS_MII }; typedef struct pcnet_dev_t { - dev_link_t link; + struct pcmcia_device *p_dev; dev_node_t node; u_int flags; void __iomem *base; @@ -240,10 +240,9 @@ static inline pcnet_dev_t *PRIV(struct net_device *dev) ======================================================================*/ -static int pcnet_probe(struct pcmcia_device *p_dev) +static int pcnet_probe(struct pcmcia_device *link) { pcnet_dev_t *info; - dev_link_t *link; struct net_device *dev; DEBUG(0, "pcnet_attach()\n"); @@ -252,7 +251,7 @@ static int pcnet_probe(struct pcmcia_device *p_dev) dev = __alloc_ei_netdev(sizeof(pcnet_dev_t)); if (!dev) return -ENOMEM; info = PRIV(dev); - link = &info->link; + info->p_dev = link; link->priv = dev; link->irq.Attributes = IRQ_TYPE_EXCLUSIVE; @@ -265,13 +264,7 @@ static int pcnet_probe(struct pcmcia_device *p_dev) dev->stop = &pcnet_close; dev->set_config = &set_config; - link->handle = p_dev; - p_dev->instance = link; - - link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; - pcnet_config(link); - - return 0; + return pcnet_config(link); } /* pcnet_attach */ /*====================================================================== @@ -283,18 +276,16 @@ static int pcnet_probe(struct pcmcia_device *p_dev) ======================================================================*/ -static void pcnet_detach(struct pcmcia_device *p_dev) +static void pcnet_detach(struct pcmcia_device *link) { - dev_link_t *link = dev_to_instance(p_dev); struct net_device *dev = link->priv; DEBUG(0, "pcnet_detach(0x%p)\n", link); - if (link->dev) + if (link->dev_node) unregister_netdev(dev); - if (link->state & DEV_CONFIG) - pcnet_release(link); + pcnet_release(link); free_netdev(dev); } /* pcnet_detach */ @@ -306,7 +297,7 @@ static void pcnet_detach(struct pcmcia_device *p_dev) ======================================================================*/ -static hw_info_t *get_hwinfo(dev_link_t *link) +static hw_info_t *get_hwinfo(struct pcmcia_device *link) { struct net_device *dev = link->priv; win_req_t req; @@ -318,9 +309,9 @@ static hw_info_t *get_hwinfo(dev_link_t *link) req.Attributes = WIN_DATA_WIDTH_8|WIN_MEMORY_TYPE_AM|WIN_ENABLE; req.Base = 0; req.Size = 0; req.AccessSpeed = 0; - i = pcmcia_request_window(&link->handle, &req, &link->win); + i = pcmcia_request_window(&link, &req, &link->win); if (i != CS_SUCCESS) { - cs_error(link->handle, RequestWindow, i); + cs_error(link, RequestWindow, i); return NULL; } @@ -343,7 +334,7 @@ static hw_info_t *get_hwinfo(dev_link_t *link) iounmap(virt); j = pcmcia_release_window(link->win); if (j != CS_SUCCESS) - cs_error(link->handle, ReleaseWindow, j); + cs_error(link, ReleaseWindow, j); return (i < NR_INFO) ? hw_info+i : NULL; } /* get_hwinfo */ @@ -355,7 +346,7 @@ static hw_info_t *get_hwinfo(dev_link_t *link) ======================================================================*/ -static hw_info_t *get_prom(dev_link_t *link) +static hw_info_t *get_prom(struct pcmcia_device *link) { struct net_device *dev = link->priv; kio_addr_t ioaddr = dev->base_addr; @@ -409,7 +400,7 @@ static hw_info_t *get_prom(dev_link_t *link) ======================================================================*/ -static hw_info_t *get_dl10019(dev_link_t *link) +static hw_info_t *get_dl10019(struct pcmcia_device *link) { struct net_device *dev = link->priv; int i; @@ -431,7 +422,7 @@ static hw_info_t *get_dl10019(dev_link_t *link) ======================================================================*/ -static hw_info_t *get_ax88190(dev_link_t *link) +static hw_info_t *get_ax88190(struct pcmcia_device *link) { struct net_device *dev = link->priv; kio_addr_t ioaddr = dev->base_addr; @@ -464,7 +455,7 @@ static hw_info_t *get_ax88190(dev_link_t *link) ======================================================================*/ -static hw_info_t *get_hwired(dev_link_t *link) +static hw_info_t *get_hwired(struct pcmcia_device *link) { struct net_device *dev = link->priv; int i; @@ -491,7 +482,7 @@ static hw_info_t *get_hwired(dev_link_t *link) #define CS_CHECK(fn, ret) \ do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0) -static int try_io_port(dev_link_t *link) +static int try_io_port(struct pcmcia_device *link) { int j, ret; if (link->io.NumPorts1 == 32) { @@ -512,18 +503,17 @@ static int try_io_port(dev_link_t *link) for (j = 0; j < 0x400; j += 0x20) { link->io.BasePort1 = j ^ 0x300; link->io.BasePort2 = (j ^ 0x300) + 0x10; - ret = pcmcia_request_io(link->handle, &link->io); + ret = pcmcia_request_io(link, &link->io); if (ret == CS_SUCCESS) return ret; } return ret; } else { - return pcmcia_request_io(link->handle, &link->io); + return pcmcia_request_io(link, &link->io); } } -static void pcnet_config(dev_link_t *link) +static int pcnet_config(struct pcmcia_device *link) { - client_handle_t handle = link->handle; struct net_device *dev = link->priv; pcnet_dev_t *info = PRIV(dev); tuple_t tuple; @@ -531,7 +521,6 @@ static void pcnet_config(dev_link_t *link) int i, last_ret, last_fn, start_pg, stop_pg, cm_offset; int manfid = 0, prodid = 0, has_shmem = 0; u_short buf[64]; - config_info_t conf; hw_info_t *hw_info; DEBUG(0, "pcnet_config(0x%p)\n", link); @@ -541,36 +530,29 @@ static void pcnet_config(dev_link_t *link) tuple.TupleDataMax = sizeof(buf); tuple.TupleOffset = 0; tuple.DesiredTuple = CISTPL_CONFIG; - CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple)); - CS_CHECK(GetTupleData, pcmcia_get_tuple_data(handle, &tuple)); - CS_CHECK(ParseTuple, pcmcia_parse_tuple(handle, &tuple, &parse)); + CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); + CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple)); + CS_CHECK(ParseTuple, pcmcia_parse_tuple(link, &tuple, &parse)); link->conf.ConfigBase = parse.config.base; link->conf.Present = parse.config.rmask[0]; - /* Configure card */ - link->state |= DEV_CONFIG; - - /* Look up current Vcc */ - CS_CHECK(GetConfigurationInfo, pcmcia_get_configuration_info(handle, &conf)); - link->conf.Vcc = conf.Vcc; - tuple.DesiredTuple = CISTPL_MANFID; tuple.Attributes = TUPLE_RETURN_COMMON; - if ((pcmcia_get_first_tuple(handle, &tuple) == CS_SUCCESS) && - (pcmcia_get_tuple_data(handle, &tuple) == CS_SUCCESS)) { + if ((pcmcia_get_first_tuple(link, &tuple) == CS_SUCCESS) && + (pcmcia_get_tuple_data(link, &tuple) == CS_SUCCESS)) { manfid = le16_to_cpu(buf[0]); prodid = le16_to_cpu(buf[1]); } tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; tuple.Attributes = 0; - CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple)); + CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); while (last_ret == CS_SUCCESS) { cistpl_cftable_entry_t *cfg = &(parse.cftable_entry); cistpl_io_t *io = &(parse.cftable_entry.io); - if (pcmcia_get_tuple_data(handle, &tuple) != 0 || - pcmcia_parse_tuple(handle, &tuple, &parse) != 0 || + if (pcmcia_get_tuple_data(link, &tuple) != 0 || + pcmcia_parse_tuple(link, &tuple, &parse) != 0 || cfg->index == 0 || cfg->io.nwin == 0) goto next_entry; @@ -594,14 +576,14 @@ static void pcnet_config(dev_link_t *link) if (last_ret == CS_SUCCESS) break; } next_entry: - last_ret = pcmcia_get_next_tuple(handle, &tuple); + last_ret = pcmcia_get_next_tuple(link, &tuple); } if (last_ret != CS_SUCCESS) { - cs_error(handle, RequestIO, last_ret); + cs_error(link, RequestIO, last_ret); goto failed; } - CS_CHECK(RequestIRQ, pcmcia_request_irq(handle, &link->irq)); + CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq)); if (link->io.NumPorts2 == 8) { link->conf.Attributes |= CONF_ENABLE_SPKR; @@ -611,7 +593,7 @@ static void pcnet_config(dev_link_t *link) (prodid == PRODID_IBM_HOME_AND_AWAY)) link->conf.ConfigIndex |= 0x10; - CS_CHECK(RequestConfiguration, pcmcia_request_configuration(handle, &link->conf)); + CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf)); dev->irq = link->irq.AssignedIRQ; dev->base_addr = link->io.BasePort1; if (info->flags & HAS_MISC_REG) { @@ -679,9 +661,8 @@ static void pcnet_config(dev_link_t *link) info->eth_phy = 0; } - link->dev = &info->node; - link->state &= ~DEV_CONFIG_PENDING; - SET_NETDEV_DEV(dev, &handle_to_dev(handle)); + link->dev_node = &info->node; + SET_NETDEV_DEV(dev, &handle_to_dev(link)); #ifdef CONFIG_NET_POLL_CONTROLLER dev->poll_controller = ei_poll; @@ -689,7 +670,7 @@ static void pcnet_config(dev_link_t *link) if (register_netdev(dev) != 0) { printk(KERN_NOTICE "pcnet_cs: register_netdev() failed\n"); - link->dev = NULL; + link->dev_node = NULL; goto failed; } @@ -712,14 +693,13 @@ static void pcnet_config(dev_link_t *link) printk(" hw_addr "); for (i = 0; i < 6; i++) printk("%02X%s", dev->dev_addr[i], ((i<5) ? ":" : "\n")); - return; + return 0; cs_failed: - cs_error(link->handle, last_fn, last_ret); + cs_error(link, last_fn, last_ret); failed: pcnet_release(link); - link->state &= ~DEV_CONFIG_PENDING; - return; + return -ENODEV; } /* pcnet_config */ /*====================================================================== @@ -730,21 +710,16 @@ failed: ======================================================================*/ -static void pcnet_release(dev_link_t *link) +static void pcnet_release(struct pcmcia_device *link) { - pcnet_dev_t *info = PRIV(link->priv); + pcnet_dev_t *info = PRIV(link->priv); - DEBUG(0, "pcnet_release(0x%p)\n", link); + DEBUG(0, "pcnet_release(0x%p)\n", link); - if (info->flags & USE_SHMEM) { - iounmap(info->base); - pcmcia_release_window(link->win); - } - pcmcia_release_configuration(link->handle); - pcmcia_release_io(link->handle, &link->io); - pcmcia_release_irq(link->handle, &link->irq); + if (info->flags & USE_SHMEM) + iounmap(info->base); - link->state &= ~DEV_CONFIG; + pcmcia_disable_device(link); } /*====================================================================== @@ -756,34 +731,24 @@ static void pcnet_release(dev_link_t *link) ======================================================================*/ -static int pcnet_suspend(struct pcmcia_device *p_dev) +static int pcnet_suspend(struct pcmcia_device *link) { - dev_link_t *link = dev_to_instance(p_dev); struct net_device *dev = link->priv; - link->state |= DEV_SUSPEND; - if (link->state & DEV_CONFIG) { - if (link->open) - netif_device_detach(dev); - pcmcia_release_configuration(link->handle); - } + if (link->open) + netif_device_detach(dev); return 0; } -static int pcnet_resume(struct pcmcia_device *p_dev) +static int pcnet_resume(struct pcmcia_device *link) { - dev_link_t *link = dev_to_instance(p_dev); struct net_device *dev = link->priv; - link->state &= ~DEV_SUSPEND; - if (link->state & DEV_CONFIG) { - pcmcia_request_configuration(link->handle, &link->conf); - if (link->open) { - pcnet_reset_8390(dev); - NS8390_init(dev, 1); - netif_device_attach(dev); - } + if (link->open) { + pcnet_reset_8390(dev); + NS8390_init(dev, 1); + netif_device_attach(dev); } return 0; @@ -1023,11 +988,11 @@ static void mii_phy_probe(struct net_device *dev) static int pcnet_open(struct net_device *dev) { pcnet_dev_t *info = PRIV(dev); - dev_link_t *link = &info->link; - + struct pcmcia_device *link = info->p_dev; + DEBUG(2, "pcnet_open('%s')\n", dev->name); - if (!DEV_OK(link)) + if (!pcmcia_dev_present(link)) return -ENODEV; link->open++; @@ -1051,7 +1016,7 @@ static int pcnet_open(struct net_device *dev) static int pcnet_close(struct net_device *dev) { pcnet_dev_t *info = PRIV(dev); - dev_link_t *link = &info->link; + struct pcmcia_device *link = info->p_dev; DEBUG(2, "pcnet_close('%s')\n", dev->name); @@ -1429,7 +1394,7 @@ static void dma_block_output(struct net_device *dev, int count, /*====================================================================*/ -static int setup_dma_config(dev_link_t *link, int start_pg, +static int setup_dma_config(struct pcmcia_device *link, int start_pg, int stop_pg) { struct net_device *dev = link->priv; @@ -1532,7 +1497,7 @@ static void shmem_block_output(struct net_device *dev, int count, /*====================================================================*/ -static int setup_shmem_window(dev_link_t *link, int start_pg, +static int setup_shmem_window(struct pcmcia_device *link, int start_pg, int stop_pg, int cm_offset) { struct net_device *dev = link->priv; @@ -1554,7 +1519,7 @@ static int setup_shmem_window(dev_link_t *link, int start_pg, req.Attributes |= WIN_USE_WAIT; req.Base = 0; req.Size = window_size; req.AccessSpeed = mem_speed; - CS_CHECK(RequestWindow, pcmcia_request_window(&link->handle, &req, &link->win)); + CS_CHECK(RequestWindow, pcmcia_request_window(&link, &req, &link->win)); mem.CardOffset = (start_pg << 8) + cm_offset; offset = mem.CardOffset % window_size; @@ -1595,7 +1560,7 @@ static int setup_shmem_window(dev_link_t *link, int start_pg, return 0; cs_failed: - cs_error(link->handle, last_fn, last_ret); + cs_error(link, last_fn, last_ret); failed: return 1; } diff --git a/drivers/net/pcmcia/smc91c92_cs.c b/drivers/net/pcmcia/smc91c92_cs.c index 8839c4faafd..e74bf5014ef 100644 --- a/drivers/net/pcmcia/smc91c92_cs.c +++ b/drivers/net/pcmcia/smc91c92_cs.c @@ -49,6 +49,7 @@ #include <pcmcia/cisreg.h> #include <pcmcia/ciscode.h> #include <pcmcia/ds.h> +#include <pcmcia/ss.h> #include <asm/io.h> #include <asm/system.h> @@ -103,7 +104,7 @@ static const char *version = #define MEMORY_WAIT_TIME 8 struct smc_private { - dev_link_t link; + struct pcmcia_device *p_dev; spinlock_t lock; u_short manfid; u_short cardid; @@ -278,8 +279,8 @@ enum RxCfg { RxAllMulti = 0x0004, RxPromisc = 0x0002, /*====================================================================*/ static void smc91c92_detach(struct pcmcia_device *p_dev); -static void smc91c92_config(dev_link_t *link); -static void smc91c92_release(dev_link_t *link); +static int smc91c92_config(struct pcmcia_device *link); +static void smc91c92_release(struct pcmcia_device *link); static int smc_open(struct net_device *dev); static int smc_close(struct net_device *dev); @@ -308,10 +309,9 @@ static struct ethtool_ops ethtool_ops; ======================================================================*/ -static int smc91c92_attach(struct pcmcia_device *p_dev) +static int smc91c92_probe(struct pcmcia_device *link) { struct smc_private *smc; - dev_link_t *link; struct net_device *dev; DEBUG(0, "smc91c92_attach()\n"); @@ -321,7 +321,7 @@ static int smc91c92_attach(struct pcmcia_device *p_dev) if (!dev) return -ENOMEM; smc = netdev_priv(dev); - link = &smc->link; + smc->p_dev = link; link->priv = dev; spin_lock_init(&smc->lock); @@ -333,7 +333,6 @@ static int smc91c92_attach(struct pcmcia_device *p_dev) link->irq.Handler = &smc_interrupt; link->irq.Instance = dev; link->conf.Attributes = CONF_ENABLE_IRQ; - link->conf.Vcc = 50; link->conf.IntType = INT_MEMORY_AND_IO; /* The SMC91c92-specific entries in the device structure. */ @@ -357,13 +356,7 @@ static int smc91c92_attach(struct pcmcia_device *p_dev) smc->mii_if.phy_id_mask = 0x1f; smc->mii_if.reg_num_mask = 0x1f; - link->handle = p_dev; - p_dev->instance = link; - - link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; - smc91c92_config(link); - - return 0; + return smc91c92_config(link); } /* smc91c92_attach */ /*====================================================================== @@ -375,18 +368,16 @@ static int smc91c92_attach(struct pcmcia_device *p_dev) ======================================================================*/ -static void smc91c92_detach(struct pcmcia_device *p_dev) +static void smc91c92_detach(struct pcmcia_device *link) { - dev_link_t *link = dev_to_instance(p_dev); struct net_device *dev = link->priv; DEBUG(0, "smc91c92_detach(0x%p)\n", link); - if (link->dev) + if (link->dev_node) unregister_netdev(dev); - if (link->state & DEV_CONFIG) - smc91c92_release(link); + smc91c92_release(link); free_netdev(dev); } /* smc91c92_detach */ @@ -414,7 +405,7 @@ static int cvt_ascii_address(struct net_device *dev, char *s) /*====================================================================*/ -static int first_tuple(client_handle_t handle, tuple_t *tuple, +static int first_tuple(struct pcmcia_device *handle, tuple_t *tuple, cisparse_t *parse) { int i; @@ -425,7 +416,7 @@ static int first_tuple(client_handle_t handle, tuple_t *tuple, return pcmcia_parse_tuple(handle, tuple, parse); } -static int next_tuple(client_handle_t handle, tuple_t *tuple, +static int next_tuple(struct pcmcia_device *handle, tuple_t *tuple, cisparse_t *parse) { int i; @@ -447,7 +438,7 @@ static int next_tuple(client_handle_t handle, tuple_t *tuple, ======================================================================*/ -static int mhz_3288_power(dev_link_t *link) +static int mhz_3288_power(struct pcmcia_device *link) { struct net_device *dev = link->priv; struct smc_private *smc = netdev_priv(dev); @@ -469,7 +460,7 @@ static int mhz_3288_power(dev_link_t *link) return 0; } -static int mhz_mfc_config(dev_link_t *link) +static int mhz_mfc_config(struct pcmcia_device *link) { struct net_device *dev = link->priv; struct smc_private *smc = netdev_priv(dev); @@ -504,7 +495,7 @@ static int mhz_mfc_config(dev_link_t *link) tuple->TupleDataMax = 255; tuple->DesiredTuple = CISTPL_CFTABLE_ENTRY; - i = first_tuple(link->handle, tuple, parse); + i = first_tuple(link, tuple, parse); /* The Megahertz combo cards have modem-like CIS entries, so we have to explicitly try a bunch of port combinations. */ while (i == CS_SUCCESS) { @@ -513,11 +504,11 @@ static int mhz_mfc_config(dev_link_t *link) for (k = 0; k < 0x400; k += 0x10) { if (k & 0x80) continue; link->io.BasePort1 = k ^ 0x300; - i = pcmcia_request_io(link->handle, &link->io); + i = pcmcia_request_io(link, &link->io); if (i == CS_SUCCESS) break; } if (i == CS_SUCCESS) break; - i = next_tuple(link->handle, tuple, parse); + i = next_tuple(link, tuple, parse); } if (i != CS_SUCCESS) goto free_cfg_mem; @@ -527,7 +518,7 @@ static int mhz_mfc_config(dev_link_t *link) req.Attributes = WIN_DATA_WIDTH_8|WIN_MEMORY_TYPE_AM|WIN_ENABLE; req.Base = req.Size = 0; req.AccessSpeed = 0; - i = pcmcia_request_window(&link->handle, &req, &link->win); + i = pcmcia_request_window(&link, &req, &link->win); if (i != CS_SUCCESS) goto free_cfg_mem; smc->base = ioremap(req.Base, req.Size); @@ -546,9 +537,8 @@ free_cfg_mem: return i; } -static int mhz_setup(dev_link_t *link) +static int mhz_setup(struct pcmcia_device *link) { - client_handle_t handle = link->handle; struct net_device *dev = link->priv; struct smc_cfg_mem *cfg_mem; tuple_t *tuple; @@ -571,13 +561,13 @@ static int mhz_setup(dev_link_t *link) /* Read the station address from the CIS. It is stored as the last (fourth) string in the Version 1 Version/ID tuple. */ tuple->DesiredTuple = CISTPL_VERS_1; - if (first_tuple(handle, tuple, parse) != CS_SUCCESS) { + if (first_tuple(link, tuple, parse) != CS_SUCCESS) { rc = -1; goto free_cfg_mem; } /* Ugh -- the EM1144 card has two VERS_1 tuples!?! */ - if (next_tuple(handle, tuple, parse) != CS_SUCCESS) - first_tuple(handle, tuple, parse); + if (next_tuple(link, tuple, parse) != CS_SUCCESS) + first_tuple(link, tuple, parse); if (parse->version_1.ns > 3) { station_addr = parse->version_1.str + parse->version_1.ofs[3]; if (cvt_ascii_address(dev, station_addr) == 0) { @@ -588,11 +578,11 @@ static int mhz_setup(dev_link_t *link) /* Another possibility: for the EM3288, in a special tuple */ tuple->DesiredTuple = 0x81; - if (pcmcia_get_first_tuple(handle, tuple) != CS_SUCCESS) { + if (pcmcia_get_first_tuple(link, tuple) != CS_SUCCESS) { rc = -1; goto free_cfg_mem; } - if (pcmcia_get_tuple_data(handle, tuple) != CS_SUCCESS) { + if (pcmcia_get_tuple_data(link, tuple) != CS_SUCCESS) { rc = -1; goto free_cfg_mem; } @@ -616,7 +606,7 @@ free_cfg_mem: ======================================================================*/ -static void mot_config(dev_link_t *link) +static void mot_config(struct pcmcia_device *link) { struct net_device *dev = link->priv; struct smc_private *smc = netdev_priv(dev); @@ -637,7 +627,7 @@ static void mot_config(dev_link_t *link) mdelay(100); } -static int mot_setup(dev_link_t *link) +static int mot_setup(struct pcmcia_device *link) { struct net_device *dev = link->priv; kio_addr_t ioaddr = dev->base_addr; @@ -671,7 +661,7 @@ static int mot_setup(dev_link_t *link) /*====================================================================*/ -static int smc_config(dev_link_t *link) +static int smc_config(struct pcmcia_device *link) { struct net_device *dev = link->priv; struct smc_cfg_mem *cfg_mem; @@ -696,16 +686,16 @@ static int smc_config(dev_link_t *link) tuple->DesiredTuple = CISTPL_CFTABLE_ENTRY; link->io.NumPorts1 = 16; - i = first_tuple(link->handle, tuple, parse); + i = first_tuple(link, tuple, parse); while (i != CS_NO_MORE_ITEMS) { if (i == CS_SUCCESS) { link->conf.ConfigIndex = cf->index; link->io.BasePort1 = cf->io.win[0].base; link->io.IOAddrLines = cf->io.flags & CISTPL_IO_LINES_MASK; - i = pcmcia_request_io(link->handle, &link->io); + i = pcmcia_request_io(link, &link->io); if (i == CS_SUCCESS) break; } - i = next_tuple(link->handle, tuple, parse); + i = next_tuple(link, tuple, parse); } if (i == CS_SUCCESS) dev->base_addr = link->io.BasePort1; @@ -714,9 +704,8 @@ static int smc_config(dev_link_t *link) return i; } -static int smc_setup(dev_link_t *link) +static int smc_setup(struct pcmcia_device *link) { - client_handle_t handle = link->handle; struct net_device *dev = link->priv; struct smc_cfg_mem *cfg_mem; tuple_t *tuple; @@ -739,11 +728,11 @@ static int smc_setup(dev_link_t *link) /* Check for a LAN function extension tuple */ tuple->DesiredTuple = CISTPL_FUNCE; - i = first_tuple(handle, tuple, parse); + i = first_tuple(link, tuple, parse); while (i == CS_SUCCESS) { if (parse->funce.type == CISTPL_FUNCE_LAN_NODE_ID) break; - i = next_tuple(handle, tuple, parse); + i = next_tuple(link, tuple, parse); } if (i == CS_SUCCESS) { node_id = (cistpl_lan_node_id_t *)parse->funce.data; @@ -756,7 +745,7 @@ static int smc_setup(dev_link_t *link) } /* Try the third string in the Version 1 Version/ID tuple. */ tuple->DesiredTuple = CISTPL_VERS_1; - if (first_tuple(handle, tuple, parse) != CS_SUCCESS) { + if (first_tuple(link, tuple, parse) != CS_SUCCESS) { rc = -1; goto free_cfg_mem; } @@ -774,7 +763,7 @@ free_cfg_mem: /*====================================================================*/ -static int osi_config(dev_link_t *link) +static int osi_config(struct pcmcia_device *link) { struct net_device *dev = link->priv; static const kio_addr_t com[4] = { 0x3f8, 0x2f8, 0x3e8, 0x2e8 }; @@ -794,22 +783,21 @@ static int osi_config(dev_link_t *link) for (i = j = 0; j < 4; j++) { link->io.BasePort2 = com[j]; - i = pcmcia_request_io(link->handle, &link->io); + i = pcmcia_request_io(link, &link->io); if (i == CS_SUCCESS) break; } if (i != CS_SUCCESS) { /* Fallback: turn off hard decode */ link->conf.ConfigIndex = 0x03; link->io.NumPorts2 = 0; - i = pcmcia_request_io(link->handle, &link->io); + i = pcmcia_request_io(link, &link->io); } dev->base_addr = link->io.BasePort1 + 0x10; return i; } -static int osi_setup(dev_link_t *link, u_short manfid, u_short cardid) +static int osi_setup(struct pcmcia_device *link, u_short manfid, u_short cardid) { - client_handle_t handle = link->handle; struct net_device *dev = link->priv; struct smc_cfg_mem *cfg_mem; tuple_t *tuple; @@ -830,12 +818,12 @@ static int osi_setup(dev_link_t *link, u_short manfid, u_short cardid) /* Read the station address from tuple 0x90, subtuple 0x04 */ tuple->DesiredTuple = 0x90; - i = pcmcia_get_first_tuple(handle, tuple); + i = pcmcia_get_first_tuple(link, tuple); while (i == CS_SUCCESS) { - i = pcmcia_get_tuple_data(handle, tuple); + i = pcmcia_get_tuple_data(link, tuple); if ((i != CS_SUCCESS) || (buf[0] == 0x04)) break; - i = pcmcia_get_next_tuple(handle, tuple); + i = pcmcia_get_next_tuple(link, tuple); } if (i != CS_SUCCESS) { rc = -1; @@ -868,57 +856,47 @@ free_cfg_mem: return rc; } -static int smc91c92_suspend(struct pcmcia_device *p_dev) +static int smc91c92_suspend(struct pcmcia_device *link) { - dev_link_t *link = dev_to_instance(p_dev); struct net_device *dev = link->priv; - link->state |= DEV_SUSPEND; - if (link->state & DEV_CONFIG) { - if (link->open) - netif_device_detach(dev); - pcmcia_release_configuration(link->handle); - } + if (link->open) + netif_device_detach(dev); return 0; } -static int smc91c92_resume(struct pcmcia_device *p_dev) +static int smc91c92_resume(struct pcmcia_device *link) { - dev_link_t *link = dev_to_instance(p_dev); struct net_device *dev = link->priv; struct smc_private *smc = netdev_priv(dev); int i; - link->state &= ~DEV_SUSPEND; - if (link->state & DEV_CONFIG) { - if ((smc->manfid == MANFID_MEGAHERTZ) && - (smc->cardid == PRODID_MEGAHERTZ_EM3288)) - mhz_3288_power(link); - pcmcia_request_configuration(link->handle, &link->conf); - if (smc->manfid == MANFID_MOTOROLA) - mot_config(link); - if ((smc->manfid == MANFID_OSITECH) && - (smc->cardid != PRODID_OSITECH_SEVEN)) { - /* Power up the card and enable interrupts */ - set_bits(0x0300, dev->base_addr-0x10+OSITECH_AUI_PWR); - set_bits(0x0300, dev->base_addr-0x10+OSITECH_RESET_ISR); - } - if (((smc->manfid == MANFID_OSITECH) && - (smc->cardid == PRODID_OSITECH_SEVEN)) || - ((smc->manfid == MANFID_PSION) && - (smc->cardid == PRODID_PSION_NET100))) { - /* Download the Seven of Diamonds firmware */ - for (i = 0; i < sizeof(__Xilinx7OD); i++) { - outb(__Xilinx7OD[i], link->io.BasePort1+2); - udelay(50); - } - } - if (link->open) { - smc_reset(dev); - netif_device_attach(dev); + if ((smc->manfid == MANFID_MEGAHERTZ) && + (smc->cardid == PRODID_MEGAHERTZ_EM3288)) + mhz_3288_power(link); + if (smc->manfid == MANFID_MOTOROLA) + mot_config(link); + if ((smc->manfid == MANFID_OSITECH) && + (smc->cardid != PRODID_OSITECH_SEVEN)) { + /* Power up the card and enable interrupts */ + set_bits(0x0300, dev->base_addr-0x10+OSITECH_AUI_PWR); + set_bits(0x0300, dev->base_addr-0x10+OSITECH_RESET_ISR); + } + if (((smc->manfid == MANFID_OSITECH) && + (smc->cardid == PRODID_OSITECH_SEVEN)) || + ((smc->manfid == MANFID_PSION) && + (smc->cardid == PRODID_PSION_NET100))) { + /* Download the Seven of Diamonds firmware */ + for (i = 0; i < sizeof(__Xilinx7OD); i++) { + outb(__Xilinx7OD[i], link->io.BasePort1+2); + udelay(50); } } + if (link->open) { + smc_reset(dev); + netif_device_attach(dev); + } return 0; } @@ -931,7 +909,7 @@ static int smc91c92_resume(struct pcmcia_device *p_dev) ======================================================================*/ -static int check_sig(dev_link_t *link) +static int check_sig(struct pcmcia_device *link) { struct net_device *dev = link->priv; kio_addr_t ioaddr = dev->base_addr; @@ -964,13 +942,15 @@ static int check_sig(dev_link_t *link) } if (width) { - printk(KERN_INFO "smc91c92_cs: using 8-bit IO window.\n"); - smc91c92_suspend(link->handle); - pcmcia_release_io(link->handle, &link->io); - link->io.Attributes1 = IO_DATA_PATH_WIDTH_8; - pcmcia_request_io(link->handle, &link->io); - smc91c92_resume(link->handle); - return check_sig(link); + modconf_t mod = { + .Attributes = CONF_IO_CHANGE_WIDTH, + }; + printk(KERN_INFO "smc91c92_cs: using 8-bit IO window.\n"); + + smc91c92_suspend(link); + pcmcia_modify_configuration(link, &mod); + smc91c92_resume(link); + return check_sig(link); } return -ENODEV; } @@ -984,11 +964,10 @@ static int check_sig(dev_link_t *link) ======================================================================*/ #define CS_EXIT_TEST(ret, svc, label) \ -if (ret != CS_SUCCESS) { cs_error(link->handle, svc, ret); goto label; } +if (ret != CS_SUCCESS) { cs_error(link, svc, ret); goto label; } -static void smc91c92_config(dev_link_t *link) +static int smc91c92_config(struct pcmcia_device *link) { - client_handle_t handle = link->handle; struct net_device *dev = link->priv; struct smc_private *smc = netdev_priv(dev); struct smc_cfg_mem *cfg_mem; @@ -1015,21 +994,18 @@ static void smc91c92_config(dev_link_t *link) tuple->TupleDataMax = 64; tuple->DesiredTuple = CISTPL_CONFIG; - i = first_tuple(handle, tuple, parse); + i = first_tuple(link, tuple, parse); CS_EXIT_TEST(i, ParseTuple, config_failed); link->conf.ConfigBase = parse->config.base; link->conf.Present = parse->config.rmask[0]; tuple->DesiredTuple = CISTPL_MANFID; tuple->Attributes = TUPLE_RETURN_COMMON; - if (first_tuple(handle, tuple, parse) == CS_SUCCESS) { + if (first_tuple(link, tuple, parse) == CS_SUCCESS) { smc->manfid = parse->manfid.manf; smc->cardid = parse->manfid.card; } - /* Configure card */ - link->state |= DEV_CONFIG; - if ((smc->manfid == MANFID_OSITECH) && (smc->cardid != PRODID_OSITECH_SEVEN)) { i = osi_config(link); @@ -1043,9 +1019,9 @@ static void smc91c92_config(dev_link_t *link) } CS_EXIT_TEST(i, RequestIO, config_failed); - i = pcmcia_request_irq(link->handle, &link->irq); + i = pcmcia_request_irq(link, &link->irq); CS_EXIT_TEST(i, RequestIRQ, config_failed); - i = pcmcia_request_configuration(link->handle, &link->conf); + i = pcmcia_request_configuration(link, &link->conf); CS_EXIT_TEST(i, RequestConfiguration, config_failed); if (smc->manfid == MANFID_MOTOROLA) @@ -1124,13 +1100,12 @@ static void smc91c92_config(dev_link_t *link) SMC_SELECT_BANK(0); } - link->dev = &smc->node; - link->state &= ~DEV_CONFIG_PENDING; - SET_NETDEV_DEV(dev, &handle_to_dev(handle)); + link->dev_node = &smc->node; + SET_NETDEV_DEV(dev, &handle_to_dev(link)); if (register_netdev(dev) != 0) { printk(KERN_ERR "smc91c92_cs: register_netdev() failed\n"); - link->dev = NULL; + link->dev_node = NULL; goto config_undo; } @@ -1160,15 +1135,14 @@ static void smc91c92_config(dev_link_t *link) } } kfree(cfg_mem); - return; + return 0; config_undo: unregister_netdev(dev); config_failed: /* CS_EXIT_TEST() calls jump to here... */ smc91c92_release(link); - link->state &= ~DEV_CONFIG_PENDING; kfree(cfg_mem); - + return -ENODEV; } /* smc91c92_config */ /*====================================================================== @@ -1179,22 +1153,15 @@ config_failed: /* CS_EXIT_TEST() calls jump to here... */ ======================================================================*/ -static void smc91c92_release(dev_link_t *link) +static void smc91c92_release(struct pcmcia_device *link) { - - DEBUG(0, "smc91c92_release(0x%p)\n", link); - - pcmcia_release_configuration(link->handle); - pcmcia_release_io(link->handle, &link->io); - pcmcia_release_irq(link->handle, &link->irq); - if (link->win) { - struct net_device *dev = link->priv; - struct smc_private *smc = netdev_priv(dev); - iounmap(smc->base); - pcmcia_release_window(link->win); - } - - link->state &= ~DEV_CONFIG; + DEBUG(0, "smc91c92_release(0x%p)\n", link); + if (link->win) { + struct net_device *dev = link->priv; + struct smc_private *smc = netdev_priv(dev); + iounmap(smc->base); + } + pcmcia_disable_device(link); } /*====================================================================== @@ -1283,7 +1250,7 @@ static void smc_dump(struct net_device *dev) static int smc_open(struct net_device *dev) { struct smc_private *smc = netdev_priv(dev); - dev_link_t *link = &smc->link; + struct pcmcia_device *link = smc->p_dev; #ifdef PCMCIA_DEBUG DEBUG(0, "%s: smc_open(%p), ID/Window %4.4x.\n", @@ -1292,7 +1259,7 @@ static int smc_open(struct net_device *dev) #endif /* Check that the PCMCIA card is still here. */ - if (!DEV_OK(link)) + if (!pcmcia_dev_present(link)) return -ENODEV; /* Physical device present signature. */ if (check_sig(link) < 0) { @@ -1320,7 +1287,7 @@ static int smc_open(struct net_device *dev) static int smc_close(struct net_device *dev) { struct smc_private *smc = netdev_priv(dev); - dev_link_t *link = &smc->link; + struct pcmcia_device *link = smc->p_dev; kio_addr_t ioaddr = dev->base_addr; DEBUG(0, "%s: smc_close(), status %4.4x.\n", @@ -2311,7 +2278,7 @@ static struct pcmcia_driver smc91c92_cs_driver = { .drv = { .name = "smc91c92_cs", }, - .probe = smc91c92_attach, + .probe = smc91c92_probe, .remove = smc91c92_detach, .id_table = smc91c92_ids, .suspend = smc91c92_suspend, diff --git a/drivers/net/pcmcia/xirc2ps_cs.c b/drivers/net/pcmcia/xirc2ps_cs.c index eed496803fe..71f45056a70 100644 --- a/drivers/net/pcmcia/xirc2ps_cs.c +++ b/drivers/net/pcmcia/xirc2ps_cs.c @@ -289,9 +289,9 @@ static void mii_wr(kio_addr_t ioaddr, u_char phyaddr, u_char phyreg, * and ejection events. They are invoked from the event handler. */ -static int has_ce2_string(dev_link_t * link); -static void xirc2ps_config(dev_link_t * link); -static void xirc2ps_release(dev_link_t * link); +static int has_ce2_string(struct pcmcia_device * link); +static int xirc2ps_config(struct pcmcia_device * link); +static void xirc2ps_release(struct pcmcia_device * link); /**************** * The attach() and detach() entry points are used to create and destroy @@ -313,10 +313,10 @@ static irqreturn_t xirc2ps_interrupt(int irq, void *dev_id, struct pt_regs *regs /**************** * A linked list of "instances" of the device. Each actual * PCMCIA card corresponds to one device instance, and is described - * by one dev_link_t structure (defined in ds.h). + * by one struct pcmcia_device structure (defined in ds.h). * * You may not want to use a linked list for this -- for example, the - * memory card driver uses an array of dev_link_t pointers, where minor + * memory card driver uses an array of struct pcmcia_device pointers, where minor * device numbers are used to derive the corresponding array index. */ @@ -326,13 +326,13 @@ static irqreturn_t xirc2ps_interrupt(int irq, void *dev_id, struct pt_regs *regs * example, ethernet cards, modems). In other cases, there may be * many actual or logical devices (SCSI adapters, memory cards with * multiple partitions). The dev_node_t structures need to be kept - * in a linked list starting at the 'dev' field of a dev_link_t + * in a linked list starting at the 'dev' field of a struct pcmcia_device * structure. We allocate them in the card's private data structure, * because they generally can't be allocated dynamically. */ typedef struct local_info_t { - dev_link_t link; + struct pcmcia_device *p_dev; dev_node_t node; struct net_device_stats stats; int card_type; @@ -355,7 +355,7 @@ static void do_tx_timeout(struct net_device *dev); static struct net_device_stats *do_get_stats(struct net_device *dev); static void set_addresses(struct net_device *dev); static void set_multicast_list(struct net_device *dev); -static int set_card_type(dev_link_t *link, const void *s); +static int set_card_type(struct pcmcia_device *link, const void *s); static int do_config(struct net_device *dev, struct ifmap *map); static int do_open(struct net_device *dev); static int do_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); @@ -368,7 +368,7 @@ static int do_stop(struct net_device *dev); /*=============== Helper functions =========================*/ static int -first_tuple(client_handle_t handle, tuple_t *tuple, cisparse_t *parse) +first_tuple(struct pcmcia_device *handle, tuple_t *tuple, cisparse_t *parse) { int err; @@ -379,7 +379,7 @@ first_tuple(client_handle_t handle, tuple_t *tuple, cisparse_t *parse) } static int -next_tuple(client_handle_t handle, tuple_t *tuple, cisparse_t *parse) +next_tuple(struct pcmcia_device *handle, tuple_t *tuple, cisparse_t *parse) { int err; @@ -553,9 +553,8 @@ mii_wr(kio_addr_t ioaddr, u_char phyaddr, u_char phyreg, unsigned data, int len) */ static int -xirc2ps_attach(struct pcmcia_device *p_dev) +xirc2ps_probe(struct pcmcia_device *link) { - dev_link_t *link; struct net_device *dev; local_info_t *local; @@ -566,12 +565,11 @@ xirc2ps_attach(struct pcmcia_device *p_dev) if (!dev) return -ENOMEM; local = netdev_priv(dev); - link = &local->link; + local->p_dev = link; link->priv = dev; /* General socket configuration */ link->conf.Attributes = CONF_ENABLE_IRQ; - link->conf.Vcc = 50; link->conf.IntType = INT_MEMORY_AND_IO; link->conf.ConfigIndex = 1; link->conf.Present = PRESENT_OPTION; @@ -593,13 +591,7 @@ xirc2ps_attach(struct pcmcia_device *p_dev) dev->watchdog_timeo = TX_TIMEOUT; #endif - link->handle = p_dev; - p_dev->instance = link; - - link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; - xirc2ps_config(link); - - return 0; + return xirc2ps_config(link); } /* xirc2ps_attach */ /**************** @@ -610,18 +602,16 @@ xirc2ps_attach(struct pcmcia_device *p_dev) */ static void -xirc2ps_detach(struct pcmcia_device *p_dev) +xirc2ps_detach(struct pcmcia_device *link) { - dev_link_t *link = dev_to_instance(p_dev); struct net_device *dev = link->priv; DEBUG(0, "detach(0x%p)\n", link); - if (link->dev) + if (link->dev_node) unregister_netdev(dev); - if (link->state & DEV_CONFIG) - xirc2ps_release(link); + xirc2ps_release(link); free_netdev(dev); } /* xirc2ps_detach */ @@ -645,7 +635,7 @@ xirc2ps_detach(struct pcmcia_device *p_dev) * */ static int -set_card_type(dev_link_t *link, const void *s) +set_card_type(struct pcmcia_device *link, const void *s) { struct net_device *dev = link->priv; local_info_t *local = netdev_priv(dev); @@ -714,9 +704,8 @@ set_card_type(dev_link_t *link, const void *s) * Returns: true if this is a CE2 */ static int -has_ce2_string(dev_link_t * link) +has_ce2_string(struct pcmcia_device * link) { - client_handle_t handle = link->handle; tuple_t tuple; cisparse_t parse; u_char buf[256]; @@ -726,7 +715,7 @@ has_ce2_string(dev_link_t * link) tuple.TupleDataMax = 254; tuple.TupleOffset = 0; tuple.DesiredTuple = CISTPL_VERS_1; - if (!first_tuple(handle, &tuple, &parse) && parse.version_1.ns > 2) { + if (!first_tuple(link, &tuple, &parse) && parse.version_1.ns > 2) { if (strstr(parse.version_1.str + parse.version_1.ofs[2], "CE2")) return 1; } @@ -738,10 +727,9 @@ has_ce2_string(dev_link_t * link) * is received, to configure the PCMCIA socket, and to make the * ethernet device available to the system. */ -static void -xirc2ps_config(dev_link_t * link) +static int +xirc2ps_config(struct pcmcia_device * link) { - client_handle_t handle = link->handle; struct net_device *dev = link->priv; local_info_t *local = netdev_priv(dev); tuple_t tuple; @@ -767,7 +755,7 @@ xirc2ps_config(dev_link_t * link) /* Is this a valid card */ tuple.DesiredTuple = CISTPL_MANFID; - if ((err=first_tuple(handle, &tuple, &parse))) { + if ((err=first_tuple(link, &tuple, &parse))) { printk(KNOT_XIRC "manfid not found in CIS\n"); goto failure; } @@ -803,15 +791,15 @@ xirc2ps_config(dev_link_t * link) /* get configuration stuff */ tuple.DesiredTuple = CISTPL_CONFIG; - if ((err=first_tuple(handle, &tuple, &parse))) + if ((err=first_tuple(link, &tuple, &parse))) goto cis_error; link->conf.ConfigBase = parse.config.base; link->conf.Present = parse.config.rmask[0]; /* get the ethernet address from the CIS */ tuple.DesiredTuple = CISTPL_FUNCE; - for (err = first_tuple(handle, &tuple, &parse); !err; - err = next_tuple(handle, &tuple, &parse)) { + for (err = first_tuple(link, &tuple, &parse); !err; + err = next_tuple(link, &tuple, &parse)) { /* Once I saw two CISTPL_FUNCE_LAN_NODE_ID entries: * the first one with a length of zero the second correct - * so I skip all entries with length 0 */ @@ -821,8 +809,8 @@ xirc2ps_config(dev_link_t * link) } if (err) { /* not found: try to get the node-id from tuple 0x89 */ tuple.DesiredTuple = 0x89; /* data layout looks like tuple 0x22 */ - if ((err = pcmcia_get_first_tuple(handle, &tuple)) == 0 && - (err = pcmcia_get_tuple_data(handle, &tuple)) == 0) { + if ((err = pcmcia_get_first_tuple(link, &tuple)) == 0 && + (err = pcmcia_get_tuple_data(link, &tuple)) == 0) { if (tuple.TupleDataLen == 8 && *buf == CISTPL_FUNCE_LAN_NODE_ID) memcpy(&parse, buf, 8); else @@ -831,8 +819,8 @@ xirc2ps_config(dev_link_t * link) } if (err) { /* another try (James Lehmer's CE2 version 4.1)*/ tuple.DesiredTuple = CISTPL_FUNCE; - for (err = first_tuple(handle, &tuple, &parse); !err; - err = next_tuple(handle, &tuple, &parse)) { + for (err = first_tuple(link, &tuple, &parse); !err; + err = next_tuple(link, &tuple, &parse)) { if (parse.funce.type == 0x02 && parse.funce.data[0] == 1 && parse.funce.data[1] == 6 && tuple.TupleDataLen == 13) { buf[1] = 4; @@ -853,9 +841,6 @@ xirc2ps_config(dev_link_t * link) for (i=0; i < 6; i++) dev->dev_addr[i] = node_id->id[i]; - /* Configure card */ - link->state |= DEV_CONFIG; - link->io.IOAddrLines =10; link->io.Attributes1 = IO_DATA_PATH_WIDTH_16; link->irq.Attributes = IRQ_HANDLE_PRESENT; @@ -875,14 +860,14 @@ xirc2ps_config(dev_link_t * link) * Ethernet port */ link->io.NumPorts1 = 16; /* no Mako stuff anymore */ tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; - for (err = first_tuple(handle, &tuple, &parse); !err; - err = next_tuple(handle, &tuple, &parse)) { + for (err = first_tuple(link, &tuple, &parse); !err; + err = next_tuple(link, &tuple, &parse)) { if (cf->io.nwin > 0 && (cf->io.win[0].base & 0xf) == 8) { for (ioaddr = 0x300; ioaddr < 0x400; ioaddr += 0x10) { link->conf.ConfigIndex = cf->index ; link->io.BasePort2 = cf->io.win[0].base; link->io.BasePort1 = ioaddr; - if (!(err=pcmcia_request_io(link->handle, &link->io))) + if (!(err=pcmcia_request_io(link, &link->io))) goto port_found; } } @@ -896,15 +881,15 @@ xirc2ps_config(dev_link_t * link) */ for (pass=0; pass < 2; pass++) { tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; - for (err = first_tuple(handle, &tuple, &parse); !err; - err = next_tuple(handle, &tuple, &parse)){ + for (err = first_tuple(link, &tuple, &parse); !err; + err = next_tuple(link, &tuple, &parse)){ if (cf->io.nwin > 0 && (cf->io.win[0].base & 0xf) == 8){ link->conf.ConfigIndex = cf->index ; link->io.BasePort2 = cf->io.win[0].base; link->io.BasePort1 = link->io.BasePort2 + (pass ? (cf->index & 0x20 ? -24:8) : (cf->index & 0x20 ? 8:-24)); - if (!(err=pcmcia_request_io(link->handle, &link->io))) + if (!(err=pcmcia_request_io(link, &link->io))) goto port_found; } } @@ -919,12 +904,12 @@ xirc2ps_config(dev_link_t * link) link->io.NumPorts1 = 16; for (ioaddr = 0x300; ioaddr < 0x400; ioaddr += 0x10) { link->io.BasePort1 = ioaddr; - if (!(err=pcmcia_request_io(link->handle, &link->io))) + if (!(err=pcmcia_request_io(link, &link->io))) goto port_found; } link->io.BasePort1 = 0; /* let CS decide */ - if ((err=pcmcia_request_io(link->handle, &link->io))) { - cs_error(link->handle, RequestIO, err); + if ((err=pcmcia_request_io(link, &link->io))) { + cs_error(link, RequestIO, err); goto config_error; } } @@ -936,8 +921,8 @@ xirc2ps_config(dev_link_t * link) * Now allocate an interrupt line. Note that this does not * actually assign a handler to the interrupt. */ - if ((err=pcmcia_request_irq(link->handle, &link->irq))) { - cs_error(link->handle, RequestIRQ, err); + if ((err=pcmcia_request_irq(link, &link->irq))) { + cs_error(link, RequestIRQ, err); goto config_error; } @@ -945,8 +930,8 @@ xirc2ps_config(dev_link_t * link) * This actually configures the PCMCIA socket -- setting up * the I/O windows and the interrupt mapping. */ - if ((err=pcmcia_request_configuration(link->handle, &link->conf))) { - cs_error(link->handle, RequestConfiguration, err); + if ((err=pcmcia_request_configuration(link, &link->conf))) { + cs_error(link, RequestConfiguration, err); goto config_error; } @@ -963,15 +948,15 @@ xirc2ps_config(dev_link_t * link) reg.Action = CS_WRITE; reg.Offset = CISREG_IOBASE_0; reg.Value = link->io.BasePort2 & 0xff; - if ((err = pcmcia_access_configuration_register(link->handle, ®))) { - cs_error(link->handle, AccessConfigurationRegister, err); + if ((err = pcmcia_access_configuration_register(link, ®))) { + cs_error(link, AccessConfigurationRegister, err); goto config_error; } reg.Action = CS_WRITE; reg.Offset = CISREG_IOBASE_1; reg.Value = (link->io.BasePort2 >> 8) & 0xff; - if ((err = pcmcia_access_configuration_register(link->handle, ®))) { - cs_error(link->handle, AccessConfigurationRegister, err); + if ((err = pcmcia_access_configuration_register(link, ®))) { + cs_error(link, AccessConfigurationRegister, err); goto config_error; } @@ -982,15 +967,15 @@ xirc2ps_config(dev_link_t * link) req.Attributes = WIN_DATA_WIDTH_8|WIN_MEMORY_TYPE_AM|WIN_ENABLE; req.Base = req.Size = 0; req.AccessSpeed = 0; - if ((err = pcmcia_request_window(&link->handle, &req, &link->win))) { - cs_error(link->handle, RequestWindow, err); + if ((err = pcmcia_request_window(&link, &req, &link->win))) { + cs_error(link, RequestWindow, err); goto config_error; } local->dingo_ccr = ioremap(req.Base,0x1000) + 0x0800; mem.CardOffset = 0x0; mem.Page = 0; if ((err = pcmcia_map_mem_page(link->win, &mem))) { - cs_error(link->handle, MapMemPage, err); + cs_error(link, MapMemPage, err); goto config_error; } @@ -1050,13 +1035,12 @@ xirc2ps_config(dev_link_t * link) if (local->dingo) do_reset(dev, 1); /* a kludge to make the cem56 work */ - link->dev = &local->node; - link->state &= ~DEV_CONFIG_PENDING; - SET_NETDEV_DEV(dev, &handle_to_dev(handle)); + link->dev_node = &local->node; + SET_NETDEV_DEV(dev, &handle_to_dev(link)); if ((err=register_netdev(dev))) { printk(KNOT_XIRC "register_netdev() failed\n"); - link->dev = NULL; + link->dev_node = NULL; goto config_error; } @@ -1069,17 +1053,16 @@ xirc2ps_config(dev_link_t * link) printk("%c%02X", i?':':' ', dev->dev_addr[i]); printk("\n"); - return; + return 0; config_error: - link->state &= ~DEV_CONFIG_PENDING; xirc2ps_release(link); - return; + return -ENODEV; cis_error: printk(KNOT_XIRC "unable to parse CIS\n"); failure: - link->state &= ~DEV_CONFIG_PENDING; + return -ENODEV; } /* xirc2ps_config */ /**************** @@ -1088,57 +1071,41 @@ xirc2ps_config(dev_link_t * link) * still open, this will be postponed until it is closed. */ static void -xirc2ps_release(dev_link_t *link) +xirc2ps_release(struct pcmcia_device *link) { + DEBUG(0, "release(0x%p)\n", link); - DEBUG(0, "release(0x%p)\n", link); - - if (link->win) { - struct net_device *dev = link->priv; - local_info_t *local = netdev_priv(dev); - if (local->dingo) - iounmap(local->dingo_ccr - 0x0800); - pcmcia_release_window(link->win); - } - pcmcia_release_configuration(link->handle); - pcmcia_release_io(link->handle, &link->io); - pcmcia_release_irq(link->handle, &link->irq); - link->state &= ~DEV_CONFIG; - + if (link->win) { + struct net_device *dev = link->priv; + local_info_t *local = netdev_priv(dev); + if (local->dingo) + iounmap(local->dingo_ccr - 0x0800); + } + pcmcia_disable_device(link); } /* xirc2ps_release */ /*====================================================================*/ -static int xirc2ps_suspend(struct pcmcia_device *p_dev) +static int xirc2ps_suspend(struct pcmcia_device *link) { - dev_link_t *link = dev_to_instance(p_dev); struct net_device *dev = link->priv; - link->state |= DEV_SUSPEND; - if (link->state & DEV_CONFIG) { - if (link->open) { - netif_device_detach(dev); - do_powerdown(dev); - } - pcmcia_release_configuration(link->handle); + if (link->open) { + netif_device_detach(dev); + do_powerdown(dev); } return 0; } -static int xirc2ps_resume(struct pcmcia_device *p_dev) +static int xirc2ps_resume(struct pcmcia_device *link) { - dev_link_t *link = dev_to_instance(p_dev); struct net_device *dev = link->priv; - link->state &= ~DEV_SUSPEND; - if (link->state & DEV_CONFIG) { - pcmcia_request_configuration(link->handle, &link->conf); - if (link->open) { - do_reset(dev,1); - netif_device_attach(dev); - } + if (link->open) { + do_reset(dev,1); + netif_device_attach(dev); } return 0; @@ -1552,13 +1519,13 @@ static int do_open(struct net_device *dev) { local_info_t *lp = netdev_priv(dev); - dev_link_t *link = &lp->link; + struct pcmcia_device *link = lp->p_dev; DEBUG(0, "do_open(%p)\n", dev); /* Check that the PCMCIA card is still here. */ /* Physical device present signature. */ - if (!DEV_OK(link)) + if (!pcmcia_dev_present(link)) return -ENODEV; /* okay */ @@ -1882,7 +1849,7 @@ do_stop(struct net_device *dev) { kio_addr_t ioaddr = dev->base_addr; local_info_t *lp = netdev_priv(dev); - dev_link_t *link = &lp->link; + struct pcmcia_device *link = lp->p_dev; DEBUG(0, "do_stop(%p)\n", dev); @@ -1935,7 +1902,7 @@ static struct pcmcia_driver xirc2ps_cs_driver = { .drv = { .name = "xirc2ps_cs", }, - .probe = xirc2ps_attach, + .probe = xirc2ps_probe, .remove = xirc2ps_detach, .id_table = xirc2ps_ids, .suspend = xirc2ps_suspend, @@ -1973,7 +1940,7 @@ static int __init setup_xirc2ps_cs(char *str) MAYBE_SET(lockup_hack, 6); #undef MAYBE_SET - return 0; + return 1; } __setup("xirc2ps_cs=", setup_xirc2ps_cs); diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index 964c0964483..770e6b6cec6 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c @@ -69,8 +69,8 @@ #define DRV_MODULE_NAME "tg3" #define PFX DRV_MODULE_NAME ": " -#define DRV_MODULE_VERSION "3.55" -#define DRV_MODULE_RELDATE "Mar 27, 2006" +#define DRV_MODULE_VERSION "3.56" +#define DRV_MODULE_RELDATE "Apr 1, 2006" #define TG3_DEF_MAC_MODE 0 #define TG3_DEF_RX_MODE 0 @@ -497,40 +497,33 @@ static void tg3_write_mem(struct tg3 *tp, u32 off, u32 val) unsigned long flags; spin_lock_irqsave(&tp->indirect_lock, flags); - if (tp->write32 != tg3_write_indirect_reg32) { - tw32_f(TG3PCI_MEM_WIN_BASE_ADDR, off); - tw32_f(TG3PCI_MEM_WIN_DATA, val); + pci_write_config_dword(tp->pdev, TG3PCI_MEM_WIN_BASE_ADDR, off); + pci_write_config_dword(tp->pdev, TG3PCI_MEM_WIN_DATA, val); - /* Always leave this as zero. */ - tw32_f(TG3PCI_MEM_WIN_BASE_ADDR, 0); - } else { - pci_write_config_dword(tp->pdev, TG3PCI_MEM_WIN_BASE_ADDR, off); - pci_write_config_dword(tp->pdev, TG3PCI_MEM_WIN_DATA, val); - - /* Always leave this as zero. */ - pci_write_config_dword(tp->pdev, TG3PCI_MEM_WIN_BASE_ADDR, 0); - } + /* Always leave this as zero. */ + pci_write_config_dword(tp->pdev, TG3PCI_MEM_WIN_BASE_ADDR, 0); spin_unlock_irqrestore(&tp->indirect_lock, flags); } +static void tg3_write_mem_fast(struct tg3 *tp, u32 off, u32 val) +{ + /* If no workaround is needed, write to mem space directly */ + if (tp->write32 != tg3_write_indirect_reg32) + tw32(NIC_SRAM_WIN_BASE + off, val); + else + tg3_write_mem(tp, off, val); +} + static void tg3_read_mem(struct tg3 *tp, u32 off, u32 *val) { unsigned long flags; spin_lock_irqsave(&tp->indirect_lock, flags); - if (tp->write32 != tg3_write_indirect_reg32) { - tw32_f(TG3PCI_MEM_WIN_BASE_ADDR, off); - *val = tr32(TG3PCI_MEM_WIN_DATA); + pci_write_config_dword(tp->pdev, TG3PCI_MEM_WIN_BASE_ADDR, off); + pci_read_config_dword(tp->pdev, TG3PCI_MEM_WIN_DATA, val); - /* Always leave this as zero. */ - tw32_f(TG3PCI_MEM_WIN_BASE_ADDR, 0); - } else { - pci_write_config_dword(tp->pdev, TG3PCI_MEM_WIN_BASE_ADDR, off); - pci_read_config_dword(tp->pdev, TG3PCI_MEM_WIN_DATA, val); - - /* Always leave this as zero. */ - pci_write_config_dword(tp->pdev, TG3PCI_MEM_WIN_BASE_ADDR, 0); - } + /* Always leave this as zero. */ + pci_write_config_dword(tp->pdev, TG3PCI_MEM_WIN_BASE_ADDR, 0); spin_unlock_irqrestore(&tp->indirect_lock, flags); } @@ -1374,12 +1367,12 @@ static int tg3_set_power_state(struct tg3 *tp, pci_power_t state) } } - tg3_write_sig_post_reset(tp, RESET_KIND_SHUTDOWN); - /* Finally, set the new power state. */ pci_write_config_word(tp->pdev, pm + PCI_PM_CTRL, power_control); udelay(100); /* Delay after power state change */ + tg3_write_sig_post_reset(tp, RESET_KIND_SHUTDOWN); + return 0; } @@ -6547,11 +6540,11 @@ static void tg3_timer(unsigned long __opaque) if (tp->tg3_flags & TG3_FLAG_ENABLE_ASF) { u32 val; - tg3_write_mem(tp, NIC_SRAM_FW_CMD_MBOX, - FWCMD_NICDRV_ALIVE2); - tg3_write_mem(tp, NIC_SRAM_FW_CMD_LEN_MBOX, 4); + tg3_write_mem_fast(tp, NIC_SRAM_FW_CMD_MBOX, + FWCMD_NICDRV_ALIVE2); + tg3_write_mem_fast(tp, NIC_SRAM_FW_CMD_LEN_MBOX, 4); /* 5 seconds timeout */ - tg3_write_mem(tp, NIC_SRAM_FW_CMD_DATA_MBOX, 5); + tg3_write_mem_fast(tp, NIC_SRAM_FW_CMD_DATA_MBOX, 5); val = tr32(GRC_RX_CPU_EVENT); val |= (1 << 14); tw32(GRC_RX_CPU_EVENT, val); diff --git a/drivers/net/tokenring/Kconfig b/drivers/net/tokenring/Kconfig index e4cfc80b283..99c4c1922f1 100644 --- a/drivers/net/tokenring/Kconfig +++ b/drivers/net/tokenring/Kconfig @@ -3,7 +3,7 @@ # menu "Token Ring devices" - depends on NETDEVICES + depends on NETDEVICES && !UML # So far, we only have PCI, ISA, and MCA token ring devices config TR diff --git a/drivers/net/wireless/Kconfig b/drivers/net/wireless/Kconfig index f85e3019000..bad09ebdb50 100644 --- a/drivers/net/wireless/Kconfig +++ b/drivers/net/wireless/Kconfig @@ -356,7 +356,7 @@ config PCI_HERMES config ATMEL tristate "Atmel at76c50x chipset 802.11b support" - depends on NET_RADIO + depends on NET_RADIO && (PCI || PCMCIA) select FW_LOADER select CRC32 ---help--- diff --git a/drivers/net/wireless/airo_cs.c b/drivers/net/wireless/airo_cs.c index a496460ce22..af0cbb6c5c0 100644 --- a/drivers/net/wireless/airo_cs.c +++ b/drivers/net/wireless/airo_cs.c @@ -80,8 +80,8 @@ MODULE_SUPPORTED_DEVICE("Aironet 4500, 4800 and Cisco 340 PCMCIA cards"); event handler. */ -static void airo_config(dev_link_t *link); -static void airo_release(dev_link_t *link); +static int airo_config(struct pcmcia_device *link); +static void airo_release(struct pcmcia_device *link); /* The attach() and detach() entry points are used to create and destroy @@ -101,10 +101,10 @@ static void airo_detach(struct pcmcia_device *p_dev); /* A linked list of "instances" of the aironet device. Each actual PCMCIA card corresponds to one device instance, and is described - by one dev_link_t structure (defined in ds.h). + by one struct pcmcia_device structure (defined in ds.h). You may not want to use a linked list for this -- for example, the - memory card driver uses an array of dev_link_t pointers, where minor + memory card driver uses an array of struct pcmcia_device pointers, where minor device numbers are used to derive the corresponding array index. */ @@ -114,7 +114,7 @@ static void airo_detach(struct pcmcia_device *p_dev); example, ethernet cards, modems). In other cases, there may be many actual or logical devices (SCSI adapters, memory cards with multiple partitions). The dev_node_t structures need to be kept - in a linked list starting at the 'dev' field of a dev_link_t + in a linked list starting at the 'dev' field of a struct pcmcia_device structure. We allocate them in the card's private data structure, because they generally shouldn't be allocated dynamically. @@ -141,24 +141,16 @@ typedef struct local_info_t { ======================================================================*/ -static int airo_attach(struct pcmcia_device *p_dev) +static int airo_probe(struct pcmcia_device *p_dev) { - dev_link_t *link; local_info_t *local; DEBUG(0, "airo_attach()\n"); - /* Initialize the dev_link_t structure */ - link = kzalloc(sizeof(struct dev_link_t), GFP_KERNEL); - if (!link) { - printk(KERN_ERR "airo_cs: no memory for new device\n"); - return -ENOMEM; - } - /* Interrupt setup */ - link->irq.Attributes = IRQ_TYPE_EXCLUSIVE; - link->irq.IRQInfo1 = IRQ_LEVEL_ID; - link->irq.Handler = NULL; + p_dev->irq.Attributes = IRQ_TYPE_EXCLUSIVE; + p_dev->irq.IRQInfo1 = IRQ_LEVEL_ID; + p_dev->irq.Handler = NULL; /* General socket configuration defaults can go here. In this @@ -167,26 +159,18 @@ static int airo_attach(struct pcmcia_device *p_dev) and attributes of IO windows) are fixed by the nature of the device, and can be hard-wired here. */ - link->conf.Attributes = 0; - link->conf.Vcc = 50; - link->conf.IntType = INT_MEMORY_AND_IO; + p_dev->conf.Attributes = 0; + p_dev->conf.IntType = INT_MEMORY_AND_IO; /* Allocate space for private device-specific data */ local = kzalloc(sizeof(local_info_t), GFP_KERNEL); if (!local) { printk(KERN_ERR "airo_cs: no memory for new device\n"); - kfree (link); return -ENOMEM; } - link->priv = local; + p_dev->priv = local; - link->handle = p_dev; - p_dev->instance = link; - - link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; - airo_config(link); - - return 0; + return airo_config(p_dev); } /* airo_attach */ /*====================================================================== @@ -198,14 +182,11 @@ static int airo_attach(struct pcmcia_device *p_dev) ======================================================================*/ -static void airo_detach(struct pcmcia_device *p_dev) +static void airo_detach(struct pcmcia_device *link) { - dev_link_t *link = dev_to_instance(p_dev); - DEBUG(0, "airo_detach(0x%p)\n", link); - if (link->state & DEV_CONFIG) - airo_release(link); + airo_release(link); if ( ((local_info_t*)link->priv)->eth_dev ) { stop_airo_card( ((local_info_t*)link->priv)->eth_dev, 0 ); @@ -213,7 +194,6 @@ static void airo_detach(struct pcmcia_device *p_dev) ((local_info_t*)link->priv)->eth_dev = NULL; kfree(link->priv); - kfree(link); } /* airo_detach */ /*====================================================================== @@ -227,9 +207,8 @@ static void airo_detach(struct pcmcia_device *p_dev) #define CS_CHECK(fn, ret) \ do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0) -static void airo_config(dev_link_t *link) +static int airo_config(struct pcmcia_device *link) { - client_handle_t handle; tuple_t tuple; cisparse_t parse; local_info_t *dev; @@ -237,8 +216,7 @@ static void airo_config(dev_link_t *link) u_char buf[64]; win_req_t req; memreq_t map; - - handle = link->handle; + dev = link->priv; DEBUG(0, "airo_config(0x%p)\n", link); @@ -252,15 +230,12 @@ static void airo_config(dev_link_t *link) tuple.TupleData = buf; tuple.TupleDataMax = sizeof(buf); tuple.TupleOffset = 0; - CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple)); - CS_CHECK(GetTupleData, pcmcia_get_tuple_data(handle, &tuple)); - CS_CHECK(ParseTuple, pcmcia_parse_tuple(handle, &tuple, &parse)); + CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); + CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple)); + CS_CHECK(ParseTuple, pcmcia_parse_tuple(link, &tuple, &parse)); link->conf.ConfigBase = parse.config.base; link->conf.Present = parse.config.rmask[0]; - - /* Configure card */ - link->state |= DEV_CONFIG; - + /* In this loop, we scan the CIS for configuration table entries, each of which describes a valid card configuration, including @@ -274,12 +249,12 @@ static void airo_config(dev_link_t *link) will only use the CIS to fill in implementation-defined details. */ tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; - CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple)); + CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); while (1) { cistpl_cftable_entry_t dflt = { 0 }; cistpl_cftable_entry_t *cfg = &(parse.cftable_entry); - if (pcmcia_get_tuple_data(handle, &tuple) != 0 || - pcmcia_parse_tuple(handle, &tuple, &parse) != 0) + if (pcmcia_get_tuple_data(link, &tuple) != 0 || + pcmcia_parse_tuple(link, &tuple, &parse) != 0) goto next_entry; if (cfg->flags & CISTPL_CFTABLE_DEFAULT) dflt = *cfg; @@ -294,16 +269,11 @@ static void airo_config(dev_link_t *link) /* Use power settings for Vcc and Vpp if present */ /* Note that the CIS values need to be rescaled */ - if (cfg->vcc.present & (1<<CISTPL_POWER_VNOM)) - link->conf.Vcc = cfg->vcc.param[CISTPL_POWER_VNOM]/10000; - else if (dflt.vcc.present & (1<<CISTPL_POWER_VNOM)) - link->conf.Vcc = dflt.vcc.param[CISTPL_POWER_VNOM]/10000; - if (cfg->vpp1.present & (1<<CISTPL_POWER_VNOM)) - link->conf.Vpp1 = link->conf.Vpp2 = + link->conf.Vpp = cfg->vpp1.param[CISTPL_POWER_VNOM]/10000; else if (dflt.vpp1.present & (1<<CISTPL_POWER_VNOM)) - link->conf.Vpp1 = link->conf.Vpp2 = + link->conf.Vpp = dflt.vpp1.param[CISTPL_POWER_VNOM]/10000; /* Do we need to allocate an interrupt? */ @@ -329,12 +299,12 @@ static void airo_config(dev_link_t *link) } /* This reserves IO space but doesn't actually enable it */ - if (pcmcia_request_io(link->handle, &link->io) != 0) + if (pcmcia_request_io(link, &link->io) != 0) goto next_entry; /* Now set up a common memory window, if needed. There is room - in the dev_link_t structure for one memory window handle, + in the struct pcmcia_device structure for one memory window handle, but if the base addresses need to be saved, or if multiple windows are needed, the info should go in the private data structure for this device. @@ -350,7 +320,7 @@ static void airo_config(dev_link_t *link) req.Base = mem->win[0].host_addr; req.Size = mem->win[0].len; req.AccessSpeed = 0; - if (pcmcia_request_window(&link->handle, &req, &link->win) != 0) + if (pcmcia_request_window(&link, &req, &link->win) != 0) goto next_entry; map.Page = 0; map.CardOffset = mem->win[0].card_addr; if (pcmcia_map_mem_page(link->win, &map) != 0) @@ -360,7 +330,7 @@ static void airo_config(dev_link_t *link) break; next_entry: - CS_CHECK(GetNextTuple, pcmcia_get_next_tuple(handle, &tuple)); + CS_CHECK(GetNextTuple, pcmcia_get_next_tuple(link, &tuple)); } /* @@ -369,33 +339,32 @@ static void airo_config(dev_link_t *link) irq structure is initialized. */ if (link->conf.Attributes & CONF_ENABLE_IRQ) - CS_CHECK(RequestIRQ, pcmcia_request_irq(link->handle, &link->irq)); + CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq)); /* This actually configures the PCMCIA socket -- setting up the I/O windows and the interrupt mapping, and putting the card and host interface into "Memory and IO" mode. */ - CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link->handle, &link->conf)); + CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf)); ((local_info_t*)link->priv)->eth_dev = init_airo_card( link->irq.AssignedIRQ, - link->io.BasePort1, 1, &handle_to_dev(handle) ); + link->io.BasePort1, 1, &handle_to_dev(link) ); if (!((local_info_t*)link->priv)->eth_dev) goto cs_failed; /* At this point, the dev_node_t structure(s) need to be - initialized and arranged in a linked list at link->dev. + initialized and arranged in a linked list at link->dev_node. */ strcpy(dev->node.dev_name, ((local_info_t*)link->priv)->eth_dev->name ); dev->node.major = dev->node.minor = 0; - link->dev = &dev->node; + link->dev_node = &dev->node; /* Finally, report what we've done */ - printk(KERN_INFO "%s: index 0x%02x: Vcc %d.%d", - dev->node.dev_name, link->conf.ConfigIndex, - link->conf.Vcc/10, link->conf.Vcc%10); - if (link->conf.Vpp1) - printk(", Vpp %d.%d", link->conf.Vpp1/10, link->conf.Vpp1%10); + printk(KERN_INFO "%s: index 0x%02x: ", + dev->node.dev_name, link->conf.ConfigIndex); + if (link->conf.Vpp) + printk(", Vpp %d.%d", link->conf.Vpp/10, link->conf.Vpp%10); if (link->conf.Attributes & CONF_ENABLE_IRQ) printk(", irq %d", link->irq.AssignedIRQ); if (link->io.NumPorts1) @@ -408,14 +377,12 @@ static void airo_config(dev_link_t *link) printk(", mem 0x%06lx-0x%06lx", req.Base, req.Base+req.Size-1); printk("\n"); - - link->state &= ~DEV_CONFIG_PENDING; - return; - + return 0; + cs_failed: - cs_error(link->handle, last_fn, last_ret); + cs_error(link, last_fn, last_ret); airo_release(link); - + return -ENODEV; } /* airo_config */ /*====================================================================== @@ -426,51 +393,26 @@ static void airo_config(dev_link_t *link) ======================================================================*/ -static void airo_release(dev_link_t *link) +static void airo_release(struct pcmcia_device *link) { DEBUG(0, "airo_release(0x%p)\n", link); - - /* Unlink the device chain */ - link->dev = NULL; - - /* - In a normal driver, additional code may be needed to release - other kernel data structures associated with this device. - */ - - /* Don't bother checking to see if these succeed or not */ - if (link->win) - pcmcia_release_window(link->win); - pcmcia_release_configuration(link->handle); - if (link->io.NumPorts1) - pcmcia_release_io(link->handle, &link->io); - if (link->irq.AssignedIRQ) - pcmcia_release_irq(link->handle, &link->irq); - link->state &= ~DEV_CONFIG; + pcmcia_disable_device(link); } -static int airo_suspend(struct pcmcia_device *p_dev) +static int airo_suspend(struct pcmcia_device *link) { - dev_link_t *link = dev_to_instance(p_dev); local_info_t *local = link->priv; - link->state |= DEV_SUSPEND; - if (link->state & DEV_CONFIG) { - netif_device_detach(local->eth_dev); - pcmcia_release_configuration(link->handle); - } + netif_device_detach(local->eth_dev); return 0; } -static int airo_resume(struct pcmcia_device *p_dev) +static int airo_resume(struct pcmcia_device *link) { - dev_link_t *link = dev_to_instance(p_dev); local_info_t *local = link->priv; - link->state &= ~DEV_SUSPEND; - if (link->state & DEV_CONFIG) { - pcmcia_request_configuration(link->handle, &link->conf); + if (link->open) { reset_airo_card(local->eth_dev); netif_device_attach(local->eth_dev); } @@ -492,7 +434,7 @@ static struct pcmcia_driver airo_driver = { .drv = { .name = "airo_cs", }, - .probe = airo_attach, + .probe = airo_probe, .remove = airo_detach, .id_table = airo_ids, .suspend = airo_suspend, diff --git a/drivers/net/wireless/atmel_cs.c b/drivers/net/wireless/atmel_cs.c index d6f4a5a3e55..26bf1127524 100644 --- a/drivers/net/wireless/atmel_cs.c +++ b/drivers/net/wireless/atmel_cs.c @@ -91,8 +91,8 @@ MODULE_SUPPORTED_DEVICE("Atmel at76c50x PCMCIA cards"); event handler. */ -static void atmel_config(dev_link_t *link); -static void atmel_release(dev_link_t *link); +static int atmel_config(struct pcmcia_device *link); +static void atmel_release(struct pcmcia_device *link); /* The attach() and detach() entry points are used to create and destroy @@ -112,10 +112,10 @@ static void atmel_detach(struct pcmcia_device *p_dev); /* A linked list of "instances" of the atmelnet device. Each actual PCMCIA card corresponds to one device instance, and is described - by one dev_link_t structure (defined in ds.h). + by one struct pcmcia_device structure (defined in ds.h). You may not want to use a linked list for this -- for example, the - memory card driver uses an array of dev_link_t pointers, where minor + memory card driver uses an array of struct pcmcia_device pointers, where minor device numbers are used to derive the corresponding array index. */ @@ -125,7 +125,7 @@ static void atmel_detach(struct pcmcia_device *p_dev); example, ethernet cards, modems). In other cases, there may be many actual or logical devices (SCSI adapters, memory cards with multiple partitions). The dev_node_t structures need to be kept - in a linked list starting at the 'dev' field of a dev_link_t + in a linked list starting at the 'dev' field of a struct pcmcia_device structure. We allocate them in the card's private data structure, because they generally shouldn't be allocated dynamically. @@ -152,24 +152,16 @@ typedef struct local_info_t { ======================================================================*/ -static int atmel_attach(struct pcmcia_device *p_dev) +static int atmel_probe(struct pcmcia_device *p_dev) { - dev_link_t *link; local_info_t *local; DEBUG(0, "atmel_attach()\n"); - /* Initialize the dev_link_t structure */ - link = kzalloc(sizeof(struct dev_link_t), GFP_KERNEL); - if (!link) { - printk(KERN_ERR "atmel_cs: no memory for new device\n"); - return -ENOMEM; - } - /* Interrupt setup */ - link->irq.Attributes = IRQ_TYPE_EXCLUSIVE; - link->irq.IRQInfo1 = IRQ_LEVEL_ID; - link->irq.Handler = NULL; + p_dev->irq.Attributes = IRQ_TYPE_EXCLUSIVE; + p_dev->irq.IRQInfo1 = IRQ_LEVEL_ID; + p_dev->irq.Handler = NULL; /* General socket configuration defaults can go here. In this @@ -178,26 +170,18 @@ static int atmel_attach(struct pcmcia_device *p_dev) and attributes of IO windows) are fixed by the nature of the device, and can be hard-wired here. */ - link->conf.Attributes = 0; - link->conf.Vcc = 50; - link->conf.IntType = INT_MEMORY_AND_IO; + p_dev->conf.Attributes = 0; + p_dev->conf.IntType = INT_MEMORY_AND_IO; /* Allocate space for private device-specific data */ local = kzalloc(sizeof(local_info_t), GFP_KERNEL); if (!local) { printk(KERN_ERR "atmel_cs: no memory for new device\n"); - kfree (link); return -ENOMEM; } - link->priv = local; + p_dev->priv = local; - link->handle = p_dev; - p_dev->instance = link; - - link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; - atmel_config(link); - - return 0; + return atmel_config(p_dev); } /* atmel_attach */ /*====================================================================== @@ -209,17 +193,13 @@ static int atmel_attach(struct pcmcia_device *p_dev) ======================================================================*/ -static void atmel_detach(struct pcmcia_device *p_dev) +static void atmel_detach(struct pcmcia_device *link) { - dev_link_t *link = dev_to_instance(p_dev); - DEBUG(0, "atmel_detach(0x%p)\n", link); - if (link->state & DEV_CONFIG) - atmel_release(link); + atmel_release(link); kfree(link->priv); - kfree(link); } /*====================================================================== @@ -236,19 +216,17 @@ do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0) /* Call-back function to interrogate PCMCIA-specific information about the current existance of the card */ static int card_present(void *arg) -{ - dev_link_t *link = (dev_link_t *)arg; - if (link->state & DEV_SUSPEND) - return 0; - else if (link->state & DEV_PRESENT) +{ + struct pcmcia_device *link = (struct pcmcia_device *)arg; + + if (pcmcia_dev_present(link)) return 1; - + return 0; } -static void atmel_config(dev_link_t *link) +static int atmel_config(struct pcmcia_device *link) { - client_handle_t handle; tuple_t tuple; cisparse_t parse; local_info_t *dev; @@ -256,9 +234,8 @@ static void atmel_config(dev_link_t *link) u_char buf[64]; struct pcmcia_device_id *did; - handle = link->handle; dev = link->priv; - did = handle_to_dev(handle).driver_data; + did = handle_to_dev(link).driver_data; DEBUG(0, "atmel_config(0x%p)\n", link); @@ -272,15 +249,12 @@ static void atmel_config(dev_link_t *link) registers. */ tuple.DesiredTuple = CISTPL_CONFIG; - CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple)); - CS_CHECK(GetTupleData, pcmcia_get_tuple_data(handle, &tuple)); - CS_CHECK(ParseTuple, pcmcia_parse_tuple(handle, &tuple, &parse)); + CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); + CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple)); + CS_CHECK(ParseTuple, pcmcia_parse_tuple(link, &tuple, &parse)); link->conf.ConfigBase = parse.config.base; link->conf.Present = parse.config.rmask[0]; - - /* Configure card */ - link->state |= DEV_CONFIG; - + /* In this loop, we scan the CIS for configuration table entries, each of which describes a valid card configuration, including @@ -294,12 +268,12 @@ static void atmel_config(dev_link_t *link) will only use the CIS to fill in implementation-defined details. */ tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; - CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple)); + CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); while (1) { cistpl_cftable_entry_t dflt = { 0 }; cistpl_cftable_entry_t *cfg = &(parse.cftable_entry); - if (pcmcia_get_tuple_data(handle, &tuple) != 0 || - pcmcia_parse_tuple(handle, &tuple, &parse) != 0) + if (pcmcia_get_tuple_data(link, &tuple) != 0 || + pcmcia_parse_tuple(link, &tuple, &parse) != 0) goto next_entry; if (cfg->flags & CISTPL_CFTABLE_DEFAULT) dflt = *cfg; @@ -314,16 +288,11 @@ static void atmel_config(dev_link_t *link) /* Use power settings for Vcc and Vpp if present */ /* Note that the CIS values need to be rescaled */ - if (cfg->vcc.present & (1<<CISTPL_POWER_VNOM)) - link->conf.Vcc = cfg->vcc.param[CISTPL_POWER_VNOM]/10000; - else if (dflt.vcc.present & (1<<CISTPL_POWER_VNOM)) - link->conf.Vcc = dflt.vcc.param[CISTPL_POWER_VNOM]/10000; - if (cfg->vpp1.present & (1<<CISTPL_POWER_VNOM)) - link->conf.Vpp1 = link->conf.Vpp2 = + link->conf.Vpp = cfg->vpp1.param[CISTPL_POWER_VNOM]/10000; else if (dflt.vpp1.present & (1<<CISTPL_POWER_VNOM)) - link->conf.Vpp1 = link->conf.Vpp2 = + link->conf.Vpp = dflt.vpp1.param[CISTPL_POWER_VNOM]/10000; /* Do we need to allocate an interrupt? */ @@ -349,14 +318,14 @@ static void atmel_config(dev_link_t *link) } /* This reserves IO space but doesn't actually enable it */ - if (pcmcia_request_io(link->handle, &link->io) != 0) + if (pcmcia_request_io(link, &link->io) != 0) goto next_entry; /* If we got this far, we're cool! */ break; next_entry: - CS_CHECK(GetNextTuple, pcmcia_get_next_tuple(handle, &tuple)); + CS_CHECK(GetNextTuple, pcmcia_get_next_tuple(link, &tuple)); } /* @@ -365,14 +334,14 @@ static void atmel_config(dev_link_t *link) irq structure is initialized. */ if (link->conf.Attributes & CONF_ENABLE_IRQ) - CS_CHECK(RequestIRQ, pcmcia_request_irq(link->handle, &link->irq)); + CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq)); /* This actually configures the PCMCIA socket -- setting up the I/O windows and the interrupt mapping, and putting the card and host interface into "Memory and IO" mode. */ - CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link->handle, &link->conf)); + CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf)); if (link->irq.AssignedIRQ == 0) { printk(KERN_ALERT @@ -384,7 +353,7 @@ static void atmel_config(dev_link_t *link) init_atmel_card(link->irq.AssignedIRQ, link->io.BasePort1, did ? did->driver_info : ATMEL_FW_TYPE_NONE, - &handle_to_dev(handle), + &handle_to_dev(link), card_present, link); if (!((local_info_t*)link->priv)->eth_dev) @@ -393,18 +362,18 @@ static void atmel_config(dev_link_t *link) /* At this point, the dev_node_t structure(s) need to be - initialized and arranged in a linked list at link->dev. + initialized and arranged in a linked list at link->dev_node. */ strcpy(dev->node.dev_name, ((local_info_t*)link->priv)->eth_dev->name ); dev->node.major = dev->node.minor = 0; - link->dev = &dev->node; - - link->state &= ~DEV_CONFIG_PENDING; - return; - + link->dev_node = &dev->node; + + return 0; + cs_failed: - cs_error(link->handle, last_fn, last_ret); + cs_error(link, last_fn, last_ret); atmel_release(link); + return -ENODEV; } /*====================================================================== @@ -415,53 +384,34 @@ static void atmel_config(dev_link_t *link) ======================================================================*/ -static void atmel_release(dev_link_t *link) +static void atmel_release(struct pcmcia_device *link) { struct net_device *dev = ((local_info_t*)link->priv)->eth_dev; - + DEBUG(0, "atmel_release(0x%p)\n", link); - - /* Unlink the device chain */ - link->dev = NULL; - - if (dev) + + if (dev) stop_atmel_card(dev); - ((local_info_t*)link->priv)->eth_dev = NULL; - - /* Don't bother checking to see if these succeed or not */ - pcmcia_release_configuration(link->handle); - if (link->io.NumPorts1) - pcmcia_release_io(link->handle, &link->io); - if (link->irq.AssignedIRQ) - pcmcia_release_irq(link->handle, &link->irq); - link->state &= ~DEV_CONFIG; + ((local_info_t*)link->priv)->eth_dev = NULL; + + pcmcia_disable_device(link); } -static int atmel_suspend(struct pcmcia_device *dev) +static int atmel_suspend(struct pcmcia_device *link) { - dev_link_t *link = dev_to_instance(dev); local_info_t *local = link->priv; - link->state |= DEV_SUSPEND; - if (link->state & DEV_CONFIG) { - netif_device_detach(local->eth_dev); - pcmcia_release_configuration(link->handle); - } + netif_device_detach(local->eth_dev); return 0; } -static int atmel_resume(struct pcmcia_device *dev) +static int atmel_resume(struct pcmcia_device *link) { - dev_link_t *link = dev_to_instance(dev); local_info_t *local = link->priv; - link->state &= ~DEV_SUSPEND; - if (link->state & DEV_CONFIG) { - pcmcia_request_configuration(link->handle, &link->conf); - atmel_open(local->eth_dev); - netif_device_attach(local->eth_dev); - } + atmel_open(local->eth_dev); + netif_device_attach(local->eth_dev); return 0; } @@ -515,7 +465,7 @@ static struct pcmcia_driver atmel_driver = { .drv = { .name = "atmel_cs", }, - .probe = atmel_attach, + .probe = atmel_probe, .remove = atmel_detach, .id_table = atmel_ids, .suspend = atmel_suspend, diff --git a/drivers/net/wireless/hostap/hostap_cs.c b/drivers/net/wireless/hostap/hostap_cs.c index d335b250923..55bed923fbe 100644 --- a/drivers/net/wireless/hostap/hostap_cs.c +++ b/drivers/net/wireless/hostap/hostap_cs.c @@ -42,7 +42,7 @@ MODULE_PARM_DESC(ignore_cis_vcc, "Ignore broken CIS VCC entry"); /* struct local_info::hw_priv */ struct hostap_cs_priv { dev_node_t node; - dev_link_t *link; + struct pcmcia_device *link; int sandisk_connectplus; }; @@ -204,15 +204,13 @@ static int hfa384x_to_bap(struct net_device *dev, u16 bap, void *buf, int len) static void prism2_detach(struct pcmcia_device *p_dev); static void prism2_release(u_long arg); -static int prism2_config(dev_link_t *link); +static int prism2_config(struct pcmcia_device *link); static int prism2_pccard_card_present(local_info_t *local) { struct hostap_cs_priv *hw_priv = local->hw_priv; - if (hw_priv != NULL && hw_priv->link != NULL && - ((hw_priv->link->state & (DEV_PRESENT | DEV_CONFIG)) == - (DEV_PRESENT | DEV_CONFIG))) + if (hw_priv != NULL && hw_priv->link != NULL && pcmcia_dev_present(hw_priv->link)) return 1; return 0; } @@ -237,7 +235,7 @@ static void sandisk_set_iobase(local_info_t *local) reg.Action = CS_WRITE; reg.Offset = 0x10; /* 0x3f0 IO base 1 */ reg.Value = hw_priv->link->io.BasePort1 & 0x00ff; - res = pcmcia_access_configuration_register(hw_priv->link->handle, + res = pcmcia_access_configuration_register(hw_priv->link, ®); if (res != CS_SUCCESS) { printk(KERN_DEBUG "Prism3 SanDisk - failed to set I/O base 0 -" @@ -249,7 +247,7 @@ static void sandisk_set_iobase(local_info_t *local) reg.Action = CS_WRITE; reg.Offset = 0x12; /* 0x3f2 IO base 2 */ reg.Value = (hw_priv->link->io.BasePort1 & 0xff00) >> 8; - res = pcmcia_access_configuration_register(hw_priv->link->handle, + res = pcmcia_access_configuration_register(hw_priv->link, ®); if (res != CS_SUCCESS) { printk(KERN_DEBUG "Prism3 SanDisk - failed to set I/O base 1 -" @@ -301,9 +299,9 @@ static int sandisk_enable_wireless(struct net_device *dev) tuple.TupleData = buf; tuple.TupleDataMax = sizeof(buf); tuple.TupleOffset = 0; - if (pcmcia_get_first_tuple(hw_priv->link->handle, &tuple) || - pcmcia_get_tuple_data(hw_priv->link->handle, &tuple) || - pcmcia_parse_tuple(hw_priv->link->handle, &tuple, parse) || + if (pcmcia_get_first_tuple(hw_priv->link, &tuple) || + pcmcia_get_tuple_data(hw_priv->link, &tuple) || + pcmcia_parse_tuple(hw_priv->link, &tuple, parse) || parse->manfid.manf != 0xd601 || parse->manfid.card != 0x0101) { /* No SanDisk manfid found */ ret = -ENODEV; @@ -311,9 +309,9 @@ static int sandisk_enable_wireless(struct net_device *dev) } tuple.DesiredTuple = CISTPL_LONGLINK_MFC; - if (pcmcia_get_first_tuple(hw_priv->link->handle, &tuple) || - pcmcia_get_tuple_data(hw_priv->link->handle, &tuple) || - pcmcia_parse_tuple(hw_priv->link->handle, &tuple, parse) || + if (pcmcia_get_first_tuple(hw_priv->link, &tuple) || + pcmcia_get_tuple_data(hw_priv->link, &tuple) || + pcmcia_parse_tuple(hw_priv->link, &tuple, parse) || parse->longlink_mfc.nfn < 2) { /* No multi-function links found */ ret = -ENODEV; @@ -328,7 +326,7 @@ static int sandisk_enable_wireless(struct net_device *dev) reg.Action = CS_WRITE; reg.Offset = CISREG_COR; reg.Value = COR_SOFT_RESET; - res = pcmcia_access_configuration_register(hw_priv->link->handle, + res = pcmcia_access_configuration_register(hw_priv->link, ®); if (res != CS_SUCCESS) { printk(KERN_DEBUG "%s: SanDisk - COR sreset failed (%d)\n", @@ -345,7 +343,7 @@ static int sandisk_enable_wireless(struct net_device *dev) * will be enabled during the first cor_sreset call. */ reg.Value = COR_LEVEL_REQ | 0x8 | COR_ADDR_DECODE | COR_FUNC_ENA; - res = pcmcia_access_configuration_register(hw_priv->link->handle, + res = pcmcia_access_configuration_register(hw_priv->link, ®); if (res != CS_SUCCESS) { printk(KERN_DEBUG "%s: SanDisk - COR sreset failed (%d)\n", @@ -380,7 +378,7 @@ static void prism2_pccard_cor_sreset(local_info_t *local) reg.Action = CS_READ; reg.Offset = CISREG_COR; reg.Value = 0; - res = pcmcia_access_configuration_register(hw_priv->link->handle, + res = pcmcia_access_configuration_register(hw_priv->link, ®); if (res != CS_SUCCESS) { printk(KERN_DEBUG "prism2_pccard_cor_sreset failed 1 (%d)\n", @@ -392,7 +390,7 @@ static void prism2_pccard_cor_sreset(local_info_t *local) reg.Action = CS_WRITE; reg.Value |= COR_SOFT_RESET; - res = pcmcia_access_configuration_register(hw_priv->link->handle, + res = pcmcia_access_configuration_register(hw_priv->link, ®); if (res != CS_SUCCESS) { printk(KERN_DEBUG "prism2_pccard_cor_sreset failed 2 (%d)\n", @@ -405,7 +403,7 @@ static void prism2_pccard_cor_sreset(local_info_t *local) reg.Value &= ~COR_SOFT_RESET; if (hw_priv->sandisk_connectplus) reg.Value |= COR_IREQ_ENA; - res = pcmcia_access_configuration_register(hw_priv->link->handle, + res = pcmcia_access_configuration_register(hw_priv->link, ®); if (res != CS_SUCCESS) { printk(KERN_DEBUG "prism2_pccard_cor_sreset failed 3 (%d)\n", @@ -439,7 +437,7 @@ static void prism2_pccard_genesis_reset(local_info_t *local, int hcr) reg.Action = CS_READ; reg.Offset = CISREG_COR; reg.Value = 0; - res = pcmcia_access_configuration_register(hw_priv->link->handle, + res = pcmcia_access_configuration_register(hw_priv->link, ®); if (res != CS_SUCCESS) { printk(KERN_DEBUG "prism2_pccard_genesis_sreset failed 1 " @@ -452,7 +450,7 @@ static void prism2_pccard_genesis_reset(local_info_t *local, int hcr) reg.Action = CS_WRITE; reg.Value |= COR_SOFT_RESET; - res = pcmcia_access_configuration_register(hw_priv->link->handle, + res = pcmcia_access_configuration_register(hw_priv->link, ®); if (res != CS_SUCCESS) { printk(KERN_DEBUG "prism2_pccard_genesis_sreset failed 2 " @@ -466,7 +464,7 @@ static void prism2_pccard_genesis_reset(local_info_t *local, int hcr) reg.Action = CS_WRITE; reg.Value = hcr; reg.Offset = CISREG_CCSR; - res = pcmcia_access_configuration_register(hw_priv->link->handle, + res = pcmcia_access_configuration_register(hw_priv->link, ®); if (res != CS_SUCCESS) { printk(KERN_DEBUG "prism2_pccard_genesis_sreset failed 3 " @@ -478,7 +476,7 @@ static void prism2_pccard_genesis_reset(local_info_t *local, int hcr) reg.Action = CS_WRITE; reg.Offset = CISREG_COR; reg.Value = old_cor & ~COR_SOFT_RESET; - res = pcmcia_access_configuration_register(hw_priv->link->handle, + res = pcmcia_access_configuration_register(hw_priv->link, ®); if (res != CS_SUCCESS) { printk(KERN_DEBUG "prism2_pccard_genesis_sreset failed 4 " @@ -501,40 +499,27 @@ static struct prism2_helper_functions prism2_pccard_funcs = /* allocate local data and register with CardServices * initialize dev_link structure, but do not configure the card yet */ -static int prism2_attach(struct pcmcia_device *p_dev) +static int hostap_cs_probe(struct pcmcia_device *p_dev) { - dev_link_t *link; - - link = kmalloc(sizeof(dev_link_t), GFP_KERNEL); - if (link == NULL) - return -ENOMEM; - - memset(link, 0, sizeof(dev_link_t)); + int ret; PDEBUG(DEBUG_HW, "%s: setting Vcc=33 (constant)\n", dev_info); - link->conf.Vcc = 33; - link->conf.IntType = INT_MEMORY_AND_IO; - - link->handle = p_dev; - p_dev->instance = link; + p_dev->conf.IntType = INT_MEMORY_AND_IO; - link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; - if (prism2_config(link)) + ret = prism2_config(p_dev); + if (ret) { PDEBUG(DEBUG_EXTRA, "prism2_config() failed\n"); + } - return 0; + return ret; } -static void prism2_detach(struct pcmcia_device *p_dev) +static void prism2_detach(struct pcmcia_device *link) { - dev_link_t *link = dev_to_instance(p_dev); - PDEBUG(DEBUG_FLOW, "prism2_detach\n"); - if (link->state & DEV_CONFIG) { - prism2_release((u_long)link); - } + prism2_release((u_long)link); /* release net devices */ if (link->priv) { @@ -547,7 +532,6 @@ static void prism2_detach(struct pcmcia_device *p_dev) prism2_free_local_data(dev); kfree(hw_priv); } - kfree(link); } @@ -558,7 +542,7 @@ do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0) do { int ret = (retf); \ if (ret != 0) { \ PDEBUG(DEBUG_EXTRA, "CardServices(" #fn ") returned %d\n", ret); \ - cs_error(link->handle, fn, ret); \ + cs_error(link, fn, ret); \ goto next_entry; \ } \ } while (0) @@ -566,7 +550,7 @@ if (ret != 0) { \ /* run after a CARD_INSERTION event is received to configure the PCMCIA * socket and make the device available to the system */ -static int prism2_config(dev_link_t *link) +static int prism2_config(struct pcmcia_device *link) { struct net_device *dev; struct hostap_interface *iface; @@ -595,27 +579,24 @@ static int prism2_config(dev_link_t *link) tuple.TupleData = buf; tuple.TupleDataMax = sizeof(buf); tuple.TupleOffset = 0; - CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link->handle, &tuple)); - CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link->handle, &tuple)); - CS_CHECK(ParseTuple, pcmcia_parse_tuple(link->handle, &tuple, parse)); + CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); + CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple)); + CS_CHECK(ParseTuple, pcmcia_parse_tuple(link, &tuple, parse)); link->conf.ConfigBase = parse->config.base; link->conf.Present = parse->config.rmask[0]; CS_CHECK(GetConfigurationInfo, - pcmcia_get_configuration_info(link->handle, &conf)); - PDEBUG(DEBUG_HW, "%s: %s Vcc=%d (from config)\n", dev_info, - ignore_cis_vcc ? "ignoring" : "setting", conf.Vcc); - link->conf.Vcc = conf.Vcc; + pcmcia_get_configuration_info(link, &conf)); /* Look for an appropriate configuration table entry in the CIS */ tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; - CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link->handle, &tuple)); + CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); for (;;) { cistpl_cftable_entry_t *cfg = &(parse->cftable_entry); CFG_CHECK2(GetTupleData, - pcmcia_get_tuple_data(link->handle, &tuple)); + pcmcia_get_tuple_data(link, &tuple)); CFG_CHECK2(ParseTuple, - pcmcia_parse_tuple(link->handle, &tuple, parse)); + pcmcia_parse_tuple(link, &tuple, parse)); if (cfg->flags & CISTPL_CFTABLE_DEFAULT) dflt = *cfg; @@ -650,10 +631,10 @@ static int prism2_config(dev_link_t *link) } if (cfg->vpp1.present & (1 << CISTPL_POWER_VNOM)) - link->conf.Vpp1 = link->conf.Vpp2 = + link->conf.Vpp = cfg->vpp1.param[CISTPL_POWER_VNOM] / 10000; else if (dflt.vpp1.present & (1 << CISTPL_POWER_VNOM)) - link->conf.Vpp1 = link->conf.Vpp2 = + link->conf.Vpp = dflt.vpp1.param[CISTPL_POWER_VNOM] / 10000; /* Do we need to allocate an interrupt? */ @@ -695,19 +676,19 @@ static int prism2_config(dev_link_t *link) /* This reserves IO space but doesn't actually enable it */ CFG_CHECK2(RequestIO, - pcmcia_request_io(link->handle, &link->io)); + pcmcia_request_io(link, &link->io)); /* This configuration table entry is OK */ break; next_entry: CS_CHECK(GetNextTuple, - pcmcia_get_next_tuple(link->handle, &tuple)); + pcmcia_get_next_tuple(link, &tuple)); } /* Need to allocate net_device before requesting IRQ handler */ dev = prism2_init_local_data(&prism2_pccard_funcs, 0, - &handle_to_dev(link->handle)); + &handle_to_dev(link)); if (dev == NULL) goto failed; link->priv = dev; @@ -717,7 +698,7 @@ static int prism2_config(dev_link_t *link) local->hw_priv = hw_priv; hw_priv->link = link; strcpy(hw_priv->node.dev_name, dev->name); - link->dev = &hw_priv->node; + link->dev_node = &hw_priv->node; /* * Allocate an interrupt line. Note that this does not assign a @@ -730,7 +711,7 @@ static int prism2_config(dev_link_t *link) link->irq.Handler = prism2_interrupt; link->irq.Instance = dev; CS_CHECK(RequestIRQ, - pcmcia_request_irq(link->handle, &link->irq)); + pcmcia_request_irq(link, &link->irq)); } /* @@ -739,18 +720,17 @@ static int prism2_config(dev_link_t *link) * card and host interface into "Memory and IO" mode. */ CS_CHECK(RequestConfiguration, - pcmcia_request_configuration(link->handle, &link->conf)); + pcmcia_request_configuration(link, &link->conf)); dev->irq = link->irq.AssignedIRQ; dev->base_addr = link->io.BasePort1; /* Finally, report what we've done */ - printk(KERN_INFO "%s: index 0x%02x: Vcc %d.%d", - dev_info, link->conf.ConfigIndex, - link->conf.Vcc / 10, link->conf.Vcc % 10); - if (link->conf.Vpp1) - printk(", Vpp %d.%d", link->conf.Vpp1 / 10, - link->conf.Vpp1 % 10); + printk(KERN_INFO "%s: index 0x%02x: ", + dev_info, link->conf.ConfigIndex); + if (link->conf.Vpp) + printk(", Vpp %d.%d", link->conf.Vpp / 10, + link->conf.Vpp % 10); if (link->conf.Attributes & CONF_ENABLE_IRQ) printk(", irq %d", link->irq.AssignedIRQ); if (link->io.NumPorts1) @@ -761,9 +741,6 @@ static int prism2_config(dev_link_t *link) link->io.BasePort2+link->io.NumPorts2-1); printk("\n"); - link->state |= DEV_CONFIG; - link->state &= ~DEV_CONFIG_PENDING; - local->shutdown = 0; sandisk_enable_wireless(dev); @@ -778,7 +755,7 @@ static int prism2_config(dev_link_t *link) return ret; cs_failed: - cs_error(link->handle, last_fn, last_ret); + cs_error(link, last_fn, last_ret); failed: kfree(parse); @@ -790,7 +767,7 @@ static int prism2_config(dev_link_t *link) static void prism2_release(u_long arg) { - dev_link_t *link = (dev_link_t *)arg; + struct pcmcia_device *link = (struct pcmcia_device *)arg; PDEBUG(DEBUG_FLOW, "prism2_release\n"); @@ -799,71 +776,54 @@ static void prism2_release(u_long arg) struct hostap_interface *iface; iface = netdev_priv(dev); - if (link->state & DEV_CONFIG) - prism2_hw_shutdown(dev, 0); + prism2_hw_shutdown(dev, 0); iface->local->shutdown = 1; } - if (link->win) - pcmcia_release_window(link->win); - pcmcia_release_configuration(link->handle); - if (link->io.NumPorts1) - pcmcia_release_io(link->handle, &link->io); - if (link->irq.AssignedIRQ) - pcmcia_release_irq(link->handle, &link->irq); - - link->state &= ~DEV_CONFIG; - + pcmcia_disable_device(link); PDEBUG(DEBUG_FLOW, "release - done\n"); } -static int hostap_cs_suspend(struct pcmcia_device *p_dev) +static int hostap_cs_suspend(struct pcmcia_device *link) { - dev_link_t *link = dev_to_instance(p_dev); struct net_device *dev = (struct net_device *) link->priv; int dev_open = 0; + struct hostap_interface *iface = NULL; - PDEBUG(DEBUG_EXTRA, "%s: CS_EVENT_PM_SUSPEND\n", dev_info); - - link->state |= DEV_SUSPEND; + if (dev) + iface = netdev_priv(dev); - if (link->state & DEV_CONFIG) { - struct hostap_interface *iface = netdev_priv(dev); - if (iface && iface->local) - dev_open = iface->local->num_dev_open > 0; - if (dev_open) { - netif_stop_queue(dev); - netif_device_detach(dev); - } - prism2_suspend(dev); - pcmcia_release_configuration(link->handle); + PDEBUG(DEBUG_EXTRA, "%s: CS_EVENT_PM_SUSPEND\n", dev_info); + if (iface && iface->local) + dev_open = iface->local->num_dev_open > 0; + if (dev_open) { + netif_stop_queue(dev); + netif_device_detach(dev); } + prism2_suspend(dev); return 0; } -static int hostap_cs_resume(struct pcmcia_device *p_dev) +static int hostap_cs_resume(struct pcmcia_device *link) { - dev_link_t *link = dev_to_instance(p_dev); struct net_device *dev = (struct net_device *) link->priv; int dev_open = 0; + struct hostap_interface *iface = NULL; - PDEBUG(DEBUG_EXTRA, "%s: CS_EVENT_PM_RESUME\n", dev_info); + if (dev) + iface = netdev_priv(dev); - link->state &= ~DEV_SUSPEND; - if (link->state & DEV_CONFIG) { - struct hostap_interface *iface = netdev_priv(dev); - if (iface && iface->local) - dev_open = iface->local->num_dev_open > 0; + PDEBUG(DEBUG_EXTRA, "%s: CS_EVENT_PM_RESUME\n", dev_info); - pcmcia_request_configuration(link->handle, &link->conf); + if (iface && iface->local) + dev_open = iface->local->num_dev_open > 0; - prism2_hw_shutdown(dev, 1); - prism2_hw_config(dev, dev_open ? 0 : 1); - if (dev_open) { - netif_device_attach(dev); - netif_start_queue(dev); - } + prism2_hw_shutdown(dev, 1); + prism2_hw_config(dev, dev_open ? 0 : 1); + if (dev_open) { + netif_device_attach(dev); + netif_start_queue(dev); } return 0; @@ -930,7 +890,7 @@ static struct pcmcia_driver hostap_driver = { .drv = { .name = "hostap_cs", }, - .probe = prism2_attach, + .probe = hostap_cs_probe, .remove = prism2_detach, .owner = THIS_MODULE, .id_table = hostap_cs_ids, diff --git a/drivers/net/wireless/netwave_cs.c b/drivers/net/wireless/netwave_cs.c index 75ce6ddb0cf..9343d970537 100644 --- a/drivers/net/wireless/netwave_cs.c +++ b/drivers/net/wireless/netwave_cs.c @@ -190,8 +190,8 @@ module_param(mem_speed, int, 0); /*====================================================================*/ /* PCMCIA (Card Services) related functions */ -static void netwave_release(dev_link_t *link); /* Card removal */ -static void netwave_pcmcia_config(dev_link_t *arg); /* Runs after card +static void netwave_release(struct pcmcia_device *link); /* Card removal */ +static int netwave_pcmcia_config(struct pcmcia_device *arg); /* Runs after card insertion */ static void netwave_detach(struct pcmcia_device *p_dev); /* Destroy instance */ @@ -221,10 +221,10 @@ static struct iw_statistics* netwave_get_wireless_stats(struct net_device *dev); static void set_multicast_list(struct net_device *dev); /* - A dev_link_t structure has fields for most things that are needed + A struct pcmcia_device structure has fields for most things that are needed to keep track of a socket, but there will usually be some device specific information that also needs to be kept track of. The - 'priv' pointer in a dev_link_t structure can be used to point to + 'priv' pointer in a struct pcmcia_device structure can be used to point to a device-specific private data structure, like this. A driver needs to provide a dev_node_t structure for each device @@ -232,7 +232,7 @@ static void set_multicast_list(struct net_device *dev); example, ethernet cards, modems). In other cases, there may be many actual or logical devices (SCSI adapters, memory cards with multiple partitions). The dev_node_t structures need to be kept - in a linked list starting at the 'dev' field of a dev_link_t + in a linked list starting at the 'dev' field of a struct pcmcia_device structure. We allocate them in the card's private data structure, because they generally can't be allocated dynamically. */ @@ -268,7 +268,7 @@ struct site_survey { }; typedef struct netwave_private { - dev_link_t link; + struct pcmcia_device *p_dev; spinlock_t spinlock; /* Serialize access to the hardware (SMP) */ dev_node_t node; u_char __iomem *ramBase; @@ -376,20 +376,19 @@ static struct iw_statistics *netwave_get_wireless_stats(struct net_device *dev) * configure the card at this point -- we wait until we receive a * card insertion event. */ -static int netwave_attach(struct pcmcia_device *p_dev) +static int netwave_probe(struct pcmcia_device *link) { - dev_link_t *link; struct net_device *dev; netwave_private *priv; DEBUG(0, "netwave_attach()\n"); - /* Initialize the dev_link_t structure */ + /* Initialize the struct pcmcia_device structure */ dev = alloc_etherdev(sizeof(netwave_private)); if (!dev) return -ENOMEM; priv = netdev_priv(dev); - link = &priv->link; + priv->p_dev = link; link->priv = dev; /* The io structure describes IO port mapping */ @@ -406,7 +405,6 @@ static int netwave_attach(struct pcmcia_device *p_dev) /* General socket configuration */ link->conf.Attributes = CONF_ENABLE_IRQ; - link->conf.Vcc = 50; link->conf.IntType = INT_MEMORY_AND_IO; link->conf.ConfigIndex = 1; link->conf.Present = PRESENT_OPTION; @@ -430,13 +428,7 @@ static int netwave_attach(struct pcmcia_device *p_dev) dev->stop = &netwave_close; link->irq.Instance = dev; - link->handle = p_dev; - p_dev->instance = link; - - link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; - netwave_pcmcia_config( link); - - return 0; + return netwave_pcmcia_config( link); } /* netwave_attach */ /* @@ -447,17 +439,15 @@ static int netwave_attach(struct pcmcia_device *p_dev) * structures are freed. Otherwise, the structures will be freed * when the device is released. */ -static void netwave_detach(struct pcmcia_device *p_dev) +static void netwave_detach(struct pcmcia_device *link) { - dev_link_t *link = dev_to_instance(p_dev); struct net_device *dev = link->priv; DEBUG(0, "netwave_detach(0x%p)\n", link); - if (link->state & DEV_CONFIG) - netwave_release(link); + netwave_release(link); - if (link->dev) + if (link->dev_node) unregister_netdev(dev); free_netdev(dev); @@ -743,8 +733,7 @@ static const struct iw_handler_def netwave_handler_def = #define CS_CHECK(fn, ret) \ do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0) -static void netwave_pcmcia_config(dev_link_t *link) { - client_handle_t handle = link->handle; +static int netwave_pcmcia_config(struct pcmcia_device *link) { struct net_device *dev = link->priv; netwave_private *priv = netdev_priv(dev); tuple_t tuple; @@ -766,15 +755,12 @@ static void netwave_pcmcia_config(dev_link_t *link) { tuple.TupleDataMax = 64; tuple.TupleOffset = 0; tuple.DesiredTuple = CISTPL_CONFIG; - CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple)); - CS_CHECK(GetTupleData, pcmcia_get_tuple_data(handle, &tuple)); - CS_CHECK(ParseTuple, pcmcia_parse_tuple(handle, &tuple, &parse)); + CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); + CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple)); + CS_CHECK(ParseTuple, pcmcia_parse_tuple(link, &tuple, &parse)); link->conf.ConfigBase = parse.config.base; link->conf.Present = parse.config.rmask[0]; - /* Configure card */ - link->state |= DEV_CONFIG; - /* * Try allocating IO ports. This tries a few fixed addresses. * If you want, you can also read the card's config table to @@ -782,11 +768,11 @@ static void netwave_pcmcia_config(dev_link_t *link) { */ for (i = j = 0x0; j < 0x400; j += 0x20) { link->io.BasePort1 = j ^ 0x300; - i = pcmcia_request_io(link->handle, &link->io); + i = pcmcia_request_io(link, &link->io); if (i == CS_SUCCESS) break; } if (i != CS_SUCCESS) { - cs_error(link->handle, RequestIO, i); + cs_error(link, RequestIO, i); goto failed; } @@ -794,16 +780,16 @@ static void netwave_pcmcia_config(dev_link_t *link) { * Now allocate an interrupt line. Note that this does not * actually assign a handler to the interrupt. */ - CS_CHECK(RequestIRQ, pcmcia_request_irq(handle, &link->irq)); + CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq)); /* * This actually configures the PCMCIA socket -- setting up * the I/O windows and the interrupt mapping. */ - CS_CHECK(RequestConfiguration, pcmcia_request_configuration(handle, &link->conf)); + CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf)); /* - * Allocate a 32K memory window. Note that the dev_link_t + * Allocate a 32K memory window. Note that the struct pcmcia_device * structure provides space for one window handle -- if your * device needs several windows, you'll need to keep track of * the handles in your private data structure, dev->priv. @@ -813,7 +799,7 @@ static void netwave_pcmcia_config(dev_link_t *link) { req.Attributes = WIN_DATA_WIDTH_8|WIN_MEMORY_TYPE_CM|WIN_ENABLE; req.Base = 0; req.Size = 0x8000; req.AccessSpeed = mem_speed; - CS_CHECK(RequestWindow, pcmcia_request_window(&link->handle, &req, &link->win)); + CS_CHECK(RequestWindow, pcmcia_request_window(&link, &req, &link->win)); mem.CardOffset = 0x20000; mem.Page = 0; CS_CHECK(MapMemPage, pcmcia_map_mem_page(link->win, &mem)); @@ -823,7 +809,7 @@ static void netwave_pcmcia_config(dev_link_t *link) { dev->irq = link->irq.AssignedIRQ; dev->base_addr = link->io.BasePort1; - SET_NETDEV_DEV(dev, &handle_to_dev(handle)); + SET_NETDEV_DEV(dev, &handle_to_dev(link)); if (register_netdev(dev) != 0) { printk(KERN_DEBUG "netwave_cs: register_netdev() failed\n"); @@ -831,8 +817,7 @@ static void netwave_pcmcia_config(dev_link_t *link) { } strcpy(priv->node.dev_name, dev->name); - link->dev = &priv->node; - link->state &= ~DEV_CONFIG_PENDING; + link->dev_node = &priv->node; /* Reset card before reading physical address */ netwave_doreset(dev->base_addr, ramBase); @@ -852,12 +837,13 @@ static void netwave_pcmcia_config(dev_link_t *link) { printk(KERN_DEBUG "Netwave_reset: revision %04x %04x\n", get_uint16(ramBase + NETWAVE_EREG_ARW), get_uint16(ramBase + NETWAVE_EREG_ARW+2)); - return; + return 0; cs_failed: - cs_error(link->handle, last_fn, last_ret); + cs_error(link, last_fn, last_ret); failed: netwave_release(link); + return -ENODEV; } /* netwave_pcmcia_config */ /* @@ -867,52 +853,35 @@ failed: * device, and release the PCMCIA configuration. If the device is * still open, this will be postponed until it is closed. */ -static void netwave_release(dev_link_t *link) +static void netwave_release(struct pcmcia_device *link) { - struct net_device *dev = link->priv; - netwave_private *priv = netdev_priv(dev); - - DEBUG(0, "netwave_release(0x%p)\n", link); + struct net_device *dev = link->priv; + netwave_private *priv = netdev_priv(dev); - /* Don't bother checking to see if these succeed or not */ - if (link->win) { - iounmap(priv->ramBase); - pcmcia_release_window(link->win); - } - pcmcia_release_configuration(link->handle); - pcmcia_release_io(link->handle, &link->io); - pcmcia_release_irq(link->handle, &link->irq); + DEBUG(0, "netwave_release(0x%p)\n", link); - link->state &= ~DEV_CONFIG; + pcmcia_disable_device(link); + if (link->win) + iounmap(priv->ramBase); } -static int netwave_suspend(struct pcmcia_device *p_dev) +static int netwave_suspend(struct pcmcia_device *link) { - dev_link_t *link = dev_to_instance(p_dev); struct net_device *dev = link->priv; - link->state |= DEV_SUSPEND; - if (link->state & DEV_CONFIG) { - if (link->open) - netif_device_detach(dev); - pcmcia_release_configuration(link->handle); - } + if (link->open) + netif_device_detach(dev); return 0; } -static int netwave_resume(struct pcmcia_device *p_dev) +static int netwave_resume(struct pcmcia_device *link) { - dev_link_t *link = dev_to_instance(p_dev); struct net_device *dev = link->priv; - link->state &= ~DEV_SUSPEND; - if (link->state & DEV_CONFIG) { - pcmcia_request_configuration(link->handle, &link->conf); - if (link->open) { - netwave_reset(dev); - netif_device_attach(dev); - } + if (link->open) { + netwave_reset(dev); + netif_device_attach(dev); } return 0; @@ -1119,7 +1088,7 @@ static irqreturn_t netwave_interrupt(int irq, void* dev_id, struct pt_regs *regs u_char __iomem *ramBase; struct net_device *dev = (struct net_device *)dev_id; struct netwave_private *priv = netdev_priv(dev); - dev_link_t *link = &priv->link; + struct pcmcia_device *link = priv->p_dev; int i; if (!netif_device_present(dev)) @@ -1138,7 +1107,7 @@ static irqreturn_t netwave_interrupt(int irq, void* dev_id, struct pt_regs *regs status = inb(iobase + NETWAVE_REG_ASR); - if (!DEV_OK(link)) { + if (!pcmcia_dev_present(link)) { DEBUG(1, "netwave_interrupt: Interrupt with status 0x%x " "from removed or suspended card!\n", status); break; @@ -1373,11 +1342,11 @@ static int netwave_rx(struct net_device *dev) static int netwave_open(struct net_device *dev) { netwave_private *priv = netdev_priv(dev); - dev_link_t *link = &priv->link; + struct pcmcia_device *link = priv->p_dev; DEBUG(1, "netwave_open: starting.\n"); - if (!DEV_OK(link)) + if (!pcmcia_dev_present(link)) return -ENODEV; link->open++; @@ -1390,7 +1359,7 @@ static int netwave_open(struct net_device *dev) { static int netwave_close(struct net_device *dev) { netwave_private *priv = netdev_priv(dev); - dev_link_t *link = &priv->link; + struct pcmcia_device *link = priv->p_dev; DEBUG(1, "netwave_close: finishing.\n"); @@ -1411,7 +1380,7 @@ static struct pcmcia_driver netwave_driver = { .drv = { .name = "netwave_cs", }, - .probe = netwave_attach, + .probe = netwave_probe, .remove = netwave_detach, .id_table = netwave_ids, .suspend = netwave_suspend, diff --git a/drivers/net/wireless/orinoco_cs.c b/drivers/net/wireless/orinoco_cs.c index ec6f2a48895..434f7d7ad84 100644 --- a/drivers/net/wireless/orinoco_cs.c +++ b/drivers/net/wireless/orinoco_cs.c @@ -49,7 +49,7 @@ MODULE_PARM_DESC(ignore_cis_vcc, "Allow voltage mismatch between card and socket /* PCMCIA specific device information (goes in the card field of * struct orinoco_private */ struct orinoco_pccard { - dev_link_t link; + struct pcmcia_device *p_dev; dev_node_t node; /* Used to handle hard reset */ @@ -63,8 +63,8 @@ struct orinoco_pccard { /* Function prototypes */ /********************************************************************/ -static void orinoco_cs_config(dev_link_t *link); -static void orinoco_cs_release(dev_link_t *link); +static int orinoco_cs_config(struct pcmcia_device *link); +static void orinoco_cs_release(struct pcmcia_device *link); static void orinoco_cs_detach(struct pcmcia_device *p_dev); /********************************************************************/ @@ -75,13 +75,13 @@ static int orinoco_cs_hard_reset(struct orinoco_private *priv) { struct orinoco_pccard *card = priv->card; - dev_link_t *link = &card->link; + struct pcmcia_device *link = card->p_dev; int err; /* We need atomic ops here, because we're not holding the lock */ set_bit(0, &card->hard_reset_in_progress); - err = pcmcia_reset_card(link->handle, NULL); + err = pcmcia_reset_card(link, NULL); if (err) return err; @@ -104,12 +104,11 @@ orinoco_cs_hard_reset(struct orinoco_private *priv) * configure the card at this point -- we wait until we receive a card * insertion event. */ static int -orinoco_cs_attach(struct pcmcia_device *p_dev) +orinoco_cs_probe(struct pcmcia_device *link) { struct net_device *dev; struct orinoco_private *priv; struct orinoco_pccard *card; - dev_link_t *link; dev = alloc_orinocodev(sizeof(*card), orinoco_cs_hard_reset); if (! dev) @@ -118,7 +117,7 @@ orinoco_cs_attach(struct pcmcia_device *p_dev) card = priv->card; /* Link both structures together */ - link = &card->link; + card->p_dev = link; link->priv = dev; /* Interrupt setup */ @@ -135,16 +134,7 @@ orinoco_cs_attach(struct pcmcia_device *p_dev) link->conf.Attributes = 0; link->conf.IntType = INT_MEMORY_AND_IO; - /* Register with Card Services */ - link->next = NULL; - - link->handle = p_dev; - p_dev->instance = link; - - link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; - orinoco_cs_config(link); - - return 0; + return orinoco_cs_config(link); } /* orinoco_cs_attach */ /* @@ -153,16 +143,14 @@ orinoco_cs_attach(struct pcmcia_device *p_dev) * are freed. Otherwise, the structures will be freed when the device * is released. */ -static void orinoco_cs_detach(struct pcmcia_device *p_dev) +static void orinoco_cs_detach(struct pcmcia_device *link) { - dev_link_t *link = dev_to_instance(p_dev); struct net_device *dev = link->priv; - if (link->state & DEV_CONFIG) - orinoco_cs_release(link); + orinoco_cs_release(link); - DEBUG(0, PFX "detach: link=%p link->dev=%p\n", link, link->dev); - if (link->dev) { + DEBUG(0, PFX "detach: link=%p link->dev_node=%p\n", link, link->dev_node); + if (link->dev_node) { DEBUG(0, PFX "About to unregister net device %p\n", dev); unregister_netdev(dev); @@ -180,11 +168,10 @@ static void orinoco_cs_detach(struct pcmcia_device *p_dev) last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; \ } while (0) -static void -orinoco_cs_config(dev_link_t *link) +static int +orinoco_cs_config(struct pcmcia_device *link) { struct net_device *dev = link->priv; - client_handle_t handle = link->handle; struct orinoco_private *priv = netdev_priv(dev); struct orinoco_pccard *card = priv->card; hermes_t *hw = &priv->hw; @@ -196,7 +183,7 @@ orinoco_cs_config(dev_link_t *link) cisparse_t parse; void __iomem *mem; - CS_CHECK(ValidateCIS, pcmcia_validate_cis(handle, &info)); + CS_CHECK(ValidateCIS, pcmcia_validate_cis(link, &info)); /* * This reads the card's CONFIG tuple to find its @@ -207,19 +194,15 @@ orinoco_cs_config(dev_link_t *link) tuple.TupleData = buf; tuple.TupleDataMax = sizeof(buf); tuple.TupleOffset = 0; - CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple)); - CS_CHECK(GetTupleData, pcmcia_get_tuple_data(handle, &tuple)); - CS_CHECK(ParseTuple, pcmcia_parse_tuple(handle, &tuple, &parse)); + CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); + CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple)); + CS_CHECK(ParseTuple, pcmcia_parse_tuple(link, &tuple, &parse)); link->conf.ConfigBase = parse.config.base; link->conf.Present = parse.config.rmask[0]; - /* Configure card */ - link->state |= DEV_CONFIG; - /* Look up the current Vcc */ CS_CHECK(GetConfigurationInfo, - pcmcia_get_configuration_info(handle, &conf)); - link->conf.Vcc = conf.Vcc; + pcmcia_get_configuration_info(link, &conf)); /* * In this loop, we scan the CIS for configuration table @@ -236,13 +219,13 @@ orinoco_cs_config(dev_link_t *link) * implementation-defined details. */ tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; - CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple)); + CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); while (1) { cistpl_cftable_entry_t *cfg = &(parse.cftable_entry); cistpl_cftable_entry_t dflt = { .index = 0 }; - if ( (pcmcia_get_tuple_data(handle, &tuple) != 0) - || (pcmcia_parse_tuple(handle, &tuple, &parse) != 0)) + if ( (pcmcia_get_tuple_data(link, &tuple) != 0) + || (pcmcia_parse_tuple(link, &tuple, &parse) != 0)) goto next_entry; if (cfg->flags & CISTPL_CFTABLE_DEFAULT) @@ -274,10 +257,10 @@ orinoco_cs_config(dev_link_t *link) } if (cfg->vpp1.present & (1 << CISTPL_POWER_VNOM)) - link->conf.Vpp1 = link->conf.Vpp2 = + link->conf.Vpp = cfg->vpp1.param[CISTPL_POWER_VNOM] / 10000; else if (dflt.vpp1.present & (1 << CISTPL_POWER_VNOM)) - link->conf.Vpp1 = link->conf.Vpp2 = + link->conf.Vpp = dflt.vpp1.param[CISTPL_POWER_VNOM] / 10000; /* Do we need to allocate an interrupt? */ @@ -307,7 +290,7 @@ orinoco_cs_config(dev_link_t *link) } /* This reserves IO space but doesn't actually enable it */ - if (pcmcia_request_io(link->handle, &link->io) != 0) + if (pcmcia_request_io(link, &link->io) != 0) goto next_entry; } @@ -317,9 +300,8 @@ orinoco_cs_config(dev_link_t *link) break; next_entry: - if (link->io.NumPorts1) - pcmcia_release_io(link->handle, &link->io); - last_ret = pcmcia_get_next_tuple(handle, &tuple); + pcmcia_disable_device(link); + last_ret = pcmcia_get_next_tuple(link, &tuple); if (last_ret == CS_NO_MORE_ITEMS) { printk(KERN_ERR PFX "GetNextTuple(): No matching " "CIS configuration. Maybe you need the " @@ -333,7 +315,7 @@ orinoco_cs_config(dev_link_t *link) * a handler to the interrupt, unless the 'Handler' member of * the irq structure is initialized. */ - CS_CHECK(RequestIRQ, pcmcia_request_irq(link->handle, &link->irq)); + CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq)); /* We initialize the hermes structure before completing PCMCIA * configuration just in case the interrupt handler gets @@ -350,7 +332,7 @@ orinoco_cs_config(dev_link_t *link) * card and host interface into "Memory and IO" mode. */ CS_CHECK(RequestConfiguration, - pcmcia_request_configuration(link->handle, &link->conf)); + pcmcia_request_configuration(link, &link->conf)); /* Ok, we have the configuration, prepare to register the netdev */ dev->base_addr = link->io.BasePort1; @@ -358,7 +340,7 @@ orinoco_cs_config(dev_link_t *link) SET_MODULE_OWNER(dev); card->node.major = card->node.minor = 0; - SET_NETDEV_DEV(dev, &handle_to_dev(handle)); + SET_NETDEV_DEV(dev, &handle_to_dev(link)); /* Tell the stack we exist */ if (register_netdev(dev) != 0) { printk(KERN_ERR PFX "register_netdev() failed\n"); @@ -366,20 +348,18 @@ orinoco_cs_config(dev_link_t *link) } /* At this point, the dev_node_t structure(s) needs to be - * initialized and arranged in a linked list at link->dev. */ + * initialized and arranged in a linked list at link->dev_node. */ strcpy(card->node.dev_name, dev->name); - link->dev = &card->node; /* link->dev being non-NULL is also + link->dev_node = &card->node; /* link->dev_node being non-NULL is also used to indicate that the net_device has been registered */ - link->state &= ~DEV_CONFIG_PENDING; /* Finally, report what we've done */ - printk(KERN_DEBUG "%s: index 0x%02x: Vcc %d.%d", - dev->name, link->conf.ConfigIndex, - link->conf.Vcc / 10, link->conf.Vcc % 10); - if (link->conf.Vpp1) - printk(", Vpp %d.%d", link->conf.Vpp1 / 10, - link->conf.Vpp1 % 10); + printk(KERN_DEBUG "%s: index 0x%02x: ", + dev->name, link->conf.ConfigIndex); + if (link->conf.Vpp) + printk(", Vpp %d.%d", link->conf.Vpp / 10, + link->conf.Vpp % 10); printk(", irq %d", link->irq.AssignedIRQ); if (link->io.NumPorts1) printk(", io 0x%04x-0x%04x", link->io.BasePort1, @@ -389,13 +369,14 @@ orinoco_cs_config(dev_link_t *link) link->io.BasePort2 + link->io.NumPorts2 - 1); printk("\n"); - return; + return 0; cs_failed: - cs_error(link->handle, last_fn, last_ret); + cs_error(link, last_fn, last_ret); failed: orinoco_cs_release(link); + return -ENODEV; } /* orinoco_cs_config */ /* @@ -404,7 +385,7 @@ orinoco_cs_config(dev_link_t *link) * still open, this will be postponed until it is closed. */ static void -orinoco_cs_release(dev_link_t *link) +orinoco_cs_release(struct pcmcia_device *link) { struct net_device *dev = link->priv; struct orinoco_private *priv = netdev_priv(dev); @@ -416,88 +397,68 @@ orinoco_cs_release(dev_link_t *link) priv->hw_unavailable++; spin_unlock_irqrestore(&priv->lock, flags); - /* Don't bother checking to see if these succeed or not */ - pcmcia_release_configuration(link->handle); - if (link->io.NumPorts1) - pcmcia_release_io(link->handle, &link->io); - if (link->irq.AssignedIRQ) - pcmcia_release_irq(link->handle, &link->irq); - link->state &= ~DEV_CONFIG; + pcmcia_disable_device(link); if (priv->hw.iobase) ioport_unmap(priv->hw.iobase); } /* orinoco_cs_release */ -static int orinoco_cs_suspend(struct pcmcia_device *p_dev) +static int orinoco_cs_suspend(struct pcmcia_device *link) { - dev_link_t *link = dev_to_instance(p_dev); struct net_device *dev = link->priv; struct orinoco_private *priv = netdev_priv(dev); struct orinoco_pccard *card = priv->card; int err = 0; unsigned long flags; - link->state |= DEV_SUSPEND; - if (link->state & DEV_CONFIG) { - /* This is probably racy, but I can't think of - a better way, short of rewriting the PCMCIA - layer to not suck :-( */ - if (! test_bit(0, &card->hard_reset_in_progress)) { - spin_lock_irqsave(&priv->lock, flags); + /* This is probably racy, but I can't think of + a better way, short of rewriting the PCMCIA + layer to not suck :-( */ + if (! test_bit(0, &card->hard_reset_in_progress)) { + spin_lock_irqsave(&priv->lock, flags); - err = __orinoco_down(dev); - if (err) - printk(KERN_WARNING "%s: Error %d downing interface\n", - dev->name, err); + err = __orinoco_down(dev); + if (err) + printk(KERN_WARNING "%s: Error %d downing interface\n", + dev->name, err); - netif_device_detach(dev); - priv->hw_unavailable++; + netif_device_detach(dev); + priv->hw_unavailable++; - spin_unlock_irqrestore(&priv->lock, flags); - } - - pcmcia_release_configuration(link->handle); + spin_unlock_irqrestore(&priv->lock, flags); } return 0; } -static int orinoco_cs_resume(struct pcmcia_device *p_dev) +static int orinoco_cs_resume(struct pcmcia_device *link) { - dev_link_t *link = dev_to_instance(p_dev); struct net_device *dev = link->priv; struct orinoco_private *priv = netdev_priv(dev); struct orinoco_pccard *card = priv->card; int err = 0; unsigned long flags; - link->state &= ~DEV_SUSPEND; - if (link->state & DEV_CONFIG) { - /* FIXME: should we double check that this is - * the same card as we had before */ - pcmcia_request_configuration(link->handle, &link->conf); - - if (! test_bit(0, &card->hard_reset_in_progress)) { - err = orinoco_reinit_firmware(dev); - if (err) { - printk(KERN_ERR "%s: Error %d re-initializing firmware\n", - dev->name, err); - return -EIO; - } - - spin_lock_irqsave(&priv->lock, flags); + if (! test_bit(0, &card->hard_reset_in_progress)) { + err = orinoco_reinit_firmware(dev); + if (err) { + printk(KERN_ERR "%s: Error %d re-initializing firmware\n", + dev->name, err); + return -EIO; + } - netif_device_attach(dev); - priv->hw_unavailable--; + spin_lock_irqsave(&priv->lock, flags); - if (priv->open && ! priv->hw_unavailable) { - err = __orinoco_up(dev); - if (err) - printk(KERN_ERR "%s: Error %d restarting card\n", - dev->name, err); - } + netif_device_attach(dev); + priv->hw_unavailable--; - spin_unlock_irqrestore(&priv->lock, flags); + if (priv->open && ! priv->hw_unavailable) { + err = __orinoco_up(dev); + if (err) + printk(KERN_ERR "%s: Error %d restarting card\n", + dev->name, err); } + + spin_unlock_irqrestore(&priv->lock, flags); } return 0; @@ -604,7 +565,7 @@ static struct pcmcia_driver orinoco_driver = { .drv = { .name = DRIVER_NAME, }, - .probe = orinoco_cs_attach, + .probe = orinoco_cs_probe, .remove = orinoco_cs_detach, .id_table = orinoco_cs_ids, .suspend = orinoco_cs_suspend, diff --git a/drivers/net/wireless/ray_cs.c b/drivers/net/wireless/ray_cs.c index 7880d8c31aa..879eb427607 100644 --- a/drivers/net/wireless/ray_cs.c +++ b/drivers/net/wireless/ray_cs.c @@ -90,8 +90,8 @@ module_param(pc_debug, int, 0); #define DEBUG(n, args...) #endif /** Prototypes based on PCMCIA skeleton driver *******************************/ -static void ray_config(dev_link_t *link); -static void ray_release(dev_link_t *link); +static int ray_config(struct pcmcia_device *link); +static void ray_release(struct pcmcia_device *link); static void ray_detach(struct pcmcia_device *p_dev); /***** Prototypes indicated by device structure ******************************/ @@ -190,20 +190,17 @@ static int bc; static char *phy_addr = NULL; -/* A linked list of "instances" of the ray device. Each actual - PCMCIA card corresponds to one device instance, and is described - by one dev_link_t structure (defined in ds.h). -*/ -static dev_link_t *dev_list = NULL; - -/* A dev_link_t structure has fields for most things that are needed +/* A struct pcmcia_device structure has fields for most things that are needed to keep track of a socket, but there will usually be some device specific information that also needs to be kept track of. The - 'priv' pointer in a dev_link_t structure can be used to point to + 'priv' pointer in a struct pcmcia_device structure can be used to point to a device-specific private data structure, like this. */ static unsigned int ray_mem_speed = 500; +/* WARNING: THIS DRIVER IS NOT CAPABLE OF HANDLING MULTIPLE DEVICES! */ +static struct pcmcia_device *this_device = NULL; + MODULE_AUTHOR("Corey Thomas <corey@world.std.com>"); MODULE_DESCRIPTION("Raylink/WebGear wireless LAN driver"); MODULE_LICENSE("GPL"); @@ -306,56 +303,46 @@ static char rcsid[] = "Raylink/WebGear wireless LAN - Corey <Thomas corey@world. configure the card at this point -- we wait until we receive a card insertion event. =============================================================================*/ -static int ray_attach(struct pcmcia_device *p_dev) +static int ray_probe(struct pcmcia_device *p_dev) { - dev_link_t *link; ray_dev_t *local; struct net_device *dev; - - DEBUG(1, "ray_attach()\n"); - /* Initialize the dev_link_t structure */ - link = kmalloc(sizeof(struct dev_link_t), GFP_KERNEL); - - if (!link) - return -ENOMEM; + DEBUG(1, "ray_attach()\n"); /* Allocate space for private device-specific data */ dev = alloc_etherdev(sizeof(ray_dev_t)); - if (!dev) goto fail_alloc_dev; local = dev->priv; - - memset(link, 0, sizeof(struct dev_link_t)); + local->finder = p_dev; /* The io structure describes IO port mapping. None used here */ - link->io.NumPorts1 = 0; - link->io.Attributes1 = IO_DATA_PATH_WIDTH_8; - link->io.IOAddrLines = 5; + p_dev->io.NumPorts1 = 0; + p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_8; + p_dev->io.IOAddrLines = 5; /* Interrupt setup. For PCMCIA, driver takes what's given */ - link->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_HANDLE_PRESENT; - link->irq.IRQInfo1 = IRQ_LEVEL_ID; - link->irq.Handler = &ray_interrupt; + p_dev->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_HANDLE_PRESENT; + p_dev->irq.IRQInfo1 = IRQ_LEVEL_ID; + p_dev->irq.Handler = &ray_interrupt; /* General socket configuration */ - link->conf.Attributes = CONF_ENABLE_IRQ; - link->conf.Vcc = 50; - link->conf.IntType = INT_MEMORY_AND_IO; - link->conf.ConfigIndex = 1; - link->conf.Present = PRESENT_OPTION; - - link->priv = dev; - link->irq.Instance = dev; + p_dev->conf.Attributes = CONF_ENABLE_IRQ; + p_dev->conf.IntType = INT_MEMORY_AND_IO; + p_dev->conf.ConfigIndex = 1; + p_dev->conf.Present = PRESENT_OPTION; + + p_dev->priv = dev; + p_dev->irq.Instance = dev; - local->finder = link; + local->finder = p_dev; local->card_status = CARD_INSERTED; local->authentication_state = UNAUTHENTICATED; local->num_multi = 0; - DEBUG(2,"ray_attach link = %p, dev = %p, local = %p, intr = %p\n", - link,dev,local,&ray_interrupt); + DEBUG(2,"ray_attach p_dev = %p, dev = %p, local = %p, intr = %p\n", + p_dev,dev,local,&ray_interrupt); /* Raylink entries in the device structure */ dev->hard_start_xmit = &ray_dev_start_xmit; @@ -379,16 +366,10 @@ static int ray_attach(struct pcmcia_device *p_dev) init_timer(&local->timer); - link->handle = p_dev; - p_dev->instance = link; - - link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; - ray_config(link); - - return 0; + this_device = p_dev; + return ray_config(p_dev); fail_alloc_dev: - kfree(link); return -ENOMEM; } /* ray_attach */ /*============================================================================= @@ -397,37 +378,25 @@ fail_alloc_dev: structures are freed. Otherwise, the structures will be freed when the device is released. =============================================================================*/ -static void ray_detach(struct pcmcia_device *p_dev) +static void ray_detach(struct pcmcia_device *link) { - dev_link_t *link = dev_to_instance(p_dev); - dev_link_t **linkp; struct net_device *dev; ray_dev_t *local; DEBUG(1, "ray_detach(0x%p)\n", link); - - /* Locate device structure */ - for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next) - if (*linkp == link) break; - if (*linkp == NULL) - return; + this_device = NULL; dev = link->priv; - if (link->state & DEV_CONFIG) { - ray_release(link); + ray_release(link); - local = (ray_dev_t *)dev->priv; - del_timer(&local->timer); - } + local = (ray_dev_t *)dev->priv; + del_timer(&local->timer); - /* Unlink device structure, free pieces */ - *linkp = link->next; if (link->priv) { - if (link->dev) unregister_netdev(dev); + if (link->dev_node) unregister_netdev(dev); free_netdev(dev); } - kfree(link); DEBUG(2,"ray_cs ray_detach ending\n"); } /* ray_detach */ /*============================================================================= @@ -438,9 +407,8 @@ static void ray_detach(struct pcmcia_device *p_dev) #define CS_CHECK(fn, ret) \ do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0) #define MAX_TUPLE_SIZE 128 -static void ray_config(dev_link_t *link) +static int ray_config(struct pcmcia_device *link) { - client_handle_t handle = link->handle; tuple_t tuple; cisparse_t parse; int last_fn = 0, last_ret = 0; @@ -455,48 +423,45 @@ static void ray_config(dev_link_t *link) /* This reads the card's CONFIG tuple to find its configuration regs */ tuple.DesiredTuple = CISTPL_CONFIG; - CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple)); + CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); tuple.TupleData = buf; tuple.TupleDataMax = MAX_TUPLE_SIZE; tuple.TupleOffset = 0; - CS_CHECK(GetTupleData, pcmcia_get_tuple_data(handle, &tuple)); - CS_CHECK(ParseTuple, pcmcia_parse_tuple(handle, &tuple, &parse)); + CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple)); + CS_CHECK(ParseTuple, pcmcia_parse_tuple(link, &tuple, &parse)); link->conf.ConfigBase = parse.config.base; link->conf.Present = parse.config.rmask[0]; /* Determine card type and firmware version */ buf[0] = buf[MAX_TUPLE_SIZE - 1] = 0; tuple.DesiredTuple = CISTPL_VERS_1; - CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple)); + CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); tuple.TupleData = buf; tuple.TupleDataMax = MAX_TUPLE_SIZE; tuple.TupleOffset = 2; - CS_CHECK(GetTupleData, pcmcia_get_tuple_data(handle, &tuple)); + CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple)); for (i=0; i<tuple.TupleDataLen - 4; i++) if (buf[i] == 0) buf[i] = ' '; printk(KERN_INFO "ray_cs Detected: %s\n",buf); - /* Configure card */ - link->state |= DEV_CONFIG; - /* Now allocate an interrupt line. Note that this does not actually assign a handler to the interrupt. */ - CS_CHECK(RequestIRQ, pcmcia_request_irq(link->handle, &link->irq)); + CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq)); dev->irq = link->irq.AssignedIRQ; /* This actually configures the PCMCIA socket -- setting up the I/O windows and the interrupt mapping. */ - CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link->handle, &link->conf)); + CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf)); /*** Set up 32k window for shared memory (transmit and control) ************/ req.Attributes = WIN_DATA_WIDTH_8 | WIN_MEMORY_TYPE_CM | WIN_ENABLE | WIN_USE_WAIT; req.Base = 0; req.Size = 0x8000; req.AccessSpeed = ray_mem_speed; - CS_CHECK(RequestWindow, pcmcia_request_window(&link->handle, &req, &link->win)); + CS_CHECK(RequestWindow, pcmcia_request_window(&link, &req, &link->win)); mem.CardOffset = 0x0000; mem.Page = 0; CS_CHECK(MapMemPage, pcmcia_map_mem_page(link->win, &mem)); local->sram = ioremap(req.Base,req.Size); @@ -506,7 +471,7 @@ static void ray_config(dev_link_t *link) req.Base = 0; req.Size = 0x4000; req.AccessSpeed = ray_mem_speed; - CS_CHECK(RequestWindow, pcmcia_request_window(&link->handle, &req, &local->rmem_handle)); + CS_CHECK(RequestWindow, pcmcia_request_window(&link, &req, &local->rmem_handle)); mem.CardOffset = 0x8000; mem.Page = 0; CS_CHECK(MapMemPage, pcmcia_map_mem_page(local->rmem_handle, &mem)); local->rmem = ioremap(req.Base,req.Size); @@ -516,7 +481,7 @@ static void ray_config(dev_link_t *link) req.Base = 0; req.Size = 0x1000; req.AccessSpeed = ray_mem_speed; - CS_CHECK(RequestWindow, pcmcia_request_window(&link->handle, &req, &local->amem_handle)); + CS_CHECK(RequestWindow, pcmcia_request_window(&link, &req, &local->amem_handle)); mem.CardOffset = 0x0000; mem.Page = 0; CS_CHECK(MapMemPage, pcmcia_map_mem_page(local->amem_handle, &mem)); local->amem = ioremap(req.Base,req.Size); @@ -526,32 +491,32 @@ static void ray_config(dev_link_t *link) DEBUG(3,"ray_config amem=%p\n",local->amem); if (ray_init(dev) < 0) { ray_release(link); - return; + return -ENODEV; } - SET_NETDEV_DEV(dev, &handle_to_dev(handle)); + SET_NETDEV_DEV(dev, &handle_to_dev(link)); i = register_netdev(dev); if (i != 0) { printk("ray_config register_netdev() failed\n"); ray_release(link); - return; + return i; } strcpy(local->node.dev_name, dev->name); - link->dev = &local->node; + link->dev_node = &local->node; - link->state &= ~DEV_CONFIG_PENDING; printk(KERN_INFO "%s: RayLink, irq %d, hw_addr ", dev->name, dev->irq); for (i = 0; i < 6; i++) printk("%02X%s", dev->dev_addr[i], ((i<5) ? ":" : "\n")); - return; + return 0; cs_failed: - cs_error(link->handle, last_fn, last_ret); + cs_error(link, last_fn, last_ret); ray_release(link); + return -ENODEV; } /* ray_config */ static inline struct ccs __iomem *ccs_base(ray_dev_t *dev) @@ -578,9 +543,9 @@ static int ray_init(struct net_device *dev) UCHAR *p; struct ccs __iomem *pccs; ray_dev_t *local = (ray_dev_t *)dev->priv; - dev_link_t *link = local->finder; + struct pcmcia_device *link = local->finder; DEBUG(1, "ray_init(0x%p)\n", dev); - if (!(link->state & DEV_PRESENT)) { + if (!(pcmcia_dev_present(link))) { DEBUG(0,"ray_init - device not present\n"); return -1; } @@ -640,10 +605,10 @@ static int dl_startup_params(struct net_device *dev) int ccsindex; ray_dev_t *local = (ray_dev_t *)dev->priv; struct ccs __iomem *pccs; - dev_link_t *link = local->finder; + struct pcmcia_device *link = local->finder; DEBUG(1,"dl_startup_params entered\n"); - if (!(link->state & DEV_PRESENT)) { + if (!(pcmcia_dev_present(link))) { DEBUG(2,"ray_cs dl_startup_params - device not present\n"); return -1; } @@ -747,9 +712,9 @@ static void verify_dl_startup(u_long data) ray_dev_t *local = (ray_dev_t *)data; struct ccs __iomem *pccs = ccs_base(local) + local->dl_param_ccs; UCHAR status; - dev_link_t *link = local->finder; + struct pcmcia_device *link = local->finder; - if (!(link->state & DEV_PRESENT)) { + if (!(pcmcia_dev_present(link))) { DEBUG(2,"ray_cs verify_dl_startup - device not present\n"); return; } @@ -787,8 +752,8 @@ static void start_net(u_long data) ray_dev_t *local = (ray_dev_t *)data; struct ccs __iomem *pccs; int ccsindex; - dev_link_t *link = local->finder; - if (!(link->state & DEV_PRESENT)) { + struct pcmcia_device *link = local->finder; + if (!(pcmcia_dev_present(link))) { DEBUG(2,"ray_cs start_net - device not present\n"); return; } @@ -814,9 +779,9 @@ static void join_net(u_long data) struct ccs __iomem *pccs; int ccsindex; - dev_link_t *link = local->finder; + struct pcmcia_device *link = local->finder; - if (!(link->state & DEV_PRESENT)) { + if (!(pcmcia_dev_present(link))) { DEBUG(2,"ray_cs join_net - device not present\n"); return; } @@ -840,7 +805,7 @@ static void join_net(u_long data) device, and release the PCMCIA configuration. If the device is still open, this will be postponed until it is closed. =============================================================================*/ -static void ray_release(dev_link_t *link) +static void ray_release(struct pcmcia_device *link) { struct net_device *dev = link->priv; ray_dev_t *local = dev->priv; @@ -849,56 +814,38 @@ static void ray_release(dev_link_t *link) DEBUG(1, "ray_release(0x%p)\n", link); del_timer(&local->timer); - link->state &= ~DEV_CONFIG; iounmap(local->sram); iounmap(local->rmem); iounmap(local->amem); /* Do bother checking to see if these succeed or not */ - i = pcmcia_release_window(link->win); - if ( i != CS_SUCCESS ) DEBUG(0,"ReleaseWindow(link->win) ret = %x\n",i); i = pcmcia_release_window(local->amem_handle); if ( i != CS_SUCCESS ) DEBUG(0,"ReleaseWindow(local->amem) ret = %x\n",i); i = pcmcia_release_window(local->rmem_handle); if ( i != CS_SUCCESS ) DEBUG(0,"ReleaseWindow(local->rmem) ret = %x\n",i); - i = pcmcia_release_configuration(link->handle); - if ( i != CS_SUCCESS ) DEBUG(0,"ReleaseConfiguration ret = %x\n",i); - i = pcmcia_release_irq(link->handle, &link->irq); - if ( i != CS_SUCCESS ) DEBUG(0,"ReleaseIRQ ret = %x\n",i); + pcmcia_disable_device(link); DEBUG(2,"ray_release ending\n"); } -static int ray_suspend(struct pcmcia_device *p_dev) +static int ray_suspend(struct pcmcia_device *link) { - dev_link_t *link = dev_to_instance(p_dev); struct net_device *dev = link->priv; - link->state |= DEV_SUSPEND; - if (link->state & DEV_CONFIG) { - if (link->open) - netif_device_detach(dev); - - pcmcia_release_configuration(link->handle); - } - + if (link->open) + netif_device_detach(dev); return 0; } -static int ray_resume(struct pcmcia_device *p_dev) +static int ray_resume(struct pcmcia_device *link) { - dev_link_t *link = dev_to_instance(p_dev); struct net_device *dev = link->priv; - link->state &= ~DEV_SUSPEND; - if (link->state & DEV_CONFIG) { - pcmcia_request_configuration(link->handle, &link->conf); - if (link->open) { - ray_reset(dev); - netif_device_attach(dev); - } - } + if (link->open) { + ray_reset(dev); + netif_device_attach(dev); + } return 0; } @@ -910,10 +857,10 @@ int ray_dev_init(struct net_device *dev) int i; #endif /* RAY_IMMEDIATE_INIT */ ray_dev_t *local = dev->priv; - dev_link_t *link = local->finder; + struct pcmcia_device *link = local->finder; DEBUG(1,"ray_dev_init(dev=%p)\n",dev); - if (!(link->state & DEV_PRESENT)) { + if (!(pcmcia_dev_present(link))) { DEBUG(2,"ray_dev_init - device not present\n"); return -1; } @@ -944,10 +891,10 @@ int ray_dev_init(struct net_device *dev) static int ray_dev_config(struct net_device *dev, struct ifmap *map) { ray_dev_t *local = dev->priv; - dev_link_t *link = local->finder; + struct pcmcia_device *link = local->finder; /* Dummy routine to satisfy device structure */ DEBUG(1,"ray_dev_config(dev=%p,ifmap=%p)\n",dev,map); - if (!(link->state & DEV_PRESENT)) { + if (!(pcmcia_dev_present(link))) { DEBUG(2,"ray_dev_config - device not present\n"); return -1; } @@ -958,10 +905,10 @@ static int ray_dev_config(struct net_device *dev, struct ifmap *map) static int ray_dev_start_xmit(struct sk_buff *skb, struct net_device *dev) { ray_dev_t *local = dev->priv; - dev_link_t *link = local->finder; + struct pcmcia_device *link = local->finder; short length = skb->len; - if (!(link->state & DEV_PRESENT)) { + if (!(pcmcia_dev_present(link))) { DEBUG(2,"ray_dev_start_xmit - device not present\n"); return -1; } @@ -1570,7 +1517,7 @@ static int ray_commit(struct net_device *dev, static iw_stats * ray_get_wireless_stats(struct net_device * dev) { ray_dev_t * local = (ray_dev_t *) dev->priv; - dev_link_t *link = local->finder; + struct pcmcia_device *link = local->finder; struct status __iomem *p = local->sram + STATUS_BASE; if(local == (ray_dev_t *) NULL) @@ -1588,7 +1535,7 @@ static iw_stats * ray_get_wireless_stats(struct net_device * dev) } #endif /* WIRELESS_SPY */ - if((link->state & DEV_PRESENT)) { + if(pcmcia_dev_present(link)) { local->wstats.qual.noise = readb(&p->rxnoise); local->wstats.qual.updated |= 4; } @@ -1657,18 +1604,14 @@ static const struct iw_handler_def ray_handler_def = /*===========================================================================*/ static int ray_open(struct net_device *dev) { - dev_link_t *link; ray_dev_t *local = (ray_dev_t *)dev->priv; + struct pcmcia_device *link; + link = local->finder; DEBUG(1, "ray_open('%s')\n", dev->name); - for (link = dev_list; link; link = link->next) - if (link->priv == dev) break; - if (!DEV_OK(link)) { - return -ENODEV; - } - - if (link->open == 0) local->num_multi = 0; + if (link->open == 0) + local->num_multi = 0; link->open++; /* If the card is not started, time to start it ! - Jean II */ @@ -1695,15 +1638,12 @@ static int ray_open(struct net_device *dev) /*===========================================================================*/ static int ray_dev_close(struct net_device *dev) { - dev_link_t *link; + ray_dev_t *local = (ray_dev_t *)dev->priv; + struct pcmcia_device *link; + link = local->finder; DEBUG(1, "ray_dev_close('%s')\n", dev->name); - for (link = dev_list; link; link = link->next) - if (link->priv == dev) break; - if (link == NULL) - return -ENODEV; - link->open--; netif_stop_queue(dev); @@ -1725,9 +1665,9 @@ static void ray_reset(struct net_device *dev) { static int interrupt_ecf(ray_dev_t *local, int ccs) { int i = 50; - dev_link_t *link = local->finder; + struct pcmcia_device *link = local->finder; - if (!(link->state & DEV_PRESENT)) { + if (!(pcmcia_dev_present(link))) { DEBUG(2,"ray_cs interrupt_ecf - device not present\n"); return -1; } @@ -1752,9 +1692,9 @@ static int get_free_tx_ccs(ray_dev_t *local) { int i; struct ccs __iomem *pccs = ccs_base(local); - dev_link_t *link = local->finder; + struct pcmcia_device *link = local->finder; - if (!(link->state & DEV_PRESENT)) { + if (!(pcmcia_dev_present(link))) { DEBUG(2,"ray_cs get_free_tx_ccs - device not present\n"); return ECARDGONE; } @@ -1783,9 +1723,9 @@ static int get_free_ccs(ray_dev_t *local) { int i; struct ccs __iomem *pccs = ccs_base(local); - dev_link_t *link = local->finder; + struct pcmcia_device *link = local->finder; - if (!(link->state & DEV_PRESENT)) { + if (!(pcmcia_dev_present(link))) { DEBUG(2,"ray_cs get_free_ccs - device not present\n"); return ECARDGONE; } @@ -1858,9 +1798,9 @@ static int parse_addr(char *in_str, UCHAR *out) static struct net_device_stats *ray_get_stats(struct net_device *dev) { ray_dev_t *local = (ray_dev_t *)dev->priv; - dev_link_t *link = local->finder; + struct pcmcia_device *link = local->finder; struct status __iomem *p = local->sram + STATUS_BASE; - if (!(link->state & DEV_PRESENT)) { + if (!(pcmcia_dev_present(link))) { DEBUG(2,"ray_cs net_device_stats - device not present\n"); return &local->stats; } @@ -1888,12 +1828,12 @@ static struct net_device_stats *ray_get_stats(struct net_device *dev) static void ray_update_parm(struct net_device *dev, UCHAR objid, UCHAR *value, int len) { ray_dev_t *local = (ray_dev_t *)dev->priv; - dev_link_t *link = local->finder; + struct pcmcia_device *link = local->finder; int ccsindex; int i; struct ccs __iomem *pccs; - if (!(link->state & DEV_PRESENT)) { + if (!(pcmcia_dev_present(link))) { DEBUG(2,"ray_update_parm - device not present\n"); return; } @@ -1925,10 +1865,10 @@ static void ray_update_multi_list(struct net_device *dev, int all) struct ccs __iomem *pccs; int i = 0; ray_dev_t *local = (ray_dev_t *)dev->priv; - dev_link_t *link = local->finder; + struct pcmcia_device *link = local->finder; void __iomem *p = local->sram + HOST_TO_ECF_BASE; - if (!(link->state & DEV_PRESENT)) { + if (!(pcmcia_dev_present(link))) { DEBUG(2,"ray_update_multi_list - device not present\n"); return; } @@ -2005,7 +1945,7 @@ static void set_multicast_list(struct net_device *dev) static irqreturn_t ray_interrupt(int irq, void *dev_id, struct pt_regs * regs) { struct net_device *dev = (struct net_device *)dev_id; - dev_link_t *link; + struct pcmcia_device *link; ray_dev_t *local; struct ccs __iomem *pccs; struct rcs __iomem *prcs; @@ -2020,8 +1960,8 @@ static irqreturn_t ray_interrupt(int irq, void *dev_id, struct pt_regs * regs) DEBUG(4,"ray_cs: interrupt for *dev=%p\n",dev); local = (ray_dev_t *)dev->priv; - link = (dev_link_t *)local->finder; - if ( ! (link->state & DEV_PRESENT) || link->state & DEV_SUSPEND ) { + link = (struct pcmcia_device *)local->finder; + if (!pcmcia_dev_present(link)) { DEBUG(2,"ray_cs interrupt from device not present or suspended.\n"); return IRQ_NONE; } @@ -2540,9 +2480,9 @@ static void release_frag_chain(ray_dev_t *local, struct rcs __iomem * prcs) /*===========================================================================*/ static void authenticate(ray_dev_t *local) { - dev_link_t *link = local->finder; + struct pcmcia_device *link = local->finder; DEBUG(0,"ray_cs Starting authentication.\n"); - if (!(link->state & DEV_PRESENT)) { + if (!(pcmcia_dev_present(link))) { DEBUG(2,"ray_cs authenticate - device not present\n"); return; } @@ -2606,10 +2546,10 @@ static void rx_authenticate(ray_dev_t *local, struct rcs __iomem *prcs, static void associate(ray_dev_t *local) { struct ccs __iomem *pccs; - dev_link_t *link = local->finder; + struct pcmcia_device *link = local->finder; struct net_device *dev = link->priv; int ccsindex; - if (!(link->state & DEV_PRESENT)) { + if (!(pcmcia_dev_present(link))) { DEBUG(2,"ray_cs associate - device not present\n"); return; } @@ -2689,14 +2629,14 @@ static int ray_cs_proc_read(char *buf, char **start, off_t offset, int len) * eg ifconfig */ int i; - dev_link_t *link; + struct pcmcia_device *link; struct net_device *dev; ray_dev_t *local; UCHAR *p; struct freq_hop_element *pfh; UCHAR c[33]; - link = dev_list; + link = this_device; if (!link) return 0; dev = (struct net_device *)link->priv; @@ -2898,7 +2838,7 @@ static struct pcmcia_driver ray_driver = { .drv = { .name = "ray_cs", }, - .probe = ray_attach, + .probe = ray_probe, .remove = ray_detach, .id_table = ray_ids, .suspend = ray_suspend, @@ -2940,7 +2880,6 @@ static void __exit exit_ray_cs(void) #endif pcmcia_unregister_driver(&ray_driver); - BUG_ON(dev_list != NULL); } /* exit_ray_cs */ module_init(init_ray_cs); diff --git a/drivers/net/wireless/ray_cs.h b/drivers/net/wireless/ray_cs.h index 42660fe64bf..bd73ebf0334 100644 --- a/drivers/net/wireless/ray_cs.h +++ b/drivers/net/wireless/ray_cs.h @@ -31,7 +31,7 @@ typedef struct ray_dev_t { void __iomem *sram; /* pointer to beginning of shared RAM */ void __iomem *amem; /* pointer to attribute mem window */ void __iomem *rmem; /* pointer to receive buffer window */ - dev_link_t *finder; /* pointer back to dev_link_t for card */ + struct pcmcia_device *finder; /* pointer back to struct pcmcia_device for card */ struct timer_list timer; long tx_ccs_lock; long ccs_lock; diff --git a/drivers/net/wireless/spectrum_cs.c b/drivers/net/wireless/spectrum_cs.c index 5fa6fbe35bb..f7b77ce54d7 100644 --- a/drivers/net/wireless/spectrum_cs.c +++ b/drivers/net/wireless/spectrum_cs.c @@ -63,7 +63,7 @@ MODULE_PARM_DESC(ignore_cis_vcc, "Allow voltage mismatch between card and socket /* PCMCIA specific device information (goes in the card field of * struct orinoco_private */ struct orinoco_pccard { - dev_link_t link; + struct pcmcia_device *p_dev; dev_node_t node; }; @@ -71,8 +71,8 @@ struct orinoco_pccard { /* Function prototypes */ /********************************************************************/ -static void spectrum_cs_config(dev_link_t *link); -static void spectrum_cs_release(dev_link_t *link); +static int spectrum_cs_config(struct pcmcia_device *link); +static void spectrum_cs_release(struct pcmcia_device *link); /********************************************************************/ /* Firmware downloader */ @@ -238,14 +238,14 @@ spectrum_aux_open(hermes_t *hw) * If IDLE is 1, stop the firmware, so that it can be safely rewritten. */ static int -spectrum_reset(dev_link_t *link, int idle) +spectrum_reset(struct pcmcia_device *link, int idle) { int last_ret, last_fn; conf_reg_t reg; u_int save_cor; /* Doing it if hardware is gone is guaranteed crash */ - if (!(link->state & DEV_CONFIG)) + if (pcmcia_dev_present(link)) return -ENODEV; /* Save original COR value */ @@ -253,7 +253,7 @@ spectrum_reset(dev_link_t *link, int idle) reg.Action = CS_READ; reg.Offset = CISREG_COR; CS_CHECK(AccessConfigurationRegister, - pcmcia_access_configuration_register(link->handle, ®)); + pcmcia_access_configuration_register(link, ®)); save_cor = reg.Value; /* Soft-Reset card */ @@ -261,14 +261,14 @@ spectrum_reset(dev_link_t *link, int idle) reg.Offset = CISREG_COR; reg.Value = (save_cor | COR_SOFT_RESET); CS_CHECK(AccessConfigurationRegister, - pcmcia_access_configuration_register(link->handle, ®)); + pcmcia_access_configuration_register(link, ®)); udelay(1000); /* Read CCSR */ reg.Action = CS_READ; reg.Offset = CISREG_CCSR; CS_CHECK(AccessConfigurationRegister, - pcmcia_access_configuration_register(link->handle, ®)); + pcmcia_access_configuration_register(link, ®)); /* * Start or stop the firmware. Memory width bit should be @@ -278,7 +278,7 @@ spectrum_reset(dev_link_t *link, int idle) reg.Offset = CISREG_CCSR; reg.Value = (idle ? HCR_IDLE : HCR_RUN) | (reg.Value & HCR_MEM16); CS_CHECK(AccessConfigurationRegister, - pcmcia_access_configuration_register(link->handle, ®)); + pcmcia_access_configuration_register(link, ®)); udelay(1000); /* Restore original COR configuration index */ @@ -286,12 +286,12 @@ spectrum_reset(dev_link_t *link, int idle) reg.Offset = CISREG_COR; reg.Value = (save_cor & ~COR_SOFT_RESET); CS_CHECK(AccessConfigurationRegister, - pcmcia_access_configuration_register(link->handle, ®)); + pcmcia_access_configuration_register(link, ®)); udelay(1000); return 0; cs_failed: - cs_error(link->handle, last_fn, last_ret); + cs_error(link, last_fn, last_ret); return -ENODEV; } @@ -441,7 +441,7 @@ spectrum_load_blocks(hermes_t *hw, const struct dblock *first_block) * care of the PDA - read it and then write it on top of the firmware. */ static int -spectrum_dl_image(hermes_t *hw, dev_link_t *link, +spectrum_dl_image(hermes_t *hw, struct pcmcia_device *link, const unsigned char *image) { int ret; @@ -505,14 +505,13 @@ spectrum_dl_image(hermes_t *hw, dev_link_t *link, * reset on the card, to make sure it's in a sane state. */ static int -spectrum_dl_firmware(hermes_t *hw, dev_link_t *link) +spectrum_dl_firmware(hermes_t *hw, struct pcmcia_device *link) { int ret; - client_handle_t handle = link->handle; const struct firmware *fw_entry; if (request_firmware(&fw_entry, primary_fw_name, - &handle_to_dev(handle)) == 0) { + &handle_to_dev(link)) == 0) { primsym = fw_entry->data; } else { printk(KERN_ERR PFX "Cannot find firmware: %s\n", @@ -521,7 +520,7 @@ spectrum_dl_firmware(hermes_t *hw, dev_link_t *link) } if (request_firmware(&fw_entry, secondary_fw_name, - &handle_to_dev(handle)) == 0) { + &handle_to_dev(link)) == 0) { secsym = fw_entry->data; } else { printk(KERN_ERR PFX "Cannot find firmware: %s\n", @@ -554,12 +553,12 @@ static int spectrum_cs_hard_reset(struct orinoco_private *priv) { struct orinoco_pccard *card = priv->card; - dev_link_t *link = &card->link; + struct pcmcia_device *link = card->p_dev; int err; if (!hermes_present(&priv->hw)) { /* The firmware needs to be reloaded */ - if (spectrum_dl_firmware(&priv->hw, &card->link) != 0) { + if (spectrum_dl_firmware(&priv->hw, link) != 0) { printk(KERN_ERR PFX "Firmware download failed\n"); err = -ENODEV; } @@ -584,12 +583,11 @@ spectrum_cs_hard_reset(struct orinoco_private *priv) * configure the card at this point -- we wait until we receive a card * insertion event. */ static int -spectrum_cs_attach(struct pcmcia_device *p_dev) +spectrum_cs_probe(struct pcmcia_device *link) { struct net_device *dev; struct orinoco_private *priv; struct orinoco_pccard *card; - dev_link_t *link; dev = alloc_orinocodev(sizeof(*card), spectrum_cs_hard_reset); if (! dev) @@ -598,7 +596,7 @@ spectrum_cs_attach(struct pcmcia_device *p_dev) card = priv->card; /* Link both structures together */ - link = &card->link; + card->p_dev = link; link->priv = dev; /* Interrupt setup */ @@ -615,13 +613,7 @@ spectrum_cs_attach(struct pcmcia_device *p_dev) link->conf.Attributes = 0; link->conf.IntType = INT_MEMORY_AND_IO; - link->handle = p_dev; - p_dev->instance = link; - - link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; - spectrum_cs_config(link); - - return 0; + return spectrum_cs_config(link); } /* spectrum_cs_attach */ /* @@ -630,16 +622,14 @@ spectrum_cs_attach(struct pcmcia_device *p_dev) * are freed. Otherwise, the structures will be freed when the device * is released. */ -static void spectrum_cs_detach(struct pcmcia_device *p_dev) +static void spectrum_cs_detach(struct pcmcia_device *link) { - dev_link_t *link = dev_to_instance(p_dev); struct net_device *dev = link->priv; - if (link->state & DEV_CONFIG) - spectrum_cs_release(link); + spectrum_cs_release(link); - DEBUG(0, PFX "detach: link=%p link->dev=%p\n", link, link->dev); - if (link->dev) { + DEBUG(0, PFX "detach: link=%p link->dev_node=%p\n", link, link->dev_node); + if (link->dev_node) { DEBUG(0, PFX "About to unregister net device %p\n", dev); unregister_netdev(dev); @@ -653,11 +643,10 @@ static void spectrum_cs_detach(struct pcmcia_device *p_dev) * device available to the system. */ -static void -spectrum_cs_config(dev_link_t *link) +static int +spectrum_cs_config(struct pcmcia_device *link) { struct net_device *dev = link->priv; - client_handle_t handle = link->handle; struct orinoco_private *priv = netdev_priv(dev); struct orinoco_pccard *card = priv->card; hermes_t *hw = &priv->hw; @@ -669,7 +658,7 @@ spectrum_cs_config(dev_link_t *link) cisparse_t parse; void __iomem *mem; - CS_CHECK(ValidateCIS, pcmcia_validate_cis(handle, &info)); + CS_CHECK(ValidateCIS, pcmcia_validate_cis(link, &info)); /* * This reads the card's CONFIG tuple to find its @@ -680,19 +669,15 @@ spectrum_cs_config(dev_link_t *link) tuple.TupleData = buf; tuple.TupleDataMax = sizeof(buf); tuple.TupleOffset = 0; - CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple)); - CS_CHECK(GetTupleData, pcmcia_get_tuple_data(handle, &tuple)); - CS_CHECK(ParseTuple, pcmcia_parse_tuple(handle, &tuple, &parse)); + CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); + CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple)); + CS_CHECK(ParseTuple, pcmcia_parse_tuple(link, &tuple, &parse)); link->conf.ConfigBase = parse.config.base; link->conf.Present = parse.config.rmask[0]; - /* Configure card */ - link->state |= DEV_CONFIG; - /* Look up the current Vcc */ CS_CHECK(GetConfigurationInfo, - pcmcia_get_configuration_info(handle, &conf)); - link->conf.Vcc = conf.Vcc; + pcmcia_get_configuration_info(link, &conf)); /* * In this loop, we scan the CIS for configuration table @@ -709,13 +694,13 @@ spectrum_cs_config(dev_link_t *link) * implementation-defined details. */ tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; - CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple)); + CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); while (1) { cistpl_cftable_entry_t *cfg = &(parse.cftable_entry); cistpl_cftable_entry_t dflt = { .index = 0 }; - if ( (pcmcia_get_tuple_data(handle, &tuple) != 0) - || (pcmcia_parse_tuple(handle, &tuple, &parse) != 0)) + if ( (pcmcia_get_tuple_data(link, &tuple) != 0) + || (pcmcia_parse_tuple(link, &tuple, &parse) != 0)) goto next_entry; if (cfg->flags & CISTPL_CFTABLE_DEFAULT) @@ -747,10 +732,10 @@ spectrum_cs_config(dev_link_t *link) } if (cfg->vpp1.present & (1 << CISTPL_POWER_VNOM)) - link->conf.Vpp1 = link->conf.Vpp2 = + link->conf.Vpp = cfg->vpp1.param[CISTPL_POWER_VNOM] / 10000; else if (dflt.vpp1.present & (1 << CISTPL_POWER_VNOM)) - link->conf.Vpp1 = link->conf.Vpp2 = + link->conf.Vpp = dflt.vpp1.param[CISTPL_POWER_VNOM] / 10000; /* Do we need to allocate an interrupt? */ @@ -780,7 +765,7 @@ spectrum_cs_config(dev_link_t *link) } /* This reserves IO space but doesn't actually enable it */ - if (pcmcia_request_io(link->handle, &link->io) != 0) + if (pcmcia_request_io(link, &link->io) != 0) goto next_entry; } @@ -790,9 +775,8 @@ spectrum_cs_config(dev_link_t *link) break; next_entry: - if (link->io.NumPorts1) - pcmcia_release_io(link->handle, &link->io); - last_ret = pcmcia_get_next_tuple(handle, &tuple); + pcmcia_disable_device(link); + last_ret = pcmcia_get_next_tuple(link, &tuple); if (last_ret == CS_NO_MORE_ITEMS) { printk(KERN_ERR PFX "GetNextTuple(): No matching " "CIS configuration. Maybe you need the " @@ -806,7 +790,7 @@ spectrum_cs_config(dev_link_t *link) * a handler to the interrupt, unless the 'Handler' member of * the irq structure is initialized. */ - CS_CHECK(RequestIRQ, pcmcia_request_irq(link->handle, &link->irq)); + CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq)); /* We initialize the hermes structure before completing PCMCIA * configuration just in case the interrupt handler gets @@ -823,7 +807,7 @@ spectrum_cs_config(dev_link_t *link) * card and host interface into "Memory and IO" mode. */ CS_CHECK(RequestConfiguration, - pcmcia_request_configuration(link->handle, &link->conf)); + pcmcia_request_configuration(link, &link->conf)); /* Ok, we have the configuration, prepare to register the netdev */ dev->base_addr = link->io.BasePort1; @@ -836,7 +820,7 @@ spectrum_cs_config(dev_link_t *link) goto failed; } - SET_NETDEV_DEV(dev, &handle_to_dev(handle)); + SET_NETDEV_DEV(dev, &handle_to_dev(link)); /* Tell the stack we exist */ if (register_netdev(dev) != 0) { printk(KERN_ERR PFX "register_netdev() failed\n"); @@ -844,20 +828,18 @@ spectrum_cs_config(dev_link_t *link) } /* At this point, the dev_node_t structure(s) needs to be - * initialized and arranged in a linked list at link->dev. */ + * initialized and arranged in a linked list at link->dev_node. */ strcpy(card->node.dev_name, dev->name); - link->dev = &card->node; /* link->dev being non-NULL is also + link->dev_node = &card->node; /* link->dev_node being non-NULL is also used to indicate that the net_device has been registered */ - link->state &= ~DEV_CONFIG_PENDING; /* Finally, report what we've done */ - printk(KERN_DEBUG "%s: index 0x%02x: Vcc %d.%d", - dev->name, link->conf.ConfigIndex, - link->conf.Vcc / 10, link->conf.Vcc % 10); - if (link->conf.Vpp1) - printk(", Vpp %d.%d", link->conf.Vpp1 / 10, - link->conf.Vpp1 % 10); + printk(KERN_DEBUG "%s: index 0x%02x: ", + dev->name, link->conf.ConfigIndex); + if (link->conf.Vpp) + printk(", Vpp %d.%d", link->conf.Vpp / 10, + link->conf.Vpp % 10); printk(", irq %d", link->irq.AssignedIRQ); if (link->io.NumPorts1) printk(", io 0x%04x-0x%04x", link->io.BasePort1, @@ -867,13 +849,14 @@ spectrum_cs_config(dev_link_t *link) link->io.BasePort2 + link->io.NumPorts2 - 1); printk("\n"); - return; + return 0; cs_failed: - cs_error(link->handle, last_fn, last_ret); + cs_error(link, last_fn, last_ret); failed: spectrum_cs_release(link); + return -ENODEV; } /* spectrum_cs_config */ /* @@ -882,7 +865,7 @@ spectrum_cs_config(dev_link_t *link) * still open, this will be postponed until it is closed. */ static void -spectrum_cs_release(dev_link_t *link) +spectrum_cs_release(struct pcmcia_device *link) { struct net_device *dev = link->priv; struct orinoco_private *priv = netdev_priv(dev); @@ -894,64 +877,46 @@ spectrum_cs_release(dev_link_t *link) priv->hw_unavailable++; spin_unlock_irqrestore(&priv->lock, flags); - /* Don't bother checking to see if these succeed or not */ - pcmcia_release_configuration(link->handle); - if (link->io.NumPorts1) - pcmcia_release_io(link->handle, &link->io); - if (link->irq.AssignedIRQ) - pcmcia_release_irq(link->handle, &link->irq); - link->state &= ~DEV_CONFIG; + pcmcia_disable_device(link); if (priv->hw.iobase) ioport_unmap(priv->hw.iobase); } /* spectrum_cs_release */ static int -spectrum_cs_suspend(struct pcmcia_device *p_dev) +spectrum_cs_suspend(struct pcmcia_device *link) { - dev_link_t *link = dev_to_instance(p_dev); struct net_device *dev = link->priv; struct orinoco_private *priv = netdev_priv(dev); unsigned long flags; int err = 0; - link->state |= DEV_SUSPEND; /* Mark the device as stopped, to block IO until later */ - if (link->state & DEV_CONFIG) { - spin_lock_irqsave(&priv->lock, flags); - - err = __orinoco_down(dev); - if (err) - printk(KERN_WARNING "%s: Error %d downing interface\n", - dev->name, err); + spin_lock_irqsave(&priv->lock, flags); - netif_device_detach(dev); - priv->hw_unavailable++; + err = __orinoco_down(dev); + if (err) + printk(KERN_WARNING "%s: Error %d downing interface\n", + dev->name, err); - spin_unlock_irqrestore(&priv->lock, flags); + netif_device_detach(dev); + priv->hw_unavailable++; - pcmcia_release_configuration(link->handle); - } + spin_unlock_irqrestore(&priv->lock, flags); return 0; } static int -spectrum_cs_resume(struct pcmcia_device *p_dev) +spectrum_cs_resume(struct pcmcia_device *link) { - dev_link_t *link = dev_to_instance(p_dev); struct net_device *dev = link->priv; struct orinoco_private *priv = netdev_priv(dev); - link->state &= ~DEV_SUSPEND; - if (link->state & DEV_CONFIG) { - /* FIXME: should we double check that this is - * the same card as we had before */ - pcmcia_request_configuration(link->handle, &link->conf); - netif_device_attach(dev); - priv->hw_unavailable--; - schedule_work(&priv->reset_work); - } + netif_device_attach(dev); + priv->hw_unavailable--; + schedule_work(&priv->reset_work); + return 0; } @@ -979,7 +944,7 @@ static struct pcmcia_driver orinoco_driver = { .drv = { .name = DRIVER_NAME, }, - .probe = spectrum_cs_attach, + .probe = spectrum_cs_probe, .remove = spectrum_cs_detach, .suspend = spectrum_cs_suspend, .resume = spectrum_cs_resume, diff --git a/drivers/net/wireless/wavelan_cs.c b/drivers/net/wireless/wavelan_cs.c index 98122f3a4bc..f7724eb2fa7 100644 --- a/drivers/net/wireless/wavelan_cs.c +++ b/drivers/net/wireless/wavelan_cs.c @@ -1005,7 +1005,7 @@ static inline void wv_82593_reconfig(struct net_device * dev) { net_local * lp = netdev_priv(dev); - dev_link_t * link = lp->link; + struct pcmcia_device * link = lp->link; unsigned long flags; /* Arm the flag, will be cleard in wv_82593_config() */ @@ -3744,16 +3744,16 @@ wv_pcmcia_reset(struct net_device * dev) { int i; conf_reg_t reg = { 0, CS_READ, CISREG_COR, 0 }; - dev_link_t * link = ((net_local *)netdev_priv(dev))->link; + struct pcmcia_device * link = ((net_local *)netdev_priv(dev))->link; #ifdef DEBUG_CONFIG_TRACE printk(KERN_DEBUG "%s: ->wv_pcmcia_reset()\n", dev->name); #endif - i = pcmcia_access_configuration_register(link->handle, ®); + i = pcmcia_access_configuration_register(link, ®); if(i != CS_SUCCESS) { - cs_error(link->handle, AccessConfigurationRegister, i); + cs_error(link, AccessConfigurationRegister, i); return FALSE; } @@ -3764,19 +3764,19 @@ wv_pcmcia_reset(struct net_device * dev) reg.Action = CS_WRITE; reg.Value = reg.Value | COR_SW_RESET; - i = pcmcia_access_configuration_register(link->handle, ®); + i = pcmcia_access_configuration_register(link, ®); if(i != CS_SUCCESS) { - cs_error(link->handle, AccessConfigurationRegister, i); + cs_error(link, AccessConfigurationRegister, i); return FALSE; } reg.Action = CS_WRITE; reg.Value = COR_LEVEL_IRQ | COR_CONFIG; - i = pcmcia_access_configuration_register(link->handle, ®); + i = pcmcia_access_configuration_register(link, ®); if(i != CS_SUCCESS) { - cs_error(link->handle, AccessConfigurationRegister, i); + cs_error(link, AccessConfigurationRegister, i); return FALSE; } @@ -3940,9 +3940,8 @@ wv_hw_reset(struct net_device * dev) * (called by wavelan_event()) */ static inline int -wv_pcmcia_config(dev_link_t * link) +wv_pcmcia_config(struct pcmcia_device * link) { - client_handle_t handle = link->handle; tuple_t tuple; cisparse_t parse; struct net_device * dev = (struct net_device *) link->priv; @@ -3965,16 +3964,16 @@ wv_pcmcia_config(dev_link_t * link) { tuple.Attributes = 0; tuple.DesiredTuple = CISTPL_CONFIG; - i = pcmcia_get_first_tuple(handle, &tuple); + i = pcmcia_get_first_tuple(link, &tuple); if(i != CS_SUCCESS) break; tuple.TupleData = (cisdata_t *)buf; tuple.TupleDataMax = 64; tuple.TupleOffset = 0; - i = pcmcia_get_tuple_data(handle, &tuple); + i = pcmcia_get_tuple_data(link, &tuple); if(i != CS_SUCCESS) break; - i = pcmcia_parse_tuple(handle, &tuple, &parse); + i = pcmcia_parse_tuple(link, &tuple, &parse); if(i != CS_SUCCESS) break; link->conf.ConfigBase = parse.config.base; @@ -3983,19 +3982,16 @@ wv_pcmcia_config(dev_link_t * link) while(0); if(i != CS_SUCCESS) { - cs_error(link->handle, ParseTuple, i); - link->state &= ~DEV_CONFIG_PENDING; + cs_error(link, ParseTuple, i); return FALSE; } - - /* Configure card */ - link->state |= DEV_CONFIG; + do { - i = pcmcia_request_io(link->handle, &link->io); + i = pcmcia_request_io(link, &link->io); if(i != CS_SUCCESS) { - cs_error(link->handle, RequestIO, i); + cs_error(link, RequestIO, i); break; } @@ -4003,10 +3999,10 @@ wv_pcmcia_config(dev_link_t * link) * Now allocate an interrupt line. Note that this does not * actually assign a handler to the interrupt. */ - i = pcmcia_request_irq(link->handle, &link->irq); + i = pcmcia_request_irq(link, &link->irq); if(i != CS_SUCCESS) { - cs_error(link->handle, RequestIRQ, i); + cs_error(link, RequestIRQ, i); break; } @@ -4015,15 +4011,15 @@ wv_pcmcia_config(dev_link_t * link) * the I/O windows and the interrupt mapping. */ link->conf.ConfigIndex = 1; - i = pcmcia_request_configuration(link->handle, &link->conf); + i = pcmcia_request_configuration(link, &link->conf); if(i != CS_SUCCESS) { - cs_error(link->handle, RequestConfiguration, i); + cs_error(link, RequestConfiguration, i); break; } /* - * Allocate a small memory window. Note that the dev_link_t + * Allocate a small memory window. Note that the struct pcmcia_device * structure provides space for one window handle -- if your * device needs several windows, you'll need to keep track of * the handles in your private data structure, link->priv. @@ -4031,10 +4027,10 @@ wv_pcmcia_config(dev_link_t * link) req.Attributes = WIN_DATA_WIDTH_8|WIN_MEMORY_TYPE_AM|WIN_ENABLE; req.Base = req.Size = 0; req.AccessSpeed = mem_speed; - i = pcmcia_request_window(&link->handle, &req, &link->win); + i = pcmcia_request_window(&link, &req, &link->win); if(i != CS_SUCCESS) { - cs_error(link->handle, RequestWindow, i); + cs_error(link, RequestWindow, i); break; } @@ -4046,7 +4042,7 @@ wv_pcmcia_config(dev_link_t * link) i = pcmcia_map_mem_page(link->win, &mem); if(i != CS_SUCCESS) { - cs_error(link->handle, MapMemPage, i); + cs_error(link, MapMemPage, i); break; } @@ -4060,7 +4056,7 @@ wv_pcmcia_config(dev_link_t * link) lp->mem, dev->irq, (u_int) dev->base_addr); #endif - SET_NETDEV_DEV(dev, &handle_to_dev(handle)); + SET_NETDEV_DEV(dev, &handle_to_dev(link)); i = register_netdev(dev); if(i != 0) { @@ -4072,7 +4068,6 @@ wv_pcmcia_config(dev_link_t * link) } while(0); /* Humm... Disguised goto !!! */ - link->state &= ~DEV_CONFIG_PENDING; /* If any step failed, release any partially configured state */ if(i != 0) { @@ -4081,7 +4076,7 @@ wv_pcmcia_config(dev_link_t * link) } strcpy(((net_local *) netdev_priv(dev))->node.dev_name, dev->name); - link->dev = &((net_local *) netdev_priv(dev))->node; + link->dev_node = &((net_local *) netdev_priv(dev))->node; #ifdef DEBUG_CONFIG_TRACE printk(KERN_DEBUG "<-wv_pcmcia_config()\n"); @@ -4096,26 +4091,20 @@ wv_pcmcia_config(dev_link_t * link) * still open, this will be postponed until it is closed. */ static void -wv_pcmcia_release(dev_link_t *link) +wv_pcmcia_release(struct pcmcia_device *link) { - struct net_device * dev = (struct net_device *) link->priv; - net_local * lp = netdev_priv(dev); + struct net_device * dev = (struct net_device *) link->priv; + net_local * lp = netdev_priv(dev); #ifdef DEBUG_CONFIG_TRACE - printk(KERN_DEBUG "%s: -> wv_pcmcia_release(0x%p)\n", dev->name, link); + printk(KERN_DEBUG "%s: -> wv_pcmcia_release(0x%p)\n", dev->name, link); #endif - /* Don't bother checking to see if these succeed or not */ - iounmap(lp->mem); - pcmcia_release_window(link->win); - pcmcia_release_configuration(link->handle); - pcmcia_release_io(link->handle, &link->io); - pcmcia_release_irq(link->handle, &link->irq); - - link->state &= ~DEV_CONFIG; + iounmap(lp->mem); + pcmcia_disable_device(link); #ifdef DEBUG_CONFIG_TRACE - printk(KERN_DEBUG "%s: <- wv_pcmcia_release()\n", dev->name); + printk(KERN_DEBUG "%s: <- wv_pcmcia_release()\n", dev->name); #endif } @@ -4479,7 +4468,7 @@ static int wavelan_open(struct net_device * dev) { net_local * lp = netdev_priv(dev); - dev_link_t * link = lp->link; + struct pcmcia_device * link = lp->link; kio_addr_t base = dev->base_addr; #ifdef DEBUG_CALLBACK_TRACE @@ -4533,7 +4522,7 @@ wavelan_open(struct net_device * dev) static int wavelan_close(struct net_device * dev) { - dev_link_t * link = ((net_local *)netdev_priv(dev))->link; + struct pcmcia_device * link = ((net_local *)netdev_priv(dev))->link; kio_addr_t base = dev->base_addr; #ifdef DEBUG_CALLBACK_TRACE @@ -4587,45 +4576,36 @@ wavelan_close(struct net_device * dev) * card insertion event. */ static int -wavelan_attach(struct pcmcia_device *p_dev) +wavelan_probe(struct pcmcia_device *p_dev) { - dev_link_t * link; /* Info for cardmgr */ struct net_device * dev; /* Interface generic data */ net_local * lp; /* Interface specific data */ + int ret; #ifdef DEBUG_CALLBACK_TRACE printk(KERN_DEBUG "-> wavelan_attach()\n"); #endif - /* Initialize the dev_link_t structure */ - link = kzalloc(sizeof(struct dev_link_t), GFP_KERNEL); - if (!link) return -ENOMEM; - /* The io structure describes IO port mapping */ - link->io.NumPorts1 = 8; - link->io.Attributes1 = IO_DATA_PATH_WIDTH_8; - link->io.IOAddrLines = 3; + p_dev->io.NumPorts1 = 8; + p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_8; + p_dev->io.IOAddrLines = 3; /* Interrupt setup */ - link->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_HANDLE_PRESENT; - link->irq.IRQInfo1 = IRQ_LEVEL_ID; - link->irq.Handler = wavelan_interrupt; + p_dev->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_HANDLE_PRESENT; + p_dev->irq.IRQInfo1 = IRQ_LEVEL_ID; + p_dev->irq.Handler = wavelan_interrupt; /* General socket configuration */ - link->conf.Attributes = CONF_ENABLE_IRQ; - link->conf.Vcc = 50; - link->conf.IntType = INT_MEMORY_AND_IO; - - /* Chain drivers */ - link->next = NULL; + p_dev->conf.Attributes = CONF_ENABLE_IRQ; + p_dev->conf.IntType = INT_MEMORY_AND_IO; /* Allocate the generic data structure */ dev = alloc_etherdev(sizeof(net_local)); - if (!dev) { - kfree(link); + if (!dev) return -ENOMEM; - } - link->priv = link->irq.Instance = dev; + + p_dev->priv = p_dev->irq.Instance = dev; lp = netdev_priv(dev); @@ -4642,7 +4622,6 @@ wavelan_attach(struct pcmcia_device *p_dev) spin_lock_init(&lp->spinlock); /* back links */ - lp->link = link; lp->dev = dev; /* wavelan NET3 callbacks */ @@ -4668,15 +4647,18 @@ wavelan_attach(struct pcmcia_device *p_dev) /* Other specific data */ dev->mtu = WAVELAN_MTU; - link->handle = p_dev; - p_dev->instance = link; + ret = wv_pcmcia_config(p_dev); + if (ret) + return ret; - link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; - if(wv_pcmcia_config(link) && - wv_hw_config(dev)) - wv_init_info(dev); - else + ret = wv_hw_config(dev); + if (ret) { dev->irq = 0; + pcmcia_disable_device(p_dev); + return ret; + } + + wv_init_info(dev); #ifdef DEBUG_CALLBACK_TRACE printk(KERN_DEBUG "<- wavelan_attach()\n"); @@ -4693,25 +4675,14 @@ wavelan_attach(struct pcmcia_device *p_dev) * is released. */ static void -wavelan_detach(struct pcmcia_device *p_dev) +wavelan_detach(struct pcmcia_device *link) { - dev_link_t *link = dev_to_instance(p_dev); - #ifdef DEBUG_CALLBACK_TRACE printk(KERN_DEBUG "-> wavelan_detach(0x%p)\n", link); #endif - /* - * If the device is currently configured and active, we won't - * actually delete it yet. Instead, it is marked so that when the - * release() function is called, that will trigger a proper - * detach(). - */ - if(link->state & DEV_CONFIG) - { - /* Some others haven't done their job : give them another chance */ - wv_pcmcia_release(link); - } + /* Some others haven't done their job : give them another chance */ + wv_pcmcia_release(link); /* Free pieces */ if(link->priv) @@ -4720,23 +4691,21 @@ wavelan_detach(struct pcmcia_device *p_dev) /* Remove ourselves from the kernel list of ethernet devices */ /* Warning : can't be called from interrupt, timer or wavelan_close() */ - if (link->dev) + if (link->dev_node) unregister_netdev(dev); - link->dev = NULL; + link->dev_node = NULL; ((net_local *)netdev_priv(dev))->link = NULL; ((net_local *)netdev_priv(dev))->dev = NULL; free_netdev(dev); } - kfree(link); #ifdef DEBUG_CALLBACK_TRACE printk(KERN_DEBUG "<- wavelan_detach()\n"); #endif } -static int wavelan_suspend(struct pcmcia_device *p_dev) +static int wavelan_suspend(struct pcmcia_device *link) { - dev_link_t *link = dev_to_instance(p_dev); struct net_device * dev = (struct net_device *) link->priv; /* NB: wavelan_close will be called, but too late, so we are @@ -4748,36 +4717,22 @@ static int wavelan_suspend(struct pcmcia_device *p_dev) /* Stop receiving new messages and wait end of transmission */ wv_ru_stop(dev); + if (link->open) + netif_device_detach(dev); + /* Power down the module */ hacr_write(dev->base_addr, HACR_DEFAULT & (~HACR_PWR_STAT)); - /* The card is now suspended */ - link->state |= DEV_SUSPEND; - - if(link->state & DEV_CONFIG) - { - if(link->open) - netif_device_detach(dev); - pcmcia_release_configuration(link->handle); - } - return 0; } -static int wavelan_resume(struct pcmcia_device *p_dev) +static int wavelan_resume(struct pcmcia_device *link) { - dev_link_t *link = dev_to_instance(p_dev); struct net_device * dev = (struct net_device *) link->priv; - link->state &= ~DEV_SUSPEND; - if(link->state & DEV_CONFIG) - { - pcmcia_request_configuration(link->handle, &link->conf); - if(link->open) /* If RESET -> True, If RESUME -> False ? */ - { - wv_hw_reset(dev); - netif_device_attach(dev); - } + if (link->open) { + wv_hw_reset(dev); + netif_device_attach(dev); } return 0; @@ -4798,7 +4753,7 @@ static struct pcmcia_driver wavelan_driver = { .drv = { .name = "wavelan_cs", }, - .probe = wavelan_attach, + .probe = wavelan_probe, .remove = wavelan_detach, .id_table = wavelan_ids, .suspend = wavelan_suspend, diff --git a/drivers/net/wireless/wavelan_cs.p.h b/drivers/net/wireless/wavelan_cs.p.h index 451f6271dcb..c65fe7a391e 100644 --- a/drivers/net/wireless/wavelan_cs.p.h +++ b/drivers/net/wireless/wavelan_cs.p.h @@ -602,7 +602,7 @@ struct net_local dev_node_t node; /* ???? What is this stuff ???? */ struct net_device * dev; /* Reverse link... */ spinlock_t spinlock; /* Serialize access to the hardware (SMP) */ - dev_link_t * link; /* pcmcia structure */ + struct pcmcia_device * link; /* pcmcia structure */ en_stats stats; /* Ethernet interface statistics */ int nresets; /* Number of hw resets */ u_char configured; /* If it is configured */ @@ -733,9 +733,9 @@ static int static inline void wv_hw_reset(struct net_device *); /* Same, + start receiver unit */ static inline int - wv_pcmcia_config(dev_link_t *); /* Configure the pcmcia interface */ + wv_pcmcia_config(struct pcmcia_device *); /* Configure the pcmcia interface */ static void - wv_pcmcia_release(dev_link_t *);/* Remove a device */ + wv_pcmcia_release(struct pcmcia_device *);/* Remove a device */ /* ---------------------- INTERRUPT HANDLING ---------------------- */ static irqreturn_t wavelan_interrupt(int, /* Interrupt handler */ diff --git a/drivers/net/wireless/wl3501.h b/drivers/net/wireless/wl3501.h index 4303c50c2ab..65ceb088f70 100644 --- a/drivers/net/wireless/wl3501.h +++ b/drivers/net/wireless/wl3501.h @@ -611,5 +611,6 @@ struct wl3501_card { struct iw_spy_data spy_data; struct iw_public_data wireless_data; struct dev_node_t node; + struct pcmcia_device *p_dev; }; #endif diff --git a/drivers/net/wireless/wl3501_cs.c b/drivers/net/wireless/wl3501_cs.c index 48e10b0c7e7..e52a650f673 100644 --- a/drivers/net/wireless/wl3501_cs.c +++ b/drivers/net/wireless/wl3501_cs.c @@ -103,8 +103,8 @@ module_param(pc_debug, int, 0); * release a socket, in response to card insertion and ejection events. They * are invoked from the wl24 event handler. */ -static void wl3501_config(dev_link_t *link); -static void wl3501_release(dev_link_t *link); +static int wl3501_config(struct pcmcia_device *link); +static void wl3501_release(struct pcmcia_device *link); /* * The dev_info variable is the "key" that is used to match up this @@ -226,17 +226,6 @@ static void iw_copy_mgmt_info_element(struct iw_mgmt_info_element *to, iw_set_mgmt_info_element(from->id, to, from->data, from->len); } -/* - * A linked list of "instances" of the wl24 device. Each actual PCMCIA card - * corresponds to one device instance, and is described by one dev_link_t - * structure (defined in ds.h). - * - * You may not want to use a linked list for this -- for example, the memory - * card driver uses an array of dev_link_t pointers, where minor device numbers - * are used to derive the corresponding array index. - */ -static dev_link_t *wl3501_dev_list; - static inline void wl3501_switch_page(struct wl3501_card *this, u8 page) { wl3501_outb(page, this->base_addr + WL3501_NIC_BSS); @@ -1281,15 +1270,10 @@ static int wl3501_close(struct net_device *dev) struct wl3501_card *this = dev->priv; int rc = -ENODEV; unsigned long flags; - dev_link_t *link; + struct pcmcia_device *link; + link = this->p_dev; spin_lock_irqsave(&this->lock, flags); - /* Check if the device is in wl3501_dev_list */ - for (link = wl3501_dev_list; link; link = link->next) - if (link->priv == dev) - break; - if (!link) - goto out; link->open--; /* Stop wl3501_hard_start_xmit() from now on */ @@ -1301,7 +1285,6 @@ static int wl3501_close(struct net_device *dev) rc = 0; printk(KERN_INFO "%s: WL3501 closed\n", dev->name); -out: spin_unlock_irqrestore(&this->lock, flags); return rc; } @@ -1400,14 +1383,11 @@ static int wl3501_open(struct net_device *dev) int rc = -ENODEV; struct wl3501_card *this = dev->priv; unsigned long flags; - dev_link_t *link; + struct pcmcia_device *link; + link = this->p_dev; spin_lock_irqsave(&this->lock, flags); - /* Check if the device is in wl3501_dev_list */ - for (link = wl3501_dev_list; link; link = link->next) - if (link->priv == dev) - break; - if (!DEV_OK(link)) + if (!pcmcia_dev_present(link)) goto out; netif_device_attach(dev); link->open++; @@ -1497,38 +1477,23 @@ static struct ethtool_ops ops = { * Services. If it has been released, all local data structures are freed. * Otherwise, the structures will be freed when the device is released. */ -static void wl3501_detach(struct pcmcia_device *p_dev) +static void wl3501_detach(struct pcmcia_device *link) { - dev_link_t *link = dev_to_instance(p_dev); - dev_link_t **linkp; struct net_device *dev = link->priv; - /* Locate device structure */ - for (linkp = &wl3501_dev_list; *linkp; linkp = &(*linkp)->next) - if (*linkp == link) - break; - if (!*linkp) - goto out; - /* If the device is currently configured and active, we won't actually * delete it yet. Instead, it is marked so that when the release() * function is called, that will trigger a proper detach(). */ - if (link->state & DEV_CONFIG) { - while (link->open > 0) - wl3501_close(dev); - - netif_device_detach(dev); - wl3501_release(link); - } + while (link->open > 0) + wl3501_close(dev); - /* Unlink device structure, free pieces */ - *linkp = link->next; + netif_device_detach(dev); + wl3501_release(link); if (link->priv) free_netdev(link->priv); - kfree(link); -out: + return; } @@ -1953,33 +1918,26 @@ static const struct iw_handler_def wl3501_handler_def = { * The dev_link structure is initialized, but we don't actually configure the * card at this point -- we wait until we receive a card insertion event. */ -static int wl3501_attach(struct pcmcia_device *p_dev) +static int wl3501_probe(struct pcmcia_device *p_dev) { - dev_link_t *link; struct net_device *dev; struct wl3501_card *this; - /* Initialize the dev_link_t structure */ - link = kzalloc(sizeof(*link), GFP_KERNEL); - if (!link) - return -ENOMEM; - /* The io structure describes IO port mapping */ - link->io.NumPorts1 = 16; - link->io.Attributes1 = IO_DATA_PATH_WIDTH_8; - link->io.IOAddrLines = 5; + p_dev->io.NumPorts1 = 16; + p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_8; + p_dev->io.IOAddrLines = 5; /* Interrupt setup */ - link->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_HANDLE_PRESENT; - link->irq.IRQInfo1 = IRQ_LEVEL_ID; - link->irq.Handler = wl3501_interrupt; + p_dev->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_HANDLE_PRESENT; + p_dev->irq.IRQInfo1 = IRQ_LEVEL_ID; + p_dev->irq.Handler = wl3501_interrupt; /* General socket configuration */ - link->conf.Attributes = CONF_ENABLE_IRQ; - link->conf.Vcc = 50; - link->conf.IntType = INT_MEMORY_AND_IO; - link->conf.ConfigIndex = 1; - link->conf.Present = PRESENT_OPTION; + p_dev->conf.Attributes = CONF_ENABLE_IRQ; + p_dev->conf.IntType = INT_MEMORY_AND_IO; + p_dev->conf.ConfigIndex = 1; + p_dev->conf.Present = PRESENT_OPTION; dev = alloc_etherdev(sizeof(struct wl3501_card)); if (!dev) @@ -1992,22 +1950,15 @@ static int wl3501_attach(struct pcmcia_device *p_dev) dev->get_stats = wl3501_get_stats; this = dev->priv; this->wireless_data.spy_data = &this->spy_data; + this->p_dev = p_dev; dev->wireless_data = &this->wireless_data; dev->wireless_handlers = (struct iw_handler_def *)&wl3501_handler_def; SET_ETHTOOL_OPS(dev, &ops); netif_stop_queue(dev); - link->priv = link->irq.Instance = dev; - - link->handle = p_dev; - p_dev->instance = link; - - link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; - wl3501_config(link); + p_dev->priv = p_dev->irq.Instance = dev; - return 0; + return wl3501_config(p_dev); out_link: - kfree(link); - link = NULL; return -ENOMEM; } @@ -2022,11 +1973,10 @@ do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0) * received, to configure the PCMCIA socket, and to make the ethernet device * available to the system. */ -static void wl3501_config(dev_link_t *link) +static int wl3501_config(struct pcmcia_device *link) { tuple_t tuple; cisparse_t parse; - client_handle_t handle = link->handle; struct net_device *dev = link->priv; int i = 0, j, last_fn, last_ret; unsigned char bf[64]; @@ -2035,18 +1985,15 @@ static void wl3501_config(dev_link_t *link) /* This reads the card's CONFIG tuple to find its config registers. */ tuple.Attributes = 0; tuple.DesiredTuple = CISTPL_CONFIG; - CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple)); + CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); tuple.TupleData = bf; tuple.TupleDataMax = sizeof(bf); tuple.TupleOffset = 0; - CS_CHECK(GetTupleData, pcmcia_get_tuple_data(handle, &tuple)); - CS_CHECK(ParseTuple, pcmcia_parse_tuple(handle, &tuple, &parse)); + CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple)); + CS_CHECK(ParseTuple, pcmcia_parse_tuple(link, &tuple, &parse)); link->conf.ConfigBase = parse.config.base; link->conf.Present = parse.config.rmask[0]; - /* Configure card */ - link->state |= DEV_CONFIG; - /* Try allocating IO ports. This tries a few fixed addresses. If you * want, you can also read the card's config table to pick addresses -- * see the serial driver for an example. */ @@ -2056,28 +2003,28 @@ static void wl3501_config(dev_link_t *link) * 0x200-0x2ff, and so on, because this seems safer */ link->io.BasePort1 = j; link->io.BasePort2 = link->io.BasePort1 + 0x10; - i = pcmcia_request_io(link->handle, &link->io); + i = pcmcia_request_io(link, &link->io); if (i == CS_SUCCESS) break; } if (i != CS_SUCCESS) { - cs_error(link->handle, RequestIO, i); + cs_error(link, RequestIO, i); goto failed; } /* Now allocate an interrupt line. Note that this does not actually * assign a handler to the interrupt. */ - CS_CHECK(RequestIRQ, pcmcia_request_irq(link->handle, &link->irq)); + CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq)); /* This actually configures the PCMCIA socket -- setting up the I/O * windows and the interrupt mapping. */ - CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link->handle, &link->conf)); + CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf)); dev->irq = link->irq.AssignedIRQ; dev->base_addr = link->io.BasePort1; - SET_NETDEV_DEV(dev, &handle_to_dev(handle)); + SET_NETDEV_DEV(dev, &handle_to_dev(link)); if (register_netdev(dev)) { printk(KERN_NOTICE "wl3501_cs: register_netdev() failed\n"); goto failed; @@ -2088,10 +2035,9 @@ static void wl3501_config(dev_link_t *link) this = dev->priv; /* * At this point, the dev_node_t structure(s) should be initialized and - * arranged in a linked list at link->dev. + * arranged in a linked list at link->dev_node. */ - link->dev = &this->node; - link->state &= ~DEV_CONFIG_PENDING; + link->dev_node = &this->node; this->base_addr = dev->base_addr; @@ -2127,13 +2073,13 @@ static void wl3501_config(dev_link_t *link) spin_lock_init(&this->lock); init_waitqueue_head(&this->wait); netif_start_queue(dev); - goto out; + return 0; + cs_failed: - cs_error(link->handle, last_fn, last_ret); + cs_error(link, last_fn, last_ret); failed: wl3501_release(link); -out: - return; + return -ENODEV; } /** @@ -2144,52 +2090,36 @@ out: * and release the PCMCIA configuration. If the device is still open, this * will be postponed until it is closed. */ -static void wl3501_release(dev_link_t *link) +static void wl3501_release(struct pcmcia_device *link) { struct net_device *dev = link->priv; /* Unlink the device chain */ - if (link->dev) { + if (link->dev_node) unregister_netdev(dev); - link->dev = NULL; - } - /* Don't bother checking to see if these succeed or not */ - pcmcia_release_configuration(link->handle); - pcmcia_release_io(link->handle, &link->io); - pcmcia_release_irq(link->handle, &link->irq); - link->state &= ~DEV_CONFIG; + pcmcia_disable_device(link); } -static int wl3501_suspend(struct pcmcia_device *p_dev) +static int wl3501_suspend(struct pcmcia_device *link) { - dev_link_t *link = dev_to_instance(p_dev); struct net_device *dev = link->priv; - link->state |= DEV_SUSPEND; - wl3501_pwr_mgmt(dev->priv, WL3501_SUSPEND); - if (link->state & DEV_CONFIG) { - if (link->open) - netif_device_detach(dev); - pcmcia_release_configuration(link->handle); - } + if (link->open) + netif_device_detach(dev); return 0; } -static int wl3501_resume(struct pcmcia_device *p_dev) +static int wl3501_resume(struct pcmcia_device *link) { - dev_link_t *link = dev_to_instance(p_dev); struct net_device *dev = link->priv; wl3501_pwr_mgmt(dev->priv, WL3501_RESUME); - if (link->state & DEV_CONFIG) { - pcmcia_request_configuration(link->handle, &link->conf); - if (link->open) { - wl3501_reset(dev); - netif_device_attach(dev); - } + if (link->open) { + wl3501_reset(dev); + netif_device_attach(dev); } return 0; @@ -2207,7 +2137,7 @@ static struct pcmcia_driver wl3501_driver = { .drv = { .name = "wl3501_cs", }, - .probe = wl3501_attach, + .probe = wl3501_probe, .remove = wl3501_detach, .id_table = wl3501_ids, .suspend = wl3501_suspend, @@ -2221,9 +2151,7 @@ static int __init wl3501_init_module(void) static void __exit wl3501_exit_module(void) { - dprintk(0, ": unloading"); pcmcia_unregister_driver(&wl3501_driver); - BUG_ON(wl3501_dev_list != NULL); } module_init(wl3501_init_module); diff --git a/drivers/parisc/ccio-dma.c b/drivers/parisc/ccio-dma.c index 93f8a8fa889..a5d826237b2 100644 --- a/drivers/parisc/ccio-dma.c +++ b/drivers/parisc/ccio-dma.c @@ -1560,7 +1560,7 @@ static int ccio_probe(struct parisc_device *dev) *ioc_p = ioc; ioc->hw_path = dev->hw_path; - ioc->ioc_regs = ioremap(dev->hpa.start, 4096); + ioc->ioc_regs = ioremap_nocache(dev->hpa.start, 4096); ccio_ioc_init(ioc); ccio_init_resources(ioc); hppa_dma_ops = &ccio_ops; diff --git a/drivers/parisc/dino.c b/drivers/parisc/dino.c index 3d1a7f98c67..6e8ed0c81a6 100644 --- a/drivers/parisc/dino.c +++ b/drivers/parisc/dino.c @@ -5,6 +5,7 @@ ** (c) Copyright 1999 SuSE GmbH ** (c) Copyright 1999,2000 Hewlett-Packard Company ** (c) Copyright 2000 Grant Grundler +** (c) Copyright 2006 Helge Deller ** ** This program is free software; you can redistribute it and/or modify ** it under the terms of the GNU General Public License as published by @@ -785,7 +786,7 @@ dino_bridge_init(struct dino_device *dino_dev, const char *name) if((io_addr & (1 << i)) == 0) continue; - start = (unsigned long)(signed int)(0xf0000000 | (i << 23)); + start = F_EXTEND(0xf0000000UL) | (i << 23); end = start + 8 * 1024 * 1024 - 1; DBG("DINO RANGE %d is at 0x%lx-0x%lx\n", count, @@ -996,7 +997,7 @@ static int __init dino_probe(struct parisc_device *dev) } dino_dev->hba.dev = dev; - dino_dev->hba.base_addr = ioremap(hpa, 4096); + dino_dev->hba.base_addr = ioremap_nocache(hpa, 4096); dino_dev->hba.lmmio_space_offset = 0; /* CPU addrs == bus addrs */ spin_lock_init(&dino_dev->dinosaur_pen); dino_dev->hba.iommu = ccio_get_iommu(dev); diff --git a/drivers/parisc/eisa.c b/drivers/parisc/eisa.c index 3d94d86c1c9..9d3bd15bf53 100644 --- a/drivers/parisc/eisa.c +++ b/drivers/parisc/eisa.c @@ -366,7 +366,7 @@ static int __devinit eisa_probe(struct parisc_device *dev) eisa_dev.eeprom_addr = MIRAGE_EEPROM_BASE_ADDR; } } - eisa_eeprom_addr = ioremap(eisa_dev.eeprom_addr, HPEE_MAX_LENGTH); + eisa_eeprom_addr = ioremap_nocache(eisa_dev.eeprom_addr, HPEE_MAX_LENGTH); result = eisa_enumerator(eisa_dev.eeprom_addr, &eisa_dev.hba.io_space, &eisa_dev.hba.lmmio_space); init_eisa_pic(); diff --git a/drivers/parisc/iosapic.c b/drivers/parisc/iosapic.c index 8d7a36392eb..7a458d5bc75 100644 --- a/drivers/parisc/iosapic.c +++ b/drivers/parisc/iosapic.c @@ -879,7 +879,7 @@ void *iosapic_register(unsigned long hpa) return NULL; } - isi->addr = ioremap(hpa, 4096); + isi->addr = ioremap_nocache(hpa, 4096); isi->isi_hpa = hpa; isi->isi_version = iosapic_rd_version(isi); isi->isi_num_vectors = IOSAPIC_IRDT_MAX_ENTRY(isi->isi_version) + 1; diff --git a/drivers/parisc/lba_pci.c b/drivers/parisc/lba_pci.c index e8a2a4a852f..3fe4a77fa16 100644 --- a/drivers/parisc/lba_pci.c +++ b/drivers/parisc/lba_pci.c @@ -1213,7 +1213,7 @@ lba_pat_resources(struct parisc_device *pa_dev, struct lba_device *lba_dev) ** Postable I/O port space is per PCI host adapter. ** base of 64MB PIOP region */ - lba_dev->iop_base = ioremap(p->start, 64 * 1024 * 1024); + lba_dev->iop_base = ioremap_nocache(p->start, 64 * 1024 * 1024); sprintf(lba_dev->hba.io_name, "PCI%02lx Ports", lba_dev->hba.bus_num.start); @@ -1525,7 +1525,7 @@ lba_driver_probe(struct parisc_device *dev) u32 func_class; void *tmp_obj; char *version; - void __iomem *addr = ioremap(dev->hpa.start, 4096); + void __iomem *addr = ioremap_nocache(dev->hpa.start, 4096); /* Read HW Rev First */ func_class = READ_REG32(addr + LBA_FCLASS); @@ -1619,7 +1619,7 @@ lba_driver_probe(struct parisc_device *dev) } else { if (!astro_iop_base) { /* Sprockets PDC uses NPIOP region */ - astro_iop_base = ioremap(LBA_PORT_BASE, 64 * 1024); + astro_iop_base = ioremap_nocache(LBA_PORT_BASE, 64 * 1024); pci_port = &lba_astro_port_ops; } @@ -1700,7 +1700,7 @@ void __init lba_init(void) */ void lba_set_iregs(struct parisc_device *lba, u32 ibase, u32 imask) { - void __iomem * base_addr = ioremap(lba->hpa.start, 4096); + void __iomem * base_addr = ioremap_nocache(lba->hpa.start, 4096); imask <<= 2; /* adjust for hints - 2 more bits */ diff --git a/drivers/parisc/pdc_stable.c b/drivers/parisc/pdc_stable.c index a28e17898fb..4e53be9c03a 100644 --- a/drivers/parisc/pdc_stable.c +++ b/drivers/parisc/pdc_stable.c @@ -4,9 +4,8 @@ * Copyright (C) 2005-2006 Thibaut VARENE <varenet@parisc-linux.org> * * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. + * it under the terms of the GNU General Public License, version 2, as + * published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/drivers/parisc/sba_iommu.c b/drivers/parisc/sba_iommu.c index 0821747e44c..42b32ff2fca 100644 --- a/drivers/parisc/sba_iommu.c +++ b/drivers/parisc/sba_iommu.c @@ -1642,9 +1642,9 @@ sba_ioc_init(struct parisc_device *sba, struct ioc *ioc, int ioc_num) ** **************************************************************************/ -static void __iomem *ioc_remap(struct sba_device *sba_dev, int offset) +static void __iomem *ioc_remap(struct sba_device *sba_dev, unsigned int offset) { - return ioremap(sba_dev->dev->hpa.start + offset, SBA_FUNC_SIZE); + return ioremap_nocache(sba_dev->dev->hpa.start + offset, SBA_FUNC_SIZE); } static void sba_hw_init(struct sba_device *sba_dev) @@ -2040,7 +2040,7 @@ sba_driver_callback(struct parisc_device *dev) u32 func_class; int i; char *version; - void __iomem *sba_addr = ioremap(dev->hpa.start, SBA_FUNC_SIZE); + void __iomem *sba_addr = ioremap_nocache(dev->hpa.start, SBA_FUNC_SIZE); struct proc_dir_entry *info_entry, *bitmap_entry, *root; sba_dump_ranges(sba_addr); diff --git a/drivers/parisc/superio.c b/drivers/parisc/superio.c index ad6d3b28a3a..719b863bc20 100644 --- a/drivers/parisc/superio.c +++ b/drivers/parisc/superio.c @@ -12,6 +12,7 @@ * (C) Copyright 2001 John Marvin <jsm fc hp com> * (C) Copyright 2003 Grant Grundler <grundler parisc-linux org> * (C) Copyright 2005 Kyle McMartin <kyle@parisc-linux.org> + * (C) Copyright 2006 Helge Deller <deller@gmx.de> * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as @@ -388,43 +389,34 @@ int superio_fixup_irq(struct pci_dev *pcidev) return local_irq; } -static struct uart_port serial[] = { - { - .iotype = UPIO_PORT, - .line = 0, - .type = PORT_16550A, - .uartclk = 115200*16, - .fifosize = 16, - }, - { - .iotype = UPIO_PORT, - .line = 1, - .type = PORT_16550A, - .uartclk = 115200*16, - .fifosize = 16, - } -}; - static void __devinit superio_serial_init(void) { #ifdef CONFIG_SERIAL_8250 int retval; - - serial[0].iobase = sio_dev.sp1_base; - serial[0].irq = SP1_IRQ; - spin_lock_init(&serial[0].lock); - - retval = early_serial_setup(&serial[0]); + struct uart_port serial_port; + + memset(&serial_port, 0, sizeof(serial_port)); + serial_port.iotype = UPIO_PORT; + serial_port.type = PORT_16550A; + serial_port.uartclk = 115200*16; + serial_port.fifosize = 16; + spin_lock_init(&serial_port.lock); + + /* serial port #1 */ + serial_port.iobase = sio_dev.sp1_base; + serial_port.irq = SP1_IRQ; + serial_port.line = 0; + retval = early_serial_setup(&serial_port); if (retval < 0) { printk(KERN_WARNING PFX "Register Serial #0 failed.\n"); return; } - serial[1].iobase = sio_dev.sp2_base; - serial[1].irq = SP2_IRQ; - spin_lock_init(&serial[1].lock); - retval = early_serial_setup(&serial[1]); - + /* serial port #2 */ + serial_port.iobase = sio_dev.sp2_base; + serial_port.irq = SP2_IRQ; + serial_port.line = 1; + retval = early_serial_setup(&serial_port); if (retval < 0) printk(KERN_WARNING PFX "Register Serial #1 failed.\n"); #endif /* CONFIG_SERIAL_8250 */ diff --git a/drivers/parport/parport_cs.c b/drivers/parport/parport_cs.c index 158d9256325..b953d5907c0 100644 --- a/drivers/parport/parport_cs.c +++ b/drivers/parport/parport_cs.c @@ -81,15 +81,15 @@ static char *version = #define FORCE_EPP_MODE 0x08 typedef struct parport_info_t { - dev_link_t link; + struct pcmcia_device *p_dev; int ndev; dev_node_t node; struct parport *port; } parport_info_t; static void parport_detach(struct pcmcia_device *p_dev); -static void parport_config(dev_link_t *link); -static void parport_cs_release(dev_link_t *); +static int parport_config(struct pcmcia_device *link); +static void parport_cs_release(struct pcmcia_device *); /*====================================================================== @@ -99,10 +99,9 @@ static void parport_cs_release(dev_link_t *); ======================================================================*/ -static int parport_attach(struct pcmcia_device *p_dev) +static int parport_probe(struct pcmcia_device *link) { parport_info_t *info; - dev_link_t *link; DEBUG(0, "parport_attach()\n"); @@ -110,23 +109,17 @@ static int parport_attach(struct pcmcia_device *p_dev) info = kmalloc(sizeof(*info), GFP_KERNEL); if (!info) return -ENOMEM; memset(info, 0, sizeof(*info)); - link = &info->link; link->priv = info; + link->priv = info; + info->p_dev = link; link->io.Attributes1 = IO_DATA_PATH_WIDTH_8; link->io.Attributes2 = IO_DATA_PATH_WIDTH_8; link->irq.Attributes = IRQ_TYPE_EXCLUSIVE; link->irq.IRQInfo1 = IRQ_LEVEL_ID; link->conf.Attributes = CONF_ENABLE_IRQ; - link->conf.Vcc = 50; link->conf.IntType = INT_MEMORY_AND_IO; - link->handle = p_dev; - p_dev->instance = link; - - link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; - parport_config(link); - - return 0; + return parport_config(link); } /* parport_attach */ /*====================================================================== @@ -138,14 +131,11 @@ static int parport_attach(struct pcmcia_device *p_dev) ======================================================================*/ -static void parport_detach(struct pcmcia_device *p_dev) +static void parport_detach(struct pcmcia_device *link) { - dev_link_t *link = dev_to_instance(p_dev); - DEBUG(0, "parport_detach(0x%p)\n", link); - if (link->state & DEV_CONFIG) - parport_cs_release(link); + parport_cs_release(link); kfree(link->priv); } /* parport_detach */ @@ -161,14 +151,12 @@ static void parport_detach(struct pcmcia_device *p_dev) #define CS_CHECK(fn, ret) \ do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0) -void parport_config(dev_link_t *link) +static int parport_config(struct pcmcia_device *link) { - client_handle_t handle = link->handle; parport_info_t *info = link->priv; tuple_t tuple; u_short buf[128]; cisparse_t parse; - config_info_t conf; cistpl_cftable_entry_t *cfg = &parse.cftable_entry; cistpl_cftable_entry_t dflt = { 0 }; struct parport *p; @@ -180,24 +168,18 @@ void parport_config(dev_link_t *link) tuple.TupleOffset = 0; tuple.TupleDataMax = 255; tuple.Attributes = 0; tuple.DesiredTuple = CISTPL_CONFIG; - CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple)); - CS_CHECK(GetTupleData, pcmcia_get_tuple_data(handle, &tuple)); - CS_CHECK(ParseTuple, pcmcia_parse_tuple(handle, &tuple, &parse)); + CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); + CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple)); + CS_CHECK(ParseTuple, pcmcia_parse_tuple(link, &tuple, &parse)); link->conf.ConfigBase = parse.config.base; link->conf.Present = parse.config.rmask[0]; - - /* Configure card */ - link->state |= DEV_CONFIG; - /* Not sure if this is right... look up the current Vcc */ - CS_CHECK(GetConfigurationInfo, pcmcia_get_configuration_info(handle, &conf)); - tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; tuple.Attributes = 0; - CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple)); + CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); while (1) { - if (pcmcia_get_tuple_data(handle, &tuple) != 0 || - pcmcia_parse_tuple(handle, &tuple, &parse) != 0) + if (pcmcia_get_tuple_data(link, &tuple) != 0 || + pcmcia_parse_tuple(link, &tuple, &parse) != 0) goto next_entry; if ((cfg->io.nwin > 0) || (dflt.io.nwin > 0)) { @@ -212,7 +194,7 @@ void parport_config(dev_link_t *link) link->io.BasePort2 = io->win[1].base; link->io.NumPorts2 = io->win[1].len; } - if (pcmcia_request_io(link->handle, &link->io) != 0) + if (pcmcia_request_io(link, &link->io) != 0) goto next_entry; /* If we've got this far, we're done */ break; @@ -220,15 +202,12 @@ void parport_config(dev_link_t *link) next_entry: if (cfg->flags & CISTPL_CFTABLE_DEFAULT) dflt = *cfg; - CS_CHECK(GetNextTuple, pcmcia_get_next_tuple(handle, &tuple)); + CS_CHECK(GetNextTuple, pcmcia_get_next_tuple(link, &tuple)); } - CS_CHECK(RequestIRQ, pcmcia_request_irq(handle, &link->irq)); - CS_CHECK(RequestConfiguration, pcmcia_request_configuration(handle, &link->conf)); + CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq)); + CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf)); - release_region(link->io.BasePort1, link->io.NumPorts1); - if (link->io.NumPorts2) - release_region(link->io.BasePort2, link->io.NumPorts2); p = parport_pc_probe_port(link->io.BasePort1, link->io.BasePort2, link->irq.AssignedIRQ, PARPORT_DMA_NONE, NULL); @@ -247,17 +226,15 @@ void parport_config(dev_link_t *link) info->node.minor = p->number; info->port = p; strcpy(info->node.dev_name, p->name); - link->dev = &info->node; + link->dev_node = &info->node; + + return 0; - link->state &= ~DEV_CONFIG_PENDING; - return; - cs_failed: - cs_error(link->handle, last_fn, last_ret); + cs_error(link, last_fn, last_ret); failed: parport_cs_release(link); - link->state &= ~DEV_CONFIG_PENDING; - + return -ENODEV; } /* parport_config */ /*====================================================================== @@ -268,53 +245,21 @@ failed: ======================================================================*/ -void parport_cs_release(dev_link_t *link) -{ - parport_info_t *info = link->priv; - - DEBUG(0, "parport_release(0x%p)\n", link); - - if (info->ndev) { - struct parport *p = info->port; - parport_pc_unregister_port(p); - request_region(link->io.BasePort1, link->io.NumPorts1, - info->node.dev_name); - if (link->io.NumPorts2) - request_region(link->io.BasePort2, link->io.NumPorts2, - info->node.dev_name); - } - info->ndev = 0; - link->dev = NULL; - - pcmcia_release_configuration(link->handle); - pcmcia_release_io(link->handle, &link->io); - pcmcia_release_irq(link->handle, &link->irq); - - link->state &= ~DEV_CONFIG; - -} /* parport_cs_release */ - -static int parport_suspend(struct pcmcia_device *dev) +void parport_cs_release(struct pcmcia_device *link) { - dev_link_t *link = dev_to_instance(dev); + parport_info_t *info = link->priv; - link->state |= DEV_SUSPEND; - if (link->state & DEV_CONFIG) - pcmcia_release_configuration(link->handle); + DEBUG(0, "parport_release(0x%p)\n", link); - return 0; -} - -static int parport_resume(struct pcmcia_device *dev) -{ - dev_link_t *link = dev_to_instance(dev); + if (info->ndev) { + struct parport *p = info->port; + parport_pc_unregister_port(p); + } + info->ndev = 0; - link->state &= ~DEV_SUSPEND; - if (DEV_OK(link)) - pcmcia_request_configuration(link->handle, &link->conf); + pcmcia_disable_device(link); +} /* parport_cs_release */ - return 0; -} static struct pcmcia_device_id parport_ids[] = { PCMCIA_DEVICE_FUNC_ID(3), @@ -328,11 +273,9 @@ static struct pcmcia_driver parport_cs_driver = { .drv = { .name = "parport_cs", }, - .probe = parport_attach, + .probe = parport_probe, .remove = parport_detach, .id_table = parport_ids, - .suspend = parport_suspend, - .resume = parport_resume, }; static int __init init_parport_cs(void) diff --git a/drivers/pcmcia/Kconfig b/drivers/pcmcia/Kconfig index 1f4ad0e7836..cba6c9eef28 100644 --- a/drivers/pcmcia/Kconfig +++ b/drivers/pcmcia/Kconfig @@ -263,6 +263,13 @@ config OMAP_CF Say Y here to support the CompactFlash controller on OMAP. Note that this doesn't support "True IDE" mode. +config AT91_CF + tristate "AT91 CompactFlash Controller" + depends on PCMCIA && ARCH_AT91RM9200 + help + Say Y here to support the CompactFlash controller on AT91 chips. + Or choose M to compile the driver as a module named "at91_cf". + config PCCARD_NONSTATIC tristate diff --git a/drivers/pcmcia/Makefile b/drivers/pcmcia/Makefile index bcecf5133b7..4276965517f 100644 --- a/drivers/pcmcia/Makefile +++ b/drivers/pcmcia/Makefile @@ -10,7 +10,7 @@ pcmcia_core-y += cs.o cistpl.o rsrc_mgr.o socket_sysfs.o pcmcia_core-$(CONFIG_CARDBUS) += cardbus.o obj-$(CONFIG_PCCARD) += pcmcia_core.o -pcmcia-y += ds.o pcmcia_compat.o pcmcia_resource.o +pcmcia-y += ds.o pcmcia_resource.o pcmcia-$(CONFIG_PCMCIA_IOCTL) += pcmcia_ioctl.o obj-$(CONFIG_PCMCIA) += pcmcia.o @@ -36,6 +36,7 @@ obj-$(CONFIG_PCMCIA_AU1X00) += au1x00_ss.o obj-$(CONFIG_PCMCIA_VRC4171) += vrc4171_card.o obj-$(CONFIG_PCMCIA_VRC4173) += vrc4173_cardu.o obj-$(CONFIG_OMAP_CF) += omap_cf.o +obj-$(CONFIG_AT91_CF) += at91_cf.o sa11xx_core-y += soc_common.o sa11xx_base.o pxa2xx_core-y += soc_common.o pxa2xx_base.o diff --git a/drivers/pcmcia/at91_cf.c b/drivers/pcmcia/at91_cf.c new file mode 100644 index 00000000000..67cc5f7d0c9 --- /dev/null +++ b/drivers/pcmcia/at91_cf.c @@ -0,0 +1,365 @@ +/* + * at91_cf.c -- AT91 CompactFlash controller driver + * + * Copyright (C) 2005 David Brownell + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ + +#include <linux/module.h> +#include <linux/kernel.h> +#include <linux/sched.h> +#include <linux/platform_device.h> +#include <linux/errno.h> +#include <linux/init.h> +#include <linux/interrupt.h> + +#include <pcmcia/ss.h> + +#include <asm/hardware.h> +#include <asm/io.h> +#include <asm/sizes.h> + +#include <asm/arch/at91rm9200.h> +#include <asm/arch/board.h> +#include <asm/arch/gpio.h> + + +#define CF_SIZE 0x30000000 /* CS5+CS6: unavailable */ + +/* + * A0..A10 work in each range; A23 indicates I/O space; A25 is CFRNW; + * some other bit in {A24,A22..A11} is nREG to flag memory access + * (vs attributes). So more than 2KB/region would just be waste. + */ +#define CF_ATTR_PHYS (AT91_CF_BASE) +#define CF_IO_PHYS (AT91_CF_BASE + (1 << 23)) +#define CF_MEM_PHYS (AT91_CF_BASE + 0x017ff800) + +/*--------------------------------------------------------------------------*/ + +static const char driver_name[] = "at91_cf"; + +struct at91_cf_socket { + struct pcmcia_socket socket; + + unsigned present:1; + + struct platform_device *pdev; + struct at91_cf_data *board; +}; + +#define SZ_2K (2 * SZ_1K) + +static inline int at91_cf_present(struct at91_cf_socket *cf) +{ + return !at91_get_gpio_value(cf->board->det_pin); +} + +/*--------------------------------------------------------------------------*/ + +static int at91_cf_ss_init(struct pcmcia_socket *s) +{ + return 0; +} + +static irqreturn_t at91_cf_irq(int irq, void *_cf, struct pt_regs *r) +{ + struct at91_cf_socket *cf = (struct at91_cf_socket *) _cf; + + if (irq == cf->board->det_pin) { + unsigned present = at91_cf_present(cf); + + /* kick pccard as needed */ + if (present != cf->present) { + cf->present = present; + pr_debug("%s: card %s\n", driver_name, present ? "present" : "gone"); + pcmcia_parse_events(&cf->socket, SS_DETECT); + } + } + + return IRQ_HANDLED; +} + +static int at91_cf_get_status(struct pcmcia_socket *s, u_int *sp) +{ + struct at91_cf_socket *cf; + + if (!sp) + return -EINVAL; + + cf = container_of(s, struct at91_cf_socket, socket); + + /* NOTE: we assume 3VCARD, not XVCARD... */ + if (at91_cf_present(cf)) { + int rdy = cf->board->irq_pin; /* RDY/nIRQ */ + int vcc = cf->board->vcc_pin; + + *sp = SS_DETECT | SS_3VCARD; + if (!rdy || at91_get_gpio_value(rdy)) + *sp |= SS_READY; + if (!vcc || at91_get_gpio_value(vcc)) + *sp |= SS_POWERON; + } else + *sp = 0; + + return 0; +} + +static int at91_cf_set_socket(struct pcmcia_socket *sock, struct socket_state_t *s) +{ + struct at91_cf_socket *cf; + + cf = container_of(sock, struct at91_cf_socket, socket); + + /* switch Vcc if needed and possible */ + if (cf->board->vcc_pin) { + switch (s->Vcc) { + case 0: + at91_set_gpio_value(cf->board->vcc_pin, 0); + break; + case 33: + at91_set_gpio_value(cf->board->vcc_pin, 1); + break; + default: + return -EINVAL; + } + } + + /* toggle reset if needed */ + at91_set_gpio_value(cf->board->rst_pin, s->flags & SS_RESET); + + pr_debug("%s: Vcc %d, io_irq %d, flags %04x csc %04x\n", + driver_name, s->Vcc, s->io_irq, s->flags, s->csc_mask); + + return 0; +} + +static int at91_cf_ss_suspend(struct pcmcia_socket *s) +{ + return at91_cf_set_socket(s, &dead_socket); +} + +/* we already mapped the I/O region */ +static int at91_cf_set_io_map(struct pcmcia_socket *s, struct pccard_io_map *io) +{ + struct at91_cf_socket *cf; + u32 csr; + + cf = container_of(s, struct at91_cf_socket, socket); + io->flags &= (MAP_ACTIVE | MAP_16BIT | MAP_AUTOSZ); + + /* + * Use 16 bit accesses unless/until we need 8-bit i/o space. + * Always set CSR4 ... PCMCIA won't always unmap things. + */ + csr = at91_sys_read(AT91_SMC_CSR(4)) & ~AT91_SMC_DBW; + + /* + * NOTE: this CF controller ignores IOIS16, so we can't really do + * MAP_AUTOSZ. The 16bit mode allows single byte access on either + * D0-D7 (even addr) or D8-D15 (odd), so it's close enough for many + * purposes (and handles ide-cs). + * + * The 8bit mode is needed for odd byte access on D0-D7. It seems + * some cards only like that way to get at the odd byte, despite + * CF 3.0 spec table 35 also giving the D8-D15 option. + */ + if (!(io->flags & (MAP_16BIT|MAP_AUTOSZ))) { + csr |= AT91_SMC_DBW_8; + pr_debug("%s: 8bit i/o bus\n", driver_name); + } else { + csr |= AT91_SMC_DBW_16; + pr_debug("%s: 16bit i/o bus\n", driver_name); + } + at91_sys_write(AT91_SMC_CSR(4), csr); + + io->start = cf->socket.io_offset; + io->stop = io->start + SZ_2K - 1; + + return 0; +} + +/* pcmcia layer maps/unmaps mem regions */ +static int at91_cf_set_mem_map(struct pcmcia_socket *s, struct pccard_mem_map *map) +{ + struct at91_cf_socket *cf; + + if (map->card_start) + return -EINVAL; + + cf = container_of(s, struct at91_cf_socket, socket); + + map->flags &= MAP_ACTIVE|MAP_ATTRIB|MAP_16BIT; + if (map->flags & MAP_ATTRIB) + map->static_start = CF_ATTR_PHYS; + else + map->static_start = CF_MEM_PHYS; + + return 0; +} + +static struct pccard_operations at91_cf_ops = { + .init = at91_cf_ss_init, + .suspend = at91_cf_ss_suspend, + .get_status = at91_cf_get_status, + .set_socket = at91_cf_set_socket, + .set_io_map = at91_cf_set_io_map, + .set_mem_map = at91_cf_set_mem_map, +}; + +/*--------------------------------------------------------------------------*/ + +static int __init at91_cf_probe(struct device *dev) +{ + struct at91_cf_socket *cf; + struct at91_cf_data *board = dev->platform_data; + struct platform_device *pdev = to_platform_device(dev); + unsigned int csa; + int status; + + if (!board || !board->det_pin || !board->rst_pin) + return -ENODEV; + + cf = kcalloc(1, sizeof *cf, GFP_KERNEL); + if (!cf) + return -ENOMEM; + + cf->board = board; + cf->pdev = pdev; + dev_set_drvdata(dev, cf); + + /* CF takes over CS4, CS5, CS6 */ + csa = at91_sys_read(AT91_EBI_CSA); + at91_sys_write(AT91_EBI_CSA, csa | AT91_EBI_CS4A_SMC_COMPACTFLASH); + + /* force poweron defaults for these pins ... */ + (void) at91_set_A_periph(AT91_PIN_PC9, 0); /* A25/CFRNW */ + (void) at91_set_A_periph(AT91_PIN_PC10, 0); /* NCS4/CFCS */ + (void) at91_set_A_periph(AT91_PIN_PC11, 0); /* NCS5/CFCE1 */ + (void) at91_set_A_periph(AT91_PIN_PC12, 0); /* NCS6/CFCE2 */ + + /* nWAIT is _not_ a default setting */ + (void) at91_set_A_periph(AT91_PIN_PC6, 1); /* nWAIT */ + + /* + * Static memory controller timing adjustments. + * REVISIT: these timings are in terms of MCK cycles, so + * when MCK changes (cpufreq etc) so must these values... + */ + at91_sys_write(AT91_SMC_CSR(4), AT91_SMC_ACSS_STD | AT91_SMC_DBW_16 | AT91_SMC_BAT | AT91_SMC_WSEN + | AT91_SMC_NWS_(32) /* wait states */ + | AT91_SMC_RWSETUP_(6) /* setup time */ + | AT91_SMC_RWHOLD_(4) /* hold time */ + ); + + /* must be a GPIO; ergo must trigger on both edges */ + status = request_irq(board->det_pin, at91_cf_irq, + SA_SAMPLE_RANDOM, driver_name, cf); + if (status < 0) + goto fail0; + + /* + * The card driver will request this irq later as needed. + * but it causes lots of "irqNN: nobody cared" messages + * unless we report that we handle everything (sigh). + * (Note: DK board doesn't wire the IRQ pin...) + */ + if (board->irq_pin) { + status = request_irq(board->irq_pin, at91_cf_irq, + SA_SHIRQ, driver_name, cf); + if (status < 0) + goto fail0a; + cf->socket.pci_irq = board->irq_pin; + } + else + cf->socket.pci_irq = NR_IRQS + 1; + + /* pcmcia layer only remaps "real" memory not iospace */ + cf->socket.io_offset = (unsigned long) ioremap(CF_IO_PHYS, SZ_2K); + if (!cf->socket.io_offset) + goto fail1; + + /* reserve CS4, CS5, and CS6 regions; but use just CS4 */ + if (!request_mem_region(AT91_CF_BASE, CF_SIZE, driver_name)) + goto fail1; + + pr_info("%s: irqs det #%d, io #%d\n", driver_name, + board->det_pin, board->irq_pin); + + cf->socket.owner = THIS_MODULE; + cf->socket.dev.dev = dev; + cf->socket.ops = &at91_cf_ops; + cf->socket.resource_ops = &pccard_static_ops; + cf->socket.features = SS_CAP_PCCARD | SS_CAP_STATIC_MAP + | SS_CAP_MEM_ALIGN; + cf->socket.map_size = SZ_2K; + cf->socket.io[0].NumPorts = SZ_2K; + + status = pcmcia_register_socket(&cf->socket); + if (status < 0) + goto fail2; + + return 0; + +fail2: + iounmap((void __iomem *) cf->socket.io_offset); + release_mem_region(AT91_CF_BASE, CF_SIZE); +fail1: + if (board->irq_pin) + free_irq(board->irq_pin, cf); +fail0a: + free_irq(board->det_pin, cf); +fail0: + at91_sys_write(AT91_EBI_CSA, csa); + kfree(cf); + return status; +} + +static int __exit at91_cf_remove(struct device *dev) +{ + struct at91_cf_socket *cf = dev_get_drvdata(dev); + unsigned int csa; + + pcmcia_unregister_socket(&cf->socket); + free_irq(cf->board->irq_pin, cf); + free_irq(cf->board->det_pin, cf); + iounmap((void __iomem *) cf->socket.io_offset); + release_mem_region(AT91_CF_BASE, CF_SIZE); + + csa = at91_sys_read(AT91_EBI_CSA); + at91_sys_write(AT91_EBI_CSA, csa & ~AT91_EBI_CS4A); + + kfree(cf); + return 0; +} + +static struct device_driver at91_cf_driver = { + .name = (char *) driver_name, + .bus = &platform_bus_type, + .probe = at91_cf_probe, + .remove = __exit_p(at91_cf_remove), + .suspend = pcmcia_socket_dev_suspend, + .resume = pcmcia_socket_dev_resume, +}; + +/*--------------------------------------------------------------------------*/ + +static int __init at91_cf_init(void) +{ + return driver_register(&at91_cf_driver); +} +module_init(at91_cf_init); + +static void __exit at91_cf_exit(void) +{ + driver_unregister(&at91_cf_driver); +} +module_exit(at91_cf_exit); + +MODULE_DESCRIPTION("AT91 Compact Flash Driver"); +MODULE_AUTHOR("David Brownell"); +MODULE_LICENSE("GPL"); diff --git a/drivers/pcmcia/cistpl.c b/drivers/pcmcia/cistpl.c index 120fa8da639..912c03e5eb0 100644 --- a/drivers/pcmcia/cistpl.c +++ b/drivers/pcmcia/cistpl.c @@ -12,7 +12,6 @@ * (C) 1999 David A. Hinds */ -#include <linux/config.h> #include <linux/module.h> #include <linux/moduleparam.h> #include <linux/kernel.h> diff --git a/drivers/pcmcia/cs.c b/drivers/pcmcia/cs.c index 613f2f1fbfd..3162998579c 100644 --- a/drivers/pcmcia/cs.c +++ b/drivers/pcmcia/cs.c @@ -16,7 +16,6 @@ #include <linux/moduleparam.h> #include <linux/init.h> #include <linux/kernel.h> -#include <linux/config.h> #include <linux/string.h> #include <linux/major.h> #include <linux/errno.h> @@ -111,9 +110,9 @@ int pcmcia_socket_dev_suspend(struct device *dev, pm_message_t state) list_for_each_entry(socket, &pcmcia_socket_list, socket_list) { if (socket->dev.dev != dev) continue; - down(&socket->skt_sem); + mutex_lock(&socket->skt_mutex); socket_suspend(socket); - up(&socket->skt_sem); + mutex_unlock(&socket->skt_mutex); } up_read(&pcmcia_socket_list_rwsem); @@ -129,9 +128,9 @@ int pcmcia_socket_dev_resume(struct device *dev) list_for_each_entry(socket, &pcmcia_socket_list, socket_list) { if (socket->dev.dev != dev) continue; - down(&socket->skt_sem); + mutex_lock(&socket->skt_mutex); socket_resume(socket); - up(&socket->skt_sem); + mutex_unlock(&socket->skt_mutex); } up_read(&pcmcia_socket_list_rwsem); @@ -237,7 +236,7 @@ int pcmcia_register_socket(struct pcmcia_socket *socket) init_completion(&socket->socket_released); init_completion(&socket->thread_done); init_waitqueue_head(&socket->thread_wait); - init_MUTEX(&socket->skt_sem); + mutex_init(&socket->skt_mutex); spin_lock_init(&socket->thread_lock); ret = kernel_thread(pccardd, socket, CLONE_KERNEL); @@ -406,8 +405,6 @@ static void socket_shutdown(struct pcmcia_socket *s) cb_free(s); #endif s->functions = 0; - kfree(s->config); - s->config = NULL; s->ops->get_status(s, &status); if (status & SS_POWERON) { @@ -664,7 +661,7 @@ static int pccardd(void *__skt) spin_unlock_irqrestore(&skt->thread_lock, flags); if (events) { - down(&skt->skt_sem); + mutex_lock(&skt->skt_mutex); if (events & SS_DETECT) socket_detect_change(skt); if (events & SS_BATDEAD) @@ -673,7 +670,7 @@ static int pccardd(void *__skt) send_event(skt, CS_EVENT_BATTERY_LOW, CS_EVENT_PRI_LOW); if (events & SS_READY) send_event(skt, CS_EVENT_READY_CHANGE, CS_EVENT_PRI_LOW); - up(&skt->skt_sem); + mutex_unlock(&skt->skt_mutex); continue; } @@ -717,8 +714,8 @@ int pccard_register_pcmcia(struct pcmcia_socket *s, struct pcmcia_callback *c) { int ret = 0; - /* s->skt_sem also protects s->callback */ - down(&s->skt_sem); + /* s->skt_mutex also protects s->callback */ + mutex_lock(&s->skt_mutex); if (c) { /* registration */ @@ -734,7 +731,7 @@ int pccard_register_pcmcia(struct pcmcia_socket *s, struct pcmcia_callback *c) } else s->callback = NULL; err: - up(&s->skt_sem); + mutex_unlock(&s->skt_mutex); return ret; } @@ -752,7 +749,7 @@ int pccard_reset_card(struct pcmcia_socket *skt) cs_dbg(skt, 1, "resetting socket\n"); - down(&skt->skt_sem); + mutex_lock(&skt->skt_mutex); do { if (!(skt->state & SOCKET_PRESENT)) { ret = CS_NO_CARD; @@ -781,7 +778,7 @@ int pccard_reset_card(struct pcmcia_socket *skt) ret = CS_SUCCESS; } while (0); - up(&skt->skt_sem); + mutex_unlock(&skt->skt_mutex); return ret; } /* reset_card */ @@ -797,7 +794,7 @@ int pcmcia_suspend_card(struct pcmcia_socket *skt) cs_dbg(skt, 1, "suspending socket\n"); - down(&skt->skt_sem); + mutex_lock(&skt->skt_mutex); do { if (!(skt->state & SOCKET_PRESENT)) { ret = CS_NO_CARD; @@ -814,7 +811,7 @@ int pcmcia_suspend_card(struct pcmcia_socket *skt) } ret = socket_suspend(skt); } while (0); - up(&skt->skt_sem); + mutex_unlock(&skt->skt_mutex); return ret; } /* suspend_card */ @@ -827,7 +824,7 @@ int pcmcia_resume_card(struct pcmcia_socket *skt) cs_dbg(skt, 1, "waking up socket\n"); - down(&skt->skt_sem); + mutex_lock(&skt->skt_mutex); do { if (!(skt->state & SOCKET_PRESENT)) { ret = CS_NO_CARD; @@ -841,7 +838,7 @@ int pcmcia_resume_card(struct pcmcia_socket *skt) if (!ret && skt->callback) skt->callback->resume(skt); } while (0); - up(&skt->skt_sem); + mutex_unlock(&skt->skt_mutex); return ret; } /* resume_card */ @@ -855,7 +852,7 @@ int pcmcia_eject_card(struct pcmcia_socket *skt) cs_dbg(skt, 1, "user eject request\n"); - down(&skt->skt_sem); + mutex_lock(&skt->skt_mutex); do { if (!(skt->state & SOCKET_PRESENT)) { ret = -ENODEV; @@ -871,7 +868,7 @@ int pcmcia_eject_card(struct pcmcia_socket *skt) socket_remove(skt); ret = 0; } while (0); - up(&skt->skt_sem); + mutex_unlock(&skt->skt_mutex); return ret; } /* eject_card */ @@ -884,7 +881,7 @@ int pcmcia_insert_card(struct pcmcia_socket *skt) cs_dbg(skt, 1, "user insert request\n"); - down(&skt->skt_sem); + mutex_lock(&skt->skt_mutex); do { if (skt->state & SOCKET_PRESENT) { ret = -EBUSY; @@ -896,7 +893,7 @@ int pcmcia_insert_card(struct pcmcia_socket *skt) } ret = 0; } while (0); - up(&skt->skt_sem); + mutex_unlock(&skt->skt_mutex); return ret; } /* insert_card */ diff --git a/drivers/pcmcia/cs_internal.h b/drivers/pcmcia/cs_internal.h index 7b37eba35bf..d6164cd583f 100644 --- a/drivers/pcmcia/cs_internal.h +++ b/drivers/pcmcia/cs_internal.h @@ -15,7 +15,7 @@ #ifndef _LINUX_CS_INTERNAL_H #define _LINUX_CS_INTERNAL_H -#include <linux/config.h> +#include <linux/kref.h> /* Flags in client state */ #define CLIENT_CONFIG_LOCKED 0x0001 @@ -23,7 +23,7 @@ #define CLIENT_IO_REQ 0x0004 #define CLIENT_UNBOUND 0x0008 #define CLIENT_STALE 0x0010 -#define CLIENT_WIN_REQ(i) (0x20<<(i)) +#define CLIENT_WIN_REQ(i) (0x1<<(i)) #define CLIENT_CARDBUS 0x8000 #define REGION_MAGIC 0xE3C9 @@ -31,7 +31,7 @@ typedef struct region_t { u_short region_magic; u_short state; dev_info_t dev_info; - client_handle_t mtd; + struct pcmcia_device *mtd; u_int MediaID; region_info_t info; } region_t; @@ -40,12 +40,12 @@ typedef struct region_t { /* Each card function gets one of these guys */ typedef struct config_t { + struct kref ref; u_int state; u_int Attributes; u_int IntType; u_int ConfigBase; u_char Status, Pin, Copy, Option, ExtStatus; - u_int Present; u_int CardValues; io_req_t io; struct { @@ -95,12 +95,6 @@ static inline void cs_socket_put(struct pcmcia_socket *skt) } } -#define CHECK_SOCKET(s) \ - (((s) >= sockets) || (socket_table[s]->ops == NULL)) - -#define SOCKET(h) (h->socket) -#define CONFIG(h) (&SOCKET(h)->config[(h)->func]) - /* In cardbus.c */ int cb_alloc(struct pcmcia_socket *s); void cb_free(struct pcmcia_socket *s); @@ -133,10 +127,9 @@ extern struct class_interface pccard_sysfs_interface; extern struct rw_semaphore pcmcia_socket_list_rwsem; extern struct list_head pcmcia_socket_list; int pcmcia_get_window(struct pcmcia_socket *s, window_handle_t *handle, int idx, win_req_t *req); -int pccard_get_configuration_info(struct pcmcia_socket *s, unsigned int function, config_info_t *config); +int pccard_get_configuration_info(struct pcmcia_socket *s, struct pcmcia_device *p_dev, config_info_t *config); int pccard_reset_card(struct pcmcia_socket *skt); -int pccard_get_status(struct pcmcia_socket *s, unsigned int function, cs_status_t *status); -int pccard_access_configuration_register(struct pcmcia_socket *s, unsigned int function, conf_reg_t *reg); +int pccard_get_status(struct pcmcia_socket *s, struct pcmcia_device *p_dev, cs_status_t *status); struct pcmcia_callback{ diff --git a/drivers/pcmcia/ds.c b/drivers/pcmcia/ds.c index bb96ce1db08..ae10d1eed65 100644 --- a/drivers/pcmcia/ds.c +++ b/drivers/pcmcia/ds.c @@ -10,10 +10,9 @@ * are Copyright (C) 1999 David A. Hinds. All Rights Reserved. * * (C) 1999 David A. Hinds - * (C) 2003 - 2005 Dominik Brodowski + * (C) 2003 - 2006 Dominik Brodowski */ -#include <linux/config.h> #include <linux/kernel.h> #include <linux/module.h> #include <linux/init.h> @@ -23,6 +22,7 @@ #include <linux/workqueue.h> #include <linux/crc32.h> #include <linux/firmware.h> +#include <linux/kref.h> #define IN_CARD_SERVICES #include <pcmcia/cs_types.h> @@ -343,12 +343,19 @@ void pcmcia_put_dev(struct pcmcia_device *p_dev) put_device(&p_dev->dev); } +static void pcmcia_release_function(struct kref *ref) +{ + struct config_t *c = container_of(ref, struct config_t, ref); + kfree(c); +} + static void pcmcia_release_dev(struct device *dev) { struct pcmcia_device *p_dev = to_pcmcia_dev(dev); ds_dbg(1, "releasing dev %p\n", p_dev); pcmcia_put_socket(p_dev->socket); kfree(p_dev->devname); + kref_put(&p_dev->function_config->ref, pcmcia_release_function); kfree(p_dev); } @@ -377,29 +384,12 @@ static int pcmcia_device_probe(struct device * dev) p_drv = to_pcmcia_drv(dev->driver); s = p_dev->socket; - if ((!p_drv->probe) || (!try_module_get(p_drv->owner))) { + if ((!p_drv->probe) || (!p_dev->function_config) || + (!try_module_get(p_drv->owner))) { ret = -EINVAL; goto put_dev; } - p_dev->state &= ~CLIENT_UNBOUND; - - /* set up the device configuration, if it hasn't been done before */ - if (!s->functions) { - cistpl_longlink_mfc_t mfc; - if (pccard_read_tuple(s, p_dev->func, CISTPL_LONGLINK_MFC, - &mfc) == CS_SUCCESS) - s->functions = mfc.nfn; - else - s->functions = 1; - s->config = kzalloc(sizeof(config_t) * s->functions, - GFP_KERNEL); - if (!s->config) { - ret = -ENOMEM; - goto put_module; - } - } - ret = p_drv->probe(p_dev); if (ret) goto put_module; @@ -425,15 +415,61 @@ static int pcmcia_device_probe(struct device * dev) } +/* + * Removes a PCMCIA card from the device tree and socket list. + */ +static void pcmcia_card_remove(struct pcmcia_socket *s, struct pcmcia_device *leftover) +{ + struct pcmcia_device *p_dev; + struct pcmcia_device *tmp; + unsigned long flags; + + ds_dbg(2, "unbind_request(%d)\n", s->sock); + + + if (!leftover) + s->device_count = 0; + else + s->device_count = 1; + + /* unregister all pcmcia_devices registered with this socket, except leftover */ + list_for_each_entry_safe(p_dev, tmp, &s->devices_list, socket_device_list) { + if (p_dev == leftover) + continue; + + spin_lock_irqsave(&pcmcia_dev_list_lock, flags); + list_del(&p_dev->socket_device_list); + p_dev->_removed=1; + spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags); + + device_unregister(&p_dev->dev); + } + + return; +} + + static int pcmcia_device_remove(struct device * dev) { struct pcmcia_device *p_dev; struct pcmcia_driver *p_drv; + struct pcmcia_device_id *did; int i; - /* detach the "instance" */ p_dev = to_pcmcia_dev(dev); p_drv = to_pcmcia_drv(dev->driver); + + /* If we're removing the primary module driving a + * pseudo multi-function card, we need to unbind + * all devices + */ + did = (struct pcmcia_device_id *) p_dev->dev.driver_data; + if (did && (did->match_flags & PCMCIA_DEV_ID_MATCH_DEVICE_NO) && + (p_dev->socket->device_count != 0) && + (p_dev->device_no == 0)) + pcmcia_card_remove(p_dev->socket, p_dev); + + /* detach the "instance" */ if (!p_drv) return 0; @@ -441,17 +477,16 @@ static int pcmcia_device_remove(struct device * dev) p_drv->remove(p_dev); /* check for proper unloading */ - if (p_dev->state & (CLIENT_IRQ_REQ|CLIENT_IO_REQ|CLIENT_CONFIG_LOCKED)) + if (p_dev->_irq || p_dev->_io || p_dev->_locked) printk(KERN_INFO "pcmcia: driver %s did not release config properly\n", p_drv->drv.name); for (i = 0; i < MAX_WIN; i++) - if (p_dev->state & CLIENT_WIN_REQ(i)) + if (p_dev->_win & CLIENT_WIN_REQ(i)) printk(KERN_INFO "pcmcia: driver %s did not release windows properly\n", p_drv->drv.name); /* references from pcmcia_probe_device */ - p_dev->state = CLIENT_UNBOUND; pcmcia_put_dev(p_dev); module_put(p_drv->owner); @@ -460,37 +495,6 @@ static int pcmcia_device_remove(struct device * dev) /* - * Removes a PCMCIA card from the device tree and socket list. - */ -static void pcmcia_card_remove(struct pcmcia_socket *s) -{ - struct pcmcia_device *p_dev; - unsigned long flags; - - ds_dbg(2, "unbind_request(%d)\n", s->sock); - - s->device_count = 0; - - for (;;) { - /* unregister all pcmcia_devices registered with this socket*/ - spin_lock_irqsave(&pcmcia_dev_list_lock, flags); - if (list_empty(&s->devices_list)) { - spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags); - return; - } - p_dev = list_entry((&s->devices_list)->next, struct pcmcia_device, socket_device_list); - list_del(&p_dev->socket_device_list); - p_dev->state |= CLIENT_STALE; - spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags); - - device_unregister(&p_dev->dev); - } - - return; -} /* unbind_request */ - - -/* * pcmcia_device_query -- determine information about a pcmcia device */ static int pcmcia_device_query(struct pcmcia_device *p_dev) @@ -546,7 +550,7 @@ static int pcmcia_device_query(struct pcmcia_device *p_dev) tmp = vers1->str + vers1->ofs[i]; length = strlen(tmp) + 1; - if ((length < 3) || (length > 255)) + if ((length < 2) || (length > 255)) continue; p_dev->prod_id[i] = kmalloc(sizeof(char) * length, @@ -571,11 +575,11 @@ static int pcmcia_device_query(struct pcmcia_device *p_dev) * won't work, this doesn't matter much at the moment: the driver core doesn't * support it either. */ -static DECLARE_MUTEX(device_add_lock); +static DEFINE_MUTEX(device_add_lock); struct pcmcia_device * pcmcia_device_add(struct pcmcia_socket *s, unsigned int function) { - struct pcmcia_device *p_dev; + struct pcmcia_device *p_dev, *tmp_dev; unsigned long flags; int bus_id_len; @@ -583,7 +587,7 @@ struct pcmcia_device * pcmcia_device_add(struct pcmcia_socket *s, unsigned int f if (!s) return NULL; - down(&device_add_lock); + mutex_lock(&device_add_lock); /* max of 2 devices per card */ if (s->device_count == 2) @@ -596,6 +600,8 @@ struct pcmcia_device * pcmcia_device_add(struct pcmcia_socket *s, unsigned int f p_dev->socket = s; p_dev->device_no = (s->device_count++); p_dev->func = function; + if (s->functions <= function) + s->functions = function + 1; p_dev->dev.bus = &pcmcia_bus_type; p_dev->dev.parent = s->dev.dev; @@ -608,36 +614,55 @@ struct pcmcia_device * pcmcia_device_add(struct pcmcia_socket *s, unsigned int f sprintf (p_dev->devname, "pcmcia%s", p_dev->dev.bus_id); /* compat */ - p_dev->state = CLIENT_UNBOUND; + spin_lock_irqsave(&pcmcia_dev_list_lock, flags); + + /* + * p_dev->function_config must be the same for all card functions. + * Note that this is serialized by the device_add_lock, so that + * only one such struct will be created. + */ + list_for_each_entry(tmp_dev, &s->devices_list, socket_device_list) + if (p_dev->func == tmp_dev->func) { + p_dev->function_config = tmp_dev->function_config; + kref_get(&p_dev->function_config->ref); + } /* Add to the list in pcmcia_bus_socket */ - spin_lock_irqsave(&pcmcia_dev_list_lock, flags); list_add_tail(&p_dev->socket_device_list, &s->devices_list); + spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags); + if (!p_dev->function_config) { + p_dev->function_config = kzalloc(sizeof(struct config_t), + GFP_KERNEL); + if (!p_dev->function_config) + goto err_unreg; + kref_init(&p_dev->function_config->ref); + } + printk(KERN_NOTICE "pcmcia: registering new device %s\n", p_dev->devname); pcmcia_device_query(p_dev); - if (device_register(&p_dev->dev)) { - spin_lock_irqsave(&pcmcia_dev_list_lock, flags); - list_del(&p_dev->socket_device_list); - spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags); - - goto err_free; - } + if (device_register(&p_dev->dev)) + goto err_unreg; - up(&device_add_lock); + mutex_unlock(&device_add_lock); return p_dev; + err_unreg: + spin_lock_irqsave(&pcmcia_dev_list_lock, flags); + list_del(&p_dev->socket_device_list); + spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags); + err_free: kfree(p_dev->devname); kfree(p_dev); s->device_count--; err_put: - up(&device_add_lock); + mutex_unlock(&device_add_lock); pcmcia_put_socket(s); return NULL; @@ -696,7 +721,7 @@ static void pcmcia_bus_rescan(struct pcmcia_socket *skt) int no_devices=0; unsigned long flags; - /* must be called with skt_sem held */ + /* must be called with skt_mutex held */ spin_lock_irqsave(&pcmcia_dev_list_lock, flags); if (list_empty(&skt->devices_list)) no_devices=1; @@ -819,9 +844,11 @@ static int pcmcia_bus_match(struct device * dev, struct device_driver * drv) { struct pcmcia_driver * p_drv = to_pcmcia_drv(drv); struct pcmcia_device_id *did = p_drv->id_table; +#ifdef CONFIG_PCMCIA_IOCTL /* matching by cardmgr */ if (p_dev->cardmgr == p_drv) return 1; +#endif while (did && did->match_flags) { if (pcmcia_devmatch(p_dev, did)) @@ -927,7 +954,7 @@ static ssize_t pcmcia_show_pm_state(struct device *dev, struct device_attribute { struct pcmcia_device *p_dev = to_pcmcia_dev(dev); - if (p_dev->dev.power.power_state.event != PM_EVENT_ON) + if (p_dev->suspended) return sprintf(buf, "off\n"); else return sprintf(buf, "on\n"); @@ -942,11 +969,9 @@ static ssize_t pcmcia_store_pm_state(struct device *dev, struct device_attribute if (!count) return -EINVAL; - if ((p_dev->dev.power.power_state.event == PM_EVENT_ON) && - (!strncmp(buf, "off", 3))) + if ((!p_dev->suspended) && !strncmp(buf, "off", 3)) ret = dpm_runtime_suspend(dev, PMSG_SUSPEND); - else if ((p_dev->dev.power.power_state.event != PM_EVENT_ON) && - (!strncmp(buf, "on", 2))) + else if (p_dev->suspended && !strncmp(buf, "on", 2)) dpm_runtime_resume(dev); return ret ? ret : count; @@ -982,9 +1007,9 @@ static ssize_t pcmcia_store_allow_func_id_match(struct device *dev, if (!count) return -EINVAL; - down(&p_dev->socket->skt_sem); + mutex_lock(&p_dev->socket->skt_mutex); p_dev->allow_func_id_match = 1; - up(&p_dev->socket->skt_sem); + mutex_unlock(&p_dev->socket->skt_mutex); bus_rescan_devices(&pcmcia_bus_type); @@ -1012,14 +1037,27 @@ static int pcmcia_dev_suspend(struct device * dev, pm_message_t state) { struct pcmcia_device *p_dev = to_pcmcia_dev(dev); struct pcmcia_driver *p_drv = NULL; + int ret = 0; if (dev->driver) p_drv = to_pcmcia_drv(dev->driver); - if (p_drv && p_drv->suspend) - return p_drv->suspend(p_dev); + if (!p_drv) + goto out; - return 0; + if (p_drv->suspend) { + ret = p_drv->suspend(p_dev); + if (ret) + goto out; + } + + if (p_dev->device_no == p_dev->func) + pcmcia_release_configuration(p_dev); + + out: + if (!ret) + p_dev->suspended = 1; + return ret; } @@ -1027,14 +1065,27 @@ static int pcmcia_dev_resume(struct device * dev) { struct pcmcia_device *p_dev = to_pcmcia_dev(dev); struct pcmcia_driver *p_drv = NULL; + int ret = 0; if (dev->driver) p_drv = to_pcmcia_drv(dev->driver); - if (p_drv && p_drv->resume) - return p_drv->resume(p_dev); + if (!p_drv) + goto out; - return 0; + if (p_dev->device_no == p_dev->func) { + ret = pcmcia_request_configuration(p_dev, &p_dev->conf); + if (ret) + goto out; + } + + if (p_drv->resume) + ret = p_drv->resume(p_dev); + + out: + if (!ret) + p_dev->suspended = 0; + return ret; } @@ -1100,7 +1151,7 @@ static int ds_event(struct pcmcia_socket *skt, event_t event, int priority) switch (event) { case CS_EVENT_CARD_REMOVAL: s->pcmcia_state.present = 0; - pcmcia_card_remove(skt); + pcmcia_card_remove(skt, NULL); handle_event(skt, event); break; @@ -1128,6 +1179,32 @@ static int ds_event(struct pcmcia_socket *skt, event_t event, int priority) } /* ds_event */ +struct pcmcia_device * pcmcia_dev_present(struct pcmcia_device *_p_dev) +{ + struct pcmcia_device *p_dev; + struct pcmcia_device *ret = NULL; + + p_dev = pcmcia_get_dev(_p_dev); + if (!p_dev) + return NULL; + + if (!p_dev->socket->pcmcia_state.present) + goto out; + + if (p_dev->_removed) + goto out; + + if (p_dev->suspended) + goto out; + + ret = p_dev; + out: + pcmcia_put_dev(p_dev); + return ret; +} +EXPORT_SYMBOL(pcmcia_dev_present); + + static struct pcmcia_callback pcmcia_bus_callback = { .owner = THIS_MODULE, .event = ds_event, diff --git a/drivers/pcmcia/ds_internal.h b/drivers/pcmcia/ds_internal.h index d359bd25a51..3a2b25e6ed7 100644 --- a/drivers/pcmcia/ds_internal.h +++ b/drivers/pcmcia/ds_internal.h @@ -8,6 +8,8 @@ extern void pcmcia_put_dev(struct pcmcia_device *p_dev); struct pcmcia_device * pcmcia_device_add(struct pcmcia_socket *s, unsigned int function); +extern int pcmcia_release_configuration(struct pcmcia_device *p_dev); + #ifdef CONFIG_PCMCIA_IOCTL extern void __init pcmcia_setup_ioctl(void); extern void __exit pcmcia_cleanup_ioctl(void); @@ -15,7 +17,7 @@ extern void handle_event(struct pcmcia_socket *s, event_t event); extern int handle_request(struct pcmcia_socket *s, event_t event); #else static inline void __init pcmcia_setup_ioctl(void) { return; } -static inline void __init pcmcia_cleanup_ioctl(void) { return; } +static inline void __exit pcmcia_cleanup_ioctl(void) { return; } static inline void handle_event(struct pcmcia_socket *s, event_t event) { return; } static inline int handle_request(struct pcmcia_socket *s, event_t event) { return CS_SUCCESS; } #endif diff --git a/drivers/pcmcia/i82092.c b/drivers/pcmcia/i82092.c index 7979c85df3d..d5f03a338c6 100644 --- a/drivers/pcmcia/i82092.c +++ b/drivers/pcmcia/i82092.c @@ -10,7 +10,6 @@ */ #include <linux/kernel.h> -#include <linux/config.h> #include <linux/module.h> #include <linux/pci.h> #include <linux/init.h> diff --git a/drivers/pcmcia/i82365.c b/drivers/pcmcia/i82365.c index 35a92d1e494..bd0308e8981 100644 --- a/drivers/pcmcia/i82365.c +++ b/drivers/pcmcia/i82365.c @@ -34,7 +34,6 @@ #include <linux/module.h> #include <linux/moduleparam.h> #include <linux/init.h> -#include <linux/config.h> #include <linux/types.h> #include <linux/fcntl.h> #include <linux/string.h> diff --git a/drivers/pcmcia/pcmcia_compat.c b/drivers/pcmcia/pcmcia_compat.c deleted file mode 100644 index ebb161c4f81..00000000000 --- a/drivers/pcmcia/pcmcia_compat.c +++ /dev/null @@ -1,65 +0,0 @@ -/* - * PCMCIA 16-bit compatibility functions - * - * The initial developer of the original code is David A. Hinds - * <dahinds@users.sourceforge.net>. Portions created by David A. Hinds - * are Copyright (C) 1999 David A. Hinds. All Rights Reserved. - * - * Copyright (C) 2004 Dominik Brodowski - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - */ - -#include <linux/config.h> -#include <linux/module.h> -#include <linux/init.h> - -#define IN_CARD_SERVICES -#include <pcmcia/cs_types.h> -#include <pcmcia/cs.h> -#include <pcmcia/bulkmem.h> -#include <pcmcia/cistpl.h> -#include <pcmcia/ds.h> -#include <pcmcia/ss.h> - -#include "cs_internal.h" - -int pcmcia_get_first_tuple(struct pcmcia_device *p_dev, tuple_t *tuple) -{ - return pccard_get_first_tuple(p_dev->socket, p_dev->func, tuple); -} -EXPORT_SYMBOL(pcmcia_get_first_tuple); - -int pcmcia_get_next_tuple(struct pcmcia_device *p_dev, tuple_t *tuple) -{ - return pccard_get_next_tuple(p_dev->socket, p_dev->func, tuple); -} -EXPORT_SYMBOL(pcmcia_get_next_tuple); - -int pcmcia_get_tuple_data(struct pcmcia_device *p_dev, tuple_t *tuple) -{ - return pccard_get_tuple_data(p_dev->socket, tuple); -} -EXPORT_SYMBOL(pcmcia_get_tuple_data); - -int pcmcia_parse_tuple(struct pcmcia_device *p_dev, tuple_t *tuple, cisparse_t *parse) -{ - return pccard_parse_tuple(tuple, parse); -} -EXPORT_SYMBOL(pcmcia_parse_tuple); - -int pcmcia_validate_cis(struct pcmcia_device *p_dev, cisinfo_t *info) -{ - return pccard_validate_cis(p_dev->socket, p_dev->func, info); -} -EXPORT_SYMBOL(pcmcia_validate_cis); - - -int pcmcia_reset_card(struct pcmcia_device *p_dev, client_req_t *req) -{ - return pccard_reset_card(p_dev->socket); -} -EXPORT_SYMBOL(pcmcia_reset_card); diff --git a/drivers/pcmcia/pcmcia_ioctl.c b/drivers/pcmcia/pcmcia_ioctl.c index 80969f7e7a0..c53db7ceda5 100644 --- a/drivers/pcmcia/pcmcia_ioctl.c +++ b/drivers/pcmcia/pcmcia_ioctl.c @@ -18,7 +18,6 @@ */ -#include <linux/config.h> #include <linux/kernel.h> #include <linux/module.h> #include <linux/init.h> @@ -70,10 +69,26 @@ extern int ds_pc_debug; #define ds_dbg(lvl, fmt, arg...) do { } while (0) #endif +static struct pcmcia_device *get_pcmcia_device(struct pcmcia_socket *s, + unsigned int function) +{ + struct pcmcia_device *p_dev = NULL; + unsigned long flags; + + spin_lock_irqsave(&pcmcia_dev_list_lock, flags); + list_for_each_entry(p_dev, &s->devices_list, socket_device_list) { + if (p_dev->func == function) { + spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags); + return pcmcia_get_dev(p_dev); + } + } + spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags); + return NULL; +} /* backwards-compatible accessing of driver --- by name! */ -static struct pcmcia_driver * get_pcmcia_driver (dev_info_t *dev_info) +static struct pcmcia_driver *get_pcmcia_driver(dev_info_t *dev_info) { struct device_driver *drv; struct pcmcia_driver *p_drv; @@ -214,7 +229,7 @@ static int bind_request(struct pcmcia_socket *s, bind_info_t *bind_info) * by userspace before, we need to * return the "instance". */ spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags); - bind_info->instance = p_dev->instance; + bind_info->instance = p_dev; ret = -EBUSY; goto err_put_module; } else { @@ -253,9 +268,9 @@ rescan: /* * Prevent this racing with a card insertion. */ - down(&s->skt_sem); + mutex_lock(&s->skt_mutex); bus_rescan_devices(&pcmcia_bus_type); - up(&s->skt_sem); + mutex_unlock(&s->skt_mutex); /* check whether the driver indeed matched. I don't care if this * is racy or not, because it can only happen on cardmgr access @@ -289,6 +304,7 @@ static int get_device_info(struct pcmcia_socket *s, bind_info_t *bind_info, int { dev_node_t *node; struct pcmcia_device *p_dev; + struct pcmcia_driver *p_drv; unsigned long flags; int ret = 0; @@ -343,16 +359,16 @@ static int get_device_info(struct pcmcia_socket *s, bind_info_t *bind_info, int found: spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags); - if ((!p_dev->instance) || - (p_dev->instance->state & DEV_CONFIG_PENDING)) { + p_drv = to_pcmcia_drv(p_dev->dev.driver); + if (p_drv && !p_dev->_locked) { ret = -EAGAIN; goto err_put; } if (first) - node = p_dev->instance->dev; + node = p_dev->dev_node; else - for (node = p_dev->instance->dev; node; node = node->next) + for (node = p_dev->dev_node; node; node = node->next) if (node == bind_info->next) break; if (!node) { @@ -583,14 +599,16 @@ static int ds_ioctl(struct inode * inode, struct file * file, if (buf->config.Function && (buf->config.Function >= s->functions)) ret = CS_BAD_ARGS; - else - ret = pccard_get_configuration_info(s, - buf->config.Function, &buf->config); + else { + struct pcmcia_device *p_dev = get_pcmcia_device(s, buf->config.Function); + ret = pccard_get_configuration_info(s, p_dev, &buf->config); + pcmcia_put_dev(p_dev); + } break; case DS_GET_FIRST_TUPLE: - down(&s->skt_sem); + mutex_lock(&s->skt_mutex); pcmcia_validate_mem(s); - up(&s->skt_sem); + mutex_unlock(&s->skt_mutex); ret = pccard_get_first_tuple(s, BIND_FN_ALL, &buf->tuple); break; case DS_GET_NEXT_TUPLE: @@ -609,16 +627,19 @@ static int ds_ioctl(struct inode * inode, struct file * file, ret = pccard_reset_card(s); break; case DS_GET_STATUS: - if (buf->status.Function && - (buf->status.Function >= s->functions)) - ret = CS_BAD_ARGS; - else - ret = pccard_get_status(s, buf->status.Function, &buf->status); - break; + if (buf->status.Function && + (buf->status.Function >= s->functions)) + ret = CS_BAD_ARGS; + else { + struct pcmcia_device *p_dev = get_pcmcia_device(s, buf->status.Function); + ret = pccard_get_status(s, p_dev, &buf->status); + pcmcia_put_dev(p_dev); + } + break; case DS_VALIDATE_CIS: - down(&s->skt_sem); + mutex_lock(&s->skt_mutex); pcmcia_validate_mem(s); - up(&s->skt_sem); + mutex_unlock(&s->skt_mutex); ret = pccard_validate_cis(s, BIND_FN_ALL, &buf->cisinfo); break; case DS_SUSPEND_CARD: @@ -638,12 +659,16 @@ static int ds_ioctl(struct inode * inode, struct file * file, err = -EPERM; goto free_out; } - if (buf->conf_reg.Function && - (buf->conf_reg.Function >= s->functions)) - ret = CS_BAD_ARGS; - else - ret = pccard_access_configuration_register(s, - buf->conf_reg.Function, &buf->conf_reg); + + ret = CS_BAD_ARGS; + + if (!(buf->conf_reg.Function && + (buf->conf_reg.Function >= s->functions))) { + struct pcmcia_device *p_dev = get_pcmcia_device(s, buf->conf_reg.Function); + if (p_dev) + ret = pcmcia_access_configuration_register(p_dev, &buf->conf_reg); + pcmcia_put_dev(p_dev); + } break; case DS_GET_FIRST_REGION: case DS_GET_NEXT_REGION: diff --git a/drivers/pcmcia/pcmcia_resource.c b/drivers/pcmcia/pcmcia_resource.c index 89022ad5b52..45063b4e5b7 100644 --- a/drivers/pcmcia/pcmcia_resource.c +++ b/drivers/pcmcia/pcmcia_resource.c @@ -14,7 +14,6 @@ * */ -#include <linux/config.h> #include <linux/module.h> #include <linux/kernel.h> #include <linux/interrupt.h> @@ -89,7 +88,7 @@ static int alloc_io_space(struct pcmcia_socket *s, u_int attr, ioaddr_t *base, } if ((s->features & SS_CAP_STATIC_MAP) && s->io_offset) { *base = s->io_offset | (*base & 0x0fff); - s->io[0].Attributes = attr; + s->io[0].res->flags = (s->io[0].res->flags & ~IORESOURCE_BITS) | (attr & IORESOURCE_BITS); return 0; } /* Check for an already-allocated window that must conflict with @@ -97,38 +96,36 @@ static int alloc_io_space(struct pcmcia_socket *s, u_int attr, ioaddr_t *base, * potential conflicts, just the most obvious ones. */ for (i = 0; i < MAX_IO_WIN; i++) - if ((s->io[i].NumPorts != 0) && - ((s->io[i].BasePort & (align-1)) == *base)) + if ((s->io[i].res) && + ((s->io[i].res->start & (align-1)) == *base)) return 1; for (i = 0; i < MAX_IO_WIN; i++) { - if (s->io[i].NumPorts == 0) { + if (!s->io[i].res) { s->io[i].res = pcmcia_find_io_region(*base, num, align, s); if (s->io[i].res) { - s->io[i].Attributes = attr; - s->io[i].BasePort = *base = s->io[i].res->start; - s->io[i].NumPorts = s->io[i].InUse = num; + *base = s->io[i].res->start; + s->io[i].res->flags = (s->io[i].res->flags & ~IORESOURCE_BITS) | (attr & IORESOURCE_BITS); + s->io[i].InUse = num; break; } else return 1; - } else if (s->io[i].Attributes != attr) + } else if ((s->io[i].res->flags & IORESOURCE_BITS) != (attr & IORESOURCE_BITS)) continue; /* Try to extend top of window */ - try = s->io[i].BasePort + s->io[i].NumPorts; + try = s->io[i].res->end + 1; if ((*base == 0) || (*base == try)) if (pcmcia_adjust_io_region(s->io[i].res, s->io[i].res->start, s->io[i].res->end + num, s) == 0) { *base = try; - s->io[i].NumPorts += num; s->io[i].InUse += num; break; } /* Try to extend bottom of window */ - try = s->io[i].BasePort - num; + try = s->io[i].res->start - num; if ((*base == 0) || (*base == try)) if (pcmcia_adjust_io_region(s->io[i].res, s->io[i].res->start - num, s->io[i].res->end, s) == 0) { - s->io[i].BasePort = *base = try; - s->io[i].NumPorts += num; + *base = try; s->io[i].InUse += num; break; } @@ -143,12 +140,13 @@ static void release_io_space(struct pcmcia_socket *s, ioaddr_t base, int i; for (i = 0; i < MAX_IO_WIN; i++) { - if ((s->io[i].BasePort <= base) && - (s->io[i].BasePort+s->io[i].NumPorts >= base+num)) { + if (!s->io[i].res) + continue; + if ((s->io[i].res->start <= base) && + (s->io[i].res->end >= base+num-1)) { s->io[i].InUse -= num; /* Free the window if no one else is using it */ if (s->io[i].InUse == 0) { - s->io[i].NumPorts = 0; release_resource(s->io[i].res); kfree(s->io[i].res); s->io[i].res = NULL; @@ -165,21 +163,19 @@ static void release_io_space(struct pcmcia_socket *s, ioaddr_t base, * this and the tuple reading services. */ -int pccard_access_configuration_register(struct pcmcia_socket *s, - unsigned int function, +int pcmcia_access_configuration_register(struct pcmcia_device *p_dev, conf_reg_t *reg) { + struct pcmcia_socket *s; config_t *c; int addr; u_char val; - if (!s || !s->config) + if (!p_dev || !p_dev->function_config) return CS_NO_CARD; - c = &s->config[function]; - - if (c == NULL) - return CS_NO_CARD; + s = p_dev->socket; + c = p_dev->function_config; if (!(c->state & CONFIG_LOCKED)) return CS_CONFIGURATION_LOCKED; @@ -200,20 +196,12 @@ int pccard_access_configuration_register(struct pcmcia_socket *s, break; } return CS_SUCCESS; -} /* pccard_access_configuration_register */ - -int pcmcia_access_configuration_register(struct pcmcia_device *p_dev, - conf_reg_t *reg) -{ - return pccard_access_configuration_register(p_dev->socket, - p_dev->func, reg); -} +} /* pcmcia_access_configuration_register */ EXPORT_SYMBOL(pcmcia_access_configuration_register); - int pccard_get_configuration_info(struct pcmcia_socket *s, - unsigned int function, + struct pcmcia_device *p_dev, config_info_t *config) { config_t *c; @@ -221,7 +209,7 @@ int pccard_get_configuration_info(struct pcmcia_socket *s, if (!(s->state & SOCKET_PRESENT)) return CS_NO_CARD; - config->Function = function; + config->Function = p_dev->func; #ifdef CONFIG_CARDBUS if (s->state & SOCKET_CARDBUS) { @@ -235,14 +223,14 @@ int pccard_get_configuration_info(struct pcmcia_socket *s, config->AssignedIRQ = s->irq.AssignedIRQ; if (config->AssignedIRQ) config->Attributes |= CONF_ENABLE_IRQ; - config->BasePort1 = s->io[0].BasePort; - config->NumPorts1 = s->io[0].NumPorts; + config->BasePort1 = s->io[0].res->start; + config->NumPorts1 = s->io[0].res->end - config->BasePort1 + 1; } return CS_SUCCESS; } #endif - c = (s->config != NULL) ? &s->config[function] : NULL; + c = (p_dev) ? p_dev->function_config : NULL; if ((c == NULL) || !(c->state & CONFIG_LOCKED)) { config->Attributes = 0; @@ -271,7 +259,7 @@ int pccard_get_configuration_info(struct pcmcia_socket *s, int pcmcia_get_configuration_info(struct pcmcia_device *p_dev, config_info_t *config) { - return pccard_get_configuration_info(p_dev->socket, p_dev->func, + return pccard_get_configuration_info(p_dev->socket, p_dev, config); } EXPORT_SYMBOL(pcmcia_get_configuration_info); @@ -317,7 +305,7 @@ EXPORT_SYMBOL(pcmcia_get_window); * SocketState yet: I haven't seen any point for it. */ -int pccard_get_status(struct pcmcia_socket *s, unsigned int function, +int pccard_get_status(struct pcmcia_socket *s, struct pcmcia_device *p_dev, cs_status_t *status) { config_t *c; @@ -334,11 +322,12 @@ int pccard_get_status(struct pcmcia_socket *s, unsigned int function, if (!(s->state & SOCKET_PRESENT)) return CS_NO_CARD; - c = (s->config != NULL) ? &s->config[function] : NULL; + c = (p_dev) ? p_dev->function_config : NULL; + if ((c != NULL) && (c->state & CONFIG_LOCKED) && (c->IntType & (INT_MEMORY_AND_IO | INT_ZOOMED_VIDEO))) { u_char reg; - if (c->Present & PRESENT_PIN_REPLACE) { + if (c->CardValues & PRESENT_PIN_REPLACE) { pcmcia_read_cis_mem(s, 1, (c->ConfigBase+CISREG_PRR)>>1, 1, ®); status->CardState |= (reg & PRR_WP_STATUS) ? CS_EVENT_WRITE_PROTECT : 0; @@ -352,7 +341,7 @@ int pccard_get_status(struct pcmcia_socket *s, unsigned int function, /* No PRR? Then assume we're always ready */ status->CardState |= CS_EVENT_READY_CHANGE; } - if (c->Present & PRESENT_EXT_STATUS) { + if (c->CardValues & PRESENT_EXT_STATUS) { pcmcia_read_cis_mem(s, 1, (c->ConfigBase+CISREG_ESR)>>1, 1, ®); status->CardState |= (reg & ESR_REQ_ATTN) ? CS_EVENT_REQUEST_ATTENTION : 0; @@ -370,11 +359,9 @@ int pccard_get_status(struct pcmcia_socket *s, unsigned int function, return CS_SUCCESS; } /* pccard_get_status */ -int pcmcia_get_status(client_handle_t handle, cs_status_t *status) +int pcmcia_get_status(struct pcmcia_device *p_dev, cs_status_t *status) { - struct pcmcia_socket *s; - s = SOCKET(handle); - return pccard_get_status(s, handle->func, status); + return pccard_get_status(p_dev->socket, p_dev, status); } EXPORT_SYMBOL(pcmcia_get_status); @@ -422,7 +409,8 @@ int pcmcia_modify_configuration(struct pcmcia_device *p_dev, config_t *c; s = p_dev->socket; - c = CONFIG(p_dev); + c = p_dev->function_config; + if (!(s->state & SOCKET_PRESENT)) return CS_NO_CARD; if (!(c->state & CONFIG_LOCKED)) @@ -454,6 +442,28 @@ int pcmcia_modify_configuration(struct pcmcia_device *p_dev, (mod->Attributes & CONF_VPP2_CHANGE_VALID)) return CS_BAD_VPP; + if (mod->Attributes & CONF_IO_CHANGE_WIDTH) { + pccard_io_map io_off = { 0, 0, 0, 0, 1 }; + pccard_io_map io_on; + int i; + + io_on.speed = io_speed; + for (i = 0; i < MAX_IO_WIN; i++) { + if (!s->io[i].res) + continue; + io_off.map = i; + io_on.map = i; + + io_on.flags = MAP_ACTIVE | IO_DATA_PATH_WIDTH_8; + io_on.start = s->io[i].res->start; + io_on.stop = s->io[i].res->end; + + s->ops->set_io_map(s, &io_off); + mdelay(40); + s->ops->set_io_map(s, &io_on); + } + } + return CS_SUCCESS; } /* modify_configuration */ EXPORT_SYMBOL(pcmcia_modify_configuration); @@ -463,23 +473,23 @@ int pcmcia_release_configuration(struct pcmcia_device *p_dev) { pccard_io_map io = { 0, 0, 0, 0, 1 }; struct pcmcia_socket *s = p_dev->socket; + config_t *c = p_dev->function_config; int i; - if (!(p_dev->state & CLIENT_CONFIG_LOCKED)) - return CS_BAD_HANDLE; - p_dev->state &= ~CLIENT_CONFIG_LOCKED; - - if (!(p_dev->state & CLIENT_STALE)) { - config_t *c = CONFIG(p_dev); + if (p_dev->_locked) { + p_dev->_locked = 0; if (--(s->lock_count) == 0) { s->socket.flags = SS_OUTPUT_ENA; /* Is this correct? */ s->socket.Vpp = 0; s->socket.io_irq = 0; s->ops->set_socket(s, &s->socket); } + } + if (c->state & CONFIG_LOCKED) { + c->state &= ~CONFIG_LOCKED; if (c->state & CONFIG_IO_REQ) for (i = 0; i < MAX_IO_WIN; i++) { - if (s->io[i].NumPorts == 0) + if (!s->io[i].res) continue; s->io[i].Config--; if (s->io[i].Config != 0) @@ -487,12 +497,10 @@ int pcmcia_release_configuration(struct pcmcia_device *p_dev) io.map = i; s->ops->set_io_map(s, &io); } - c->state &= ~CONFIG_LOCKED; } return CS_SUCCESS; } /* pcmcia_release_configuration */ -EXPORT_SYMBOL(pcmcia_release_configuration); /** pcmcia_release_io @@ -503,25 +511,23 @@ EXPORT_SYMBOL(pcmcia_release_configuration); * don't bother checking the port ranges against the current socket * values. */ -int pcmcia_release_io(struct pcmcia_device *p_dev, io_req_t *req) +static int pcmcia_release_io(struct pcmcia_device *p_dev, io_req_t *req) { struct pcmcia_socket *s = p_dev->socket; + config_t *c = p_dev->function_config; - if (!(p_dev->state & CLIENT_IO_REQ)) + if (!p_dev->_io ) return CS_BAD_HANDLE; - p_dev->state &= ~CLIENT_IO_REQ; - - if (!(p_dev->state & CLIENT_STALE)) { - config_t *c = CONFIG(p_dev); - if (c->state & CONFIG_LOCKED) - return CS_CONFIGURATION_LOCKED; - if ((c->io.BasePort1 != req->BasePort1) || - (c->io.NumPorts1 != req->NumPorts1) || - (c->io.BasePort2 != req->BasePort2) || - (c->io.NumPorts2 != req->NumPorts2)) - return CS_BAD_ARGS; - c->state &= ~CONFIG_IO_REQ; - } + + p_dev->_io = 0; + + if ((c->io.BasePort1 != req->BasePort1) || + (c->io.NumPorts1 != req->NumPorts1) || + (c->io.BasePort2 != req->BasePort2) || + (c->io.NumPorts2 != req->NumPorts2)) + return CS_BAD_ARGS; + + c->state &= ~CONFIG_IO_REQ; release_io_space(s, req->BasePort1, req->NumPorts1); if (req->NumPorts2) @@ -529,28 +535,26 @@ int pcmcia_release_io(struct pcmcia_device *p_dev, io_req_t *req) return CS_SUCCESS; } /* pcmcia_release_io */ -EXPORT_SYMBOL(pcmcia_release_io); -int pcmcia_release_irq(struct pcmcia_device *p_dev, irq_req_t *req) +static int pcmcia_release_irq(struct pcmcia_device *p_dev, irq_req_t *req) { struct pcmcia_socket *s = p_dev->socket; - if (!(p_dev->state & CLIENT_IRQ_REQ)) + config_t *c= p_dev->function_config; + + if (!p_dev->_irq) return CS_BAD_HANDLE; - p_dev->state &= ~CLIENT_IRQ_REQ; - - if (!(p_dev->state & CLIENT_STALE)) { - config_t *c = CONFIG(p_dev); - if (c->state & CONFIG_LOCKED) - return CS_CONFIGURATION_LOCKED; - if (c->irq.Attributes != req->Attributes) - return CS_BAD_ATTRIBUTE; - if (s->irq.AssignedIRQ != req->AssignedIRQ) - return CS_BAD_IRQ; - if (--s->irq.Config == 0) { - c->state &= ~CONFIG_IRQ_REQ; - s->irq.AssignedIRQ = 0; - } + p_dev->_irq = 0; + + if (c->state & CONFIG_LOCKED) + return CS_CONFIGURATION_LOCKED; + if (c->irq.Attributes != req->Attributes) + return CS_BAD_ATTRIBUTE; + if (s->irq.AssignedIRQ != req->AssignedIRQ) + return CS_BAD_IRQ; + if (--s->irq.Config == 0) { + c->state &= ~CONFIG_IRQ_REQ; + s->irq.AssignedIRQ = 0; } if (req->Attributes & IRQ_HANDLE_PRESENT) { @@ -563,7 +567,6 @@ int pcmcia_release_irq(struct pcmcia_device *p_dev, irq_req_t *req) return CS_SUCCESS; } /* pcmcia_release_irq */ -EXPORT_SYMBOL(pcmcia_release_irq); int pcmcia_release_window(window_handle_t win) @@ -573,7 +576,7 @@ int pcmcia_release_window(window_handle_t win) if ((win == NULL) || (win->magic != WINDOW_MAGIC)) return CS_BAD_HANDLE; s = win->sock; - if (!(win->handle->state & CLIENT_WIN_REQ(win->index))) + if (!(win->handle->_win & CLIENT_WIN_REQ(win->index))) return CS_BAD_HANDLE; /* Shut down memory window */ @@ -587,7 +590,7 @@ int pcmcia_release_window(window_handle_t win) kfree(win->ctl.res); win->ctl.res = NULL; } - win->handle->state &= ~CLIENT_WIN_REQ(win->index); + win->handle->_win &= ~CLIENT_WIN_REQ(win->index); win->magic = 0; @@ -610,16 +613,12 @@ int pcmcia_request_configuration(struct pcmcia_device *p_dev, if (req->IntType & INT_CARDBUS) return CS_UNSUPPORTED_MODE; - c = CONFIG(p_dev); + c = p_dev->function_config; if (c->state & CONFIG_LOCKED) return CS_CONFIGURATION_LOCKED; /* Do power control. We don't allow changes in Vcc. */ - if (s->socket.Vcc != req->Vcc) - return CS_BAD_VCC; - if (req->Vpp1 != req->Vpp2) - return CS_BAD_VPP; - s->socket.Vpp = req->Vpp1; + s->socket.Vpp = req->Vpp; if (s->ops->set_socket(s, &s->socket)) return CS_BAD_VPP; @@ -643,7 +642,7 @@ int pcmcia_request_configuration(struct pcmcia_device *p_dev, /* Set up CIS configuration registers */ base = c->ConfigBase = req->ConfigBase; - c->Present = c->CardValues = req->Present; + c->CardValues = req->Present; if (req->Present & PRESENT_COPY) { c->Copy = req->Copy; pcmcia_write_cis_mem(s, 1, (base + CISREG_SCR)>>1, 1, &c->Copy); @@ -690,10 +689,10 @@ int pcmcia_request_configuration(struct pcmcia_device *p_dev, if (c->state & CONFIG_IO_REQ) { iomap.speed = io_speed; for (i = 0; i < MAX_IO_WIN; i++) - if (s->io[i].NumPorts != 0) { + if (s->io[i].res) { iomap.map = i; iomap.flags = MAP_ACTIVE; - switch (s->io[i].Attributes & IO_DATA_PATH_WIDTH) { + switch (s->io[i].res->flags & IO_DATA_PATH_WIDTH) { case IO_DATA_PATH_WIDTH_16: iomap.flags |= MAP_16BIT; break; case IO_DATA_PATH_WIDTH_AUTO: @@ -701,15 +700,15 @@ int pcmcia_request_configuration(struct pcmcia_device *p_dev, default: break; } - iomap.start = s->io[i].BasePort; - iomap.stop = iomap.start + s->io[i].NumPorts - 1; + iomap.start = s->io[i].res->start; + iomap.stop = s->io[i].res->end; s->ops->set_io_map(s, &iomap); s->io[i].Config++; } } c->state |= CONFIG_LOCKED; - p_dev->state |= CLIENT_CONFIG_LOCKED; + p_dev->_locked = 1; return CS_SUCCESS; } /* pcmcia_request_configuration */ EXPORT_SYMBOL(pcmcia_request_configuration); @@ -730,7 +729,7 @@ int pcmcia_request_io(struct pcmcia_device *p_dev, io_req_t *req) if (!req) return CS_UNSUPPORTED_MODE; - c = CONFIG(p_dev); + c = p_dev->function_config; if (c->state & CONFIG_LOCKED) return CS_CONFIGURATION_LOCKED; if (c->state & CONFIG_IO_REQ) @@ -755,7 +754,7 @@ int pcmcia_request_io(struct pcmcia_device *p_dev, io_req_t *req) c->io = *req; c->state |= CONFIG_IO_REQ; - p_dev->state |= CLIENT_IO_REQ; + p_dev->_io = 1; return CS_SUCCESS; } /* pcmcia_request_io */ EXPORT_SYMBOL(pcmcia_request_io); @@ -786,7 +785,7 @@ int pcmcia_request_irq(struct pcmcia_device *p_dev, irq_req_t *req) if (!(s->state & SOCKET_PRESENT)) return CS_NO_CARD; - c = CONFIG(p_dev); + c = p_dev->function_config; if (c->state & CONFIG_LOCKED) return CS_CONFIGURATION_LOCKED; if (c->state & CONFIG_IRQ_REQ) @@ -851,7 +850,7 @@ int pcmcia_request_irq(struct pcmcia_device *p_dev, irq_req_t *req) s->irq.Config++; c->state |= CONFIG_IRQ_REQ; - p_dev->state |= CLIENT_IRQ_REQ; + p_dev->_irq = 1; #ifdef CONFIG_PCMCIA_PROBE pcmcia_used_irq[irq]++; @@ -911,7 +910,7 @@ int pcmcia_request_window(struct pcmcia_device **p_dev, win_req_t *req, window_h if (!win->ctl.res) return CS_IN_USE; } - (*p_dev)->state |= CLIENT_WIN_REQ(w); + (*p_dev)->_win |= CLIENT_WIN_REQ(w); /* Configure the socket controller */ win->ctl.map = w+1; @@ -941,3 +940,14 @@ int pcmcia_request_window(struct pcmcia_device **p_dev, win_req_t *req, window_h return CS_SUCCESS; } /* pcmcia_request_window */ EXPORT_SYMBOL(pcmcia_request_window); + +void pcmcia_disable_device(struct pcmcia_device *p_dev) { + pcmcia_release_configuration(p_dev); + pcmcia_release_io(p_dev, &p_dev->io); + pcmcia_release_irq(p_dev, &p_dev->irq); + if (&p_dev->win) + pcmcia_release_window(p_dev->win); + + p_dev->dev_node = NULL; +} +EXPORT_SYMBOL(pcmcia_disable_device); diff --git a/drivers/pcmcia/pd6729.c b/drivers/pcmcia/pd6729.c index f2789afb22b..16d1ea7b0a1 100644 --- a/drivers/pcmcia/pd6729.c +++ b/drivers/pcmcia/pd6729.c @@ -8,7 +8,6 @@ */ #include <linux/kernel.h> -#include <linux/config.h> #include <linux/module.h> #include <linux/pci.h> #include <linux/init.h> diff --git a/drivers/pcmcia/rsrc_mgr.c b/drivers/pcmcia/rsrc_mgr.c index 51460936983..81dfc2cac2b 100644 --- a/drivers/pcmcia/rsrc_mgr.c +++ b/drivers/pcmcia/rsrc_mgr.c @@ -12,7 +12,6 @@ * (C) 1999 David A. Hinds */ -#include <linux/config.h> #include <linux/module.h> #include <linux/kernel.h> @@ -22,6 +21,8 @@ #include "cs_internal.h" +#ifdef CONFIG_PCMCIA_IOCTL + #ifdef CONFIG_PCMCIA_PROBE static int adjust_irq(struct pcmcia_socket *s, adjust_t *adj) @@ -98,6 +99,8 @@ int pcmcia_adjust_resource_info(adjust_t *adj) } EXPORT_SYMBOL(pcmcia_adjust_resource_info); +#endif + int pcmcia_validate_mem(struct pcmcia_socket *s) { if (s->resource_ops->validate_mem) diff --git a/drivers/pcmcia/rsrc_nonstatic.c b/drivers/pcmcia/rsrc_nonstatic.c index 5301ac60358..0f8b157c971 100644 --- a/drivers/pcmcia/rsrc_nonstatic.c +++ b/drivers/pcmcia/rsrc_nonstatic.c @@ -12,7 +12,6 @@ * (C) 1999 David A. Hinds */ -#include <linux/config.h> #include <linux/module.h> #include <linux/moduleparam.h> #include <linux/init.h> @@ -61,7 +60,7 @@ struct socket_data { unsigned int rsrc_mem_probe; }; -static DECLARE_MUTEX(rsrc_sem); +static DEFINE_MUTEX(rsrc_mutex); #define MEM_PROBE_LOW (1 << 0) #define MEM_PROBE_HIGH (1 << 1) @@ -484,7 +483,7 @@ static int validate_mem(struct pcmcia_socket *s, unsigned int probe_mask) /* - * Locking note: Must be called with skt_sem held! + * Locking note: Must be called with skt_mutex held! */ static int pcmcia_nonstatic_validate_mem(struct pcmcia_socket *s) { @@ -495,7 +494,7 @@ static int pcmcia_nonstatic_validate_mem(struct pcmcia_socket *s) if (!probe_mem) return 0; - down(&rsrc_sem); + mutex_lock(&rsrc_mutex); if (s->features & SS_CAP_PAGE_REGS) probe_mask = MEM_PROBE_HIGH; @@ -507,7 +506,7 @@ static int pcmcia_nonstatic_validate_mem(struct pcmcia_socket *s) s_data->rsrc_mem_probe |= probe_mask; } - up(&rsrc_sem); + mutex_unlock(&rsrc_mutex); return ret; } @@ -585,7 +584,7 @@ static int nonstatic_adjust_io_region(struct resource *res, unsigned long r_star struct socket_data *s_data = s->resource_data; int ret = -ENOMEM; - down(&rsrc_sem); + mutex_lock(&rsrc_mutex); for (m = s_data->io_db.next; m != &s_data->io_db; m = m->next) { unsigned long start = m->base; unsigned long end = m->base + m->num - 1; @@ -596,7 +595,7 @@ static int nonstatic_adjust_io_region(struct resource *res, unsigned long r_star ret = adjust_resource(res, r_start, r_end - r_start + 1); break; } - up(&rsrc_sem); + mutex_unlock(&rsrc_mutex); return ret; } @@ -630,7 +629,7 @@ static struct resource *nonstatic_find_io_region(unsigned long base, int num, data.offset = base & data.mask; data.map = &s_data->io_db; - down(&rsrc_sem); + mutex_lock(&rsrc_mutex); #ifdef CONFIG_PCI if (s->cb_dev) { ret = pci_bus_alloc_resource(s->cb_dev->bus, res, num, 1, @@ -639,7 +638,7 @@ static struct resource *nonstatic_find_io_region(unsigned long base, int num, #endif ret = allocate_resource(&ioport_resource, res, num, min, ~0UL, 1, pcmcia_align, &data); - up(&rsrc_sem); + mutex_unlock(&rsrc_mutex); if (ret != 0) { kfree(res); @@ -672,7 +671,7 @@ static struct resource * nonstatic_find_mem_region(u_long base, u_long num, min = 0x100000UL + base; } - down(&rsrc_sem); + mutex_lock(&rsrc_mutex); #ifdef CONFIG_PCI if (s->cb_dev) { ret = pci_bus_alloc_resource(s->cb_dev->bus, res, num, @@ -682,7 +681,7 @@ static struct resource * nonstatic_find_mem_region(u_long base, u_long num, #endif ret = allocate_resource(&iomem_resource, res, num, min, max, 1, pcmcia_align, &data); - up(&rsrc_sem); + mutex_unlock(&rsrc_mutex); if (ret == 0 || low) break; low = 1; @@ -705,7 +704,7 @@ static int adjust_memory(struct pcmcia_socket *s, unsigned int action, unsigned if (end < start) return -EINVAL; - down(&rsrc_sem); + mutex_lock(&rsrc_mutex); switch (action) { case ADD_MANAGED_RESOURCE: ret = add_interval(&data->mem_db, start, size); @@ -723,7 +722,7 @@ static int adjust_memory(struct pcmcia_socket *s, unsigned int action, unsigned default: ret = -EINVAL; } - up(&rsrc_sem); + mutex_unlock(&rsrc_mutex); return ret; } @@ -741,7 +740,7 @@ static int adjust_io(struct pcmcia_socket *s, unsigned int action, unsigned long if (end > IO_SPACE_LIMIT) return -EINVAL; - down(&rsrc_sem); + mutex_lock(&rsrc_mutex); switch (action) { case ADD_MANAGED_RESOURCE: if (add_interval(&data->io_db, start, size) != 0) { @@ -760,7 +759,7 @@ static int adjust_io(struct pcmcia_socket *s, unsigned int action, unsigned long ret = -EINVAL; break; } - up(&rsrc_sem); + mutex_unlock(&rsrc_mutex); return ret; } @@ -867,7 +866,7 @@ static void nonstatic_release_resource_db(struct pcmcia_socket *s) struct socket_data *data = s->resource_data; struct resource_map *p, *q; - down(&rsrc_sem); + mutex_lock(&rsrc_mutex); for (p = data->mem_db.next; p != &data->mem_db; p = q) { q = p->next; kfree(p); @@ -876,7 +875,7 @@ static void nonstatic_release_resource_db(struct pcmcia_socket *s) q = p->next; kfree(p); } - up(&rsrc_sem); + mutex_unlock(&rsrc_mutex); } @@ -901,7 +900,7 @@ static ssize_t show_io_db(struct class_device *class_dev, char *buf) struct resource_map *p; ssize_t ret = 0; - down(&rsrc_sem); + mutex_lock(&rsrc_mutex); data = s->resource_data; for (p = data->io_db.next; p != &data->io_db; p = p->next) { @@ -913,7 +912,7 @@ static ssize_t show_io_db(struct class_device *class_dev, char *buf) ((unsigned long) p->base + p->num - 1)); } - up(&rsrc_sem); + mutex_unlock(&rsrc_mutex); return (ret); } @@ -953,7 +952,7 @@ static ssize_t show_mem_db(struct class_device *class_dev, char *buf) struct resource_map *p; ssize_t ret = 0; - down(&rsrc_sem); + mutex_lock(&rsrc_mutex); data = s->resource_data; for (p = data->mem_db.next; p != &data->mem_db; p = p->next) { @@ -965,7 +964,7 @@ static ssize_t show_mem_db(struct class_device *class_dev, char *buf) ((unsigned long) p->base + p->num - 1)); } - up(&rsrc_sem); + mutex_unlock(&rsrc_mutex); return (ret); } diff --git a/drivers/pcmcia/sa1100_cerf.c b/drivers/pcmcia/sa1100_cerf.c index 2b3c2895b43..eb89928f233 100644 --- a/drivers/pcmcia/sa1100_cerf.c +++ b/drivers/pcmcia/sa1100_cerf.c @@ -5,7 +5,6 @@ * Based off the Assabet. * */ -#include <linux/config.h> #include <linux/module.h> #include <linux/kernel.h> #include <linux/sched.h> diff --git a/drivers/pcmcia/socket_sysfs.c b/drivers/pcmcia/socket_sysfs.c index 5ab1cdef7c4..c5d7476da47 100644 --- a/drivers/pcmcia/socket_sysfs.c +++ b/drivers/pcmcia/socket_sysfs.c @@ -12,7 +12,6 @@ #include <linux/moduleparam.h> #include <linux/init.h> #include <linux/kernel.h> -#include <linux/config.h> #include <linux/string.h> #include <linux/major.h> #include <linux/errno.h> @@ -25,6 +24,7 @@ #include <linux/pm.h> #include <linux/pci.h> #include <linux/device.h> +#include <linux/mutex.h> #include <asm/system.h> #include <asm/irq.h> @@ -183,7 +183,7 @@ static ssize_t pccard_store_resource(struct class_device *dev, const char *buf, s->resource_setup_done = 1; spin_unlock_irqrestore(&s->lock, flags); - down(&s->skt_sem); + mutex_lock(&s->skt_mutex); if ((s->callback) && (s->state & SOCKET_PRESENT) && !(s->state & SOCKET_CARDBUS)) { @@ -192,7 +192,7 @@ static ssize_t pccard_store_resource(struct class_device *dev, const char *buf, module_put(s->callback->owner); } } - up(&s->skt_sem); + mutex_unlock(&s->skt_mutex); return count; } @@ -322,7 +322,7 @@ static ssize_t pccard_store_cis(struct kobject *kobj, char *buf, loff_t off, siz kfree(cis); if (!ret) { - down(&s->skt_sem); + mutex_lock(&s->skt_mutex); if ((s->callback) && (s->state & SOCKET_PRESENT) && !(s->state & SOCKET_CARDBUS)) { if (try_module_get(s->callback->owner)) { @@ -330,7 +330,7 @@ static ssize_t pccard_store_cis(struct kobject *kobj, char *buf, loff_t off, siz module_put(s->callback->owner); } } - up(&s->skt_sem); + mutex_unlock(&s->skt_mutex); } diff --git a/drivers/pcmcia/ti113x.h b/drivers/pcmcia/ti113x.h index d5b4ff74462..7a3d1b8e16b 100644 --- a/drivers/pcmcia/ti113x.h +++ b/drivers/pcmcia/ti113x.h @@ -30,7 +30,6 @@ #ifndef _LINUX_TI113X_H #define _LINUX_TI113X_H -#include <linux/config.h> /* Register definitions for TI 113X PCI-to-CardBus bridges */ diff --git a/drivers/pcmcia/vrc4171_card.c b/drivers/pcmcia/vrc4171_card.c index 0574efd7828..459e6e1946f 100644 --- a/drivers/pcmcia/vrc4171_card.c +++ b/drivers/pcmcia/vrc4171_card.c @@ -634,7 +634,7 @@ static void vrc4171_remove_sockets(void) static int __devinit vrc4171_card_setup(char *options) { if (options == NULL || *options == '\0') - return 0; + return 1; if (strncmp(options, "irq:", 4) == 0) { int irq; @@ -644,7 +644,7 @@ static int __devinit vrc4171_card_setup(char *options) vrc4171_irq = irq; if (*options != ',') - return 0; + return 1; options++; } @@ -663,10 +663,10 @@ static int __devinit vrc4171_card_setup(char *options) } if (*options != ',') - return 0; + return 1; options++; } else - return 0; + return 1; } @@ -688,7 +688,7 @@ static int __devinit vrc4171_card_setup(char *options) } if (*options != ',') - return 0; + return 1; options++; if (strncmp(options, "memnoprobe", 10) == 0) @@ -700,7 +700,7 @@ static int __devinit vrc4171_card_setup(char *options) } } - return 0; + return 1; } __setup("vrc4171_card=", vrc4171_card_setup); diff --git a/drivers/pcmcia/vrc4173_cardu.c b/drivers/pcmcia/vrc4173_cardu.c index 57f38dba0a4..6004196f7cc 100644 --- a/drivers/pcmcia/vrc4173_cardu.c +++ b/drivers/pcmcia/vrc4173_cardu.c @@ -516,7 +516,7 @@ static int __devinit vrc4173_cardu_probe(struct pci_dev *dev, static int __devinit vrc4173_cardu_setup(char *options) { if (options == NULL || *options == '\0') - return 0; + return 1; if (strncmp(options, "cardu1:", 7) == 0) { options += 7; @@ -527,9 +527,9 @@ static int __devinit vrc4173_cardu_setup(char *options) } if (*options != ',') - return 0; + return 1; } else - return 0; + return 1; } if (strncmp(options, "cardu2:", 7) == 0) { @@ -538,7 +538,7 @@ static int __devinit vrc4173_cardu_setup(char *options) cardu_sockets[CARDU2].noprobe = 1; } - return 0; + return 1; } __setup("vrc4173_cardu=", vrc4173_cardu_setup); diff --git a/drivers/scsi/ahci.c b/drivers/scsi/ahci.c index ffba65656a8..1bd82c4e52a 100644 --- a/drivers/scsi/ahci.c +++ b/drivers/scsi/ahci.c @@ -293,6 +293,10 @@ static const struct pci_device_id ahci_pci_tbl[] = { board_ahci }, /* JMicron JMB360 */ { 0x197b, 0x2363, PCI_ANY_ID, PCI_ANY_ID, 0, 0, board_ahci }, /* JMicron JMB363 */ + { PCI_VENDOR_ID_ATI, 0x4380, PCI_ANY_ID, PCI_ANY_ID, 0, 0, + board_ahci }, /* ATI SB600 non-raid */ + { PCI_VENDOR_ID_ATI, 0x4381, PCI_ANY_ID, PCI_ANY_ID, 0, 0, + board_ahci }, /* ATI SB600 raid */ { } /* terminate list */ }; diff --git a/drivers/scsi/ata_piix.c b/drivers/scsi/ata_piix.c index 2d5be84d8bd..24e71b55517 100644 --- a/drivers/scsi/ata_piix.c +++ b/drivers/scsi/ata_piix.c @@ -301,7 +301,7 @@ static struct piix_map_db ich6_map_db = { .mask = 0x3, .map = { /* PM PS SM SS MAP */ - { P0, P1, P2, P3 }, /* 00b */ + { P0, P2, P1, P3 }, /* 00b */ { IDE, IDE, P1, P3 }, /* 01b */ { P0, P2, IDE, IDE }, /* 10b */ { RV, RV, RV, RV }, @@ -312,7 +312,7 @@ static struct piix_map_db ich6m_map_db = { .mask = 0x3, .map = { /* PM PS SM SS MAP */ - { P0, P1, P2, P3 }, /* 00b */ + { P0, P2, RV, RV }, /* 00b */ { RV, RV, RV, RV }, { P0, P2, IDE, IDE }, /* 10b */ { RV, RV, RV, RV }, diff --git a/drivers/scsi/ibmmca.c b/drivers/scsi/ibmmca.c index 3a8462e8d06..24eb59e143a 100644 --- a/drivers/scsi/ibmmca.c +++ b/drivers/scsi/ibmmca.c @@ -2488,7 +2488,7 @@ static int option_setup(char *str) } ints[0] = i - 1; internal_ibmmca_scsi_setup(cur, ints); - return 0; + return 1; } __setup("ibmmcascsi=", option_setup); diff --git a/drivers/scsi/ibmvscsi/rpa_vscsi.c b/drivers/scsi/ibmvscsi/rpa_vscsi.c index f47dd87c05e..892e8ed6309 100644 --- a/drivers/scsi/ibmvscsi/rpa_vscsi.c +++ b/drivers/scsi/ibmvscsi/rpa_vscsi.c @@ -80,7 +80,7 @@ void ibmvscsi_release_crq_queue(struct crq_queue *queue, tasklet_kill(&hostdata->srp_task); do { rc = plpar_hcall_norets(H_FREE_CRQ, vdev->unit_address); - } while ((rc == H_Busy) || (H_isLongBusy(rc))); + } while ((rc == H_BUSY) || (H_IS_LONG_BUSY(rc))); dma_unmap_single(hostdata->dev, queue->msg_token, queue->size * sizeof(*queue->msgs), DMA_BIDIRECTIONAL); @@ -230,7 +230,7 @@ int ibmvscsi_init_crq_queue(struct crq_queue *queue, rc = plpar_hcall_norets(H_REG_CRQ, vdev->unit_address, queue->msg_token, PAGE_SIZE); - if (rc == H_Resource) + if (rc == H_RESOURCE) /* maybe kexecing and resource is busy. try a reset */ rc = ibmvscsi_reset_crq_queue(queue, hostdata); @@ -269,7 +269,7 @@ int ibmvscsi_init_crq_queue(struct crq_queue *queue, req_irq_failed: do { rc = plpar_hcall_norets(H_FREE_CRQ, vdev->unit_address); - } while ((rc == H_Busy) || (H_isLongBusy(rc))); + } while ((rc == H_BUSY) || (H_IS_LONG_BUSY(rc))); reg_crq_failed: dma_unmap_single(hostdata->dev, queue->msg_token, @@ -295,7 +295,7 @@ int ibmvscsi_reenable_crq_queue(struct crq_queue *queue, /* Re-enable the CRQ */ do { rc = plpar_hcall_norets(H_ENABLE_CRQ, vdev->unit_address); - } while ((rc == H_InProgress) || (rc == H_Busy) || (H_isLongBusy(rc))); + } while ((rc == H_IN_PROGRESS) || (rc == H_BUSY) || (H_IS_LONG_BUSY(rc))); if (rc) printk(KERN_ERR "ibmvscsi: Error %d enabling adapter\n", rc); @@ -317,7 +317,7 @@ int ibmvscsi_reset_crq_queue(struct crq_queue *queue, /* Close the CRQ */ do { rc = plpar_hcall_norets(H_FREE_CRQ, vdev->unit_address); - } while ((rc == H_Busy) || (H_isLongBusy(rc))); + } while ((rc == H_BUSY) || (H_IS_LONG_BUSY(rc))); /* Clean out the queue */ memset(queue->msgs, 0x00, PAGE_SIZE); diff --git a/drivers/scsi/lasi700.c b/drivers/scsi/lasi700.c index 459a4daebec..eb7bd310cc8 100644 --- a/drivers/scsi/lasi700.c +++ b/drivers/scsi/lasi700.c @@ -112,7 +112,7 @@ lasi700_probe(struct parisc_device *dev) hostdata->dev = &dev->dev; dma_set_mask(&dev->dev, DMA_32BIT_MASK); - hostdata->base = ioremap(base, 0x100); + hostdata->base = ioremap_nocache(base, 0x100); hostdata->differential = 0; if (dev->id.sversion == LASI_700_SVERSION) { diff --git a/drivers/scsi/libata-core.c b/drivers/scsi/libata-core.c index 21b0ed583b8..e63c1ff1e10 100644 --- a/drivers/scsi/libata-core.c +++ b/drivers/scsi/libata-core.c @@ -278,7 +278,7 @@ static void ata_unpack_xfermask(unsigned int xfer_mask, } static const struct ata_xfer_ent { - unsigned int shift, bits; + int shift, bits; u8 base; } ata_xfer_tbl[] = { { ATA_SHIFT_PIO, ATA_BITS_PIO, XFER_PIO_0 }, @@ -989,9 +989,7 @@ ata_exec_internal(struct ata_port *ap, struct ata_device *dev, qc->private_data = &wait; qc->complete_fn = ata_qc_complete_internal; - qc->err_mask = ata_qc_issue(qc); - if (qc->err_mask) - ata_qc_complete(qc); + ata_qc_issue(qc); spin_unlock_irqrestore(&ap->host_set->lock, flags); @@ -3997,15 +3995,14 @@ static inline int ata_should_dma_map(struct ata_queued_cmd *qc) * * LOCKING: * spin_lock_irqsave(host_set lock) - * - * RETURNS: - * Zero on success, AC_ERR_* mask on failure */ - -unsigned int ata_qc_issue(struct ata_queued_cmd *qc) +void ata_qc_issue(struct ata_queued_cmd *qc) { struct ata_port *ap = qc->ap; + qc->ap->active_tag = qc->tag; + qc->flags |= ATA_QCFLAG_ACTIVE; + if (ata_should_dma_map(qc)) { if (qc->flags & ATA_QCFLAG_SG) { if (ata_sg_setup(qc)) @@ -4020,17 +4017,18 @@ unsigned int ata_qc_issue(struct ata_queued_cmd *qc) ap->ops->qc_prep(qc); - qc->ap->active_tag = qc->tag; - qc->flags |= ATA_QCFLAG_ACTIVE; - - return ap->ops->qc_issue(qc); + qc->err_mask |= ap->ops->qc_issue(qc); + if (unlikely(qc->err_mask)) + goto err; + return; sg_err: qc->flags &= ~ATA_QCFLAG_DMAMAP; - return AC_ERR_SYSTEM; + qc->err_mask |= AC_ERR_SYSTEM; +err: + ata_qc_complete(qc); } - /** * ata_qc_issue_prot - issue taskfile to device in proto-dependent manner * @qc: command to issue to device diff --git a/drivers/scsi/libata-scsi.c b/drivers/scsi/libata-scsi.c index 628191bfd99..53f5b0d9161 100644 --- a/drivers/scsi/libata-scsi.c +++ b/drivers/scsi/libata-scsi.c @@ -1431,9 +1431,7 @@ static void ata_scsi_translate(struct ata_port *ap, struct ata_device *dev, goto early_finish; /* select device, send command to hardware */ - qc->err_mask = ata_qc_issue(qc); - if (qc->err_mask) - ata_qc_complete(qc); + ata_qc_issue(qc); VPRINTK("EXIT\n"); return; @@ -2199,9 +2197,7 @@ static void atapi_request_sense(struct ata_queued_cmd *qc) qc->complete_fn = atapi_sense_complete; - qc->err_mask = ata_qc_issue(qc); - if (qc->err_mask) - ata_qc_complete(qc); + ata_qc_issue(qc); DPRINTK("EXIT\n"); } diff --git a/drivers/scsi/libata.h b/drivers/scsi/libata.h index 65f52beea88..1c755b14521 100644 --- a/drivers/scsi/libata.h +++ b/drivers/scsi/libata.h @@ -47,7 +47,7 @@ extern struct ata_queued_cmd *ata_qc_new_init(struct ata_port *ap, extern int ata_rwcmd_protocol(struct ata_queued_cmd *qc); extern void ata_port_flush_task(struct ata_port *ap); extern void ata_qc_free(struct ata_queued_cmd *qc); -extern unsigned int ata_qc_issue(struct ata_queued_cmd *qc); +extern void ata_qc_issue(struct ata_queued_cmd *qc); extern int ata_check_atapi_dma(struct ata_queued_cmd *qc); extern void ata_dev_select(struct ata_port *ap, unsigned int device, unsigned int wait, unsigned int can_sleep); diff --git a/drivers/scsi/pcmcia/aha152x_stub.c b/drivers/scsi/pcmcia/aha152x_stub.c index 5609847e254..ee449b29fc8 100644 --- a/drivers/scsi/pcmcia/aha152x_stub.c +++ b/drivers/scsi/pcmcia/aha152x_stub.c @@ -89,29 +89,29 @@ MODULE_LICENSE("Dual MPL/GPL"); /*====================================================================*/ typedef struct scsi_info_t { - dev_link_t link; + struct pcmcia_device *p_dev; dev_node_t node; struct Scsi_Host *host; } scsi_info_t; -static void aha152x_release_cs(dev_link_t *link); +static void aha152x_release_cs(struct pcmcia_device *link); static void aha152x_detach(struct pcmcia_device *p_dev); -static void aha152x_config_cs(dev_link_t *link); +static int aha152x_config_cs(struct pcmcia_device *link); -static dev_link_t *dev_list; +static struct pcmcia_device *dev_list; -static int aha152x_attach(struct pcmcia_device *p_dev) +static int aha152x_probe(struct pcmcia_device *link) { scsi_info_t *info; - dev_link_t *link; - + DEBUG(0, "aha152x_attach()\n"); /* Create new SCSI device */ info = kmalloc(sizeof(*info), GFP_KERNEL); if (!info) return -ENOMEM; memset(info, 0, sizeof(*info)); - link = &info->link; link->priv = info; + info->p_dev = link; + link->priv = info; link->io.NumPorts1 = 0x20; link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO; @@ -119,41 +119,22 @@ static int aha152x_attach(struct pcmcia_device *p_dev) link->irq.Attributes = IRQ_TYPE_EXCLUSIVE; link->irq.IRQInfo1 = IRQ_LEVEL_ID; link->conf.Attributes = CONF_ENABLE_IRQ; - link->conf.Vcc = 50; link->conf.IntType = INT_MEMORY_AND_IO; link->conf.Present = PRESENT_OPTION; - link->handle = p_dev; - p_dev->instance = link; - - link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; - aha152x_config_cs(link); - - return 0; + return aha152x_config_cs(link); } /* aha152x_attach */ /*====================================================================*/ -static void aha152x_detach(struct pcmcia_device *p_dev) +static void aha152x_detach(struct pcmcia_device *link) { - dev_link_t *link = dev_to_instance(p_dev); - dev_link_t **linkp; - DEBUG(0, "aha152x_detach(0x%p)\n", link); - - /* Locate device structure */ - for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next) - if (*linkp == link) break; - if (*linkp == NULL) - return; - if (link->state & DEV_CONFIG) - aha152x_release_cs(link); + aha152x_release_cs(link); /* Unlink device structure, free bits */ - *linkp = link->next; kfree(link->priv); - } /* aha152x_detach */ /*====================================================================*/ @@ -161,9 +142,8 @@ static void aha152x_detach(struct pcmcia_device *p_dev) #define CS_CHECK(fn, ret) \ do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0) -static void aha152x_config_cs(dev_link_t *link) +static int aha152x_config_cs(struct pcmcia_device *link) { - client_handle_t handle = link->handle; scsi_info_t *info = link->priv; struct aha152x_setup s; tuple_t tuple; @@ -178,19 +158,16 @@ static void aha152x_config_cs(dev_link_t *link) tuple.TupleData = tuple_data; tuple.TupleDataMax = 64; tuple.TupleOffset = 0; - CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple)); - CS_CHECK(GetTupleData, pcmcia_get_tuple_data(handle, &tuple)); - CS_CHECK(ParseTuple, pcmcia_parse_tuple(handle, &tuple, &parse)); + CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); + CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple)); + CS_CHECK(ParseTuple, pcmcia_parse_tuple(link, &tuple, &parse)); link->conf.ConfigBase = parse.config.base; - /* Configure card */ - link->state |= DEV_CONFIG; - tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; - CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple)); + CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); while (1) { - if (pcmcia_get_tuple_data(handle, &tuple) != 0 || - pcmcia_parse_tuple(handle, &tuple, &parse) != 0) + if (pcmcia_get_tuple_data(link, &tuple) != 0 || + pcmcia_parse_tuple(link, &tuple, &parse) != 0) goto next_entry; /* For New Media T&J, look for a SCSI window */ if (parse.cftable_entry.io.win[0].len >= 0x20) @@ -201,15 +178,15 @@ static void aha152x_config_cs(dev_link_t *link) if ((parse.cftable_entry.io.nwin > 0) && (link->io.BasePort1 < 0xffff)) { link->conf.ConfigIndex = parse.cftable_entry.index; - i = pcmcia_request_io(handle, &link->io); + i = pcmcia_request_io(link, &link->io); if (i == CS_SUCCESS) break; } next_entry: - CS_CHECK(GetNextTuple, pcmcia_get_next_tuple(handle, &tuple)); + CS_CHECK(GetNextTuple, pcmcia_get_next_tuple(link, &tuple)); } - CS_CHECK(RequestIRQ, pcmcia_request_irq(handle, &link->irq)); - CS_CHECK(RequestConfiguration, pcmcia_request_configuration(handle, &link->conf)); + CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq)); + CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf)); /* Set configuration options for the aha152x driver */ memset(&s, 0, sizeof(s)); @@ -231,53 +208,30 @@ static void aha152x_config_cs(dev_link_t *link) } sprintf(info->node.dev_name, "scsi%d", host->host_no); - link->dev = &info->node; + link->dev_node = &info->node; info->host = host; - link->state &= ~DEV_CONFIG_PENDING; - return; - + return 0; + cs_failed: - cs_error(link->handle, last_fn, last_ret); + cs_error(link, last_fn, last_ret); aha152x_release_cs(link); - return; + return -ENODEV; } -static void aha152x_release_cs(dev_link_t *link) +static void aha152x_release_cs(struct pcmcia_device *link) { scsi_info_t *info = link->priv; aha152x_release(info->host); - link->dev = NULL; - - pcmcia_release_configuration(link->handle); - pcmcia_release_io(link->handle, &link->io); - pcmcia_release_irq(link->handle, &link->irq); - - link->state &= ~DEV_CONFIG; + pcmcia_disable_device(link); } -static int aha152x_suspend(struct pcmcia_device *dev) +static int aha152x_resume(struct pcmcia_device *link) { - dev_link_t *link = dev_to_instance(dev); - - link->state |= DEV_SUSPEND; - if (link->state & DEV_CONFIG) - pcmcia_release_configuration(link->handle); - - return 0; -} - -static int aha152x_resume(struct pcmcia_device *dev) -{ - dev_link_t *link = dev_to_instance(dev); scsi_info_t *info = link->priv; - link->state &= ~DEV_SUSPEND; - if (link->state & DEV_CONFIG) { - pcmcia_request_configuration(link->handle, &link->conf); - aha152x_host_reset_host(info->host); - } + aha152x_host_reset_host(info->host); return 0; } @@ -297,10 +251,9 @@ static struct pcmcia_driver aha152x_cs_driver = { .drv = { .name = "aha152x_cs", }, - .probe = aha152x_attach, + .probe = aha152x_probe, .remove = aha152x_detach, .id_table = aha152x_ids, - .suspend = aha152x_suspend, .resume = aha152x_resume, }; @@ -317,4 +270,3 @@ static void __exit exit_aha152x_cs(void) module_init(init_aha152x_cs); module_exit(exit_aha152x_cs); - diff --git a/drivers/scsi/pcmcia/fdomain_stub.c b/drivers/scsi/pcmcia/fdomain_stub.c index 788c58d805f..85f7ffac19a 100644 --- a/drivers/scsi/pcmcia/fdomain_stub.c +++ b/drivers/scsi/pcmcia/fdomain_stub.c @@ -73,57 +73,48 @@ static char *version = /*====================================================================*/ typedef struct scsi_info_t { - dev_link_t link; + struct pcmcia_device *p_dev; dev_node_t node; struct Scsi_Host *host; } scsi_info_t; -static void fdomain_release(dev_link_t *link); +static void fdomain_release(struct pcmcia_device *link); static void fdomain_detach(struct pcmcia_device *p_dev); -static void fdomain_config(dev_link_t *link); +static int fdomain_config(struct pcmcia_device *link); -static int fdomain_attach(struct pcmcia_device *p_dev) +static int fdomain_probe(struct pcmcia_device *link) { - scsi_info_t *info; - dev_link_t *link; - - DEBUG(0, "fdomain_attach()\n"); - - /* Create new SCSI device */ - info = kmalloc(sizeof(*info), GFP_KERNEL); - if (!info) return -ENOMEM; - memset(info, 0, sizeof(*info)); - link = &info->link; link->priv = info; - link->io.NumPorts1 = 0x10; - link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO; - link->io.IOAddrLines = 10; - link->irq.Attributes = IRQ_TYPE_EXCLUSIVE; - link->irq.IRQInfo1 = IRQ_LEVEL_ID; - link->conf.Attributes = CONF_ENABLE_IRQ; - link->conf.Vcc = 50; - link->conf.IntType = INT_MEMORY_AND_IO; - link->conf.Present = PRESENT_OPTION; - - link->handle = p_dev; - p_dev->instance = link; - - link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; - fdomain_config(link); - - return 0; + scsi_info_t *info; + + DEBUG(0, "fdomain_attach()\n"); + + /* Create new SCSI device */ + info = kzalloc(sizeof(*info), GFP_KERNEL); + if (!info) + return -ENOMEM; + + info->p_dev = link; + link->priv = info; + link->io.NumPorts1 = 0x10; + link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO; + link->io.IOAddrLines = 10; + link->irq.Attributes = IRQ_TYPE_EXCLUSIVE; + link->irq.IRQInfo1 = IRQ_LEVEL_ID; + link->conf.Attributes = CONF_ENABLE_IRQ; + link->conf.IntType = INT_MEMORY_AND_IO; + link->conf.Present = PRESENT_OPTION; + + return fdomain_config(link); } /* fdomain_attach */ /*====================================================================*/ -static void fdomain_detach(struct pcmcia_device *p_dev) +static void fdomain_detach(struct pcmcia_device *link) { - dev_link_t *link = dev_to_instance(p_dev); - DEBUG(0, "fdomain_detach(0x%p)\n", link); - if (link->state & DEV_CONFIG) - fdomain_release(link); + fdomain_release(link); kfree(link->priv); } /* fdomain_detach */ @@ -133,9 +124,8 @@ static void fdomain_detach(struct pcmcia_device *p_dev) #define CS_CHECK(fn, ret) \ do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0) -static void fdomain_config(dev_link_t *link) +static int fdomain_config(struct pcmcia_device *link) { - client_handle_t handle = link->handle; scsi_info_t *info = link->priv; tuple_t tuple; cisparse_t parse; @@ -150,103 +140,75 @@ static void fdomain_config(dev_link_t *link) tuple.TupleData = tuple_data; tuple.TupleDataMax = 64; tuple.TupleOffset = 0; - CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple)); - CS_CHECK(GetTupleData, pcmcia_get_tuple_data(handle, &tuple)); - CS_CHECK(ParseTuple, pcmcia_parse_tuple(handle, &tuple, &parse)); + CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); + CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple)); + CS_CHECK(ParseTuple, pcmcia_parse_tuple(link, &tuple, &parse)); link->conf.ConfigBase = parse.config.base; - /* Configure card */ - link->state |= DEV_CONFIG; - tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; - CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple)); + CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); while (1) { - if (pcmcia_get_tuple_data(handle, &tuple) != 0 || - pcmcia_parse_tuple(handle, &tuple, &parse) != 0) + if (pcmcia_get_tuple_data(link, &tuple) != 0 || + pcmcia_parse_tuple(link, &tuple, &parse) != 0) goto next_entry; link->conf.ConfigIndex = parse.cftable_entry.index; link->io.BasePort1 = parse.cftable_entry.io.win[0].base; - i = pcmcia_request_io(handle, &link->io); + i = pcmcia_request_io(link, &link->io); if (i == CS_SUCCESS) break; next_entry: - CS_CHECK(GetNextTuple, pcmcia_get_next_tuple(handle, &tuple)); + CS_CHECK(GetNextTuple, pcmcia_get_next_tuple(link, &tuple)); } - CS_CHECK(RequestIRQ, pcmcia_request_irq(handle, &link->irq)); - CS_CHECK(RequestConfiguration, pcmcia_request_configuration(handle, &link->conf)); - + CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq)); + CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf)); + /* A bad hack... */ release_region(link->io.BasePort1, link->io.NumPorts1); /* Set configuration options for the fdomain driver */ sprintf(str, "%d,%d", link->io.BasePort1, link->irq.AssignedIRQ); fdomain_setup(str); - + host = __fdomain_16x0_detect(&fdomain_driver_template); if (!host) { printk(KERN_INFO "fdomain_cs: no SCSI devices found\n"); goto cs_failed; } - - scsi_add_host(host, NULL); /* XXX handle failure */ + + if (scsi_add_host(host, NULL)) + goto cs_failed; scsi_scan_host(host); sprintf(info->node.dev_name, "scsi%d", host->host_no); - link->dev = &info->node; + link->dev_node = &info->node; info->host = host; - - link->state &= ~DEV_CONFIG_PENDING; - return; - + + return 0; + cs_failed: - cs_error(link->handle, last_fn, last_ret); + cs_error(link, last_fn, last_ret); fdomain_release(link); - return; - + return -ENODEV; } /* fdomain_config */ /*====================================================================*/ -static void fdomain_release(dev_link_t *link) +static void fdomain_release(struct pcmcia_device *link) { - scsi_info_t *info = link->priv; + scsi_info_t *info = link->priv; - DEBUG(0, "fdomain_release(0x%p)\n", link); + DEBUG(0, "fdomain_release(0x%p)\n", link); - scsi_remove_host(info->host); - link->dev = NULL; - - pcmcia_release_configuration(link->handle); - pcmcia_release_io(link->handle, &link->io); - pcmcia_release_irq(link->handle, &link->irq); - - scsi_unregister(info->host); - - link->state &= ~DEV_CONFIG; + scsi_remove_host(info->host); + pcmcia_disable_device(link); + scsi_unregister(info->host); } /*====================================================================*/ -static int fdomain_suspend(struct pcmcia_device *dev) +static int fdomain_resume(struct pcmcia_device *link) { - dev_link_t *link = dev_to_instance(dev); - - link->state |= DEV_SUSPEND; - if (link->state & DEV_CONFIG) - pcmcia_release_configuration(link->handle); - - return 0; -} - -static int fdomain_resume(struct pcmcia_device *dev) -{ - dev_link_t *link = dev_to_instance(dev); - - link->state &= ~DEV_SUSPEND; - if (link->state & DEV_CONFIG) { - pcmcia_request_configuration(link->handle, &link->conf); - fdomain_16x0_bus_reset(NULL); - } + fdomain_16x0_bus_reset(NULL); return 0; } @@ -264,10 +226,9 @@ static struct pcmcia_driver fdomain_cs_driver = { .drv = { .name = "fdomain_cs", }, - .probe = fdomain_attach, + .probe = fdomain_probe, .remove = fdomain_detach, .id_table = fdomain_ids, - .suspend = fdomain_suspend, .resume = fdomain_resume, }; diff --git a/drivers/scsi/pcmcia/nsp_cs.c b/drivers/scsi/pcmcia/nsp_cs.c index 9e3ab3fd535..231f9c311c6 100644 --- a/drivers/scsi/pcmcia/nsp_cs.c +++ b/drivers/scsi/pcmcia/nsp_cs.c @@ -1593,11 +1593,11 @@ static int nsp_eh_host_reset(Scsi_Cmnd *SCpnt) configure the card at this point -- we wait until we receive a card insertion event. ======================================================================*/ -static int nsp_cs_attach(struct pcmcia_device *p_dev) +static int nsp_cs_probe(struct pcmcia_device *link) { scsi_info_t *info; - dev_link_t *link; nsp_hw_data *data = &nsp_data_base; + int ret; nsp_dbg(NSP_DEBUG_INIT, "in"); @@ -1605,7 +1605,7 @@ static int nsp_cs_attach(struct pcmcia_device *p_dev) info = kmalloc(sizeof(*info), GFP_KERNEL); if (info == NULL) { return -ENOMEM; } memset(info, 0, sizeof(*info)); - link = &info->link; + info->p_dev = link; link->priv = info; data->ScsiInfo = info; @@ -1627,18 +1627,13 @@ static int nsp_cs_attach(struct pcmcia_device *p_dev) /* General socket configuration */ link->conf.Attributes = CONF_ENABLE_IRQ; - link->conf.Vcc = 50; link->conf.IntType = INT_MEMORY_AND_IO; link->conf.Present = PRESENT_OPTION; - link->handle = p_dev; - p_dev->instance = link; - - link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; - nsp_cs_config(link); + ret = nsp_cs_config(link); nsp_dbg(NSP_DEBUG_INIT, "link=0x%p", link); - return 0; + return ret; } /* nsp_cs_attach */ @@ -1648,16 +1643,12 @@ static int nsp_cs_attach(struct pcmcia_device *p_dev) structures are freed. Otherwise, the structures will be freed when the device is released. ======================================================================*/ -static void nsp_cs_detach(struct pcmcia_device *p_dev) +static void nsp_cs_detach(struct pcmcia_device *link) { - dev_link_t *link = dev_to_instance(p_dev); - nsp_dbg(NSP_DEBUG_INIT, "in, link=0x%p", link); - if (link->state & DEV_CONFIG) { - ((scsi_info_t *)link->priv)->stop = 1; - nsp_cs_release(link); - } + ((scsi_info_t *)link->priv)->stop = 1; + nsp_cs_release(link); kfree(link->priv); link->priv = NULL; @@ -1672,9 +1663,9 @@ static void nsp_cs_detach(struct pcmcia_device *p_dev) #define CS_CHECK(fn, ret) \ do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0) /*====================================================================*/ -static void nsp_cs_config(dev_link_t *link) +static int nsp_cs_config(struct pcmcia_device *link) { - client_handle_t handle = link->handle; + int ret; scsi_info_t *info = link->priv; tuple_t tuple; cisparse_t parse; @@ -1698,26 +1689,22 @@ static void nsp_cs_config(dev_link_t *link) tuple.TupleData = tuple_data; tuple.TupleDataMax = sizeof(tuple_data); tuple.TupleOffset = 0; - CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple)); - CS_CHECK(GetTupleData, pcmcia_get_tuple_data(handle, &tuple)); - CS_CHECK(ParseTuple, pcmcia_parse_tuple(handle, &tuple, &parse)); + CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); + CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple)); + CS_CHECK(ParseTuple, pcmcia_parse_tuple(link, &tuple, &parse)); link->conf.ConfigBase = parse.config.base; link->conf.Present = parse.config.rmask[0]; - /* Configure card */ - link->state |= DEV_CONFIG; - /* Look up the current Vcc */ - CS_CHECK(GetConfigurationInfo, pcmcia_get_configuration_info(handle, &conf)); - link->conf.Vcc = conf.Vcc; + CS_CHECK(GetConfigurationInfo, pcmcia_get_configuration_info(link, &conf)); tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; - CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple)); + CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); while (1) { cistpl_cftable_entry_t *cfg = &(parse.cftable_entry); - if (pcmcia_get_tuple_data(handle, &tuple) != 0 || - pcmcia_parse_tuple(handle, &tuple, &parse) != 0) + if (pcmcia_get_tuple_data(link, &tuple) != 0 || + pcmcia_parse_tuple(link, &tuple, &parse) != 0) goto next_entry; if (cfg->flags & CISTPL_CFTABLE_DEFAULT) { dflt = *cfg; } @@ -1743,10 +1730,10 @@ static void nsp_cs_config(dev_link_t *link) } if (cfg->vpp1.present & (1 << CISTPL_POWER_VNOM)) { - link->conf.Vpp1 = link->conf.Vpp2 = + link->conf.Vpp = cfg->vpp1.param[CISTPL_POWER_VNOM] / 10000; } else if (dflt.vpp1.present & (1 << CISTPL_POWER_VNOM)) { - link->conf.Vpp1 = link->conf.Vpp2 = + link->conf.Vpp = dflt.vpp1.param[CISTPL_POWER_VNOM] / 10000; } @@ -1773,7 +1760,7 @@ static void nsp_cs_config(dev_link_t *link) link->io.NumPorts2 = io->win[1].len; } /* This reserves IO space but doesn't actually enable it */ - if (pcmcia_request_io(link->handle, &link->io) != 0) + if (pcmcia_request_io(link, &link->io) != 0) goto next_entry; } @@ -1788,7 +1775,7 @@ static void nsp_cs_config(dev_link_t *link) req.Size = 0x1000; } req.AccessSpeed = 0; - if (pcmcia_request_window(&link->handle, &req, &link->win) != 0) + if (pcmcia_request_window(&link, &req, &link->win) != 0) goto next_entry; map.Page = 0; map.CardOffset = mem->win[0].card_addr; if (pcmcia_map_mem_page(link->win, &map) != 0) @@ -1802,17 +1789,14 @@ static void nsp_cs_config(dev_link_t *link) next_entry: nsp_dbg(NSP_DEBUG_INIT, "next"); - - if (link->io.NumPorts1) { - pcmcia_release_io(link->handle, &link->io); - } - CS_CHECK(GetNextTuple, pcmcia_get_next_tuple(handle, &tuple)); + pcmcia_disable_device(link); + CS_CHECK(GetNextTuple, pcmcia_get_next_tuple(link, &tuple)); } if (link->conf.Attributes & CONF_ENABLE_IRQ) { - CS_CHECK(RequestIRQ, pcmcia_request_irq(link->handle, &link->irq)); + CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq)); } - CS_CHECK(RequestConfiguration, pcmcia_request_configuration(handle, &link->conf)); + CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf)); if (free_ports) { if (link->io.BasePort1) { @@ -1854,16 +1838,19 @@ static void nsp_cs_config(dev_link_t *link) #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,74)) - scsi_add_host (host, NULL); + ret = scsi_add_host (host, NULL); + if (ret) + goto cs_failed; + scsi_scan_host(host); snprintf(info->node.dev_name, sizeof(info->node.dev_name), "scsi%d", host->host_no); - link->dev = &info->node; + link->dev_node = &info->node; info->host = host; #else nsp_dbg(NSP_DEBUG_INIT, "GET_SCSI_INFO"); - tail = &link->dev; + tail = &link->dev_node; info->ndev = 0; nsp_dbg(NSP_DEBUG_INIT, "host=0x%p", host); @@ -1908,11 +1895,10 @@ static void nsp_cs_config(dev_link_t *link) #endif /* Finally, report what we've done */ - printk(KERN_INFO "nsp_cs: index 0x%02x: Vcc %d.%d", - link->conf.ConfigIndex, - link->conf.Vcc/10, link->conf.Vcc%10); - if (link->conf.Vpp1) { - printk(", Vpp %d.%d", link->conf.Vpp1/10, link->conf.Vpp1%10); + printk(KERN_INFO "nsp_cs: index 0x%02x: ", + link->conf.ConfigIndex); + if (link->conf.Vpp) { + printk(", Vpp %d.%d", link->conf.Vpp/10, link->conf.Vpp%10); } if (link->conf.Attributes & CONF_ENABLE_IRQ) { printk(", irq %d", link->irq.AssignedIRQ); @@ -1929,15 +1915,14 @@ static void nsp_cs_config(dev_link_t *link) req.Base+req.Size-1); printk("\n"); - link->state &= ~DEV_CONFIG_PENDING; - return; + return 0; cs_failed: nsp_dbg(NSP_DEBUG_INIT, "config fail"); - cs_error(link->handle, last_fn, last_ret); + cs_error(link, last_fn, last_ret); nsp_cs_release(link); - return; + return -ENODEV; } /* nsp_cs_config */ #undef CS_CHECK @@ -1947,7 +1932,7 @@ static void nsp_cs_config(dev_link_t *link) device, and release the PCMCIA configuration. If the device is still open, this will be postponed until it is closed. ======================================================================*/ -static void nsp_cs_release(dev_link_t *link) +static void nsp_cs_release(struct pcmcia_device *link) { scsi_info_t *info = link->priv; nsp_hw_data *data = NULL; @@ -1968,22 +1953,15 @@ static void nsp_cs_release(dev_link_t *link) #else scsi_unregister_host(&nsp_driver_template); #endif - link->dev = NULL; + link->dev_node = NULL; if (link->win) { if (data != NULL) { iounmap((void *)(data->MmioAddress)); } - pcmcia_release_window(link->win); - } - pcmcia_release_configuration(link->handle); - if (link->io.NumPorts1) { - pcmcia_release_io(link->handle, &link->io); } - if (link->irq.AssignedIRQ) { - pcmcia_release_irq(link->handle, &link->irq); - } - link->state &= ~DEV_CONFIG; + pcmcia_disable_device(link); + #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,2)) if (info->host != NULL) { scsi_host_put(info->host); @@ -1991,14 +1969,11 @@ static void nsp_cs_release(dev_link_t *link) #endif } /* nsp_cs_release */ -static int nsp_cs_suspend(struct pcmcia_device *dev) +static int nsp_cs_suspend(struct pcmcia_device *link) { - dev_link_t *link = dev_to_instance(dev); scsi_info_t *info = link->priv; nsp_hw_data *data; - link->state |= DEV_SUSPEND; - nsp_dbg(NSP_DEBUG_INIT, "event: suspend"); if (info->host != NULL) { @@ -2011,25 +1986,16 @@ static int nsp_cs_suspend(struct pcmcia_device *dev) info->stop = 1; - if (link->state & DEV_CONFIG) - pcmcia_release_configuration(link->handle); - return 0; } -static int nsp_cs_resume(struct pcmcia_device *dev) +static int nsp_cs_resume(struct pcmcia_device *link) { - dev_link_t *link = dev_to_instance(dev); scsi_info_t *info = link->priv; nsp_hw_data *data; nsp_dbg(NSP_DEBUG_INIT, "event: resume"); - link->state &= ~DEV_SUSPEND; - - if (link->state & DEV_CONFIG) - pcmcia_request_configuration(link->handle, &link->conf); - info->stop = 0; if (info->host != NULL) { @@ -2065,7 +2031,7 @@ static struct pcmcia_driver nsp_driver = { .drv = { .name = "nsp_cs", }, - .probe = nsp_cs_attach, + .probe = nsp_cs_probe, .remove = nsp_cs_detach, .id_table = nsp_cs_ids, .suspend = nsp_cs_suspend, @@ -2098,19 +2064,7 @@ static int __init nsp_cs_init(void) static void __exit nsp_cs_exit(void) { nsp_msg(KERN_INFO, "unloading..."); - -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,68)) pcmcia_unregister_driver(&nsp_driver); -#else - unregister_pcmcia_driver(&dev_info); - /* XXX: this really needs to move into generic code.. */ - while (dev_list != NULL) { - if (dev_list->state & DEV_CONFIG) { - nsp_cs_release(dev_list); - } - nsp_cs_detach(dev_list); - } -#endif } diff --git a/drivers/scsi/pcmcia/nsp_cs.h b/drivers/scsi/pcmcia/nsp_cs.h index b66b140a745..8908b8e5b78 100644 --- a/drivers/scsi/pcmcia/nsp_cs.h +++ b/drivers/scsi/pcmcia/nsp_cs.h @@ -225,7 +225,7 @@ /*====================================================================*/ typedef struct scsi_info_t { - dev_link_t link; + struct pcmcia_device *p_dev; struct Scsi_Host *host; #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,74)) dev_node_t node; @@ -297,8 +297,8 @@ typedef struct _nsp_hw_data { /* Card service functions */ static void nsp_cs_detach (struct pcmcia_device *p_dev); -static void nsp_cs_release(dev_link_t *link); -static void nsp_cs_config (dev_link_t *link); +static void nsp_cs_release(struct pcmcia_device *link); +static int nsp_cs_config (struct pcmcia_device *link); /* Linux SCSI subsystem specific functions */ static struct Scsi_Host *nsp_detect (struct scsi_host_template *sht); @@ -450,7 +450,7 @@ static inline struct Scsi_Host *scsi_host_hn_get(unsigned short hostno) return host; } -static void cs_error(client_handle_t handle, int func, int ret) +static void cs_error(struct pcmcia_device *handle, int func, int ret) { error_info_t err = { func, ret }; pcmcia_report_error(handle, &err); diff --git a/drivers/scsi/pcmcia/qlogic_stub.c b/drivers/scsi/pcmcia/qlogic_stub.c index dce7e687fd4..86c2ac6ae62 100644 --- a/drivers/scsi/pcmcia/qlogic_stub.c +++ b/drivers/scsi/pcmcia/qlogic_stub.c @@ -91,18 +91,18 @@ static struct scsi_host_template qlogicfas_driver_template = { /*====================================================================*/ typedef struct scsi_info_t { - dev_link_t link; + struct pcmcia_device *p_dev; dev_node_t node; struct Scsi_Host *host; unsigned short manf_id; } scsi_info_t; -static void qlogic_release(dev_link_t *link); +static void qlogic_release(struct pcmcia_device *link); static void qlogic_detach(struct pcmcia_device *p_dev); -static void qlogic_config(dev_link_t * link); +static int qlogic_config(struct pcmcia_device * link); static struct Scsi_Host *qlogic_detect(struct scsi_host_template *host, - dev_link_t *link, int qbase, int qlirq) + struct pcmcia_device *link, int qbase, int qlirq) { int qltyp; /* type of chip */ int qinitid; @@ -156,10 +156,9 @@ free_scsi_host: err: return NULL; } -static int qlogic_attach(struct pcmcia_device *p_dev) +static int qlogic_probe(struct pcmcia_device *link) { scsi_info_t *info; - dev_link_t *link; DEBUG(0, "qlogic_attach()\n"); @@ -168,7 +167,7 @@ static int qlogic_attach(struct pcmcia_device *p_dev) if (!info) return -ENOMEM; memset(info, 0, sizeof(*info)); - link = &info->link; + info->p_dev = link; link->priv = info; link->io.NumPorts1 = 16; link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO; @@ -176,30 +175,19 @@ static int qlogic_attach(struct pcmcia_device *p_dev) link->irq.Attributes = IRQ_TYPE_EXCLUSIVE; link->irq.IRQInfo1 = IRQ_LEVEL_ID; link->conf.Attributes = CONF_ENABLE_IRQ; - link->conf.Vcc = 50; link->conf.IntType = INT_MEMORY_AND_IO; link->conf.Present = PRESENT_OPTION; - link->handle = p_dev; - p_dev->instance = link; - - link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; - qlogic_config(link); - - return 0; + return qlogic_config(link); } /* qlogic_attach */ /*====================================================================*/ -static void qlogic_detach(struct pcmcia_device *p_dev) +static void qlogic_detach(struct pcmcia_device *link) { - dev_link_t *link = dev_to_instance(p_dev); - DEBUG(0, "qlogic_detach(0x%p)\n", link); - if (link->state & DEV_CONFIG) - qlogic_release(link); - + qlogic_release(link); kfree(link->priv); } /* qlogic_detach */ @@ -209,9 +197,8 @@ static void qlogic_detach(struct pcmcia_device *p_dev) #define CS_CHECK(fn, ret) \ do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0) -static void qlogic_config(dev_link_t * link) +static int qlogic_config(struct pcmcia_device * link) { - client_handle_t handle = link->handle; scsi_info_t *info = link->priv; tuple_t tuple; cisparse_t parse; @@ -225,38 +212,35 @@ static void qlogic_config(dev_link_t * link) tuple.TupleDataMax = 64; tuple.TupleOffset = 0; tuple.DesiredTuple = CISTPL_CONFIG; - CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple)); - CS_CHECK(GetTupleData, pcmcia_get_tuple_data(handle, &tuple)); - CS_CHECK(ParseTuple, pcmcia_parse_tuple(handle, &tuple, &parse)); + CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); + CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple)); + CS_CHECK(ParseTuple, pcmcia_parse_tuple(link, &tuple, &parse)); link->conf.ConfigBase = parse.config.base; tuple.DesiredTuple = CISTPL_MANFID; - if ((pcmcia_get_first_tuple(handle, &tuple) == CS_SUCCESS) && (pcmcia_get_tuple_data(handle, &tuple) == CS_SUCCESS)) + if ((pcmcia_get_first_tuple(link, &tuple) == CS_SUCCESS) && (pcmcia_get_tuple_data(link, &tuple) == CS_SUCCESS)) info->manf_id = le16_to_cpu(tuple.TupleData[0]); - /* Configure card */ - link->state |= DEV_CONFIG; - tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; - CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple)); + CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); while (1) { - if (pcmcia_get_tuple_data(handle, &tuple) != 0 || - pcmcia_parse_tuple(handle, &tuple, &parse) != 0) + if (pcmcia_get_tuple_data(link, &tuple) != 0 || + pcmcia_parse_tuple(link, &tuple, &parse) != 0) goto next_entry; link->conf.ConfigIndex = parse.cftable_entry.index; link->io.BasePort1 = parse.cftable_entry.io.win[0].base; link->io.NumPorts1 = parse.cftable_entry.io.win[0].len; if (link->io.BasePort1 != 0) { - i = pcmcia_request_io(handle, &link->io); + i = pcmcia_request_io(link, &link->io); if (i == CS_SUCCESS) break; } next_entry: - CS_CHECK(GetNextTuple, pcmcia_get_next_tuple(handle, &tuple)); + CS_CHECK(GetNextTuple, pcmcia_get_next_tuple(link, &tuple)); } - CS_CHECK(RequestIRQ, pcmcia_request_irq(handle, &link->irq)); - CS_CHECK(RequestConfiguration, pcmcia_request_configuration(handle, &link->conf)); + CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq)); + CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf)); if ((info->manf_id == MANFID_MACNICA) || (info->manf_id == MANFID_PIONEER) || (info->manf_id == 0x0098)) { /* set ATAcmd */ @@ -275,82 +259,54 @@ static void qlogic_config(dev_link_t * link) if (!host) { printk(KERN_INFO "%s: no SCSI devices found\n", qlogic_name); - goto out; + goto cs_failed; } sprintf(info->node.dev_name, "scsi%d", host->host_no); - link->dev = &info->node; + link->dev_node = &info->node; info->host = host; -out: - link->state &= ~DEV_CONFIG_PENDING; - return; + return 0; cs_failed: - cs_error(link->handle, last_fn, last_ret); - link->dev = NULL; - pcmcia_release_configuration(link->handle); - pcmcia_release_io(link->handle, &link->io); - pcmcia_release_irq(link->handle, &link->irq); - link->state &= ~DEV_CONFIG; - return; + cs_error(link, last_fn, last_ret); + pcmcia_disable_device(link); + return -ENODEV; } /* qlogic_config */ /*====================================================================*/ -static void qlogic_release(dev_link_t *link) +static void qlogic_release(struct pcmcia_device *link) { scsi_info_t *info = link->priv; DEBUG(0, "qlogic_release(0x%p)\n", link); scsi_remove_host(info->host); - link->dev = NULL; free_irq(link->irq.AssignedIRQ, info->host); - - pcmcia_release_configuration(link->handle); - pcmcia_release_io(link->handle, &link->io); - pcmcia_release_irq(link->handle, &link->irq); + pcmcia_disable_device(link); scsi_host_put(info->host); - - link->state &= ~DEV_CONFIG; } /*====================================================================*/ -static int qlogic_suspend(struct pcmcia_device *dev) +static int qlogic_resume(struct pcmcia_device *link) { - dev_link_t *link = dev_to_instance(dev); - - link->state |= DEV_SUSPEND; - if (link->state & DEV_CONFIG) - pcmcia_release_configuration(link->handle); - - return 0; -} + scsi_info_t *info = link->priv; -static int qlogic_resume(struct pcmcia_device *dev) -{ - dev_link_t *link = dev_to_instance(dev); - - link->state &= ~DEV_SUSPEND; - if (link->state & DEV_CONFIG) { - scsi_info_t *info = link->priv; - - pcmcia_request_configuration(link->handle, &link->conf); - if ((info->manf_id == MANFID_MACNICA) || - (info->manf_id == MANFID_PIONEER) || - (info->manf_id == 0x0098)) { - outb(0x80, link->io.BasePort1 + 0xd); - outb(0x24, link->io.BasePort1 + 0x9); - outb(0x04, link->io.BasePort1 + 0xd); - } - /* Ugggglllyyyy!!! */ - qlogicfas408_bus_reset(NULL); + pcmcia_request_configuration(link, &link->conf); + if ((info->manf_id == MANFID_MACNICA) || + (info->manf_id == MANFID_PIONEER) || + (info->manf_id == 0x0098)) { + outb(0x80, link->io.BasePort1 + 0xd); + outb(0x24, link->io.BasePort1 + 0x9); + outb(0x04, link->io.BasePort1 + 0xd); } + /* Ugggglllyyyy!!! */ + qlogicfas408_bus_reset(NULL); return 0; } @@ -382,10 +338,9 @@ static struct pcmcia_driver qlogic_cs_driver = { .drv = { .name = "qlogic_cs", }, - .probe = qlogic_attach, + .probe = qlogic_probe, .remove = qlogic_detach, .id_table = qlogic_ids, - .suspend = qlogic_suspend, .resume = qlogic_resume, }; diff --git a/drivers/scsi/pcmcia/sym53c500_cs.c b/drivers/scsi/pcmcia/sym53c500_cs.c index 3a4dd6f5b81..9f59827707f 100644 --- a/drivers/scsi/pcmcia/sym53c500_cs.c +++ b/drivers/scsi/pcmcia/sym53c500_cs.c @@ -202,7 +202,7 @@ static char *version = /* ================================================================== */ struct scsi_info_t { - dev_link_t link; + struct pcmcia_device *p_dev; dev_node_t node; struct Scsi_Host *host; unsigned short manf_id; @@ -527,7 +527,7 @@ idle_out: } static void -SYM53C500_release(dev_link_t *link) +SYM53C500_release(struct pcmcia_device *link) { struct scsi_info_t *info = link->priv; struct Scsi_Host *shost = info->host; @@ -550,13 +550,7 @@ SYM53C500_release(dev_link_t *link) if (shost->io_port && shost->n_io_port) release_region(shost->io_port, shost->n_io_port); - link->dev = NULL; - - pcmcia_release_configuration(link->handle); - pcmcia_release_io(link->handle, &link->io); - pcmcia_release_irq(link->handle, &link->irq); - - link->state &= ~DEV_CONFIG; + pcmcia_disable_device(link); scsi_host_put(shost); } /* SYM53C500_release */ @@ -713,10 +707,9 @@ static struct scsi_host_template sym53c500_driver_template = { #define CS_CHECK(fn, ret) \ do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0) -static void -SYM53C500_config(dev_link_t *link) +static int +SYM53C500_config(struct pcmcia_device *link) { - client_handle_t handle = link->handle; struct scsi_info_t *info = link->priv; tuple_t tuple; cisparse_t parse; @@ -733,40 +726,37 @@ SYM53C500_config(dev_link_t *link) tuple.TupleDataMax = 64; tuple.TupleOffset = 0; tuple.DesiredTuple = CISTPL_CONFIG; - CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple)); - CS_CHECK(GetTupleData, pcmcia_get_tuple_data(handle, &tuple)); - CS_CHECK(ParseTuple, pcmcia_parse_tuple(handle, &tuple, &parse)); + CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); + CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple)); + CS_CHECK(ParseTuple, pcmcia_parse_tuple(link, &tuple, &parse)); link->conf.ConfigBase = parse.config.base; tuple.DesiredTuple = CISTPL_MANFID; - if ((pcmcia_get_first_tuple(handle, &tuple) == CS_SUCCESS) && - (pcmcia_get_tuple_data(handle, &tuple) == CS_SUCCESS)) + if ((pcmcia_get_first_tuple(link, &tuple) == CS_SUCCESS) && + (pcmcia_get_tuple_data(link, &tuple) == CS_SUCCESS)) info->manf_id = le16_to_cpu(tuple.TupleData[0]); - /* Configure card */ - link->state |= DEV_CONFIG; - tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; - CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple)); + CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); while (1) { - if (pcmcia_get_tuple_data(handle, &tuple) != 0 || - pcmcia_parse_tuple(handle, &tuple, &parse) != 0) + if (pcmcia_get_tuple_data(link, &tuple) != 0 || + pcmcia_parse_tuple(link, &tuple, &parse) != 0) goto next_entry; link->conf.ConfigIndex = parse.cftable_entry.index; link->io.BasePort1 = parse.cftable_entry.io.win[0].base; link->io.NumPorts1 = parse.cftable_entry.io.win[0].len; if (link->io.BasePort1 != 0) { - i = pcmcia_request_io(handle, &link->io); + i = pcmcia_request_io(link, &link->io); if (i == CS_SUCCESS) break; } next_entry: - CS_CHECK(GetNextTuple, pcmcia_get_next_tuple(handle, &tuple)); + CS_CHECK(GetNextTuple, pcmcia_get_next_tuple(link, &tuple)); } - CS_CHECK(RequestIRQ, pcmcia_request_irq(handle, &link->irq)); - CS_CHECK(RequestConfiguration, pcmcia_request_configuration(handle, &link->conf)); + CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq)); + CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf)); /* * That's the trouble with copying liberally from another driver. @@ -835,7 +825,7 @@ next_entry: data->fast_pio = USE_FAST_PIO; sprintf(info->node.dev_name, "scsi%d", host->host_no); - link->dev = &info->node; + link->dev_node = &info->node; info->host = host; if (scsi_add_host(host, NULL)) @@ -843,7 +833,7 @@ next_entry: scsi_scan_host(host); - goto out; /* SUCCESS */ + return 0; err_free_irq: free_irq(irq_level, host); @@ -852,74 +842,50 @@ err_free_scsi: err_release: release_region(port_base, 0x10); printk(KERN_INFO "sym53c500_cs: no SCSI devices found\n"); - -out: - link->state &= ~DEV_CONFIG_PENDING; - return; + return -ENODEV; cs_failed: - cs_error(link->handle, last_fn, last_ret); + cs_error(link, last_fn, last_ret); SYM53C500_release(link); - return; + return -ENODEV; } /* SYM53C500_config */ -static int sym53c500_suspend(struct pcmcia_device *dev) -{ - dev_link_t *link = dev_to_instance(dev); - - link->state |= DEV_SUSPEND; - if (link->state & DEV_CONFIG) - pcmcia_release_configuration(link->handle); - - return 0; -} - -static int sym53c500_resume(struct pcmcia_device *dev) +static int sym53c500_resume(struct pcmcia_device *link) { - dev_link_t *link = dev_to_instance(dev); struct scsi_info_t *info = link->priv; - link->state &= ~DEV_SUSPEND; - if (link->state & DEV_CONFIG) { - pcmcia_request_configuration(link->handle, &link->conf); - - /* See earlier comment about manufacturer IDs. */ - if ((info->manf_id == MANFID_MACNICA) || - (info->manf_id == MANFID_PIONEER) || - (info->manf_id == 0x0098)) { - outb(0x80, link->io.BasePort1 + 0xd); - outb(0x24, link->io.BasePort1 + 0x9); - outb(0x04, link->io.BasePort1 + 0xd); - } - /* - * If things don't work after a "resume", - * this is a good place to start looking. - */ - SYM53C500_int_host_reset(link->io.BasePort1); + /* See earlier comment about manufacturer IDs. */ + if ((info->manf_id == MANFID_MACNICA) || + (info->manf_id == MANFID_PIONEER) || + (info->manf_id == 0x0098)) { + outb(0x80, link->io.BasePort1 + 0xd); + outb(0x24, link->io.BasePort1 + 0x9); + outb(0x04, link->io.BasePort1 + 0xd); } + /* + * If things don't work after a "resume", + * this is a good place to start looking. + */ + SYM53C500_int_host_reset(link->io.BasePort1); return 0; } static void -SYM53C500_detach(struct pcmcia_device *p_dev) +SYM53C500_detach(struct pcmcia_device *link) { - dev_link_t *link = dev_to_instance(p_dev); - DEBUG(0, "SYM53C500_detach(0x%p)\n", link); - if (link->state & DEV_CONFIG) - SYM53C500_release(link); + SYM53C500_release(link); kfree(link->priv); link->priv = NULL; } /* SYM53C500_detach */ static int -SYM53C500_attach(struct pcmcia_device *p_dev) +SYM53C500_probe(struct pcmcia_device *link) { struct scsi_info_t *info; - dev_link_t *link; DEBUG(0, "SYM53C500_attach()\n"); @@ -928,7 +894,7 @@ SYM53C500_attach(struct pcmcia_device *p_dev) if (!info) return -ENOMEM; memset(info, 0, sizeof(*info)); - link = &info->link; + info->p_dev = link; link->priv = info; link->io.NumPorts1 = 16; link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO; @@ -936,17 +902,10 @@ SYM53C500_attach(struct pcmcia_device *p_dev) link->irq.Attributes = IRQ_TYPE_EXCLUSIVE; link->irq.IRQInfo1 = IRQ_LEVEL_ID; link->conf.Attributes = CONF_ENABLE_IRQ; - link->conf.Vcc = 50; link->conf.IntType = INT_MEMORY_AND_IO; link->conf.Present = PRESENT_OPTION; - link->handle = p_dev; - p_dev->instance = link; - - link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; - SYM53C500_config(link); - - return 0; + return SYM53C500_config(link); } /* SYM53C500_attach */ MODULE_AUTHOR("Bob Tracy <rct@frus.com>"); @@ -966,10 +925,9 @@ static struct pcmcia_driver sym53c500_cs_driver = { .drv = { .name = "sym53c500_cs", }, - .probe = SYM53C500_attach, + .probe = SYM53C500_probe, .remove = SYM53C500_detach, .id_table = sym53c500_ids, - .suspend = sym53c500_suspend, .resume = sym53c500_resume, }; diff --git a/drivers/scsi/zalon.c b/drivers/scsi/zalon.c index b131432c677..a6cfbb3b361 100644 --- a/drivers/scsi/zalon.c +++ b/drivers/scsi/zalon.c @@ -88,7 +88,7 @@ zalon_probe(struct parisc_device *dev) struct gsc_irq gsc_irq; u32 zalon_vers; int error = -ENODEV; - void __iomem *zalon = ioremap(dev->hpa.start, 4096); + void __iomem *zalon = ioremap_nocache(dev->hpa.start, 4096); void __iomem *io_port = zalon + GSC_SCSI_ZALON_OFFSET; static int unit = 0; struct Scsi_Host *host; diff --git a/drivers/serial/8250_gsc.c b/drivers/serial/8250_gsc.c index 8b4947933d9..913c71cc056 100644 --- a/drivers/serial/8250_gsc.c +++ b/drivers/serial/8250_gsc.c @@ -52,13 +52,14 @@ serial_init_chip(struct parisc_device *dev) address += 0x800; } - memset(&port, 0, sizeof(struct uart_port)); - port.mapbase = address; - port.irq = dev->irq; - port.iotype = UPIO_MEM; - port.flags = UPF_IOREMAP | UPF_BOOT_AUTOCONF; - port.uartclk = LASI_BASE_BAUD * 16; - port.dev = &dev->dev; + memset(&port, 0, sizeof(port)); + port.iotype = UPIO_MEM; + port.uartclk = LASI_BASE_BAUD * 16; + port.mapbase = address; + port.membase = ioremap_nocache(address, 16); + port.irq = dev->irq; + port.flags = UPF_BOOT_AUTOCONF; + port.dev = &dev->dev; err = serial8250_register_port(&port); if (err < 0) { diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig index fe0d8b8e91c..7d22dc0478d 100644 --- a/drivers/serial/Kconfig +++ b/drivers/serial/Kconfig @@ -63,6 +63,33 @@ config SERIAL_8250_CONSOLE If unsure, say N. +config SERIAL_8250_GSC + tristate + depends on SERIAL_8250 && GSC + default SERIAL_8250 + +config SERIAL_8250_PCI + tristate "8250/16550 PCI device support" if EMBEDDED + depends on SERIAL_8250 && PCI + default SERIAL_8250 + help + This builds standard PCI serial support. You may be able to + disable this feature if you only need legacy serial support. + Saves about 9K. + +config SERIAL_8250_PNP + tristate "8250/16550 PNP device support" if EMBEDDED + depends on SERIAL_8250 && PNP + default SERIAL_8250 + help + This builds standard PNP serial support. You may be able to + disable this feature if you only need legacy serial support. + +config SERIAL_8250_HP300 + tristate + depends on SERIAL_8250 && HP300 + default SERIAL_8250 + config SERIAL_8250_CS tristate "8250/16550 PCMCIA device support" depends on PCMCIA && SERIAL_8250 diff --git a/drivers/serial/Makefile b/drivers/serial/Makefile index d2b4c214876..0a71bf68a03 100644 --- a/drivers/serial/Makefile +++ b/drivers/serial/Makefile @@ -4,15 +4,13 @@ # $Id: Makefile,v 1.8 2002/07/21 21:32:30 rmk Exp $ # -serial-8250-y := -serial-8250-$(CONFIG_PNP) += 8250_pnp.o -serial-8250-$(CONFIG_GSC) += 8250_gsc.o -serial-8250-$(CONFIG_PCI) += 8250_pci.o -serial-8250-$(CONFIG_HP300) += 8250_hp300.o - obj-$(CONFIG_SERIAL_CORE) += serial_core.o obj-$(CONFIG_SERIAL_21285) += 21285.o -obj-$(CONFIG_SERIAL_8250) += 8250.o $(serial-8250-y) +obj-$(CONFIG_SERIAL_8250) += 8250.o +obj-$(CONFIG_SERIAL_8250_PNP) += 8250_pnp.o +obj-$(CONFIG_SERIAL_8250_GSC) += 8250_gsc.o +obj-$(CONFIG_SERIAL_8250_PCI) += 8250_pci.o +obj-$(CONFIG_SERIAL_8250_HP300) += 8250_hp300.o obj-$(CONFIG_SERIAL_8250_CS) += serial_cs.o obj-$(CONFIG_SERIAL_8250_ACORN) += 8250_acorn.o obj-$(CONFIG_SERIAL_8250_CONSOLE) += 8250_early.o diff --git a/drivers/serial/jsm/jsm_tty.c b/drivers/serial/jsm/jsm_tty.c index 4d48b625cd3..7d823705193 100644 --- a/drivers/serial/jsm/jsm_tty.c +++ b/drivers/serial/jsm/jsm_tty.c @@ -142,12 +142,14 @@ static void jsm_tty_send_xchar(struct uart_port *port, char ch) { unsigned long lock_flags; struct jsm_channel *channel = (struct jsm_channel *)port; + struct termios *termios; spin_lock_irqsave(&port->lock, lock_flags); - if (ch == port->info->tty->termios->c_cc[VSTART]) + termios = port->info->tty->termios; + if (ch == termios->c_cc[VSTART]) channel->ch_bd->bd_ops->send_start_character(channel); - if (ch == port->info->tty->termios->c_cc[VSTOP]) + if (ch == termios->c_cc[VSTOP]) channel->ch_bd->bd_ops->send_stop_character(channel); spin_unlock_irqrestore(&port->lock, lock_flags); } @@ -178,6 +180,7 @@ static int jsm_tty_open(struct uart_port *port) struct jsm_board *brd; int rc = 0; struct jsm_channel *channel = (struct jsm_channel *)port; + struct termios *termios; /* Get board pointer from our array of majors we have allocated */ brd = channel->ch_bd; @@ -239,12 +242,13 @@ static int jsm_tty_open(struct uart_port *port) channel->ch_cached_lsr = 0; channel->ch_stops_sent = 0; - channel->ch_c_cflag = port->info->tty->termios->c_cflag; - channel->ch_c_iflag = port->info->tty->termios->c_iflag; - channel->ch_c_oflag = port->info->tty->termios->c_oflag; - channel->ch_c_lflag = port->info->tty->termios->c_lflag; - channel->ch_startc = port->info->tty->termios->c_cc[VSTART]; - channel->ch_stopc = port->info->tty->termios->c_cc[VSTOP]; + termios = port->info->tty->termios; + channel->ch_c_cflag = termios->c_cflag; + channel->ch_c_iflag = termios->c_iflag; + channel->ch_c_oflag = termios->c_oflag; + channel->ch_c_lflag = termios->c_lflag; + channel->ch_startc = termios->c_cc[VSTART]; + channel->ch_stopc = termios->c_cc[VSTOP]; /* Tell UART to init itself */ brd->bd_ops->uart_init(channel); @@ -784,6 +788,7 @@ static void jsm_carrier(struct jsm_channel *ch) void jsm_check_queue_flow_control(struct jsm_channel *ch) { + struct board_ops *bd_ops = ch->ch_bd->bd_ops; int qleft = 0; /* Store how much space we have left in the queue */ @@ -809,7 +814,7 @@ void jsm_check_queue_flow_control(struct jsm_channel *ch) /* HWFLOW */ if (ch->ch_c_cflag & CRTSCTS) { if(!(ch->ch_flags & CH_RECEIVER_OFF)) { - ch->ch_bd->bd_ops->disable_receiver(ch); + bd_ops->disable_receiver(ch); ch->ch_flags |= (CH_RECEIVER_OFF); jsm_printk(READ, INFO, &ch->ch_bd->pci_dev, "Internal queue hit hilevel mark (%d)! Turning off interrupts.\n", @@ -819,7 +824,7 @@ void jsm_check_queue_flow_control(struct jsm_channel *ch) /* SWFLOW */ else if (ch->ch_c_iflag & IXOFF) { if (ch->ch_stops_sent <= MAX_STOPS_SENT) { - ch->ch_bd->bd_ops->send_stop_character(ch); + bd_ops->send_stop_character(ch); ch->ch_stops_sent++; jsm_printk(READ, INFO, &ch->ch_bd->pci_dev, "Sending stop char! Times sent: %x\n", ch->ch_stops_sent); @@ -846,7 +851,7 @@ void jsm_check_queue_flow_control(struct jsm_channel *ch) /* HWFLOW */ if (ch->ch_c_cflag & CRTSCTS) { if (ch->ch_flags & CH_RECEIVER_OFF) { - ch->ch_bd->bd_ops->enable_receiver(ch); + bd_ops->enable_receiver(ch); ch->ch_flags &= ~(CH_RECEIVER_OFF); jsm_printk(READ, INFO, &ch->ch_bd->pci_dev, "Internal queue hit lowlevel mark (%d)! Turning on interrupts.\n", @@ -856,7 +861,7 @@ void jsm_check_queue_flow_control(struct jsm_channel *ch) /* SWFLOW */ else if (ch->ch_c_iflag & IXOFF && ch->ch_stops_sent) { ch->ch_stops_sent = 0; - ch->ch_bd->bd_ops->send_start_character(ch); + bd_ops->send_start_character(ch); jsm_printk(READ, INFO, &ch->ch_bd->pci_dev, "Sending start char!\n"); } } diff --git a/drivers/serial/mux.c b/drivers/serial/mux.c index 868eaf4a1a6..64c0e89124c 100644 --- a/drivers/serial/mux.c +++ b/drivers/serial/mux.c @@ -51,7 +51,7 @@ #define MUX_BREAK(status) ((status & 0xF000) == 0x2000) #define MUX_NR 256 -static unsigned int port_cnt = 0; +static unsigned int port_cnt __read_mostly; static struct uart_port mux_ports[MUX_NR]; static struct uart_driver mux_driver = { @@ -461,7 +461,7 @@ static int __init mux_probe(struct parisc_device *dev) port->iobase = 0; port->mapbase = dev->hpa.start + MUX_OFFSET + (i * MUX_LINE_OFFSET); - port->membase = ioremap(port->mapbase, MUX_LINE_OFFSET); + port->membase = ioremap_nocache(port->mapbase, MUX_LINE_OFFSET); port->iotype = UPIO_MEM; port->type = PORT_MUX; port->irq = NO_IRQ; diff --git a/drivers/serial/serial_cs.c b/drivers/serial/serial_cs.c index c30333694fd..2c70773543e 100644 --- a/drivers/serial/serial_cs.c +++ b/drivers/serial/serial_cs.c @@ -41,6 +41,7 @@ #include <linux/string.h> #include <linux/timer.h> #include <linux/serial_core.h> +#include <linux/delay.h> #include <linux/major.h> #include <asm/io.h> #include <asm/system.h> @@ -97,11 +98,13 @@ static const struct multi_id multi_id[] = { #define MULTI_COUNT (sizeof(multi_id)/sizeof(struct multi_id)) struct serial_info { - dev_link_t link; + struct pcmcia_device *p_dev; int ndev; int multi; int slave; int manfid; + int prodid; + int c950ctrl; dev_node_t node[4]; int line[4]; }; @@ -113,9 +116,36 @@ struct serial_cfg_mem { }; -static void serial_config(dev_link_t * link); +static int serial_config(struct pcmcia_device * link); +static void wakeup_card(struct serial_info *info) +{ + int ctrl = info->c950ctrl; + + if (info->manfid == MANFID_OXSEMI) { + outb(12, ctrl + 1); + } else if (info->manfid == MANFID_POSSIO && info->prodid == PRODID_POSSIO_GCC) { + /* request_region? oxsemi branch does no request_region too... */ + /* This sequence is needed to properly initialize MC45 attached to OXCF950. + * I tried decreasing these msleep()s, but it worked properly (survived + * 1000 stop/start operations) with these timeouts (or bigger). */ + outb(0xA, ctrl + 1); + msleep(100); + outb(0xE, ctrl + 1); + msleep(300); + outb(0xC, ctrl + 1); + msleep(100); + outb(0xE, ctrl + 1); + msleep(200); + outb(0xF, ctrl + 1); + msleep(100); + outb(0xE, ctrl + 1); + msleep(100); + outb(0xC, ctrl + 1); + } +} + /*====================================================================== After a card is removed, serial_remove() will unregister @@ -123,67 +153,45 @@ static void serial_config(dev_link_t * link); ======================================================================*/ -static void serial_remove(dev_link_t *link) +static void serial_remove(struct pcmcia_device *link) { struct serial_info *info = link->priv; int i; - link->state &= ~DEV_PRESENT; - DEBUG(0, "serial_release(0x%p)\n", link); /* * Recheck to see if the device is still configured. */ - if (info->link.state & DEV_CONFIG) { - for (i = 0; i < info->ndev; i++) - serial8250_unregister_port(info->line[i]); + for (i = 0; i < info->ndev; i++) + serial8250_unregister_port(info->line[i]); - info->link.dev = NULL; + info->p_dev->dev_node = NULL; - if (!info->slave) { - pcmcia_release_configuration(info->link.handle); - pcmcia_release_io(info->link.handle, &info->link.io); - pcmcia_release_irq(info->link.handle, &info->link.irq); - } - - info->link.state &= ~DEV_CONFIG; - } + if (!info->slave) + pcmcia_disable_device(link); } -static int serial_suspend(struct pcmcia_device *dev) +static int serial_suspend(struct pcmcia_device *link) { - dev_link_t *link = dev_to_instance(dev); - link->state |= DEV_SUSPEND; - - if (link->state & DEV_CONFIG) { - struct serial_info *info = link->priv; - int i; - - for (i = 0; i < info->ndev; i++) - serial8250_suspend_port(info->line[i]); + struct serial_info *info = link->priv; + int i; - if (!info->slave) - pcmcia_release_configuration(link->handle); - } + for (i = 0; i < info->ndev; i++) + serial8250_suspend_port(info->line[i]); return 0; } -static int serial_resume(struct pcmcia_device *dev) +static int serial_resume(struct pcmcia_device *link) { - dev_link_t *link = dev_to_instance(dev); - link->state &= ~DEV_SUSPEND; - - if (DEV_OK(link)) { + if (pcmcia_dev_present(link)) { struct serial_info *info = link->priv; int i; - if (!info->slave) - pcmcia_request_configuration(link->handle, &link->conf); - for (i = 0; i < info->ndev; i++) serial8250_resume_port(info->line[i]); + wakeup_card(info); } return 0; @@ -197,10 +205,9 @@ static int serial_resume(struct pcmcia_device *dev) ======================================================================*/ -static int serial_probe(struct pcmcia_device *p_dev) +static int serial_probe(struct pcmcia_device *link) { struct serial_info *info; - dev_link_t *link; DEBUG(0, "serial_attach()\n"); @@ -209,7 +216,7 @@ static int serial_probe(struct pcmcia_device *p_dev) if (!info) return -ENOMEM; memset(info, 0, sizeof (*info)); - link = &info->link; + info->p_dev = link; link->priv = info; link->io.Attributes1 = IO_DATA_PATH_WIDTH_8; @@ -223,12 +230,7 @@ static int serial_probe(struct pcmcia_device *p_dev) } link->conf.IntType = INT_MEMORY_AND_IO; - link->handle = p_dev; - p_dev->instance = link; - link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; - serial_config(link); - - return 0; + return serial_config(link); } /*====================================================================== @@ -240,9 +242,8 @@ static int serial_probe(struct pcmcia_device *p_dev) ======================================================================*/ -static void serial_detach(struct pcmcia_device *p_dev) +static void serial_detach(struct pcmcia_device *link) { - dev_link_t *link = dev_to_instance(p_dev); struct serial_info *info = link->priv; DEBUG(0, "serial_detach(0x%p)\n", link); @@ -263,7 +264,7 @@ static void serial_detach(struct pcmcia_device *p_dev) /*====================================================================*/ -static int setup_serial(client_handle_t handle, struct serial_info * info, +static int setup_serial(struct pcmcia_device *handle, struct serial_info * info, kio_addr_t iobase, int irq) { struct uart_port port; @@ -298,7 +299,7 @@ static int setup_serial(client_handle_t handle, struct serial_info * info, /*====================================================================*/ static int -first_tuple(client_handle_t handle, tuple_t * tuple, cisparse_t * parse) +first_tuple(struct pcmcia_device *handle, tuple_t * tuple, cisparse_t * parse) { int i; i = pcmcia_get_first_tuple(handle, tuple); @@ -311,7 +312,7 @@ first_tuple(client_handle_t handle, tuple_t * tuple, cisparse_t * parse) } static int -next_tuple(client_handle_t handle, tuple_t * tuple, cisparse_t * parse) +next_tuple(struct pcmcia_device *handle, tuple_t * tuple, cisparse_t * parse) { int i; i = pcmcia_get_next_tuple(handle, tuple); @@ -325,11 +326,10 @@ next_tuple(client_handle_t handle, tuple_t * tuple, cisparse_t * parse) /*====================================================================*/ -static int simple_config(dev_link_t *link) +static int simple_config(struct pcmcia_device *link) { static const kio_addr_t base[5] = { 0x3f8, 0x2f8, 0x3e8, 0x2e8, 0x0 }; static const int size_table[2] = { 8, 16 }; - client_handle_t handle = link->handle; struct serial_info *info = link->priv; struct serial_cfg_mem *cfg_mem; tuple_t *tuple; @@ -350,7 +350,7 @@ static int simple_config(dev_link_t *link) buf = cfg_mem->buf; /* If the card is already configured, look up the port and irq */ - i = pcmcia_get_configuration_info(handle, &config); + i = pcmcia_get_configuration_info(link, &config); if ((i == CS_SUCCESS) && (config.Attributes & CONF_VALID_CLIENT)) { kio_addr_t port = 0; if ((config.BasePort2 != 0) && (config.NumPorts2 == 8)) { @@ -363,10 +363,9 @@ static int simple_config(dev_link_t *link) } if (info->slave) { kfree(cfg_mem); - return setup_serial(handle, info, port, config.AssignedIRQ); + return setup_serial(link, info, port, config.AssignedIRQ); } } - link->conf.Vcc = config.Vcc; /* First pass: look for a config entry that looks normal. */ tuple->TupleData = (cisdata_t *) buf; @@ -377,12 +376,12 @@ static int simple_config(dev_link_t *link) /* Two tries: without IO aliases, then with aliases */ for (s = 0; s < 2; s++) { for (try = 0; try < 2; try++) { - i = first_tuple(handle, tuple, parse); + i = first_tuple(link, tuple, parse); while (i != CS_NO_MORE_ITEMS) { if (i != CS_SUCCESS) goto next_entry; if (cf->vpp1.present & (1 << CISTPL_POWER_VNOM)) - link->conf.Vpp1 = link->conf.Vpp2 = + link->conf.Vpp = cf->vpp1.param[CISTPL_POWER_VNOM] / 10000; if ((cf->io.nwin > 0) && (cf->io.win[0].len == size_table[s]) && (cf->io.win[0].base != 0)) { @@ -390,19 +389,19 @@ static int simple_config(dev_link_t *link) link->io.BasePort1 = cf->io.win[0].base; link->io.IOAddrLines = (try == 0) ? 16 : cf->io.flags & CISTPL_IO_LINES_MASK; - i = pcmcia_request_io(link->handle, &link->io); + i = pcmcia_request_io(link, &link->io); if (i == CS_SUCCESS) goto found_port; } next_entry: - i = next_tuple(handle, tuple, parse); + i = next_tuple(link, tuple, parse); } } } /* Second pass: try to find an entry that isn't picky about its base address, then try to grab any standard serial port address, and finally try to get any free port. */ - i = first_tuple(handle, tuple, parse); + i = first_tuple(link, tuple, parse); while (i != CS_NO_MORE_ITEMS) { if ((i == CS_SUCCESS) && (cf->io.nwin > 0) && ((cf->io.flags & CISTPL_IO_LINES_MASK) <= 3)) { @@ -410,50 +409,48 @@ next_entry: for (j = 0; j < 5; j++) { link->io.BasePort1 = base[j]; link->io.IOAddrLines = base[j] ? 16 : 3; - i = pcmcia_request_io(link->handle, &link->io); + i = pcmcia_request_io(link, &link->io); if (i == CS_SUCCESS) goto found_port; } } - i = next_tuple(handle, tuple, parse); + i = next_tuple(link, tuple, parse); } found_port: if (i != CS_SUCCESS) { printk(KERN_NOTICE "serial_cs: no usable port range found, giving up\n"); - cs_error(link->handle, RequestIO, i); + cs_error(link, RequestIO, i); kfree(cfg_mem); return -1; } - i = pcmcia_request_irq(link->handle, &link->irq); + i = pcmcia_request_irq(link, &link->irq); if (i != CS_SUCCESS) { - cs_error(link->handle, RequestIRQ, i); + cs_error(link, RequestIRQ, i); link->irq.AssignedIRQ = 0; } if (info->multi && (info->manfid == MANFID_3COM)) link->conf.ConfigIndex &= ~(0x08); - i = pcmcia_request_configuration(link->handle, &link->conf); + i = pcmcia_request_configuration(link, &link->conf); if (i != CS_SUCCESS) { - cs_error(link->handle, RequestConfiguration, i); + cs_error(link, RequestConfiguration, i); kfree(cfg_mem); return -1; } kfree(cfg_mem); - return setup_serial(handle, info, link->io.BasePort1, link->irq.AssignedIRQ); + return setup_serial(link, info, link->io.BasePort1, link->irq.AssignedIRQ); } -static int multi_config(dev_link_t * link) +static int multi_config(struct pcmcia_device * link) { - client_handle_t handle = link->handle; struct serial_info *info = link->priv; struct serial_cfg_mem *cfg_mem; tuple_t *tuple; u_char *buf; cisparse_t *parse; cistpl_cftable_entry_t *cf; - config_info_t config; int i, rc, base2 = 0; cfg_mem = kmalloc(sizeof(struct serial_cfg_mem), GFP_KERNEL); @@ -464,14 +461,6 @@ static int multi_config(dev_link_t * link) cf = &parse->cftable_entry; buf = cfg_mem->buf; - i = pcmcia_get_configuration_info(handle, &config); - if (i != CS_SUCCESS) { - cs_error(handle, GetConfigurationInfo, i); - rc = -1; - goto free_cfg_mem; - } - link->conf.Vcc = config.Vcc; - tuple->TupleData = (cisdata_t *) buf; tuple->TupleOffset = 0; tuple->TupleDataMax = 255; @@ -480,7 +469,7 @@ static int multi_config(dev_link_t * link) /* First, look for a generic full-sized window */ link->io.NumPorts1 = info->multi * 8; - i = first_tuple(handle, tuple, parse); + i = first_tuple(link, tuple, parse); while (i != CS_NO_MORE_ITEMS) { /* The quad port cards have bad CIS's, so just look for a window larger than 8 ports and assume it will be right */ @@ -490,19 +479,19 @@ static int multi_config(dev_link_t * link) link->io.BasePort1 = cf->io.win[0].base; link->io.IOAddrLines = cf->io.flags & CISTPL_IO_LINES_MASK; - i = pcmcia_request_io(link->handle, &link->io); + i = pcmcia_request_io(link, &link->io); base2 = link->io.BasePort1 + 8; if (i == CS_SUCCESS) break; } - i = next_tuple(handle, tuple, parse); + i = next_tuple(link, tuple, parse); } /* If that didn't work, look for two windows */ if (i != CS_SUCCESS) { link->io.NumPorts1 = link->io.NumPorts2 = 8; info->multi = 2; - i = first_tuple(handle, tuple, parse); + i = first_tuple(link, tuple, parse); while (i != CS_NO_MORE_ITEMS) { if ((i == CS_SUCCESS) && (cf->io.nwin == 2)) { link->conf.ConfigIndex = cf->index; @@ -510,26 +499,26 @@ static int multi_config(dev_link_t * link) link->io.BasePort2 = cf->io.win[1].base; link->io.IOAddrLines = cf->io.flags & CISTPL_IO_LINES_MASK; - i = pcmcia_request_io(link->handle, &link->io); + i = pcmcia_request_io(link, &link->io); base2 = link->io.BasePort2; if (i == CS_SUCCESS) break; } - i = next_tuple(handle, tuple, parse); + i = next_tuple(link, tuple, parse); } } if (i != CS_SUCCESS) { - cs_error(link->handle, RequestIO, i); + cs_error(link, RequestIO, i); rc = -1; goto free_cfg_mem; } - i = pcmcia_request_irq(link->handle, &link->irq); + i = pcmcia_request_irq(link, &link->irq); if (i != CS_SUCCESS) { printk(KERN_NOTICE "serial_cs: no usable port range found, giving up\n"); - cs_error(link->handle, RequestIRQ, i); + cs_error(link, RequestIRQ, i); link->irq.AssignedIRQ = 0; } /* Socket Dual IO: this enables irq's for second port */ @@ -537,35 +526,43 @@ static int multi_config(dev_link_t * link) link->conf.Present |= PRESENT_EXT_STATUS; link->conf.ExtStatus = ESR_REQ_ATTN_ENA; } - i = pcmcia_request_configuration(link->handle, &link->conf); + i = pcmcia_request_configuration(link, &link->conf); if (i != CS_SUCCESS) { - cs_error(link->handle, RequestConfiguration, i); + cs_error(link, RequestConfiguration, i); rc = -1; goto free_cfg_mem; } /* The Oxford Semiconductor OXCF950 cards are in fact single-port: - 8 registers are for the UART, the others are extra registers */ - if (info->manfid == MANFID_OXSEMI) { + * 8 registers are for the UART, the others are extra registers. + * Siemen's MC45 PCMCIA (Possio's GCC) is OXCF950 based too. + */ + if (info->manfid == MANFID_OXSEMI || (info->manfid == MANFID_POSSIO && + info->prodid == PRODID_POSSIO_GCC)) { + int err; + if (cf->index == 1 || cf->index == 3) { - setup_serial(handle, info, base2, link->irq.AssignedIRQ); - outb(12, link->io.BasePort1 + 1); + err = setup_serial(link, info, base2, + link->irq.AssignedIRQ); + base2 = link->io.BasePort1; } else { - setup_serial(handle, info, link->io.BasePort1, link->irq.AssignedIRQ); - outb(12, base2 + 1); + err = setup_serial(link, info, link->io.BasePort1, + link->irq.AssignedIRQ); } + info->c950ctrl = base2; + wakeup_card(info); rc = 0; goto free_cfg_mem; } - setup_serial(handle, info, link->io.BasePort1, link->irq.AssignedIRQ); + setup_serial(link, info, link->io.BasePort1, link->irq.AssignedIRQ); /* The Nokia cards are not really multiport cards */ if (info->manfid == MANFID_NOKIA) { rc = 0; goto free_cfg_mem; } for (i = 0; i < info->multi - 1; i++) - setup_serial(handle, info, base2 + (8 * i), + setup_serial(link, info, base2 + (8 * i), link->irq.AssignedIRQ); rc = 0; free_cfg_mem: @@ -581,9 +578,8 @@ free_cfg_mem: ======================================================================*/ -void serial_config(dev_link_t * link) +static int serial_config(struct pcmcia_device * link) { - client_handle_t handle = link->handle; struct serial_info *info = link->priv; struct serial_cfg_mem *cfg_mem; tuple_t *tuple; @@ -609,7 +605,7 @@ void serial_config(dev_link_t * link) tuple->Attributes = 0; /* Get configuration register information */ tuple->DesiredTuple = CISTPL_CONFIG; - last_ret = first_tuple(handle, tuple, parse); + last_ret = first_tuple(link, tuple, parse); if (last_ret != CS_SUCCESS) { last_fn = ParseTuple; goto cs_failed; @@ -617,18 +613,16 @@ void serial_config(dev_link_t * link) link->conf.ConfigBase = parse->config.base; link->conf.Present = parse->config.rmask[0]; - /* Configure card */ - link->state |= DEV_CONFIG; - /* Is this a compliant multifunction card? */ tuple->DesiredTuple = CISTPL_LONGLINK_MFC; tuple->Attributes = TUPLE_RETURN_COMMON | TUPLE_RETURN_LINK; - info->multi = (first_tuple(handle, tuple, parse) == CS_SUCCESS); + info->multi = (first_tuple(link, tuple, parse) == CS_SUCCESS); /* Is this a multiport card? */ tuple->DesiredTuple = CISTPL_MANFID; - if (first_tuple(handle, tuple, parse) == CS_SUCCESS) { + if (first_tuple(link, tuple, parse) == CS_SUCCESS) { info->manfid = parse->manfid.manf; + info->prodid = le16_to_cpu(buf[1]); for (i = 0; i < MULTI_COUNT; i++) if ((info->manfid == multi_id[i].manfid) && (parse->manfid.card == multi_id[i].prodid)) @@ -641,11 +635,11 @@ void serial_config(dev_link_t * link) multifunction cards that ask for appropriate IO port ranges */ tuple->DesiredTuple = CISTPL_FUNCID; if ((info->multi == 0) && - ((first_tuple(handle, tuple, parse) != CS_SUCCESS) || + ((first_tuple(link, tuple, parse) != CS_SUCCESS) || (parse->funcid.func == CISTPL_FUNCID_MULTI) || (parse->funcid.func == CISTPL_FUNCID_SERIAL))) { tuple->DesiredTuple = CISTPL_CFTABLE_ENTRY; - if (first_tuple(handle, tuple, parse) == CS_SUCCESS) { + if (first_tuple(link, tuple, parse) == CS_SUCCESS) { if ((cf->io.nwin == 1) && (cf->io.win[0].len % 8 == 0)) info->multi = cf->io.win[0].len >> 3; if ((cf->io.nwin == 2) && (cf->io.win[0].len == 8) && @@ -664,31 +658,30 @@ void serial_config(dev_link_t * link) if (info->manfid == MANFID_IBM) { conf_reg_t reg = { 0, CS_READ, 0x800, 0 }; - last_ret = pcmcia_access_configuration_register(link->handle, ®); + last_ret = pcmcia_access_configuration_register(link, ®); if (last_ret) { last_fn = AccessConfigurationRegister; goto cs_failed; } reg.Action = CS_WRITE; reg.Value = reg.Value | 1; - last_ret = pcmcia_access_configuration_register(link->handle, ®); + last_ret = pcmcia_access_configuration_register(link, ®); if (last_ret) { last_fn = AccessConfigurationRegister; goto cs_failed; } } - link->dev = &info->node[0]; - link->state &= ~DEV_CONFIG_PENDING; + link->dev_node = &info->node[0]; kfree(cfg_mem); - return; + return 0; cs_failed: - cs_error(link->handle, last_fn, last_ret); + cs_error(link, last_fn, last_ret); failed: serial_remove(link); - link->state &= ~DEV_CONFIG_PENDING; kfree(cfg_mem); + return -ENODEV; } static struct pcmcia_device_id serial_ids[] = { @@ -739,6 +732,7 @@ static struct pcmcia_device_id serial_ids[] = { PCMCIA_MFC_DEVICE_PROD_ID1(1, "Motorola MARQUIS", 0xf03e4e77), PCMCIA_MFC_DEVICE_PROD_ID2(1, "FAX/Modem/Ethernet Combo Card ", 0x1ed59302), PCMCIA_DEVICE_MANF_CARD(0x0089, 0x0301), + PCMCIA_DEVICE_MANF_CARD(0x00a4, 0x0276), PCMCIA_DEVICE_MANF_CARD(0x0101, 0x0039), PCMCIA_DEVICE_MANF_CARD(0x0104, 0x0006), PCMCIA_DEVICE_MANF_CARD(0x0105, 0x410a), @@ -757,6 +751,7 @@ static struct pcmcia_device_id serial_ids[] = { PCMCIA_DEVICE_PROD_ID14("MEGAHERTZ", "PCMCIA MODEM", 0xf510db04, 0xbd6c43ef), PCMCIA_DEVICE_PROD_ID124("TOSHIBA", "T144PF", "PCMCIA MODEM", 0xb4585a1a, 0x7271409c, 0xbd6c43ef), PCMCIA_DEVICE_PROD_ID123("FUJITSU", "FC14F ", "MBH10213", 0x6ee5a3d8, 0x30ead12b, 0xb00f05a0), + PCMCIA_DEVICE_PROD_ID123("Novatel Wireless", "Merlin UMTS Modem", "U630", 0x32607776, 0xd9e73b13, 0xe87332e), PCMCIA_DEVICE_PROD_ID13("MEGAHERTZ", "V.34 PCMCIA MODEM", 0xf510db04, 0xbb2cce4a), PCMCIA_DEVICE_PROD_ID12("Brain Boxes", "Bluetooth PC Card", 0xee138382, 0xd4ce9b02), PCMCIA_DEVICE_PROD_ID12("CIRRUS LOGIC", "FAX MODEM", 0xe625f451, 0xcecd6dfa), diff --git a/drivers/telephony/ixj_pcmcia.c b/drivers/telephony/ixj_pcmcia.c index d3a7b0c3d38..dda0ca45d90 100644 --- a/drivers/telephony/ixj_pcmcia.c +++ b/drivers/telephony/ixj_pcmcia.c @@ -35,73 +35,52 @@ typedef struct ixj_info_t { } ixj_info_t; static void ixj_detach(struct pcmcia_device *p_dev); -static void ixj_config(dev_link_t * link); -static void ixj_cs_release(dev_link_t * link); +static int ixj_config(struct pcmcia_device * link); +static void ixj_cs_release(struct pcmcia_device * link); -static int ixj_attach(struct pcmcia_device *p_dev) +static int ixj_probe(struct pcmcia_device *p_dev) { - dev_link_t *link; - DEBUG(0, "ixj_attach()\n"); /* Create new ixj device */ - link = kmalloc(sizeof(struct dev_link_t), GFP_KERNEL); - if (!link) - return -ENOMEM; - memset(link, 0, sizeof(struct dev_link_t)); - link->io.Attributes1 = IO_DATA_PATH_WIDTH_8; - link->io.Attributes2 = IO_DATA_PATH_WIDTH_8; - link->io.IOAddrLines = 3; - link->conf.Vcc = 50; - link->conf.IntType = INT_MEMORY_AND_IO; - link->priv = kmalloc(sizeof(struct ixj_info_t), GFP_KERNEL); - if (!link->priv) { - kfree(link); + p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_8; + p_dev->io.Attributes2 = IO_DATA_PATH_WIDTH_8; + p_dev->io.IOAddrLines = 3; + p_dev->conf.IntType = INT_MEMORY_AND_IO; + p_dev->priv = kmalloc(sizeof(struct ixj_info_t), GFP_KERNEL); + if (!p_dev->priv) { return -ENOMEM; } - memset(link->priv, 0, sizeof(struct ixj_info_t)); - - link->handle = p_dev; - p_dev->instance = link; + memset(p_dev->priv, 0, sizeof(struct ixj_info_t)); - link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; - ixj_config(link); - - return 0; + return ixj_config(p_dev); } -static void ixj_detach(struct pcmcia_device *p_dev) +static void ixj_detach(struct pcmcia_device *link) { - dev_link_t *link = dev_to_instance(p_dev); - DEBUG(0, "ixj_detach(0x%p)\n", link); - link->state &= ~DEV_RELEASE_PENDING; - if (link->state & DEV_CONFIG) - ixj_cs_release(link); + ixj_cs_release(link); kfree(link->priv); - kfree(link); } #define CS_CHECK(fn, ret) \ do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0) -static void ixj_get_serial(dev_link_t * link, IXJ * j) +static void ixj_get_serial(struct pcmcia_device * link, IXJ * j) { - client_handle_t handle; tuple_t tuple; u_short buf[128]; char *str; int last_ret, last_fn, i, place; - handle = link->handle; DEBUG(0, "ixj_get_serial(0x%p)\n", link); tuple.TupleData = (cisdata_t *) buf; tuple.TupleOffset = 0; tuple.TupleDataMax = 80; tuple.Attributes = 0; tuple.DesiredTuple = CISTPL_VERS_1; - CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple)); - CS_CHECK(GetTupleData, pcmcia_get_tuple_data(handle, &tuple)); + CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); + CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple)); str = (char *) buf; printk("PCMCIA Version %d.%d\n", str[0], str[1]); str += 2; @@ -149,22 +128,19 @@ static void ixj_get_serial(dev_link_t * link, IXJ * j) return; } -static void ixj_config(dev_link_t * link) +static int ixj_config(struct pcmcia_device * link) { IXJ *j; - client_handle_t handle; ixj_info_t *info; tuple_t tuple; u_short buf[128]; cisparse_t parse; - config_info_t conf; cistpl_cftable_entry_t *cfg = &parse.cftable_entry; cistpl_cftable_entry_t dflt = { 0 }; int last_ret, last_fn; - handle = link->handle; info = link->priv; DEBUG(0, "ixj_config(0x%p)\n", link); tuple.TupleData = (cisdata_t *) buf; @@ -172,19 +148,17 @@ static void ixj_config(dev_link_t * link) tuple.TupleDataMax = 255; tuple.Attributes = 0; tuple.DesiredTuple = CISTPL_CONFIG; - CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple)); - CS_CHECK(GetTupleData, pcmcia_get_tuple_data(handle, &tuple)); - CS_CHECK(ParseTuple, pcmcia_parse_tuple(handle, &tuple, &parse)); + CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); + CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple)); + CS_CHECK(ParseTuple, pcmcia_parse_tuple(link, &tuple, &parse)); link->conf.ConfigBase = parse.config.base; link->conf.Present = parse.config.rmask[0]; - link->state |= DEV_CONFIG; - CS_CHECK(GetConfigurationInfo, pcmcia_get_configuration_info(handle, &conf)); tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; tuple.Attributes = 0; - CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple)); + CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); while (1) { - if (pcmcia_get_tuple_data(handle, &tuple) != 0 || - pcmcia_parse_tuple(handle, &tuple, &parse) != 0) + if (pcmcia_get_tuple_data(link, &tuple) != 0 || + pcmcia_parse_tuple(link, &tuple, &parse) != 0) goto next_entry; if ((cfg->io.nwin > 0) || (dflt.io.nwin > 0)) { cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt.io; @@ -195,7 +169,7 @@ static void ixj_config(dev_link_t * link) link->io.BasePort2 = io->win[1].base; link->io.NumPorts2 = io->win[1].len; } - if (pcmcia_request_io(link->handle, &link->io) != 0) + if (pcmcia_request_io(link, &link->io) != 0) goto next_entry; /* If we've got this far, we're done */ break; @@ -203,10 +177,10 @@ static void ixj_config(dev_link_t * link) next_entry: if (cfg->flags & CISTPL_CFTABLE_DEFAULT) dflt = *cfg; - CS_CHECK(GetNextTuple, pcmcia_get_next_tuple(handle, &tuple)); + CS_CHECK(GetNextTuple, pcmcia_get_next_tuple(link, &tuple)); } - CS_CHECK(RequestConfiguration, pcmcia_request_configuration(handle, &link->conf)); + CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf)); /* * Register the card with the core. @@ -215,46 +189,21 @@ static void ixj_config(dev_link_t * link) info->ndev = 1; info->node.major = PHONE_MAJOR; - link->dev = &info->node; + link->dev_node = &info->node; ixj_get_serial(link, j); - link->state &= ~DEV_CONFIG_PENDING; - return; + return 0; cs_failed: - cs_error(link->handle, last_fn, last_ret); + cs_error(link, last_fn, last_ret); ixj_cs_release(link); + return -ENODEV; } -static void ixj_cs_release(dev_link_t *link) +static void ixj_cs_release(struct pcmcia_device *link) { ixj_info_t *info = link->priv; DEBUG(0, "ixj_cs_release(0x%p)\n", link); info->ndev = 0; - link->dev = NULL; - pcmcia_release_configuration(link->handle); - pcmcia_release_io(link->handle, &link->io); - link->state &= ~DEV_CONFIG; -} - -static int ixj_suspend(struct pcmcia_device *dev) -{ - dev_link_t *link = dev_to_instance(dev); - - link->state |= DEV_SUSPEND; - if (link->state & DEV_CONFIG) - pcmcia_release_configuration(link->handle); - - return 0; -} - -static int ixj_resume(struct pcmcia_device *dev) -{ - dev_link_t *link = dev_to_instance(dev); - - link->state &= ~DEV_SUSPEND; - if (DEV_OK(link)) - pcmcia_request_configuration(link->handle, &link->conf); - - return 0; + pcmcia_disable_device(link); } static struct pcmcia_device_id ixj_ids[] = { @@ -268,11 +217,9 @@ static struct pcmcia_driver ixj_driver = { .drv = { .name = "ixj_cs", }, - .probe = ixj_attach, + .probe = ixj_probe, .remove = ixj_detach, .id_table = ixj_ids, - .suspend = ixj_suspend, - .resume = ixj_resume, }; static int __init ixj_pcmcia_init(void) diff --git a/drivers/usb/host/sl811_cs.c b/drivers/usb/host/sl811_cs.c index 134d2000128..302aa1ec312 100644 --- a/drivers/usb/host/sl811_cs.c +++ b/drivers/usb/host/sl811_cs.c @@ -67,11 +67,11 @@ module_param(pc_debug, int, 0644); static const char driver_name[DEV_NAME_LEN] = "sl811_cs"; typedef struct local_info_t { - dev_link_t link; + struct pcmcia_device *p_dev; dev_node_t node; } local_info_t; -static void sl811_cs_release(dev_link_t * link); +static void sl811_cs_release(struct pcmcia_device * link); /*====================================================================*/ @@ -138,41 +138,27 @@ static int sl811_hc_init(struct device *parent, ioaddr_t base_addr, int irq) /*====================================================================*/ -static void sl811_cs_detach(struct pcmcia_device *p_dev) +static void sl811_cs_detach(struct pcmcia_device *link) { - dev_link_t *link = dev_to_instance(p_dev); - DBG(0, "sl811_cs_detach(0x%p)\n", link); - link->state &= ~DEV_PRESENT; - if (link->state & DEV_CONFIG) - sl811_cs_release(link); + sl811_cs_release(link); /* This points to the parent local_info_t struct */ kfree(link->priv); } -static void sl811_cs_release(dev_link_t * link) +static void sl811_cs_release(struct pcmcia_device * link) { - DBG(0, "sl811_cs_release(0x%p)\n", link); - /* Unlink the device chain */ - link->dev = NULL; - + pcmcia_disable_device(link); platform_device_unregister(&platform_dev); - pcmcia_release_configuration(link->handle); - if (link->io.NumPorts1) - pcmcia_release_io(link->handle, &link->io); - if (link->irq.AssignedIRQ) - pcmcia_release_irq(link->handle, &link->irq); - link->state &= ~DEV_CONFIG; } -static void sl811_cs_config(dev_link_t *link) +static int sl811_cs_config(struct pcmcia_device *link) { - client_handle_t handle = link->handle; - struct device *parent = &handle_to_dev(handle); + struct device *parent = &handle_to_dev(link); local_info_t *dev = link->priv; tuple_t tuple; cisparse_t parse; @@ -188,27 +174,23 @@ static void sl811_cs_config(dev_link_t *link) tuple.TupleData = buf; tuple.TupleDataMax = sizeof(buf); tuple.TupleOffset = 0; - CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple)); - CS_CHECK(GetTupleData, pcmcia_get_tuple_data(handle, &tuple)); - CS_CHECK(ParseTuple, pcmcia_parse_tuple(handle, &tuple, &parse)); + CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); + CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple)); + CS_CHECK(ParseTuple, pcmcia_parse_tuple(link, &tuple, &parse)); link->conf.ConfigBase = parse.config.base; link->conf.Present = parse.config.rmask[0]; - /* Configure card */ - link->state |= DEV_CONFIG; - /* Look up the current Vcc */ CS_CHECK(GetConfigurationInfo, - pcmcia_get_configuration_info(handle, &conf)); - link->conf.Vcc = conf.Vcc; + pcmcia_get_configuration_info(link, &conf)); tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; - CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple)); + CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); while (1) { cistpl_cftable_entry_t *cfg = &(parse.cftable_entry); - if (pcmcia_get_tuple_data(handle, &tuple) != 0 - || pcmcia_parse_tuple(handle, &tuple, &parse) + if (pcmcia_get_tuple_data(link, &tuple) != 0 + || pcmcia_parse_tuple(link, &tuple, &parse) != 0) goto next_entry; @@ -234,10 +216,10 @@ static void sl811_cs_config(dev_link_t *link) } if (cfg->vpp1.present & (1<<CISTPL_POWER_VNOM)) - link->conf.Vpp1 = link->conf.Vpp2 = + link->conf.Vpp = cfg->vpp1.param[CISTPL_POWER_VNOM]/10000; else if (dflt.vpp1.present & (1<<CISTPL_POWER_VNOM)) - link->conf.Vpp1 = link->conf.Vpp2 = + link->conf.Vpp = dflt.vpp1.param[CISTPL_POWER_VNOM]/10000; /* we need an interrupt */ @@ -254,15 +236,14 @@ static void sl811_cs_config(dev_link_t *link) link->io.BasePort1 = io->win[0].base; link->io.NumPorts1 = io->win[0].len; - if (pcmcia_request_io(link->handle, &link->io) != 0) + if (pcmcia_request_io(link, &link->io) != 0) goto next_entry; } break; next_entry: - if (link->io.NumPorts1) - pcmcia_release_io(link->handle, &link->io); - last_ret = pcmcia_get_next_tuple(handle, &tuple); + pcmcia_disable_device(link); + last_ret = pcmcia_get_next_tuple(link, &tuple); } /* require an IRQ and two registers */ @@ -270,71 +251,46 @@ next_entry: goto cs_failed; if (link->conf.Attributes & CONF_ENABLE_IRQ) CS_CHECK(RequestIRQ, - pcmcia_request_irq(link->handle, &link->irq)); + pcmcia_request_irq(link, &link->irq)); else goto cs_failed; CS_CHECK(RequestConfiguration, - pcmcia_request_configuration(link->handle, &link->conf)); + pcmcia_request_configuration(link, &link->conf)); sprintf(dev->node.dev_name, driver_name); dev->node.major = dev->node.minor = 0; - link->dev = &dev->node; + link->dev_node = &dev->node; - printk(KERN_INFO "%s: index 0x%02x: Vcc %d.%d", - dev->node.dev_name, link->conf.ConfigIndex, - link->conf.Vcc/10, link->conf.Vcc%10); - if (link->conf.Vpp1) - printk(", Vpp %d.%d", link->conf.Vpp1/10, link->conf.Vpp1%10); + printk(KERN_INFO "%s: index 0x%02x: ", + dev->node.dev_name, link->conf.ConfigIndex); + if (link->conf.Vpp) + printk(", Vpp %d.%d", link->conf.Vpp/10, link->conf.Vpp%10); printk(", irq %d", link->irq.AssignedIRQ); printk(", io 0x%04x-0x%04x", link->io.BasePort1, link->io.BasePort1+link->io.NumPorts1-1); printk("\n"); - link->state &= ~DEV_CONFIG_PENDING; - if (sl811_hc_init(parent, link->io.BasePort1, link->irq.AssignedIRQ) < 0) { cs_failed: printk("sl811_cs_config failed\n"); - cs_error(link->handle, last_fn, last_ret); + cs_error(link, last_fn, last_ret); sl811_cs_release(link); - link->state &= ~DEV_CONFIG_PENDING; + return -ENODEV; } -} - -static int sl811_suspend(struct pcmcia_device *dev) -{ - dev_link_t *link = dev_to_instance(dev); - - link->state |= DEV_SUSPEND; - if (link->state & DEV_CONFIG) - pcmcia_release_configuration(link->handle); - - return 0; -} - -static int sl811_resume(struct pcmcia_device *dev) -{ - dev_link_t *link = dev_to_instance(dev); - - link->state &= ~DEV_SUSPEND; - if (link->state & DEV_CONFIG) - pcmcia_request_configuration(link->handle, &link->conf); - return 0; } -static int sl811_cs_attach(struct pcmcia_device *p_dev) +static int sl811_cs_probe(struct pcmcia_device *link) { local_info_t *local; - dev_link_t *link; local = kmalloc(sizeof(local_info_t), GFP_KERNEL); if (!local) return -ENOMEM; memset(local, 0, sizeof(local_info_t)); - link = &local->link; + local->p_dev = link; link->priv = local; /* Initialize */ @@ -343,16 +299,9 @@ static int sl811_cs_attach(struct pcmcia_device *p_dev) link->irq.Handler = NULL; link->conf.Attributes = 0; - link->conf.Vcc = 33; link->conf.IntType = INT_MEMORY_AND_IO; - link->handle = p_dev; - p_dev->instance = link; - - link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; - sl811_cs_config(link); - - return 0; + return sl811_cs_config(link); } static struct pcmcia_device_id sl811_ids[] = { @@ -366,11 +315,9 @@ static struct pcmcia_driver sl811_cs_driver = { .drv = { .name = (char *)driver_name, }, - .probe = sl811_cs_attach, + .probe = sl811_cs_probe, .remove = sl811_cs_detach, .id_table = sl811_ids, - .suspend = sl811_suspend, - .resume = sl811_resume, }; /*====================================================================*/ diff --git a/drivers/usb/input/hid-input.c b/drivers/usb/input/hid-input.c index cb0d80f4925..25bc85f8ce3 100644 --- a/drivers/usb/input/hid-input.c +++ b/drivers/usb/input/hid-input.c @@ -510,7 +510,7 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel case 0x025: map_key_clear(KEY_TV); break; case 0x026: map_key_clear(KEY_MENU); break; case 0x031: map_key_clear(KEY_AUDIO); break; - case 0x032: map_key_clear(KEY_SUBTITLE); break; + case 0x032: map_key_clear(KEY_TEXT); break; case 0x033: map_key_clear(KEY_LAST); break; case 0x047: map_key_clear(KEY_MP3); break; case 0x048: map_key_clear(KEY_DVD); break; diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig index 22e9d696fdd..f87c0171f4e 100644 --- a/drivers/video/Kconfig +++ b/drivers/video/Kconfig @@ -904,18 +904,6 @@ config FB_MATROX_MULTIHEAD There is no need for enabling 'Matrox multihead support' if you have only one Matrox card in the box. -config FB_RADEON_OLD - tristate "ATI Radeon display support (Old driver)" - depends on FB && PCI - select FB_CFB_FILLRECT - select FB_CFB_COPYAREA - select FB_CFB_IMAGEBLIT - select FB_MACMODES if PPC - help - Choose this option if you want to use an ATI Radeon graphics card as - a framebuffer device. There are both PCI and AGP versions. You - don't need to choose this to run the Radeon in plain VGA mode. - config FB_RADEON tristate "ATI Radeon display support" depends on FB && PCI diff --git a/drivers/video/Makefile b/drivers/video/Makefile index cb90218515a..23de3b2c785 100644 --- a/drivers/video/Makefile +++ b/drivers/video/Makefile @@ -39,7 +39,6 @@ obj-$(CONFIG_FB_KYRO) += kyro/ obj-$(CONFIG_FB_SAVAGE) += savage/ obj-$(CONFIG_FB_GEODE) += geode/ obj-$(CONFIG_FB_I810) += vgastate.o -obj-$(CONFIG_FB_RADEON_OLD) += radeonfb.o obj-$(CONFIG_FB_NEOMAGIC) += neofb.o vgastate.o obj-$(CONFIG_FB_VIRGE) += virgefb.o obj-$(CONFIG_FB_3DFX) += tdfxfb.o diff --git a/drivers/video/backlight/Kconfig b/drivers/video/backlight/Kconfig index 9d996f2c10d..b895eaaa73f 100644 --- a/drivers/video/backlight/Kconfig +++ b/drivers/video/backlight/Kconfig @@ -43,11 +43,11 @@ config LCD_DEVICE default y config BACKLIGHT_CORGI - tristate "Sharp Corgi Backlight Driver (SL-C7xx Series)" + tristate "Sharp Corgi Backlight Driver (SL Series)" depends on BACKLIGHT_DEVICE && PXA_SHARPSL default y help - If you have a Sharp Zaurus SL-C7xx, say y to enable the + If you have a Sharp Zaurus SL-C7xx, SL-Cxx00 or SL-6000x say y to enable the backlight driver. config BACKLIGHT_HP680 diff --git a/drivers/video/backlight/backlight.c b/drivers/video/backlight/backlight.c index 151fda8dded..334b1db1bd7 100644 --- a/drivers/video/backlight/backlight.c +++ b/drivers/video/backlight/backlight.c @@ -16,14 +16,12 @@ static ssize_t backlight_show_power(struct class_device *cdev, char *buf) { - int rc; + int rc = -ENXIO; struct backlight_device *bd = to_backlight_device(cdev); down(&bd->sem); - if (likely(bd->props && bd->props->get_power)) - rc = sprintf(buf, "%d\n", bd->props->get_power(bd)); - else - rc = -ENXIO; + if (likely(bd->props)) + rc = sprintf(buf, "%d\n", bd->props->power); up(&bd->sem); return rc; @@ -31,7 +29,7 @@ static ssize_t backlight_show_power(struct class_device *cdev, char *buf) static ssize_t backlight_store_power(struct class_device *cdev, const char *buf, size_t count) { - int rc, power; + int rc = -ENXIO, power; char *endp; struct backlight_device *bd = to_backlight_device(cdev); @@ -40,12 +38,13 @@ static ssize_t backlight_store_power(struct class_device *cdev, const char *buf, return -EINVAL; down(&bd->sem); - if (likely(bd->props && bd->props->set_power)) { + if (likely(bd->props)) { pr_debug("backlight: set power to %d\n", power); - bd->props->set_power(bd, power); + bd->props->power = power; + if (likely(bd->props->update_status)) + bd->props->update_status(bd); rc = count; - } else - rc = -ENXIO; + } up(&bd->sem); return rc; @@ -53,14 +52,12 @@ static ssize_t backlight_store_power(struct class_device *cdev, const char *buf, static ssize_t backlight_show_brightness(struct class_device *cdev, char *buf) { - int rc; + int rc = -ENXIO; struct backlight_device *bd = to_backlight_device(cdev); down(&bd->sem); - if (likely(bd->props && bd->props->get_brightness)) - rc = sprintf(buf, "%d\n", bd->props->get_brightness(bd)); - else - rc = -ENXIO; + if (likely(bd->props)) + rc = sprintf(buf, "%d\n", bd->props->brightness); up(&bd->sem); return rc; @@ -68,7 +65,7 @@ static ssize_t backlight_show_brightness(struct class_device *cdev, char *buf) static ssize_t backlight_store_brightness(struct class_device *cdev, const char *buf, size_t count) { - int rc, brightness; + int rc = -ENXIO, brightness; char *endp; struct backlight_device *bd = to_backlight_device(cdev); @@ -77,12 +74,18 @@ static ssize_t backlight_store_brightness(struct class_device *cdev, const char return -EINVAL; down(&bd->sem); - if (likely(bd->props && bd->props->set_brightness)) { - pr_debug("backlight: set brightness to %d\n", brightness); - bd->props->set_brightness(bd, brightness); - rc = count; - } else - rc = -ENXIO; + if (likely(bd->props)) { + if (brightness > bd->props->max_brightness) + rc = -EINVAL; + else { + pr_debug("backlight: set brightness to %d\n", + brightness); + bd->props->brightness = brightness; + if (likely(bd->props->update_status)) + bd->props->update_status(bd); + rc = count; + } + } up(&bd->sem); return rc; @@ -90,14 +93,26 @@ static ssize_t backlight_store_brightness(struct class_device *cdev, const char static ssize_t backlight_show_max_brightness(struct class_device *cdev, char *buf) { - int rc; + int rc = -ENXIO; struct backlight_device *bd = to_backlight_device(cdev); down(&bd->sem); if (likely(bd->props)) rc = sprintf(buf, "%d\n", bd->props->max_brightness); - else - rc = -ENXIO; + up(&bd->sem); + + return rc; +} + +static ssize_t backlight_show_actual_brightness(struct class_device *cdev, + char *buf) +{ + int rc = -ENXIO; + struct backlight_device *bd = to_backlight_device(cdev); + + down(&bd->sem); + if (likely(bd->props && bd->props->get_brightness)) + rc = sprintf(buf, "%d\n", bd->props->get_brightness(bd)); up(&bd->sem); return rc; @@ -123,7 +138,10 @@ static struct class backlight_class = { static struct class_device_attribute bl_class_device_attributes[] = { DECLARE_ATTR(power, 0644, backlight_show_power, backlight_store_power), - DECLARE_ATTR(brightness, 0644, backlight_show_brightness, backlight_store_brightness), + DECLARE_ATTR(brightness, 0644, backlight_show_brightness, + backlight_store_brightness), + DECLARE_ATTR(actual_brightness, 0444, backlight_show_actual_brightness, + NULL), DECLARE_ATTR(max_brightness, 0444, backlight_show_max_brightness, NULL), }; @@ -144,8 +162,12 @@ static int fb_notifier_callback(struct notifier_block *self, bd = container_of(self, struct backlight_device, fb_notif); down(&bd->sem); if (bd->props) - if (!bd->props->check_fb || bd->props->check_fb(evdata->info)) - bd->props->set_power(bd, *(int *)evdata->data); + if (!bd->props->check_fb || + bd->props->check_fb(evdata->info)) { + bd->props->fb_blank = *(int *)evdata->data; + if (likely(bd->props && bd->props->update_status)) + bd->props->update_status(bd); + } up(&bd->sem); return 0; } @@ -231,6 +253,12 @@ void backlight_device_unregister(struct backlight_device *bd) &bl_class_device_attributes[i]); down(&bd->sem); + if (likely(bd->props && bd->props->update_status)) { + bd->props->brightness = 0; + bd->props->power = 0; + bd->props->update_status(bd); + } + bd->props = NULL; up(&bd->sem); diff --git a/drivers/video/backlight/corgi_bl.c b/drivers/video/backlight/corgi_bl.c index d0aaf450e8c..2ebbfd95145 100644 --- a/drivers/video/backlight/corgi_bl.c +++ b/drivers/video/backlight/corgi_bl.c @@ -1,7 +1,7 @@ /* - * Backlight Driver for Sharp Corgi + * Backlight Driver for Sharp Zaurus Handhelds (various models) * - * Copyright (c) 2004-2005 Richard Purdie + * Copyright (c) 2004-2006 Richard Purdie * * Based on Sharp's 2.4 Backlight Driver * @@ -15,80 +15,63 @@ #include <linux/kernel.h> #include <linux/init.h> #include <linux/platform_device.h> -#include <linux/spinlock.h> +#include <linux/mutex.h> #include <linux/fb.h> #include <linux/backlight.h> - #include <asm/arch/sharpsl.h> #include <asm/hardware/sharpsl_pm.h> -#define CORGI_DEFAULT_INTENSITY 0x1f -#define CORGI_LIMIT_MASK 0x0b - -static int corgibl_powermode = FB_BLANK_UNBLANK; -static int current_intensity = 0; -static int corgibl_limit = 0; -static void (*corgibl_mach_set_intensity)(int intensity); -static spinlock_t bl_lock = SPIN_LOCK_UNLOCKED; +static int corgibl_intensity; +static DEFINE_MUTEX(bl_mutex); static struct backlight_properties corgibl_data; +static struct backlight_device *corgi_backlight_device; +static struct corgibl_machinfo *bl_machinfo; -static void corgibl_send_intensity(int intensity) +static unsigned long corgibl_flags; +#define CORGIBL_SUSPENDED 0x01 +#define CORGIBL_BATTLOW 0x02 + +static int corgibl_send_intensity(struct backlight_device *bd) { - unsigned long flags; void (*corgi_kick_batt)(void); + int intensity = bd->props->brightness; - if (corgibl_powermode != FB_BLANK_UNBLANK) { + if (bd->props->power != FB_BLANK_UNBLANK) intensity = 0; - } else { - if (corgibl_limit) - intensity &= CORGI_LIMIT_MASK; - } - - spin_lock_irqsave(&bl_lock, flags); + if (bd->props->fb_blank != FB_BLANK_UNBLANK) + intensity = 0; + if (corgibl_flags & CORGIBL_SUSPENDED) + intensity = 0; + if (corgibl_flags & CORGIBL_BATTLOW) + intensity &= bl_machinfo->limit_mask; - corgibl_mach_set_intensity(intensity); + mutex_lock(&bl_mutex); + bl_machinfo->set_bl_intensity(intensity); + mutex_unlock(&bl_mutex); - spin_unlock_irqrestore(&bl_lock, flags); + corgibl_intensity = intensity; corgi_kick_batt = symbol_get(sharpsl_battery_kick); if (corgi_kick_batt) { corgi_kick_batt(); symbol_put(sharpsl_battery_kick); } -} -static void corgibl_blank(int blank) -{ - switch(blank) { - - case FB_BLANK_NORMAL: - case FB_BLANK_VSYNC_SUSPEND: - case FB_BLANK_HSYNC_SUSPEND: - case FB_BLANK_POWERDOWN: - if (corgibl_powermode == FB_BLANK_UNBLANK) { - corgibl_send_intensity(0); - corgibl_powermode = blank; - } - break; - case FB_BLANK_UNBLANK: - if (corgibl_powermode != FB_BLANK_UNBLANK) { - corgibl_powermode = blank; - corgibl_send_intensity(current_intensity); - } - break; - } + return 0; } #ifdef CONFIG_PM static int corgibl_suspend(struct platform_device *dev, pm_message_t state) { - corgibl_blank(FB_BLANK_POWERDOWN); + corgibl_flags |= CORGIBL_SUSPENDED; + corgibl_send_intensity(corgi_backlight_device); return 0; } static int corgibl_resume(struct platform_device *dev) { - corgibl_blank(FB_BLANK_UNBLANK); + corgibl_flags &= ~CORGIBL_SUSPENDED; + corgibl_send_intensity(corgi_backlight_device); return 0; } #else @@ -96,68 +79,55 @@ static int corgibl_resume(struct platform_device *dev) #define corgibl_resume NULL #endif - -static int corgibl_set_power(struct backlight_device *bd, int state) -{ - corgibl_blank(state); - return 0; -} - -static int corgibl_get_power(struct backlight_device *bd) +static int corgibl_get_intensity(struct backlight_device *bd) { - return corgibl_powermode; + return corgibl_intensity; } -static int corgibl_set_intensity(struct backlight_device *bd, int intensity) +static int corgibl_set_intensity(struct backlight_device *bd) { - if (intensity > corgibl_data.max_brightness) - intensity = corgibl_data.max_brightness; - corgibl_send_intensity(intensity); - current_intensity=intensity; + corgibl_send_intensity(corgi_backlight_device); return 0; } -static int corgibl_get_intensity(struct backlight_device *bd) -{ - return current_intensity; -} - /* * Called when the battery is low to limit the backlight intensity. * If limit==0 clear any limit, otherwise limit the intensity */ void corgibl_limit_intensity(int limit) { - corgibl_limit = (limit ? 1 : 0); - corgibl_send_intensity(current_intensity); + if (limit) + corgibl_flags |= CORGIBL_BATTLOW; + else + corgibl_flags &= ~CORGIBL_BATTLOW; + corgibl_send_intensity(corgi_backlight_device); } EXPORT_SYMBOL(corgibl_limit_intensity); static struct backlight_properties corgibl_data = { - .owner = THIS_MODULE, - .get_power = corgibl_get_power, - .set_power = corgibl_set_power, + .owner = THIS_MODULE, .get_brightness = corgibl_get_intensity, - .set_brightness = corgibl_set_intensity, + .update_status = corgibl_set_intensity, }; -static struct backlight_device *corgi_backlight_device; - static int __init corgibl_probe(struct platform_device *pdev) { struct corgibl_machinfo *machinfo = pdev->dev.platform_data; + bl_machinfo = machinfo; corgibl_data.max_brightness = machinfo->max_intensity; - corgibl_mach_set_intensity = machinfo->set_bl_intensity; + if (!machinfo->limit_mask) + machinfo->limit_mask = -1; corgi_backlight_device = backlight_device_register ("corgi-bl", NULL, &corgibl_data); if (IS_ERR (corgi_backlight_device)) return PTR_ERR (corgi_backlight_device); - corgibl_set_intensity(NULL, CORGI_DEFAULT_INTENSITY); - corgibl_limit_intensity(0); + corgibl_data.power = FB_BLANK_UNBLANK; + corgibl_data.brightness = machinfo->default_intensity; + corgibl_send_intensity(corgi_backlight_device); printk("Corgi Backlight Driver Initialized.\n"); return 0; @@ -167,8 +137,6 @@ static int corgibl_remove(struct platform_device *dev) { backlight_device_unregister(corgi_backlight_device); - corgibl_set_intensity(NULL, 0); - printk("Corgi Backlight Driver Unloaded\n"); return 0; } diff --git a/drivers/video/backlight/hp680_bl.c b/drivers/video/backlight/hp680_bl.c index 95da4c9ed1f..a71e984c93d 100644 --- a/drivers/video/backlight/hp680_bl.c +++ b/drivers/video/backlight/hp680_bl.c @@ -13,7 +13,7 @@ #include <linux/module.h> #include <linux/kernel.h> #include <linux/init.h> -#include <linux/device.h> +#include <linux/platform_device.h> #include <linux/spinlock.h> #include <linux/fb.h> #include <linux/backlight.h> @@ -25,66 +25,58 @@ #define HP680_MAX_INTENSITY 255 #define HP680_DEFAULT_INTENSITY 10 -static int hp680bl_powermode = FB_BLANK_UNBLANK; +static int hp680bl_suspended; static int current_intensity = 0; static spinlock_t bl_lock = SPIN_LOCK_UNLOCKED; +static struct backlight_device *hp680_backlight_device; -static void hp680bl_send_intensity(int intensity) +static void hp680bl_send_intensity(struct backlight_device *bd) { unsigned long flags; + u16 v; + int intensity = bd->props->brightness; - if (hp680bl_powermode != FB_BLANK_UNBLANK) + if (bd->props->power != FB_BLANK_UNBLANK) + intensity = 0; + if (bd->props->fb_blank != FB_BLANK_UNBLANK) + intensity = 0; + if (hp680bl_suspended) intensity = 0; spin_lock_irqsave(&bl_lock, flags); - sh_dac_output(255-(u8)intensity, DAC_LCD_BRIGHTNESS); + if (intensity && current_intensity == 0) { + sh_dac_enable(DAC_LCD_BRIGHTNESS); + v = inw(HD64461_GPBDR); + v &= ~HD64461_GPBDR_LCDOFF; + outw(v, HD64461_GPBDR); + sh_dac_output(255-(u8)intensity, DAC_LCD_BRIGHTNESS); + } else if (intensity == 0 && current_intensity != 0) { + sh_dac_output(255-(u8)intensity, DAC_LCD_BRIGHTNESS); + sh_dac_disable(DAC_LCD_BRIGHTNESS); + v = inw(HD64461_GPBDR); + v |= HD64461_GPBDR_LCDOFF; + outw(v, HD64461_GPBDR); + } else if (intensity) { + sh_dac_output(255-(u8)intensity, DAC_LCD_BRIGHTNESS); + } spin_unlock_irqrestore(&bl_lock, flags); -} -static void hp680bl_blank(int blank) -{ - u16 v; - - switch(blank) { - - case FB_BLANK_NORMAL: - case FB_BLANK_VSYNC_SUSPEND: - case FB_BLANK_HSYNC_SUSPEND: - case FB_BLANK_POWERDOWN: - if (hp680bl_powermode == FB_BLANK_UNBLANK) { - hp680bl_send_intensity(0); - hp680bl_powermode = blank; - sh_dac_disable(DAC_LCD_BRIGHTNESS); - v = inw(HD64461_GPBDR); - v |= HD64461_GPBDR_LCDOFF; - outw(v, HD64461_GPBDR); - } - break; - case FB_BLANK_UNBLANK: - if (hp680bl_powermode != FB_BLANK_UNBLANK) { - sh_dac_enable(DAC_LCD_BRIGHTNESS); - v = inw(HD64461_GPBDR); - v &= ~HD64461_GPBDR_LCDOFF; - outw(v, HD64461_GPBDR); - hp680bl_powermode = blank; - hp680bl_send_intensity(current_intensity); - } - break; - } + current_intensity = intensity; } + #ifdef CONFIG_PM -static int hp680bl_suspend(struct device *dev, pm_message_t state, u32 level) +static int hp680bl_suspend(struct platform_device *dev, pm_message_t state) { - if (level == SUSPEND_POWER_DOWN) - hp680bl_blank(FB_BLANK_POWERDOWN); + hp680bl_suspended = 1; + hp680bl_send_intensity(hp680_backlight_device); return 0; } -static int hp680bl_resume(struct device *dev, u32 level) +static int hp680bl_resume(struct platform_device *dev) { - if (level == RESUME_POWER_ON) - hp680bl_blank(FB_BLANK_UNBLANK); + hp680bl_suspended = 0; + hp680bl_send_intensity(hp680_backlight_device); return 0; } #else @@ -92,24 +84,9 @@ static int hp680bl_resume(struct device *dev, u32 level) #define hp680bl_resume NULL #endif - -static int hp680bl_set_power(struct backlight_device *bd, int state) +static int hp680bl_set_intensity(struct backlight_device *bd) { - hp680bl_blank(state); - return 0; -} - -static int hp680bl_get_power(struct backlight_device *bd) -{ - return hp680bl_powermode; -} - -static int hp680bl_set_intensity(struct backlight_device *bd, int intensity) -{ - if (intensity > HP680_MAX_INTENSITY) - intensity = HP680_MAX_INTENSITY; - hp680bl_send_intensity(intensity); - current_intensity = intensity; + hp680bl_send_intensity(bd); return 0; } @@ -120,65 +97,67 @@ static int hp680bl_get_intensity(struct backlight_device *bd) static struct backlight_properties hp680bl_data = { .owner = THIS_MODULE, - .get_power = hp680bl_get_power, - .set_power = hp680bl_set_power, .max_brightness = HP680_MAX_INTENSITY, .get_brightness = hp680bl_get_intensity, - .set_brightness = hp680bl_set_intensity, + .update_status = hp680bl_set_intensity, }; -static struct backlight_device *hp680_backlight_device; - -static int __init hp680bl_probe(struct device *dev) +static int __init hp680bl_probe(struct platform_device *dev) { hp680_backlight_device = backlight_device_register ("hp680-bl", NULL, &hp680bl_data); if (IS_ERR (hp680_backlight_device)) return PTR_ERR (hp680_backlight_device); - hp680bl_set_intensity(NULL, HP680_DEFAULT_INTENSITY); + hp680_backlight_device->props->brightness = HP680_DEFAULT_INTENSITY; + hp680bl_send_intensity(hp680_backlight_device); return 0; } -static int hp680bl_remove(struct device *dev) +static int hp680bl_remove(struct platform_device *dev) { backlight_device_unregister(hp680_backlight_device); return 0; } -static struct device_driver hp680bl_driver = { - .name = "hp680-bl", - .bus = &platform_bus_type, +static struct platform_driver hp680bl_driver = { .probe = hp680bl_probe, .remove = hp680bl_remove, .suspend = hp680bl_suspend, .resume = hp680bl_resume, + .driver = { + .name = "hp680-bl", + }, }; -static struct platform_device hp680bl_device = { - .name = "hp680-bl", - .id = -1, -}; +static struct platform_device *hp680bl_device; static int __init hp680bl_init(void) { int ret; - ret=driver_register(&hp680bl_driver); + ret = platform_driver_register(&hp680bl_driver); if (!ret) { - ret = platform_device_register(&hp680bl_device); - if (ret) - driver_unregister(&hp680bl_driver); + hp680bl_device = platform_device_alloc("hp680-bl", -1); + if (!hp680bl_device) + return -ENOMEM; + + ret = platform_device_add(hp680bl_device); + + if (ret) { + platform_device_put(hp680bl_device); + platform_driver_unregister(&hp680bl_driver); + } } return ret; } static void __exit hp680bl_exit(void) { - platform_device_unregister(&hp680bl_device); - driver_unregister(&hp680bl_driver); + platform_device_unregister(hp680bl_device); + platform_driver_unregister(&hp680bl_driver); } module_init(hp680bl_init); diff --git a/drivers/video/cfbimgblt.c b/drivers/video/cfbimgblt.c index 910e2338a27..8ba6152db2f 100644 --- a/drivers/video/cfbimgblt.c +++ b/drivers/video/cfbimgblt.c @@ -169,7 +169,7 @@ static inline void slow_imageblit(const struct fb_image *image, struct fb_info * while (j--) { l--; - color = (*s & 1 << (FB_BIT_NR(l))) ? fgcolor : bgcolor; + color = (*s & (1 << l)) ? fgcolor : bgcolor; val |= FB_SHIFT_HIGH(color, shift); /* Did the bitshift spill bits to the next long? */ diff --git a/drivers/video/console/fbcon.c b/drivers/video/console/fbcon.c index 041d0698786..ca020719d20 100644 --- a/drivers/video/console/fbcon.c +++ b/drivers/video/console/fbcon.c @@ -466,7 +466,7 @@ static int __init fb_console_setup(char *this_opt) int i, j; if (!this_opt || !*this_opt) - return 0; + return 1; while ((options = strsep(&this_opt, ",")) != NULL) { if (!strncmp(options, "font:", 5)) @@ -481,10 +481,10 @@ static int __init fb_console_setup(char *this_opt) options++; } if (*options != ',') - return 0; + return 1; options++; } else - return 0; + return 1; } if (!strncmp(options, "map:", 4)) { @@ -496,7 +496,7 @@ static int __init fb_console_setup(char *this_opt) con2fb_map_boot[i] = (options[j++]-'0') % FB_MAX; } - return 0; + return 1; } if (!strncmp(options, "vc:", 3)) { @@ -518,7 +518,7 @@ static int __init fb_console_setup(char *this_opt) rotate = 0; } } - return 0; + return 1; } __setup("fbcon=", fb_console_setup); @@ -1142,6 +1142,7 @@ static void fbcon_init(struct vc_data *vc, int init) set_blitting_type(vc, info); } + ops->p = &fb_display[fg_console]; } static void fbcon_deinit(struct vc_data *vc) diff --git a/drivers/video/console/sticore.c b/drivers/video/console/sticore.c index 0339f5640a7..74ac2acaf72 100644 --- a/drivers/video/console/sticore.c +++ b/drivers/video/console/sticore.c @@ -275,7 +275,7 @@ static int __init sti_setup(char *str) if (str) strlcpy (default_sti_path, str, sizeof (default_sti_path)); - return 0; + return 1; } /* Assuming the machine has multiple STI consoles (=graphic cards) which @@ -321,7 +321,7 @@ static int __init sti_font_setup(char *str) i++; } - return 0; + return 1; } /* The optional linux kernel parameter "sti_font" defines which font @@ -373,7 +373,7 @@ sti_dump_globcfg(struct sti_glob_cfg *glob_cfg, unsigned int sti_mem_request) glob_cfg->save_addr)); /* dump extended cfg */ - cfg = PTR_STI(glob_cfg->ext_ptr); + cfg = PTR_STI((unsigned long)glob_cfg->ext_ptr); DPRINTK(( KERN_INFO "monitor %d\n" "in friendly mode: %d\n" @@ -453,25 +453,11 @@ sti_init_glob_cfg(struct sti_struct *sti, sti->regions_phys[i] = REGION_OFFSET_TO_PHYS(sti->regions[i], newhpa); - /* remap virtually */ - /* FIXME: add BTLB support if btlb==1 */ len = sti->regions[i].region_desc.length * 4096; - -/* XXX: Enabling IOREMAP debugging causes a crash, so we must be passing - * a virtual address to something expecting a physical address that doesn't - * go through a readX macro */ -#if 0 - if (len) - glob_cfg->region_ptrs[i] = (unsigned long) ( - sti->regions[i].region_desc.cache ? - ioremap(sti->regions_phys[i], len) : - ioremap_nocache(sti->regions_phys[i], len) ); -#else if (len) glob_cfg->region_ptrs[i] = sti->regions_phys[i]; -#endif - DPRINTK(("region #%d: phys %08lx, virt %08x, len=%lukB, " + DPRINTK(("region #%d: phys %08lx, region_ptr %08x, len=%lukB, " "btlb=%d, sysonly=%d, cache=%d, last=%d\n", i, sti->regions_phys[i], glob_cfg->region_ptrs[i], len/1024, diff --git a/drivers/video/fbmem.c b/drivers/video/fbmem.c index b1a8dca7643..944855b3e4a 100644 --- a/drivers/video/fbmem.c +++ b/drivers/video/fbmem.c @@ -1588,7 +1588,7 @@ static int __init video_setup(char *options) } } - return 0; + return 1; } __setup("video=", video_setup); #endif diff --git a/drivers/video/pxafb.c b/drivers/video/pxafb.c index 53ad61f1038..809fc5eefc1 100644 --- a/drivers/video/pxafb.c +++ b/drivers/video/pxafb.c @@ -232,9 +232,9 @@ static int pxafb_check_var(struct fb_var_screeninfo *var, struct fb_info *info) if (var->yres < MIN_YRES) var->yres = MIN_YRES; if (var->xres > fbi->max_xres) - var->xres = fbi->max_xres; + return -EINVAL; if (var->yres > fbi->max_yres) - var->yres = fbi->max_yres; + return -EINVAL; var->xres_virtual = max(var->xres_virtual, var->xres); var->yres_virtual = @@ -781,7 +781,7 @@ static void pxafb_disable_controller(struct pxafb_info *fbi) LCCR0 &= ~LCCR0_LDM; /* Enable LCD Disable Done Interrupt */ LCCR0 |= LCCR0_DIS; /* Disable LCD Controller */ - schedule_timeout(20 * HZ / 1000); + schedule_timeout(200 * HZ / 1000); remove_wait_queue(&fbi->ctrlr_wait, &wait); /* disable LCD controller clock */ @@ -1274,7 +1274,7 @@ int __init pxafb_probe(struct platform_device *dev) struct pxafb_mach_info *inf; int ret; - dev_dbg(dev, "pxafb_probe\n"); + dev_dbg(&dev->dev, "pxafb_probe\n"); inf = dev->dev.platform_data; ret = -ENOMEM; diff --git a/drivers/video/radeonfb.c b/drivers/video/radeonfb.c deleted file mode 100644 index afb6c2ead59..00000000000 --- a/drivers/video/radeonfb.c +++ /dev/null @@ -1,3167 +0,0 @@ -/* - * drivers/video/radeonfb.c - * framebuffer driver for ATI Radeon chipset video boards - * - * Copyright 2000 Ani Joshi <ajoshi@kernel.crashing.org> - * - * - * ChangeLog: - * 2000-08-03 initial version 0.0.1 - * 2000-09-10 more bug fixes, public release 0.0.5 - * 2001-02-19 mode bug fixes, 0.0.7 - * 2001-07-05 fixed scrolling issues, engine initialization, - * and minor mode tweaking, 0.0.9 - * 2001-09-07 Radeon VE support, Nick Kurshev - * blanking, pan_display, and cmap fixes, 0.1.0 - * 2001-10-10 Radeon 7500 and 8500 support, and experimental - * flat panel support, 0.1.1 - * 2001-11-17 Radeon M6 (ppc) support, Daniel Berlin, 0.1.2 - * 2001-11-18 DFP fixes, Kevin Hendricks, 0.1.3 - * 2001-11-29 more cmap, backlight fixes, Benjamin Herrenschmidt - * 2002-01-18 DFP panel detection via BIOS, Michael Clark, 0.1.4 - * 2002-06-02 console switching, mode set fixes, accel fixes - * 2002-06-03 MTRR support, Peter Horton, 0.1.5 - * 2002-09-21 rv250, r300, m9 initial support, - * added mirror option, 0.1.6 - * - * Special thanks to ATI DevRel team for their hardware donations. - * - */ - - -#define RADEON_VERSION "0.1.6" - - -#include <linux/config.h> -#include <linux/module.h> -#include <linux/kernel.h> -#include <linux/errno.h> -#include <linux/string.h> -#include <linux/mm.h> -#include <linux/tty.h> -#include <linux/slab.h> -#include <linux/delay.h> -#include <linux/fb.h> -#include <linux/ioport.h> -#include <linux/init.h> -#include <linux/pci.h> -#include <linux/vmalloc.h> - -#include <asm/io.h> -#include <asm/uaccess.h> -#if defined(__powerpc__) -#include <asm/prom.h> -#include <asm/pci-bridge.h> -#include "macmodes.h" - -#ifdef CONFIG_NVRAM -#include <linux/nvram.h> -#endif - -#ifdef CONFIG_PMAC_BACKLIGHT -#include <asm/backlight.h> -#endif - -#ifdef CONFIG_BOOTX_TEXT -#include <asm/btext.h> -#endif - -#ifdef CONFIG_ADB_PMU -#include <linux/adb.h> -#include <linux/pmu.h> -#endif - -#endif /* __powerpc__ */ - -#ifdef CONFIG_MTRR -#include <asm/mtrr.h> -#endif - -#include <video/radeon.h> -#include <linux/radeonfb.h> - -#define DEBUG 0 - -#if DEBUG -#define RTRACE printk -#else -#define RTRACE if(0) printk -#endif - -// XXX -#undef CONFIG_PMAC_PBOOK - - -enum radeon_chips { - RADEON_QD, - RADEON_QE, - RADEON_QF, - RADEON_QG, - RADEON_QY, - RADEON_QZ, - RADEON_LW, - RADEON_LX, - RADEON_LY, - RADEON_LZ, - RADEON_QL, - RADEON_QN, - RADEON_QO, - RADEON_Ql, - RADEON_BB, - RADEON_QW, - RADEON_QX, - RADEON_Id, - RADEON_Ie, - RADEON_If, - RADEON_Ig, - RADEON_Ya, - RADEON_Yd, - RADEON_Ld, - RADEON_Le, - RADEON_Lf, - RADEON_Lg, - RADEON_ND, - RADEON_NE, - RADEON_NF, - RADEON_NG, - RADEON_QM -}; - -enum radeon_arch { - RADEON_R100, - RADEON_RV100, - RADEON_R200, - RADEON_RV200, - RADEON_RV250, - RADEON_R300, - RADEON_M6, - RADEON_M7, - RADEON_M9 -}; - -static struct radeon_chip_info { - const char *name; - unsigned char arch; -} radeon_chip_info[] __devinitdata = { - { "QD", RADEON_R100 }, - { "QE", RADEON_R100 }, - { "QF", RADEON_R100 }, - { "QG", RADEON_R100 }, - { "VE QY", RADEON_RV100 }, - { "VE QZ", RADEON_RV100 }, - { "M7 LW", RADEON_M7 }, - { "M7 LX", RADEON_M7 }, - { "M6 LY", RADEON_M6 }, - { "M6 LZ", RADEON_M6 }, - { "8500 QL", RADEON_R200 }, - { "8500 QN", RADEON_R200 }, - { "8500 QO", RADEON_R200 }, - { "8500 Ql", RADEON_R200 }, - { "8500 BB", RADEON_R200 }, - { "7500 QW", RADEON_RV200 }, - { "7500 QX", RADEON_RV200 }, - { "9000 Id", RADEON_RV250 }, - { "9000 Ie", RADEON_RV250 }, - { "9000 If", RADEON_RV250 }, - { "9000 Ig", RADEON_RV250 }, - { "M9 Ld", RADEON_M9 }, - { "M9 Le", RADEON_M9 }, - { "M9 Lf", RADEON_M9 }, - { "M9 Lg", RADEON_M9 }, - { "9700 ND", RADEON_R300 }, - { "9700 NE", RADEON_R300 }, - { "9700 NF", RADEON_R300 }, - { "9700 NG", RADEON_R300 }, - { "9100 QM", RADEON_R200 } -}; - - -enum radeon_montype -{ - MT_NONE, - MT_CRT, /* CRT */ - MT_LCD, /* LCD */ - MT_DFP, /* DVI */ - MT_CTV, /* composite TV */ - MT_STV /* S-Video out */ -}; - - -static struct pci_device_id radeonfb_pci_table[] = { - { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_QD, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_QD}, - { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_QE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_QE}, - { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_QF, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_QF}, - { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_QG, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_QG}, - { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_QY, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_QY}, - { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_QZ, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_QZ}, - { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_LW, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_LW}, - { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_LX, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_LX}, - { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_LY, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_LY}, - { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_LZ, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_LZ}, - { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_QL, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_QL}, - { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_QN, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_QN}, - { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_QO, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_QO}, - { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_Ql, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_Ql}, - { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_BB, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_BB}, - { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_QW, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_QW}, - { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_QX, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_QX}, - { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_Id, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_Id}, - { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_Ie, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_Ie}, - { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_If, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_If}, - { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_Ig, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_Ig}, - { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_Ya, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_Ya}, - { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_Yd, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_Yd}, - { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_Ld, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_Ld}, - { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_Le, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_Le}, - { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_Lf, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_Lf}, - { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_Lg, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_Lg}, - { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_ND, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_ND}, - { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_NE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_NE}, - { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_NF, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_NF}, - { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_NG, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_NG}, - { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_QM, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_QM}, - { 0, } -}; -MODULE_DEVICE_TABLE(pci, radeonfb_pci_table); - - -typedef struct { - u16 reg; - u32 val; -} reg_val; - - -/* these common regs are cleared before mode setting so they do not - * interfere with anything - */ -static reg_val common_regs[] = { - { OVR_CLR, 0 }, - { OVR_WID_LEFT_RIGHT, 0 }, - { OVR_WID_TOP_BOTTOM, 0 }, - { OV0_SCALE_CNTL, 0 }, - { SUBPIC_CNTL, 0 }, - { VIPH_CONTROL, 0 }, - { I2C_CNTL_1, 0 }, - { GEN_INT_CNTL, 0 }, - { CAP0_TRIG_CNTL, 0 }, -}; - -static reg_val common_regs_m6[] = { - { OVR_CLR, 0 }, - { OVR_WID_LEFT_RIGHT, 0 }, - { OVR_WID_TOP_BOTTOM, 0 }, - { OV0_SCALE_CNTL, 0 }, - { SUBPIC_CNTL, 0 }, - { GEN_INT_CNTL, 0 }, - { CAP0_TRIG_CNTL, 0 } -}; - -typedef struct { - u8 clock_chip_type; - u8 struct_size; - u8 accelerator_entry; - u8 VGA_entry; - u16 VGA_table_offset; - u16 POST_table_offset; - u16 XCLK; - u16 MCLK; - u8 num_PLL_blocks; - u8 size_PLL_blocks; - u16 PCLK_ref_freq; - u16 PCLK_ref_divider; - u32 PCLK_min_freq; - u32 PCLK_max_freq; - u16 MCLK_ref_freq; - u16 MCLK_ref_divider; - u32 MCLK_min_freq; - u32 MCLK_max_freq; - u16 XCLK_ref_freq; - u16 XCLK_ref_divider; - u32 XCLK_min_freq; - u32 XCLK_max_freq; -} __attribute__ ((packed)) PLL_BLOCK; - - -struct pll_info { - int ppll_max; - int ppll_min; - int xclk; - int ref_div; - int ref_clk; -}; - - -struct ram_info { - int ml; - int mb; - int trcd; - int trp; - int twr; - int cl; - int tr2w; - int loop_latency; - int rloop; -}; - - -struct radeon_regs { - /* CRTC regs */ - u32 crtc_h_total_disp; - u32 crtc_h_sync_strt_wid; - u32 crtc_v_total_disp; - u32 crtc_v_sync_strt_wid; - u32 crtc_pitch; - u32 crtc_gen_cntl; - u32 crtc_ext_cntl; - u32 dac_cntl; - - u32 flags; - u32 pix_clock; - int xres, yres; - - /* DDA regs */ - u32 dda_config; - u32 dda_on_off; - - /* PLL regs */ - u32 ppll_div_3; - u32 ppll_ref_div; - u32 vclk_ecp_cntl; - - /* Flat panel regs */ - u32 fp_crtc_h_total_disp; - u32 fp_crtc_v_total_disp; - u32 fp_gen_cntl; - u32 fp_h_sync_strt_wid; - u32 fp_horz_stretch; - u32 fp_panel_cntl; - u32 fp_v_sync_strt_wid; - u32 fp_vert_stretch; - u32 lvds_gen_cntl; - u32 lvds_pll_cntl; - u32 tmds_crc; - u32 tmds_transmitter_cntl; - -#if defined(__BIG_ENDIAN) - u32 surface_cntl; -#endif -}; - - -struct radeonfb_info { - struct fb_info info; - - struct radeon_regs state; - struct radeon_regs init_state; - - char name[32]; - char ram_type[12]; - - unsigned long mmio_base_phys; - unsigned long fb_base_phys; - - void __iomem *mmio_base; - void __iomem *fb_base; - - struct pci_dev *pdev; - - unsigned char *EDID; - unsigned char __iomem *bios_seg; - - u32 pseudo_palette[17]; - struct { u8 red, green, blue, pad; } palette[256]; - - int chipset; - unsigned char arch; - int video_ram; - u8 rev; - int pitch, bpp, depth; - int xres, yres, pixclock; - int xres_virtual, yres_virtual; - u32 accel_flags; - - int use_default_var; - int got_dfpinfo; - - int hasCRTC2; - int crtDisp_type; - int dviDisp_type; - - int panel_xres, panel_yres; - int clock; - int hOver_plus, hSync_width, hblank; - int vOver_plus, vSync_width, vblank; - int hAct_high, vAct_high, interlaced; - int synct, misc; - - u32 dp_gui_master_cntl; - - struct pll_info pll; - int pll_output_freq, post_div, fb_div; - - struct ram_info ram; - - int mtrr_hdl; - -#ifdef CONFIG_PMAC_PBOOK - int pm_reg; - u32 save_regs[64]; - u32 mdll, mdll2; -#endif /* CONFIG_PMAC_PBOOK */ - int asleep; - - struct radeonfb_info *next; -}; - - -static struct fb_var_screeninfo radeonfb_default_var = { - 640, 480, 640, 480, 0, 0, 8, 0, - {0, 6, 0}, {0, 6, 0}, {0, 6, 0}, {0, 0, 0}, - 0, 0, -1, -1, 0, 39721, 40, 24, 32, 11, 96, 2, - 0, FB_VMODE_NONINTERLACED -}; - -/* - * IO macros - */ - -#define INREG8(addr) readb((rinfo->mmio_base)+addr) -#define OUTREG8(addr,val) writeb(val, (rinfo->mmio_base)+addr) -#define INREG(addr) readl((rinfo->mmio_base)+addr) -#define OUTREG(addr,val) writel(val, (rinfo->mmio_base)+addr) - -#define OUTPLL(addr,val) \ - do { \ - OUTREG8(CLOCK_CNTL_INDEX, (addr & 0x0000003f) | 0x00000080); \ - OUTREG(CLOCK_CNTL_DATA, val); \ - } while(0) - -#define OUTPLLP(addr,val,mask) \ - do { \ - unsigned int _tmp = INPLL(addr); \ - _tmp &= (mask); \ - _tmp |= (val); \ - OUTPLL(addr, _tmp); \ - } while (0) - -#define OUTREGP(addr,val,mask) \ - do { \ - unsigned int _tmp = INREG(addr); \ - _tmp &= (mask); \ - _tmp |= (val); \ - OUTREG(addr, _tmp); \ - } while (0) - - -static __inline__ u32 _INPLL(struct radeonfb_info *rinfo, u32 addr) -{ - OUTREG8(CLOCK_CNTL_INDEX, addr & 0x0000003f); - return (INREG(CLOCK_CNTL_DATA)); -} - -#define INPLL(addr) _INPLL(rinfo, addr) - -#define PRIMARY_MONITOR(rinfo) ((rinfo->dviDisp_type != MT_NONE) && \ - (rinfo->dviDisp_type != MT_STV) && \ - (rinfo->dviDisp_type != MT_CTV) ? \ - rinfo->dviDisp_type : rinfo->crtDisp_type) - -static char *GET_MON_NAME(int type) -{ - char *pret = NULL; - - switch (type) { - case MT_NONE: - pret = "no"; - break; - case MT_CRT: - pret = "CRT"; - break; - case MT_DFP: - pret = "DFP"; - break; - case MT_LCD: - pret = "LCD"; - break; - case MT_CTV: - pret = "CTV"; - break; - case MT_STV: - pret = "STV"; - break; - } - - return pret; -} - - -/* - * 2D engine routines - */ - -static __inline__ void radeon_engine_flush (struct radeonfb_info *rinfo) -{ - int i; - - /* initiate flush */ - OUTREGP(RB2D_DSTCACHE_CTLSTAT, RB2D_DC_FLUSH_ALL, - ~RB2D_DC_FLUSH_ALL); - - for (i=0; i < 2000000; i++) { - if (!(INREG(RB2D_DSTCACHE_CTLSTAT) & RB2D_DC_BUSY)) - break; - } -} - - -static __inline__ void _radeon_fifo_wait (struct radeonfb_info *rinfo, int entries) -{ - int i; - - for (i=0; i<2000000; i++) - if ((INREG(RBBM_STATUS) & 0x7f) >= entries) - return; -} - - -static __inline__ void _radeon_engine_idle (struct radeonfb_info *rinfo) -{ - int i; - - /* ensure FIFO is empty before waiting for idle */ - _radeon_fifo_wait (rinfo, 64); - - for (i=0; i<2000000; i++) { - if (((INREG(RBBM_STATUS) & GUI_ACTIVE)) == 0) { - radeon_engine_flush (rinfo); - return; - } - } -} - - -#define radeon_engine_idle() _radeon_engine_idle(rinfo) -#define radeon_fifo_wait(entries) _radeon_fifo_wait(rinfo,entries) - - - -/* - * helper routines - */ - -static __inline__ u32 radeon_get_dstbpp(u16 depth) -{ - switch (depth) { - case 8: - return DST_8BPP; - case 15: - return DST_15BPP; - case 16: - return DST_16BPP; - case 32: - return DST_32BPP; - default: - return 0; - } -} - - -static inline int var_to_depth(const struct fb_var_screeninfo *var) -{ - if (var->bits_per_pixel != 16) - return var->bits_per_pixel; - return (var->green.length == 6) ? 16 : 15; -} - - -static void _radeon_engine_reset(struct radeonfb_info *rinfo) -{ - u32 clock_cntl_index, mclk_cntl, rbbm_soft_reset; - - radeon_engine_flush (rinfo); - - clock_cntl_index = INREG(CLOCK_CNTL_INDEX); - mclk_cntl = INPLL(MCLK_CNTL); - - OUTPLL(MCLK_CNTL, (mclk_cntl | - FORCEON_MCLKA | - FORCEON_MCLKB | - FORCEON_YCLKA | - FORCEON_YCLKB | - FORCEON_MC | - FORCEON_AIC)); - rbbm_soft_reset = INREG(RBBM_SOFT_RESET); - - OUTREG(RBBM_SOFT_RESET, rbbm_soft_reset | - SOFT_RESET_CP | - SOFT_RESET_HI | - SOFT_RESET_SE | - SOFT_RESET_RE | - SOFT_RESET_PP | - SOFT_RESET_E2 | - SOFT_RESET_RB); - INREG(RBBM_SOFT_RESET); - OUTREG(RBBM_SOFT_RESET, rbbm_soft_reset & (u32) - ~(SOFT_RESET_CP | - SOFT_RESET_HI | - SOFT_RESET_SE | - SOFT_RESET_RE | - SOFT_RESET_PP | - SOFT_RESET_E2 | - SOFT_RESET_RB)); - INREG(RBBM_SOFT_RESET); - - OUTPLL(MCLK_CNTL, mclk_cntl); - OUTREG(CLOCK_CNTL_INDEX, clock_cntl_index); - OUTREG(RBBM_SOFT_RESET, rbbm_soft_reset); - - return; -} - -#define radeon_engine_reset() _radeon_engine_reset(rinfo) - - -static __inline__ int round_div(int num, int den) -{ - return (num + (den / 2)) / den; -} - - - -static __inline__ int min_bits_req(int val) -{ - int bits_req = 0; - - if (val == 0) - bits_req = 1; - - while (val) { - val >>= 1; - bits_req++; - } - - return (bits_req); -} - - -static __inline__ int _max(int val1, int val2) -{ - if (val1 >= val2) - return val1; - else - return val2; -} - - - -/* - * globals - */ - -#ifndef MODULE -static char *mode_option; -#endif - -static char noaccel = 0; -static char mirror = 0; -static int panel_yres = 0; -static char force_dfp = 0; -static struct radeonfb_info *board_list = NULL; -static char nomtrr = 0; - -/* - * prototypes - */ - -static void radeon_save_state (struct radeonfb_info *rinfo, - struct radeon_regs *save); -static void radeon_engine_init (struct radeonfb_info *rinfo); -static void radeon_write_mode (struct radeonfb_info *rinfo, - struct radeon_regs *mode); -static int __devinit radeon_set_fbinfo (struct radeonfb_info *rinfo); -static int __devinit radeon_init_disp (struct radeonfb_info *rinfo); -static int radeon_init_disp_var (struct radeonfb_info *rinfo, struct fb_var_screeninfo *var); -static void __iomem *radeon_find_rom(struct radeonfb_info *rinfo); -static void radeon_get_pllinfo(struct radeonfb_info *rinfo, void __iomem *bios_seg); -static void radeon_get_moninfo (struct radeonfb_info *rinfo); -static int radeon_get_dfpinfo (struct radeonfb_info *rinfo); -static int radeon_get_dfpinfo_BIOS(struct radeonfb_info *rinfo); -static void radeon_get_EDID(struct radeonfb_info *rinfo); -static int radeon_dfp_parse_EDID(struct radeonfb_info *rinfo); -static void radeon_update_default_var(struct radeonfb_info *rinfo); - -#ifdef CONFIG_PPC_OF - -static int radeon_read_OF (struct radeonfb_info *rinfo); -static int radeon_get_EDID_OF(struct radeonfb_info *rinfo); -extern struct device_node *pci_device_to_OF_node(struct pci_dev *dev); - -#ifdef CONFIG_PMAC_PBOOK -int radeon_sleep_notify(struct pmu_sleep_notifier *self, int when); -static struct pmu_sleep_notifier radeon_sleep_notifier = { - radeon_sleep_notify, SLEEP_LEVEL_VIDEO, -}; -#endif /* CONFIG_PMAC_PBOOK */ -#ifdef CONFIG_PMAC_BACKLIGHT -static int radeon_set_backlight_enable(int on, int level, void *data); -static int radeon_set_backlight_level(int level, void *data); -static struct backlight_controller radeon_backlight_controller = { - radeon_set_backlight_enable, - radeon_set_backlight_level -}; -#endif /* CONFIG_PMAC_BACKLIGHT */ - -#endif /* CONFIG_PPC_OF */ - - -static void __iomem *radeon_find_rom(struct radeonfb_info *rinfo) -{ -#if defined(__i386__) - u32 segstart; - char __iomem *rom_base; - char __iomem *rom; - int stage; - int i,j; - char aty_rom_sig[] = "761295520"; - char *radeon_sig[] = { - "RG6", - "RADEON" - }; - - for(segstart=0x000c0000; segstart<0x000f0000; segstart+=0x00001000) { - - stage = 1; - - rom_base = ioremap(segstart, 0x1000); - - if ((*rom_base == 0x55) && (((*(rom_base + 1)) & 0xff) == 0xaa)) - stage = 2; - - - if (stage != 2) { - iounmap(rom_base); - continue; - } - - rom = rom_base; - - for (i = 0; (i < 128 - strlen(aty_rom_sig)) && (stage != 3); i++) { - if (aty_rom_sig[0] == *rom) - if (strncmp(aty_rom_sig, rom, - strlen(aty_rom_sig)) == 0) - stage = 3; - rom++; - } - if (stage != 3) { - iounmap(rom_base); - continue; - } - rom = rom_base; - - for (i = 0; (i < 512) && (stage != 4); i++) { - for (j = 0; j < ARRAY_SIZE(radeon_sig); j++) { - if (radeon_sig[j][0] == *rom) - if (strncmp(radeon_sig[j], rom, - strlen(radeon_sig[j])) == 0) { - stage = 4; - break; - } - } - rom++; - } - if (stage != 4) { - iounmap(rom_base); - continue; - } - - return rom_base; - } -#endif - return NULL; -} - - - - -static void radeon_get_pllinfo(struct radeonfb_info *rinfo, void __iomem *bios_seg) -{ - void __iomem *bios_header; - void __iomem *header_ptr; - u16 bios_header_offset, pll_info_offset; - PLL_BLOCK pll; - - if (bios_seg) { - bios_header = bios_seg + 0x48L; - header_ptr = bios_header; - - bios_header_offset = readw(header_ptr); - bios_header = bios_seg + bios_header_offset; - bios_header += 0x30; - - header_ptr = bios_header; - pll_info_offset = readw(header_ptr); - header_ptr = bios_seg + pll_info_offset; - - memcpy_fromio(&pll, header_ptr, 50); - - rinfo->pll.xclk = (u32)pll.XCLK; - rinfo->pll.ref_clk = (u32)pll.PCLK_ref_freq; - rinfo->pll.ref_div = (u32)pll.PCLK_ref_divider; - rinfo->pll.ppll_min = pll.PCLK_min_freq; - rinfo->pll.ppll_max = pll.PCLK_max_freq; - - printk("radeonfb: ref_clk=%d, ref_div=%d, xclk=%d from BIOS\n", - rinfo->pll.ref_clk, rinfo->pll.ref_div, rinfo->pll.xclk); - } else { -#ifdef CONFIG_PPC_OF - if (radeon_read_OF(rinfo)) { - unsigned int tmp, Nx, M, ref_div, xclk; - - tmp = INPLL(M_SPLL_REF_FB_DIV); - ref_div = INPLL(PPLL_REF_DIV) & 0x3ff; - - Nx = (tmp & 0xff00) >> 8; - M = (tmp & 0xff); - xclk = ((((2 * Nx * rinfo->pll.ref_clk) + (M)) / - (2 * M))); - - rinfo->pll.xclk = xclk; - rinfo->pll.ref_div = ref_div; - rinfo->pll.ppll_min = 12000; - rinfo->pll.ppll_max = 35000; - - printk("radeonfb: ref_clk=%d, ref_div=%d, xclk=%d from OF\n", - rinfo->pll.ref_clk, rinfo->pll.ref_div, rinfo->pll.xclk); - - return; - } -#endif - /* no BIOS or BIOS not found, use defaults */ - switch (rinfo->chipset) { - case PCI_DEVICE_ID_ATI_RADEON_QW: - case PCI_DEVICE_ID_ATI_RADEON_QX: - rinfo->pll.ppll_max = 35000; - rinfo->pll.ppll_min = 12000; - rinfo->pll.xclk = 23000; - rinfo->pll.ref_div = 12; - rinfo->pll.ref_clk = 2700; - break; - case PCI_DEVICE_ID_ATI_RADEON_QL: - case PCI_DEVICE_ID_ATI_RADEON_QN: - case PCI_DEVICE_ID_ATI_RADEON_QO: - case PCI_DEVICE_ID_ATI_RADEON_Ql: - case PCI_DEVICE_ID_ATI_RADEON_BB: - rinfo->pll.ppll_max = 35000; - rinfo->pll.ppll_min = 12000; - rinfo->pll.xclk = 27500; - rinfo->pll.ref_div = 12; - rinfo->pll.ref_clk = 2700; - break; - case PCI_DEVICE_ID_ATI_RADEON_Id: - case PCI_DEVICE_ID_ATI_RADEON_Ie: - case PCI_DEVICE_ID_ATI_RADEON_If: - case PCI_DEVICE_ID_ATI_RADEON_Ig: - rinfo->pll.ppll_max = 35000; - rinfo->pll.ppll_min = 12000; - rinfo->pll.xclk = 25000; - rinfo->pll.ref_div = 12; - rinfo->pll.ref_clk = 2700; - break; - case PCI_DEVICE_ID_ATI_RADEON_ND: - case PCI_DEVICE_ID_ATI_RADEON_NE: - case PCI_DEVICE_ID_ATI_RADEON_NF: - case PCI_DEVICE_ID_ATI_RADEON_NG: - rinfo->pll.ppll_max = 40000; - rinfo->pll.ppll_min = 20000; - rinfo->pll.xclk = 27000; - rinfo->pll.ref_div = 12; - rinfo->pll.ref_clk = 2700; - break; - case PCI_DEVICE_ID_ATI_RADEON_QD: - case PCI_DEVICE_ID_ATI_RADEON_QE: - case PCI_DEVICE_ID_ATI_RADEON_QF: - case PCI_DEVICE_ID_ATI_RADEON_QG: - default: - rinfo->pll.ppll_max = 35000; - rinfo->pll.ppll_min = 12000; - rinfo->pll.xclk = 16600; - rinfo->pll.ref_div = 67; - rinfo->pll.ref_clk = 2700; - break; - } - - printk("radeonfb: ref_clk=%d, ref_div=%d, xclk=%d defaults\n", - rinfo->pll.ref_clk, rinfo->pll.ref_div, rinfo->pll.xclk); - } -} - - -static void radeon_get_moninfo (struct radeonfb_info *rinfo) -{ - unsigned int tmp; - - if (force_dfp) { - rinfo->dviDisp_type = MT_DFP; - return; - } - - tmp = INREG(BIOS_4_SCRATCH); - printk(KERN_DEBUG "radeon_get_moninfo: bios 4 scratch = %x\n", tmp); - - if (rinfo->hasCRTC2) { - /* primary DVI port */ - if (tmp & 0x08) - rinfo->dviDisp_type = MT_DFP; - else if (tmp & 0x4) - rinfo->dviDisp_type = MT_LCD; - else if (tmp & 0x200) - rinfo->dviDisp_type = MT_CRT; - else if (tmp & 0x10) - rinfo->dviDisp_type = MT_CTV; - else if (tmp & 0x20) - rinfo->dviDisp_type = MT_STV; - - /* secondary CRT port */ - if (tmp & 0x2) - rinfo->crtDisp_type = MT_CRT; - else if (tmp & 0x800) - rinfo->crtDisp_type = MT_DFP; - else if (tmp & 0x400) - rinfo->crtDisp_type = MT_LCD; - else if (tmp & 0x1000) - rinfo->crtDisp_type = MT_CTV; - else if (tmp & 0x2000) - rinfo->crtDisp_type = MT_STV; - } else { - rinfo->dviDisp_type = MT_NONE; - - tmp = INREG(FP_GEN_CNTL); - - if (tmp & FP_EN_TMDS) - rinfo->crtDisp_type = MT_DFP; - else - rinfo->crtDisp_type = MT_CRT; - } -} - - - -static void radeon_get_EDID(struct radeonfb_info *rinfo) -{ -#ifdef CONFIG_PPC_OF - if (!radeon_get_EDID_OF(rinfo)) - RTRACE("radeonfb: could not retrieve EDID from OF\n"); -#else - /* XXX use other methods later */ -#endif -} - - -#ifdef CONFIG_PPC_OF -static int radeon_get_EDID_OF(struct radeonfb_info *rinfo) -{ - struct device_node *dp; - unsigned char *pedid = NULL; - static char *propnames[] = { "DFP,EDID", "LCD,EDID", "EDID", "EDID1", NULL }; - int i; - - dp = pci_device_to_OF_node(rinfo->pdev); - while (dp != NULL) { - for (i = 0; propnames[i] != NULL; ++i) { - pedid = (unsigned char *) - get_property(dp, propnames[i], NULL); - if (pedid != NULL) { - rinfo->EDID = pedid; - return 1; - } - } - dp = dp->child; - } - return 0; -} -#endif /* CONFIG_PPC_OF */ - - -static int radeon_dfp_parse_EDID(struct radeonfb_info *rinfo) -{ - unsigned char *block = rinfo->EDID; - - if (!block) - return 0; - - /* jump to the detailed timing block section */ - block += 54; - - rinfo->clock = (block[0] + (block[1] << 8)); - rinfo->panel_xres = (block[2] + ((block[4] & 0xf0) << 4)); - rinfo->hblank = (block[3] + ((block[4] & 0x0f) << 8)); - rinfo->panel_yres = (block[5] + ((block[7] & 0xf0) << 4)); - rinfo->vblank = (block[6] + ((block[7] & 0x0f) << 8)); - rinfo->hOver_plus = (block[8] + ((block[11] & 0xc0) << 2)); - rinfo->hSync_width = (block[9] + ((block[11] & 0x30) << 4)); - rinfo->vOver_plus = ((block[10] >> 4) + ((block[11] & 0x0c) << 2)); - rinfo->vSync_width = ((block[10] & 0x0f) + ((block[11] & 0x03) << 4)); - rinfo->interlaced = ((block[17] & 0x80) >> 7); - rinfo->synct = ((block[17] & 0x18) >> 3); - rinfo->misc = ((block[17] & 0x06) >> 1); - rinfo->hAct_high = rinfo->vAct_high = 0; - if (rinfo->synct == 3) { - if (rinfo->misc & 2) - rinfo->hAct_high = 1; - if (rinfo->misc & 1) - rinfo->vAct_high = 1; - } - - printk("radeonfb: detected DFP panel size from EDID: %dx%d\n", - rinfo->panel_xres, rinfo->panel_yres); - - rinfo->got_dfpinfo = 1; - - return 1; -} - - -static void radeon_update_default_var(struct radeonfb_info *rinfo) -{ - struct fb_var_screeninfo *var = &radeonfb_default_var; - - var->xres = rinfo->panel_xres; - var->yres = rinfo->panel_yres; - var->xres_virtual = rinfo->panel_xres; - var->yres_virtual = rinfo->panel_yres; - var->xoffset = var->yoffset = 0; - var->bits_per_pixel = 8; - var->pixclock = 100000000 / rinfo->clock; - var->left_margin = (rinfo->hblank - rinfo->hOver_plus - rinfo->hSync_width); - var->right_margin = rinfo->hOver_plus; - var->upper_margin = (rinfo->vblank - rinfo->vOver_plus - rinfo->vSync_width); - var->lower_margin = rinfo->vOver_plus; - var->hsync_len = rinfo->hSync_width; - var->vsync_len = rinfo->vSync_width; - var->sync = 0; - if (rinfo->synct == 3) { - if (rinfo->hAct_high) - var->sync |= FB_SYNC_HOR_HIGH_ACT; - if (rinfo->vAct_high) - var->sync |= FB_SYNC_VERT_HIGH_ACT; - } - - var->vmode = 0; - if (rinfo->interlaced) - var->vmode |= FB_VMODE_INTERLACED; - - rinfo->use_default_var = 1; -} - - -static int radeon_get_dfpinfo_BIOS(struct radeonfb_info *rinfo) -{ - char __iomem *fpbiosstart, *tmp, *tmp0; - char stmp[30]; - int i; - - if (!rinfo->bios_seg) - return 0; - - if (!(fpbiosstart = rinfo->bios_seg + readw(rinfo->bios_seg + 0x48))) { - printk("radeonfb: Failed to detect DFP panel info using BIOS\n"); - return 0; - } - - if (!(tmp = rinfo->bios_seg + readw(fpbiosstart + 0x40))) { - printk("radeonfb: Failed to detect DFP panel info using BIOS\n"); - return 0; - } - - for(i=0; i<24; i++) - stmp[i] = readb(tmp+i+1); - stmp[24] = 0; - printk("radeonfb: panel ID string: %s\n", stmp); - rinfo->panel_xres = readw(tmp + 25); - rinfo->panel_yres = readw(tmp + 27); - printk("radeonfb: detected DFP panel size from BIOS: %dx%d\n", - rinfo->panel_xres, rinfo->panel_yres); - - for(i=0; i<32; i++) { - tmp0 = rinfo->bios_seg + readw(tmp+64+i*2); - if (tmp0 == 0) - break; - if ((readw(tmp0) == rinfo->panel_xres) && - (readw(tmp0+2) == rinfo->panel_yres)) { - rinfo->hblank = (readw(tmp0+17) - readw(tmp0+19)) * 8; - rinfo->hOver_plus = ((readw(tmp0+21) - readw(tmp0+19) -1) * 8) & 0x7fff; - rinfo->hSync_width = readb(tmp0+23) * 8; - rinfo->vblank = readw(tmp0+24) - readw(tmp0+26); - rinfo->vOver_plus = (readw(tmp0+28) & 0x7ff) - readw(tmp0+26); - rinfo->vSync_width = (readw(tmp0+28) & 0xf800) >> 11; - rinfo->clock = readw(tmp0+9); - - rinfo->got_dfpinfo = 1; - return 1; - } - } - - return 0; -} - - - -static int radeon_get_dfpinfo (struct radeonfb_info *rinfo) -{ - unsigned int tmp; - unsigned short a, b; - - if (radeon_get_dfpinfo_BIOS(rinfo)) - radeon_update_default_var(rinfo); - - if (radeon_dfp_parse_EDID(rinfo)) - radeon_update_default_var(rinfo); - - if (!rinfo->got_dfpinfo) { - /* - * it seems all else has failed now and we - * resort to probing registers for our DFP info - */ - if (panel_yres) { - rinfo->panel_yres = panel_yres; - } else { - tmp = INREG(FP_VERT_STRETCH); - tmp &= 0x00fff000; - rinfo->panel_yres = (unsigned short)(tmp >> 0x0c) + 1; - } - - switch (rinfo->panel_yres) { - case 480: - rinfo->panel_xres = 640; - break; - case 600: - rinfo->panel_xres = 800; - break; - case 768: -#if defined(__powerpc__) - if (rinfo->dviDisp_type == MT_LCD) - rinfo->panel_xres = 1152; - else -#endif - rinfo->panel_xres = 1024; - break; - case 1024: - rinfo->panel_xres = 1280; - break; - case 1050: - rinfo->panel_xres = 1400; - break; - case 1200: - rinfo->panel_xres = 1600; - break; - default: - printk("radeonfb: Failed to detect DFP panel size\n"); - return 0; - } - - printk("radeonfb: detected DFP panel size from registers: %dx%d\n", - rinfo->panel_xres, rinfo->panel_yres); - - tmp = INREG(FP_CRTC_H_TOTAL_DISP); - a = (tmp & FP_CRTC_H_TOTAL_MASK) + 4; - b = (tmp & 0x01ff0000) >> FP_CRTC_H_DISP_SHIFT; - rinfo->hblank = (a - b + 1) * 8; - - tmp = INREG(FP_H_SYNC_STRT_WID); - rinfo->hOver_plus = (unsigned short) ((tmp & FP_H_SYNC_STRT_CHAR_MASK) >> - FP_H_SYNC_STRT_CHAR_SHIFT) - b - 1; - rinfo->hOver_plus *= 8; - rinfo->hSync_width = (unsigned short) ((tmp & FP_H_SYNC_WID_MASK) >> - FP_H_SYNC_WID_SHIFT); - rinfo->hSync_width *= 8; - tmp = INREG(FP_CRTC_V_TOTAL_DISP); - a = (tmp & FP_CRTC_V_TOTAL_MASK) + 1; - b = (tmp & FP_CRTC_V_DISP_MASK) >> FP_CRTC_V_DISP_SHIFT; - rinfo->vblank = a - b /* + 24 */ ; - - tmp = INREG(FP_V_SYNC_STRT_WID); - rinfo->vOver_plus = (unsigned short) (tmp & FP_V_SYNC_STRT_MASK) - - b + 1; - rinfo->vSync_width = (unsigned short) ((tmp & FP_V_SYNC_WID_MASK) >> - FP_V_SYNC_WID_SHIFT); - - return 1; - } - - return 1; -} - - -#ifdef CONFIG_PPC_OF -static int radeon_read_OF (struct radeonfb_info *rinfo) -{ - struct device_node *dp; - unsigned int *xtal; - - dp = pci_device_to_OF_node(rinfo->pdev); - - xtal = (unsigned int *) get_property(dp, "ATY,RefCLK", NULL); - - rinfo->pll.ref_clk = *xtal / 10; - - if (*xtal) - return 1; - else - return 0; -} -#endif - - -static void radeon_engine_init (struct radeonfb_info *rinfo) -{ - u32 temp; - - /* disable 3D engine */ - OUTREG(RB3D_CNTL, 0); - - radeon_engine_reset (); - - radeon_fifo_wait (1); - OUTREG(RB2D_DSTCACHE_MODE, 0); - - radeon_fifo_wait (1); - temp = INREG(DEFAULT_PITCH_OFFSET); - OUTREG(DEFAULT_PITCH_OFFSET, ((temp & 0xc0000000) | - (rinfo->pitch << 0x16))); - - radeon_fifo_wait (1); - OUTREGP(DP_DATATYPE, 0, ~HOST_BIG_ENDIAN_EN); - - radeon_fifo_wait (1); - OUTREG(DEFAULT_SC_BOTTOM_RIGHT, (DEFAULT_SC_RIGHT_MAX | - DEFAULT_SC_BOTTOM_MAX)); - - temp = radeon_get_dstbpp(rinfo->depth); - rinfo->dp_gui_master_cntl = ((temp << 8) | GMC_CLR_CMP_CNTL_DIS); - radeon_fifo_wait (1); - OUTREG(DP_GUI_MASTER_CNTL, (rinfo->dp_gui_master_cntl | - GMC_BRUSH_SOLID_COLOR | - GMC_SRC_DATATYPE_COLOR)); - - radeon_fifo_wait (7); - - /* clear line drawing regs */ - OUTREG(DST_LINE_START, 0); - OUTREG(DST_LINE_END, 0); - - /* set brush color regs */ - OUTREG(DP_BRUSH_FRGD_CLR, 0xffffffff); - OUTREG(DP_BRUSH_BKGD_CLR, 0x00000000); - - /* set source color regs */ - OUTREG(DP_SRC_FRGD_CLR, 0xffffffff); - OUTREG(DP_SRC_BKGD_CLR, 0x00000000); - - /* default write mask */ - OUTREG(DP_WRITE_MSK, 0xffffffff); - - radeon_engine_idle (); -} - - -static int __devinit radeon_init_disp (struct radeonfb_info *rinfo) -{ - struct fb_info *info = &rinfo->info; - struct fb_var_screeninfo var; - - var = radeonfb_default_var; - if ((radeon_init_disp_var(rinfo, &var)) < 0) - return -1; - - rinfo->depth = var_to_depth(&var); - rinfo->bpp = var.bits_per_pixel; - - info->var = var; - fb_alloc_cmap(&info->cmap, 256, 0); - - var.activate = FB_ACTIVATE_NOW; - return 0; -} - - -static int radeon_init_disp_var (struct radeonfb_info *rinfo, - struct fb_var_screeninfo *var) -{ -#ifndef MODULE - if (mode_option) - fb_find_mode (var, &rinfo->info, mode_option, - NULL, 0, NULL, 8); - else -#endif - if (rinfo->use_default_var) - /* We will use the modified default far */ - *var = radeonfb_default_var; - else - - fb_find_mode (var, &rinfo->info, "640x480-8@60", - NULL, 0, NULL, 0); - - if (noaccel) - var->accel_flags &= ~FB_ACCELF_TEXT; - else - var->accel_flags |= FB_ACCELF_TEXT; - - return 0; -} - - -static int radeon_do_maximize(struct radeonfb_info *rinfo, - struct fb_var_screeninfo *var, - struct fb_var_screeninfo *v, - int nom, int den) -{ - static struct { - int xres, yres; - } modes[] = { - {1600, 1280}, - {1280, 1024}, - {1024, 768}, - {800, 600}, - {640, 480}, - {-1, -1} - }; - int i; - - /* use highest possible virtual resolution */ - if (v->xres_virtual == -1 && v->yres_virtual == -1) { - printk("radeonfb: using max available virtual resolution\n"); - for (i=0; modes[i].xres != -1; i++) { - if (modes[i].xres * nom / den * modes[i].yres < - rinfo->video_ram / 2) - break; - } - if (modes[i].xres == -1) { - printk("radeonfb: could not find virtual resolution that fits into video memory!\n"); - return -EINVAL; - } - v->xres_virtual = modes[i].xres; - v->yres_virtual = modes[i].yres; - - printk("radeonfb: virtual resolution set to max of %dx%d\n", - v->xres_virtual, v->yres_virtual); - } else if (v->xres_virtual == -1) { - v->xres_virtual = (rinfo->video_ram * den / - (nom * v->yres_virtual * 2)) & ~15; - } else if (v->yres_virtual == -1) { - v->xres_virtual = (v->xres_virtual + 15) & ~15; - v->yres_virtual = rinfo->video_ram * den / - (nom * v->xres_virtual *2); - } else { - if (v->xres_virtual * nom / den * v->yres_virtual > - rinfo->video_ram) { - return -EINVAL; - } - } - - if (v->xres_virtual * nom / den >= 8192) { - v->xres_virtual = 8192 * den / nom - 16; - } - - if (v->xres_virtual < v->xres) - return -EINVAL; - - if (v->yres_virtual < v->yres) - return -EINVAL; - - return 0; -} - - -static int radeonfb_check_var (struct fb_var_screeninfo *var, struct fb_info *info) -{ - struct radeonfb_info *rinfo = (struct radeonfb_info *) info->par; - struct fb_var_screeninfo v; - int nom, den; - - memcpy (&v, var, sizeof (v)); - - switch (v.bits_per_pixel) { - case 0 ... 8: - v.bits_per_pixel = 8; - break; - case 9 ... 16: - v.bits_per_pixel = 16; - break; - case 17 ... 24: -#if 0 /* Doesn't seem to work */ - v.bits_per_pixel = 24; - break; -#endif - return -EINVAL; - case 25 ... 32: - v.bits_per_pixel = 32; - break; - default: - return -EINVAL; - } - - switch (var_to_depth(&v)) { - case 8: - nom = den = 1; - v.red.offset = v.green.offset = v.blue.offset = 0; - v.red.length = v.green.length = v.blue.length = 8; - v.transp.offset = v.transp.length = 0; - break; - case 15: - nom = 2; - den = 1; - v.red.offset = 10; - v.green.offset = 5; - v.blue.offset = 0; - v.red.length = v.green.length = v.blue.length = 5; - v.transp.offset = v.transp.length = 0; - break; - case 16: - nom = 2; - den = 1; - v.red.offset = 11; - v.green.offset = 5; - v.blue.offset = 0; - v.red.length = 5; - v.green.length = 6; - v.blue.length = 5; - v.transp.offset = v.transp.length = 0; - break; - case 24: - nom = 4; - den = 1; - v.red.offset = 16; - v.green.offset = 8; - v.blue.offset = 0; - v.red.length = v.blue.length = v.green.length = 8; - v.transp.offset = v.transp.length = 0; - break; - case 32: - nom = 4; - den = 1; - v.red.offset = 16; - v.green.offset = 8; - v.blue.offset = 0; - v.red.length = v.blue.length = v.green.length = 8; - v.transp.offset = 24; - v.transp.length = 8; - break; - default: - printk ("radeonfb: mode %dx%dx%d rejected, color depth invalid\n", - var->xres, var->yres, var->bits_per_pixel); - return -EINVAL; - } - - if (radeon_do_maximize(rinfo, var, &v, nom, den) < 0) - return -EINVAL; - - if (v.xoffset < 0) - v.xoffset = 0; - if (v.yoffset < 0) - v.yoffset = 0; - - if (v.xoffset > v.xres_virtual - v.xres) - v.xoffset = v.xres_virtual - v.xres - 1; - - if (v.yoffset > v.yres_virtual - v.yres) - v.yoffset = v.yres_virtual - v.yres - 1; - - v.red.msb_right = v.green.msb_right = v.blue.msb_right = - v.transp.offset = v.transp.length = - v.transp.msb_right = 0; - - if (noaccel) - v.accel_flags = 0; - - memcpy(var, &v, sizeof(v)); - - return 0; -} - - -static int radeonfb_pan_display (struct fb_var_screeninfo *var, - struct fb_info *info) -{ - struct radeonfb_info *rinfo = (struct radeonfb_info *) info; - - if ((var->xoffset + var->xres > var->xres_virtual) - || (var->yoffset + var->yres > var->yres_virtual)) - return -EINVAL; - - if (rinfo->asleep) - return 0; - - OUTREG(CRTC_OFFSET, ((var->yoffset * var->xres_virtual + var->xoffset) - * var->bits_per_pixel / 8) & ~7); - return 0; -} - - -static int radeonfb_ioctl (struct fb_info *info, unsigned int cmd, - unsigned long arg) -{ - struct radeonfb_info *rinfo = (struct radeonfb_info *) info; - unsigned int tmp; - u32 value = 0; - int rc; - - switch (cmd) { - /* - * TODO: set mirror accordingly for non-Mobility chipsets with 2 CRTC's - */ - case FBIO_RADEON_SET_MIRROR: - switch (rinfo->arch) { - case RADEON_R100: - case RADEON_RV100: - case RADEON_R200: - case RADEON_RV200: - case RADEON_RV250: - case RADEON_R300: - return -EINVAL; - default: - /* RADEON M6, RADEON_M7, RADEON_M9 */ - break; - } - - rc = get_user(value, (__u32 __user *)arg); - - if (rc) - return rc; - - if (value & 0x01) { - tmp = INREG(LVDS_GEN_CNTL); - - tmp |= (LVDS_ON | LVDS_BLON); - } else { - tmp = INREG(LVDS_GEN_CNTL); - - tmp &= ~(LVDS_ON | LVDS_BLON); - } - - OUTREG(LVDS_GEN_CNTL, tmp); - - if (value & 0x02) { - tmp = INREG(CRTC_EXT_CNTL); - tmp |= CRTC_CRT_ON; - - mirror = 1; - } else { - tmp = INREG(CRTC_EXT_CNTL); - tmp &= ~CRTC_CRT_ON; - - mirror = 0; - } - - OUTREG(CRTC_EXT_CNTL, tmp); - - break; - case FBIO_RADEON_GET_MIRROR: - switch (rinfo->arch) { - case RADEON_R100: - case RADEON_RV100: - case RADEON_R200: - case RADEON_RV200: - case RADEON_RV250: - case RADEON_R300: - return -EINVAL; - default: - /* RADEON M6, RADEON_M7, RADEON_M9 */ - break; - } - - tmp = INREG(LVDS_GEN_CNTL); - if ((LVDS_ON | LVDS_BLON) & tmp) - value |= 0x01; - - tmp = INREG(CRTC_EXT_CNTL); - if (CRTC_CRT_ON & tmp) - value |= 0x02; - - return put_user(value, (__u32 __user *)arg); - default: - return -EINVAL; - } - - return -EINVAL; -} - - -static int radeonfb_blank (int blank, struct fb_info *info) -{ - struct radeonfb_info *rinfo = (struct radeonfb_info *) info; - u32 val = INREG(CRTC_EXT_CNTL); - u32 val2 = INREG(LVDS_GEN_CNTL); - - if (rinfo->asleep) - return 0; - -#ifdef CONFIG_PMAC_BACKLIGHT - if (rinfo->dviDisp_type == MT_LCD && machine_is(powermac)) { - set_backlight_enable(!blank); - return 0; - } -#endif - - /* reset it */ - val &= ~(CRTC_DISPLAY_DIS | CRTC_HSYNC_DIS | - CRTC_VSYNC_DIS); - val2 &= ~(LVDS_DISPLAY_DIS); - - switch (blank) { - case FB_BLANK_UNBLANK: - case FB_BLANK_NORMAL: - break; - case FB_BLANK_VSYNC_SUSPEND: - val |= (CRTC_DISPLAY_DIS | CRTC_VSYNC_DIS); - break; - case FB_BLANK_HSYNC_SUSPEND: - val |= (CRTC_DISPLAY_DIS | CRTC_HSYNC_DIS); - break; - case FB_BLANK_POWERDOWN: - val |= (CRTC_DISPLAY_DIS | CRTC_VSYNC_DIS | - CRTC_HSYNC_DIS); - val2 |= (LVDS_DISPLAY_DIS); - break; - } - - switch (rinfo->dviDisp_type) { - case MT_LCD: - OUTREG(LVDS_GEN_CNTL, val2); - break; - case MT_CRT: - default: - OUTREG(CRTC_EXT_CNTL, val); - break; - } - - /* let fbcon do a soft blank for us */ - return (blank == FB_BLANK_NORMAL) ? 1 : 0; -} - - -static int radeonfb_setcolreg (unsigned regno, unsigned red, unsigned green, - unsigned blue, unsigned transp, struct fb_info *info) -{ - struct radeonfb_info *rinfo = (struct radeonfb_info *) info; - u32 pindex, vclk_cntl; - unsigned int i; - - if (regno > 255) - return 1; - - red >>= 8; - green >>= 8; - blue >>= 8; - rinfo->palette[regno].red = red; - rinfo->palette[regno].green = green; - rinfo->palette[regno].blue = blue; - - /* default */ - pindex = regno; - - if (!rinfo->asleep) { - vclk_cntl = INPLL(VCLK_ECP_CNTL); - OUTPLL(VCLK_ECP_CNTL, vclk_cntl & ~PIXCLK_DAC_ALWAYS_ONb); - - if (rinfo->bpp == 16) { - pindex = regno * 8; - - if (rinfo->depth == 16 && regno > 63) - return 1; - if (rinfo->depth == 15 && regno > 31) - return 1; - - /* For 565, the green component is mixed one order below */ - if (rinfo->depth == 16) { - OUTREG(PALETTE_INDEX, pindex>>1); - OUTREG(PALETTE_DATA, (rinfo->palette[regno>>1].red << 16) | - (green << 8) | (rinfo->palette[regno>>1].blue)); - green = rinfo->palette[regno<<1].green; - } - } - - if (rinfo->depth != 16 || regno < 32) { - OUTREG(PALETTE_INDEX, pindex); - OUTREG(PALETTE_DATA, (red << 16) | (green << 8) | blue); - } - - OUTPLL(VCLK_ECP_CNTL, vclk_cntl); - } - if (regno < 16) { - switch (rinfo->depth) { - case 15: - ((u16 *) (info->pseudo_palette))[regno] = - (regno << 10) | (regno << 5) | regno; - break; - case 16: - ((u16 *) (info->pseudo_palette))[regno] = - (regno << 11) | (regno << 6) | regno; - break; - case 24: - ((u32 *) (info->pseudo_palette))[regno] = - (regno << 16) | (regno << 8) | regno; - break; - case 32: - i = (regno << 8) | regno; - ((u32 *) (info->pseudo_palette))[regno] = - (i << 16) | i; - break; - } - } - return 0; -} - - - -static void radeon_save_state (struct radeonfb_info *rinfo, - struct radeon_regs *save) -{ - /* CRTC regs */ - save->crtc_gen_cntl = INREG(CRTC_GEN_CNTL); - save->crtc_ext_cntl = INREG(CRTC_EXT_CNTL); - save->dac_cntl = INREG(DAC_CNTL); - save->crtc_h_total_disp = INREG(CRTC_H_TOTAL_DISP); - save->crtc_h_sync_strt_wid = INREG(CRTC_H_SYNC_STRT_WID); - save->crtc_v_total_disp = INREG(CRTC_V_TOTAL_DISP); - save->crtc_v_sync_strt_wid = INREG(CRTC_V_SYNC_STRT_WID); - save->crtc_pitch = INREG(CRTC_PITCH); -#if defined(__BIG_ENDIAN) - save->surface_cntl = INREG(SURFACE_CNTL); -#endif - - /* FP regs */ - save->fp_crtc_h_total_disp = INREG(FP_CRTC_H_TOTAL_DISP); - save->fp_crtc_v_total_disp = INREG(FP_CRTC_V_TOTAL_DISP); - save->fp_gen_cntl = INREG(FP_GEN_CNTL); - save->fp_h_sync_strt_wid = INREG(FP_H_SYNC_STRT_WID); - save->fp_horz_stretch = INREG(FP_HORZ_STRETCH); - save->fp_v_sync_strt_wid = INREG(FP_V_SYNC_STRT_WID); - save->fp_vert_stretch = INREG(FP_VERT_STRETCH); - save->lvds_gen_cntl = INREG(LVDS_GEN_CNTL); - save->lvds_pll_cntl = INREG(LVDS_PLL_CNTL); - save->tmds_crc = INREG(TMDS_CRC); - save->tmds_transmitter_cntl = INREG(TMDS_TRANSMITTER_CNTL); - save->vclk_ecp_cntl = INPLL(VCLK_ECP_CNTL); -} - - - -static int radeonfb_set_par (struct fb_info *info) -{ - struct radeonfb_info *rinfo = (struct radeonfb_info *)info->par; - struct fb_var_screeninfo *mode = &info->var; - struct radeon_regs newmode; - int hTotal, vTotal, hSyncStart, hSyncEnd, - hSyncPol, vSyncStart, vSyncEnd, vSyncPol, cSync; - u8 hsync_adj_tab[] = {0, 0x12, 9, 9, 6, 5}; - u8 hsync_fudge_fp[] = {2, 2, 0, 0, 5, 5}; - u32 dotClock = 1000000000 / mode->pixclock, - sync, h_sync_pol, v_sync_pol; - int freq = dotClock / 10; /* x 100 */ - int xclk_freq, vclk_freq, xclk_per_trans, xclk_per_trans_precise; - int useable_precision, roff, ron; - int min_bits, format = 0; - int hsync_start, hsync_fudge, bytpp, hsync_wid, vsync_wid; - int primary_mon = PRIMARY_MONITOR(rinfo); - int depth = var_to_depth(mode); - int accel = (mode->accel_flags & FB_ACCELF_TEXT) != 0; - - rinfo->xres = mode->xres; - rinfo->yres = mode->yres; - rinfo->xres_virtual = mode->xres_virtual; - rinfo->yres_virtual = mode->yres_virtual; - rinfo->pixclock = mode->pixclock; - - hSyncStart = mode->xres + mode->right_margin; - hSyncEnd = hSyncStart + mode->hsync_len; - hTotal = hSyncEnd + mode->left_margin; - - vSyncStart = mode->yres + mode->lower_margin; - vSyncEnd = vSyncStart + mode->vsync_len; - vTotal = vSyncEnd + mode->upper_margin; - - if ((primary_mon == MT_DFP) || (primary_mon == MT_LCD)) { - if (rinfo->panel_xres < mode->xres) - rinfo->xres = mode->xres = rinfo->panel_xres; - if (rinfo->panel_yres < mode->yres) - rinfo->yres = mode->yres = rinfo->panel_yres; - - hTotal = mode->xres + rinfo->hblank; - hSyncStart = mode->xres + rinfo->hOver_plus; - hSyncEnd = hSyncStart + rinfo->hSync_width; - - vTotal = mode->yres + rinfo->vblank; - vSyncStart = mode->yres + rinfo->vOver_plus; - vSyncEnd = vSyncStart + rinfo->vSync_width; - } - - sync = mode->sync; - h_sync_pol = sync & FB_SYNC_HOR_HIGH_ACT ? 0 : 1; - v_sync_pol = sync & FB_SYNC_VERT_HIGH_ACT ? 0 : 1; - - RTRACE("hStart = %d, hEnd = %d, hTotal = %d\n", - hSyncStart, hSyncEnd, hTotal); - RTRACE("vStart = %d, vEnd = %d, vTotal = %d\n", - vSyncStart, vSyncEnd, vTotal); - - hsync_wid = (hSyncEnd - hSyncStart) / 8; - vsync_wid = vSyncEnd - vSyncStart; - if (hsync_wid == 0) - hsync_wid = 1; - else if (hsync_wid > 0x3f) /* max */ - hsync_wid = 0x3f; - - if (vsync_wid == 0) - vsync_wid = 1; - else if (vsync_wid > 0x1f) /* max */ - vsync_wid = 0x1f; - - hSyncPol = mode->sync & FB_SYNC_HOR_HIGH_ACT ? 0 : 1; - vSyncPol = mode->sync & FB_SYNC_VERT_HIGH_ACT ? 0 : 1; - - cSync = mode->sync & FB_SYNC_COMP_HIGH_ACT ? (1 << 4) : 0; - - format = radeon_get_dstbpp(depth); - bytpp = mode->bits_per_pixel >> 3; - - if ((primary_mon == MT_DFP) || (primary_mon == MT_LCD)) - hsync_fudge = hsync_fudge_fp[format-1]; - else - hsync_fudge = hsync_adj_tab[format-1]; - - hsync_start = hSyncStart - 8 + hsync_fudge; - - newmode.crtc_gen_cntl = CRTC_EXT_DISP_EN | CRTC_EN | - (format << 8); - - if ((primary_mon == MT_DFP) || (primary_mon == MT_LCD)) { - newmode.crtc_ext_cntl = VGA_ATI_LINEAR | XCRT_CNT_EN; - if (mirror) - newmode.crtc_ext_cntl |= CRTC_CRT_ON; - - newmode.crtc_gen_cntl &= ~(CRTC_DBL_SCAN_EN | - CRTC_INTERLACE_EN); - } else { - newmode.crtc_ext_cntl = VGA_ATI_LINEAR | XCRT_CNT_EN | - CRTC_CRT_ON; - } - - newmode.dac_cntl = /* INREG(DAC_CNTL) | */ DAC_MASK_ALL | DAC_VGA_ADR_EN | - DAC_8BIT_EN; - - newmode.crtc_h_total_disp = ((((hTotal / 8) - 1) & 0x3ff) | - (((mode->xres / 8) - 1) << 16)); - - newmode.crtc_h_sync_strt_wid = ((hsync_start & 0x1fff) | - (hsync_wid << 16) | (h_sync_pol << 23)); - - newmode.crtc_v_total_disp = ((vTotal - 1) & 0xffff) | - ((mode->yres - 1) << 16); - - newmode.crtc_v_sync_strt_wid = (((vSyncStart - 1) & 0xfff) | - (vsync_wid << 16) | (v_sync_pol << 23)); - - if (accel) { - /* We first calculate the engine pitch */ - rinfo->pitch = ((mode->xres_virtual * ((mode->bits_per_pixel + 1) / 8) + 0x3f) - & ~(0x3f)) >> 6; - - /* Then, re-multiply it to get the CRTC pitch */ - newmode.crtc_pitch = (rinfo->pitch << 3) / ((mode->bits_per_pixel + 1) / 8); - } else - newmode.crtc_pitch = (mode->xres_virtual >> 3); - newmode.crtc_pitch |= (newmode.crtc_pitch << 16); - -#if defined(__BIG_ENDIAN) - /* - * It looks like recent chips have a problem with SURFACE_CNTL, - * setting SURF_TRANSLATION_DIS completely disables the - * swapper as well, so we leave it unset now. - */ - newmode.surface_cntl = 0; - - /* Setup swapping on both apertures, though we currently - * only use aperture 0, enabling swapper on aperture 1 - * won't harm - */ - switch (mode->bits_per_pixel) { - case 16: - newmode.surface_cntl |= NONSURF_AP0_SWP_16BPP; - newmode.surface_cntl |= NONSURF_AP1_SWP_16BPP; - break; - case 24: - case 32: - newmode.surface_cntl |= NONSURF_AP0_SWP_32BPP; - newmode.surface_cntl |= NONSURF_AP1_SWP_32BPP; - break; - } -#endif - - rinfo->pitch = ((mode->xres_virtual * ((mode->bits_per_pixel + 1) / 8) + 0x3f) - & ~(0x3f)) / 64; - - RTRACE("h_total_disp = 0x%x\t hsync_strt_wid = 0x%x\n", - newmode.crtc_h_total_disp, newmode.crtc_h_sync_strt_wid); - RTRACE("v_total_disp = 0x%x\t vsync_strt_wid = 0x%x\n", - newmode.crtc_v_total_disp, newmode.crtc_v_sync_strt_wid); - - newmode.xres = mode->xres; - newmode.yres = mode->yres; - - rinfo->bpp = mode->bits_per_pixel; - rinfo->depth = depth; - - if (freq > rinfo->pll.ppll_max) - freq = rinfo->pll.ppll_max; - if (freq*12 < rinfo->pll.ppll_min) - freq = rinfo->pll.ppll_min / 12; - - { - struct { - int divider; - int bitvalue; - } *post_div, - post_divs[] = { - { 1, 0 }, - { 2, 1 }, - { 4, 2 }, - { 8, 3 }, - { 3, 4 }, - { 16, 5 }, - { 6, 6 }, - { 12, 7 }, - { 0, 0 }, - }; - - for (post_div = &post_divs[0]; post_div->divider; ++post_div) { - rinfo->pll_output_freq = post_div->divider * freq; - if (rinfo->pll_output_freq >= rinfo->pll.ppll_min && - rinfo->pll_output_freq <= rinfo->pll.ppll_max) - break; - } - - rinfo->post_div = post_div->divider; - rinfo->fb_div = round_div(rinfo->pll.ref_div*rinfo->pll_output_freq, - rinfo->pll.ref_clk); - newmode.ppll_ref_div = rinfo->pll.ref_div; - newmode.ppll_div_3 = rinfo->fb_div | (post_div->bitvalue << 16); - } - newmode.vclk_ecp_cntl = rinfo->init_state.vclk_ecp_cntl; - -#ifdef CONFIG_PPC_OF - /* Gross hack for iBook with M7 until I find out a proper fix */ - if (machine_is_compatible("PowerBook4,3") && rinfo->arch == RADEON_M7) - newmode.ppll_div_3 = 0x000600ad; -#endif /* CONFIG_PPC_OF */ - - RTRACE("post div = 0x%x\n", rinfo->post_div); - RTRACE("fb_div = 0x%x\n", rinfo->fb_div); - RTRACE("ppll_div_3 = 0x%x\n", newmode.ppll_div_3); - - /* DDA */ - vclk_freq = round_div(rinfo->pll.ref_clk * rinfo->fb_div, - rinfo->pll.ref_div * rinfo->post_div); - xclk_freq = rinfo->pll.xclk; - - xclk_per_trans = round_div(xclk_freq * 128, vclk_freq * mode->bits_per_pixel); - - min_bits = min_bits_req(xclk_per_trans); - useable_precision = min_bits + 1; - - xclk_per_trans_precise = round_div((xclk_freq * 128) << (11 - useable_precision), - vclk_freq * mode->bits_per_pixel); - - ron = (4 * rinfo->ram.mb + 3 * _max(rinfo->ram.trcd - 2, 0) + - 2 * rinfo->ram.trp + rinfo->ram.twr + rinfo->ram.cl + rinfo->ram.tr2w + - xclk_per_trans) << (11 - useable_precision); - roff = xclk_per_trans_precise * (32 - 4); - - RTRACE("ron = %d, roff = %d\n", ron, roff); - RTRACE("vclk_freq = %d, per = %d\n", vclk_freq, xclk_per_trans_precise); - - if ((ron + rinfo->ram.rloop) >= roff) { - printk("radeonfb: error ron out of range\n"); - return -EINVAL; - } - - newmode.dda_config = (xclk_per_trans_precise | - (useable_precision << 16) | - (rinfo->ram.rloop << 20)); - newmode.dda_on_off = (ron << 16) | roff; - - if ((primary_mon == MT_DFP) || (primary_mon == MT_LCD)) { - unsigned int hRatio, vRatio; - - /* We force the pixel clock to be always enabled. Allowing it - * to be power managed during blanking would save power, but has - * nasty interactions with the 2D engine & sleep code that haven't - * been solved yet. --BenH - */ - newmode.vclk_ecp_cntl &= ~PIXCLK_DAC_ALWAYS_ONb; - - if (mode->xres > rinfo->panel_xres) - mode->xres = rinfo->panel_xres; - if (mode->yres > rinfo->panel_yres) - mode->yres = rinfo->panel_yres; - - newmode.fp_horz_stretch = (((rinfo->panel_xres / 8) - 1) - << HORZ_PANEL_SHIFT); - newmode.fp_vert_stretch = ((rinfo->panel_yres - 1) - << VERT_PANEL_SHIFT); - - if (mode->xres != rinfo->panel_xres) { - hRatio = round_div(mode->xres * HORZ_STRETCH_RATIO_MAX, - rinfo->panel_xres); - newmode.fp_horz_stretch = (((((unsigned long)hRatio) & HORZ_STRETCH_RATIO_MASK)) | - (newmode.fp_horz_stretch & - (HORZ_PANEL_SIZE | HORZ_FP_LOOP_STRETCH | - HORZ_AUTO_RATIO_INC))); - newmode.fp_horz_stretch |= (HORZ_STRETCH_BLEND | - HORZ_STRETCH_ENABLE); - } - newmode.fp_horz_stretch &= ~HORZ_AUTO_RATIO; - - if (mode->yres != rinfo->panel_yres) { - vRatio = round_div(mode->yres * VERT_STRETCH_RATIO_MAX, - rinfo->panel_yres); - newmode.fp_vert_stretch = (((((unsigned long)vRatio) & VERT_STRETCH_RATIO_MASK)) | - (newmode.fp_vert_stretch & - (VERT_PANEL_SIZE | VERT_STRETCH_RESERVED))); - newmode.fp_vert_stretch |= (VERT_STRETCH_BLEND | - VERT_STRETCH_ENABLE); - } - newmode.fp_vert_stretch &= ~VERT_AUTO_RATIO_EN; - - newmode.fp_gen_cntl = (rinfo->init_state.fp_gen_cntl & (u32) - ~(FP_SEL_CRTC2 | - FP_RMX_HVSYNC_CONTROL_EN | - FP_DFP_SYNC_SEL | - FP_CRT_SYNC_SEL | - FP_CRTC_LOCK_8DOT | - FP_USE_SHADOW_EN | - FP_CRTC_USE_SHADOW_VEND | - FP_CRT_SYNC_ALT)); - - newmode.fp_gen_cntl |= (FP_CRTC_DONT_SHADOW_VPAR | - FP_CRTC_DONT_SHADOW_HEND); - - newmode.lvds_gen_cntl = rinfo->init_state.lvds_gen_cntl; - newmode.lvds_pll_cntl = rinfo->init_state.lvds_pll_cntl; - newmode.tmds_crc = rinfo->init_state.tmds_crc; - newmode.tmds_transmitter_cntl = rinfo->init_state.tmds_transmitter_cntl; - - if (primary_mon == MT_LCD) { - newmode.lvds_gen_cntl |= (LVDS_ON | LVDS_BLON); - newmode.fp_gen_cntl &= ~(FP_FPON | FP_TMDS_EN); - } else { - /* DFP */ - newmode.fp_gen_cntl |= (FP_FPON | FP_TMDS_EN); - newmode.tmds_transmitter_cntl = (TMDS_RAN_PAT_RST | - TMDS_ICHCSEL | TMDS_PLL_EN) & - ~(TMDS_PLLRST); - newmode.crtc_ext_cntl &= ~CRTC_CRT_ON; - } - - newmode.fp_crtc_h_total_disp = (((rinfo->hblank / 8) & 0x3ff) | - (((mode->xres / 8) - 1) << 16)); - newmode.fp_crtc_v_total_disp = (rinfo->vblank & 0xffff) | - ((mode->yres - 1) << 16); - newmode.fp_h_sync_strt_wid = ((rinfo->hOver_plus & 0x1fff) | - (hsync_wid << 16) | (h_sync_pol << 23)); - newmode.fp_v_sync_strt_wid = ((rinfo->vOver_plus & 0xfff) | - (vsync_wid << 16) | (v_sync_pol << 23)); - } - - /* do it! */ - if (!rinfo->asleep) { - radeon_write_mode (rinfo, &newmode); - /* (re)initialize the engine */ - if (noaccel) - radeon_engine_init (rinfo); - - } - /* Update fix */ - if (accel) - info->fix.line_length = rinfo->pitch*64; - else - info->fix.line_length = mode->xres_virtual * ((mode->bits_per_pixel + 1) / 8); - info->fix.visual = rinfo->depth == 8 ? FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_DIRECTCOLOR; - -#ifdef CONFIG_BOOTX_TEXT - /* Update debug text engine */ - btext_update_display(rinfo->fb_base_phys, mode->xres, mode->yres, - rinfo->depth, info->fix.line_length); -#endif - - return 0; -} - - -static void radeon_write_mode (struct radeonfb_info *rinfo, - struct radeon_regs *mode) -{ - int i; - int primary_mon = PRIMARY_MONITOR(rinfo); - - radeonfb_blank(VESA_POWERDOWN, (struct fb_info *)rinfo); - - - if (rinfo->arch == RADEON_M6) { - for (i=0; i<7; i++) - OUTREG(common_regs_m6[i].reg, common_regs_m6[i].val); - } else { - for (i=0; i<9; i++) - OUTREG(common_regs[i].reg, common_regs[i].val); - } - - OUTREG(CRTC_GEN_CNTL, mode->crtc_gen_cntl); - OUTREGP(CRTC_EXT_CNTL, mode->crtc_ext_cntl, - CRTC_HSYNC_DIS | CRTC_VSYNC_DIS | CRTC_DISPLAY_DIS); - OUTREGP(DAC_CNTL, mode->dac_cntl, DAC_RANGE_CNTL | DAC_BLANKING); - OUTREG(CRTC_H_TOTAL_DISP, mode->crtc_h_total_disp); - OUTREG(CRTC_H_SYNC_STRT_WID, mode->crtc_h_sync_strt_wid); - OUTREG(CRTC_V_TOTAL_DISP, mode->crtc_v_total_disp); - OUTREG(CRTC_V_SYNC_STRT_WID, mode->crtc_v_sync_strt_wid); - OUTREG(CRTC_OFFSET, 0); - OUTREG(CRTC_OFFSET_CNTL, 0); - OUTREG(CRTC_PITCH, mode->crtc_pitch); - -#if defined(__BIG_ENDIAN) - OUTREG(SURFACE_CNTL, mode->surface_cntl); -#endif - - while ((INREG(CLOCK_CNTL_INDEX) & PPLL_DIV_SEL_MASK) != - PPLL_DIV_SEL_MASK) { - OUTREGP(CLOCK_CNTL_INDEX, PPLL_DIV_SEL_MASK, 0xffff); - } - - OUTPLLP(PPLL_CNTL, PPLL_RESET, 0xffff); - - while ((INPLL(PPLL_REF_DIV) & PPLL_REF_DIV_MASK) != - (mode->ppll_ref_div & PPLL_REF_DIV_MASK)) { - OUTPLLP(PPLL_REF_DIV, mode->ppll_ref_div, ~PPLL_REF_DIV_MASK); - } - - while ((INPLL(PPLL_DIV_3) & PPLL_FB3_DIV_MASK) != - (mode->ppll_div_3 & PPLL_FB3_DIV_MASK)) { - OUTPLLP(PPLL_DIV_3, mode->ppll_div_3, ~PPLL_FB3_DIV_MASK); - } - - while ((INPLL(PPLL_DIV_3) & PPLL_POST3_DIV_MASK) != - (mode->ppll_div_3 & PPLL_POST3_DIV_MASK)) { - OUTPLLP(PPLL_DIV_3, mode->ppll_div_3, ~PPLL_POST3_DIV_MASK); - } - - OUTPLL(HTOTAL_CNTL, 0); - - OUTPLLP(PPLL_CNTL, 0, ~PPLL_RESET); - -// OUTREG(DDA_CONFIG, mode->dda_config); -// OUTREG(DDA_ON_OFF, mode->dda_on_off); - - if ((primary_mon == MT_DFP) || (primary_mon == MT_LCD)) { - OUTREG(FP_CRTC_H_TOTAL_DISP, mode->fp_crtc_h_total_disp); - OUTREG(FP_CRTC_V_TOTAL_DISP, mode->fp_crtc_v_total_disp); - OUTREG(FP_H_SYNC_STRT_WID, mode->fp_h_sync_strt_wid); - OUTREG(FP_V_SYNC_STRT_WID, mode->fp_v_sync_strt_wid); - OUTREG(FP_HORZ_STRETCH, mode->fp_horz_stretch); - OUTREG(FP_VERT_STRETCH, mode->fp_vert_stretch); - OUTREG(FP_GEN_CNTL, mode->fp_gen_cntl); - OUTREG(TMDS_CRC, mode->tmds_crc); - OUTREG(TMDS_TRANSMITTER_CNTL, mode->tmds_transmitter_cntl); - - if (primary_mon == MT_LCD) { - unsigned int tmp = INREG(LVDS_GEN_CNTL); - - mode->lvds_gen_cntl &= ~LVDS_STATE_MASK; - mode->lvds_gen_cntl |= (rinfo->init_state.lvds_gen_cntl & LVDS_STATE_MASK); - - if ((tmp & (LVDS_ON | LVDS_BLON)) == - (mode->lvds_gen_cntl & (LVDS_ON | LVDS_BLON))) { - OUTREG(LVDS_GEN_CNTL, mode->lvds_gen_cntl); - } else { - if (mode->lvds_gen_cntl & (LVDS_ON | LVDS_BLON)) { - udelay(1000); - OUTREG(LVDS_GEN_CNTL, mode->lvds_gen_cntl); - } else { - OUTREG(LVDS_GEN_CNTL, mode->lvds_gen_cntl | - LVDS_BLON); - udelay(1000); - OUTREG(LVDS_GEN_CNTL, mode->lvds_gen_cntl); - } - } - } - } - - radeonfb_blank(VESA_NO_BLANKING, (struct fb_info *)rinfo); - - OUTPLL(VCLK_ECP_CNTL, mode->vclk_ecp_cntl); - - return; -} - -static struct fb_ops radeonfb_ops = { - .owner = THIS_MODULE, - .fb_check_var = radeonfb_check_var, - .fb_set_par = radeonfb_set_par, - .fb_setcolreg = radeonfb_setcolreg, - .fb_pan_display = radeonfb_pan_display, - .fb_blank = radeonfb_blank, - .fb_ioctl = radeonfb_ioctl, -#if 0 - .fb_fillrect = radeonfb_fillrect, - .fb_copyarea = radeonfb_copyarea, - .fb_imageblit = radeonfb_imageblit, - .fb_rasterimg = radeonfb_rasterimg, -#else - .fb_fillrect = cfb_fillrect, - .fb_copyarea = cfb_copyarea, - .fb_imageblit = cfb_imageblit, -#endif -}; - - -static int __devinit radeon_set_fbinfo (struct radeonfb_info *rinfo) -{ - struct fb_info *info; - - info = &rinfo->info; - - info->par = rinfo; - info->pseudo_palette = rinfo->pseudo_palette; - info->flags = FBINFO_DEFAULT | FBINFO_HWACCEL_YPAN; - info->fbops = &radeonfb_ops; - info->screen_base = rinfo->fb_base; - - /* Fill fix common fields */ - strlcpy(info->fix.id, rinfo->name, sizeof(info->fix.id)); - info->fix.smem_start = rinfo->fb_base_phys; - info->fix.smem_len = rinfo->video_ram; - info->fix.type = FB_TYPE_PACKED_PIXELS; - info->fix.visual = FB_VISUAL_PSEUDOCOLOR; - info->fix.xpanstep = 8; - info->fix.ypanstep = 1; - info->fix.ywrapstep = 0; - info->fix.type_aux = 0; - info->fix.mmio_start = rinfo->mmio_base_phys; - info->fix.mmio_len = RADEON_REGSIZE; - if (noaccel) - info->fix.accel = FB_ACCEL_NONE; - else - info->fix.accel = FB_ACCEL_ATI_RADEON; - - if (radeon_init_disp (rinfo) < 0) - return -1; - - return 0; -} - - -#ifdef CONFIG_PMAC_BACKLIGHT - -/* TODO: Dbl check these tables, we don't go up to full ON backlight - * in these, possibly because we noticed MacOS doesn't, but I'd prefer - * having some more official numbers from ATI - */ -static int backlight_conv_m6[] = { - 0xff, 0xc0, 0xb5, 0xaa, 0x9f, 0x94, 0x89, 0x7e, - 0x73, 0x68, 0x5d, 0x52, 0x47, 0x3c, 0x31, 0x24 -}; -static int backlight_conv_m7[] = { - 0x00, 0x3f, 0x4a, 0x55, 0x60, 0x6b, 0x76, 0x81, - 0x8c, 0x97, 0xa2, 0xad, 0xb8, 0xc3, 0xce, 0xd9 -}; - -#define BACKLIGHT_LVDS_OFF -#undef BACKLIGHT_DAC_OFF - -/* We turn off the LCD completely instead of just dimming the backlight. - * This provides some greater power saving and the display is useless - * without backlight anyway. - */ - -static int radeon_set_backlight_enable(int on, int level, void *data) -{ - struct radeonfb_info *rinfo = (struct radeonfb_info *)data; - unsigned int lvds_gen_cntl = INREG(LVDS_GEN_CNTL); - int* conv_table; - - /* Pardon me for that hack... maybe some day we can figure - * out in what direction backlight should work on a given - * panel ? - */ - if ((rinfo->arch == RADEON_M7 || rinfo->arch == RADEON_M9) - && !machine_is_compatible("PowerBook4,3")) - conv_table = backlight_conv_m7; - else - conv_table = backlight_conv_m6; - - lvds_gen_cntl |= (LVDS_BL_MOD_EN | LVDS_BLON); - if (on && (level > BACKLIGHT_OFF)) { - lvds_gen_cntl |= LVDS_DIGON; - if (!(lvds_gen_cntl & LVDS_ON)) { - lvds_gen_cntl &= ~LVDS_BLON; - OUTREG(LVDS_GEN_CNTL, lvds_gen_cntl); - (void)INREG(LVDS_GEN_CNTL); - mdelay(10); - lvds_gen_cntl |= LVDS_BLON; - OUTREG(LVDS_GEN_CNTL, lvds_gen_cntl); - } - lvds_gen_cntl &= ~LVDS_BL_MOD_LEVEL_MASK; - lvds_gen_cntl |= (conv_table[level] << - LVDS_BL_MOD_LEVEL_SHIFT); - lvds_gen_cntl |= (LVDS_ON | LVDS_EN); - lvds_gen_cntl &= ~LVDS_DISPLAY_DIS; - } else { - lvds_gen_cntl &= ~LVDS_BL_MOD_LEVEL_MASK; - lvds_gen_cntl |= (conv_table[0] << - LVDS_BL_MOD_LEVEL_SHIFT); - lvds_gen_cntl |= LVDS_DISPLAY_DIS; - OUTREG(LVDS_GEN_CNTL, lvds_gen_cntl); - udelay(10); - lvds_gen_cntl &= ~(LVDS_ON | LVDS_EN | LVDS_BLON | LVDS_DIGON); - } - - OUTREG(LVDS_GEN_CNTL, lvds_gen_cntl); - rinfo->init_state.lvds_gen_cntl &= ~LVDS_STATE_MASK; - rinfo->init_state.lvds_gen_cntl |= (lvds_gen_cntl & LVDS_STATE_MASK); - - return 0; -} - -static int radeon_set_backlight_level(int level, void *data) -{ - return radeon_set_backlight_enable(1, level, data); -} -#endif /* CONFIG_PMAC_BACKLIGHT */ - - -#ifdef CONFIG_PMAC_PBOOK - -static u32 dbg_clk; - -/* - * Radeon M6 Power Management code. This code currently only supports - * the mobile chips, it's based from some informations provided by ATI - * along with hours of tracing of MacOS drivers - */ - -static void radeon_pm_save_regs(struct radeonfb_info *rinfo) -{ - rinfo->save_regs[0] = INPLL(PLL_PWRMGT_CNTL); - rinfo->save_regs[1] = INPLL(CLK_PWRMGT_CNTL); - rinfo->save_regs[2] = INPLL(MCLK_CNTL); - rinfo->save_regs[3] = INPLL(SCLK_CNTL); - rinfo->save_regs[4] = INPLL(CLK_PIN_CNTL); - rinfo->save_regs[5] = INPLL(VCLK_ECP_CNTL); - rinfo->save_regs[6] = INPLL(PIXCLKS_CNTL); - rinfo->save_regs[7] = INPLL(MCLK_MISC); - rinfo->save_regs[8] = INPLL(P2PLL_CNTL); - - rinfo->save_regs[9] = INREG(DISP_MISC_CNTL); - rinfo->save_regs[10] = INREG(DISP_PWR_MAN); - rinfo->save_regs[11] = INREG(LVDS_GEN_CNTL); - rinfo->save_regs[12] = INREG(LVDS_PLL_CNTL); - rinfo->save_regs[13] = INREG(TV_DAC_CNTL); - rinfo->save_regs[14] = INREG(BUS_CNTL1); - rinfo->save_regs[15] = INREG(CRTC_OFFSET_CNTL); - rinfo->save_regs[16] = INREG(AGP_CNTL); - rinfo->save_regs[17] = (INREG(CRTC_GEN_CNTL) & 0xfdffffff) | 0x04000000; - rinfo->save_regs[18] = (INREG(CRTC2_GEN_CNTL) & 0xfdffffff) | 0x04000000; - rinfo->save_regs[19] = INREG(GPIOPAD_A); - rinfo->save_regs[20] = INREG(GPIOPAD_EN); - rinfo->save_regs[21] = INREG(GPIOPAD_MASK); - rinfo->save_regs[22] = INREG(ZV_LCDPAD_A); - rinfo->save_regs[23] = INREG(ZV_LCDPAD_EN); - rinfo->save_regs[24] = INREG(ZV_LCDPAD_MASK); - rinfo->save_regs[25] = INREG(GPIO_VGA_DDC); - rinfo->save_regs[26] = INREG(GPIO_DVI_DDC); - rinfo->save_regs[27] = INREG(GPIO_MONID); - rinfo->save_regs[28] = INREG(GPIO_CRT2_DDC); - - rinfo->save_regs[29] = INREG(SURFACE_CNTL); - rinfo->save_regs[30] = INREG(MC_FB_LOCATION); - rinfo->save_regs[31] = INREG(DISPLAY_BASE_ADDR); - rinfo->save_regs[32] = INREG(MC_AGP_LOCATION); - rinfo->save_regs[33] = INREG(CRTC2_DISPLAY_BASE_ADDR); -} - -static void radeon_pm_restore_regs(struct radeonfb_info *rinfo) -{ - OUTPLL(P2PLL_CNTL, rinfo->save_regs[8] & 0xFFFFFFFE); /* First */ - - OUTPLL(PLL_PWRMGT_CNTL, rinfo->save_regs[0]); - OUTPLL(CLK_PWRMGT_CNTL, rinfo->save_regs[1]); - OUTPLL(MCLK_CNTL, rinfo->save_regs[2]); - OUTPLL(SCLK_CNTL, rinfo->save_regs[3]); - OUTPLL(CLK_PIN_CNTL, rinfo->save_regs[4]); - OUTPLL(VCLK_ECP_CNTL, rinfo->save_regs[5]); - OUTPLL(PIXCLKS_CNTL, rinfo->save_regs[6]); - OUTPLL(MCLK_MISC, rinfo->save_regs[7]); - - OUTREG(DISP_MISC_CNTL, rinfo->save_regs[9]); - OUTREG(DISP_PWR_MAN, rinfo->save_regs[10]); - OUTREG(LVDS_GEN_CNTL, rinfo->save_regs[11]); - OUTREG(LVDS_PLL_CNTL,rinfo->save_regs[12]); - OUTREG(TV_DAC_CNTL, rinfo->save_regs[13]); - OUTREG(BUS_CNTL1, rinfo->save_regs[14]); - OUTREG(CRTC_OFFSET_CNTL, rinfo->save_regs[15]); - OUTREG(AGP_CNTL, rinfo->save_regs[16]); - OUTREG(CRTC_GEN_CNTL, rinfo->save_regs[17]); - OUTREG(CRTC2_GEN_CNTL, rinfo->save_regs[18]); - - // wait VBL before that one ? - OUTPLL(P2PLL_CNTL, rinfo->save_regs[8]); - - OUTREG(GPIOPAD_A, rinfo->save_regs[19]); - OUTREG(GPIOPAD_EN, rinfo->save_regs[20]); - OUTREG(GPIOPAD_MASK, rinfo->save_regs[21]); - OUTREG(ZV_LCDPAD_A, rinfo->save_regs[22]); - OUTREG(ZV_LCDPAD_EN, rinfo->save_regs[23]); - OUTREG(ZV_LCDPAD_MASK, rinfo->save_regs[24]); - OUTREG(GPIO_VGA_DDC, rinfo->save_regs[25]); - OUTREG(GPIO_DVI_DDC, rinfo->save_regs[26]); - OUTREG(GPIO_MONID, rinfo->save_regs[27]); - OUTREG(GPIO_CRT2_DDC, rinfo->save_regs[28]); -} - -static void radeon_pm_disable_iopad(struct radeonfb_info *rinfo) -{ - OUTREG(GPIOPAD_MASK, 0x0001ffff); - OUTREG(GPIOPAD_EN, 0x00000400); - OUTREG(GPIOPAD_A, 0x00000000); - OUTREG(ZV_LCDPAD_MASK, 0x00000000); - OUTREG(ZV_LCDPAD_EN, 0x00000000); - OUTREG(ZV_LCDPAD_A, 0x00000000); - OUTREG(GPIO_VGA_DDC, 0x00030000); - OUTREG(GPIO_DVI_DDC, 0x00000000); - OUTREG(GPIO_MONID, 0x00030000); - OUTREG(GPIO_CRT2_DDC, 0x00000000); -} - -static void radeon_pm_program_v2clk(struct radeonfb_info *rinfo) -{ -// -// u32 reg; -// -// OUTPLL(P2PLL_REF_DIV, 0x0c); -// -// .../... figure out what macos does here -} - -static void radeon_pm_low_current(struct radeonfb_info *rinfo) -{ - u32 reg; - - reg = INREG(BUS_CNTL1); - reg &= ~BUS_CNTL1_MOBILE_PLATFORM_SEL_MASK; - reg |= BUS_CNTL1_AGPCLK_VALID | (1<<BUS_CNTL1_MOBILE_PLATFORM_SEL_SHIFT); - OUTREG(BUS_CNTL1, reg); - - reg = INPLL(PLL_PWRMGT_CNTL); - reg |= PLL_PWRMGT_CNTL_SPLL_TURNOFF | PLL_PWRMGT_CNTL_PPLL_TURNOFF | - PLL_PWRMGT_CNTL_P2PLL_TURNOFF | PLL_PWRMGT_CNTL_TVPLL_TURNOFF; - reg &= ~PLL_PWRMGT_CNTL_SU_MCLK_USE_BCLK; - reg &= ~PLL_PWRMGT_CNTL_MOBILE_SU; - OUTPLL(PLL_PWRMGT_CNTL, reg); - -// reg = INPLL(TV_PLL_CNTL1); -// reg |= TV_PLL_CNTL1__TVPLL_RESET | TV_PLL_CNTL1__TVPLL_SLEEP; -// OUTPLL(TV_PLL_CNTL1, reg); - - reg = INREG(TV_DAC_CNTL); - reg &= ~(TV_DAC_CNTL_BGADJ_MASK |TV_DAC_CNTL_DACADJ_MASK); - reg |=TV_DAC_CNTL_BGSLEEP | TV_DAC_CNTL_RDACPD | TV_DAC_CNTL_GDACPD | - TV_DAC_CNTL_BDACPD | - (8<<TV_DAC_CNTL_BGADJ__SHIFT) | (8<<TV_DAC_CNTL_DACADJ__SHIFT); - OUTREG(TV_DAC_CNTL, reg); - - reg = INREG(TMDS_TRANSMITTER_CNTL); - reg &= ~(TMDS_PLL_EN |TMDS_PLLRST); - OUTREG(TMDS_TRANSMITTER_CNTL, reg); - -// lvds_pll_cntl = regr32(g, LVDS_PLL_CNTL); -// lvds_pll_cntl &= ~LVDS_PLL_CNTL__LVDS_PLL_EN; -// lvds_pll_cntl |= LVDS_PLL_CNTL__LVDS_PLL_RESET; -// regw32(g, LVDS_PLL_CNTL, lvds_pll_cntl); - - reg = INREG(DAC_CNTL); - reg &= ~DAC_CMP_EN; - OUTREG(DAC_CNTL, reg); - - reg = INREG(DAC_CNTL2); - reg &= ~DAC2_CMP_EN; - OUTREG(DAC_CNTL2, reg); - - reg = INREG(TV_DAC_CNTL); - reg &= ~TV_DAC_CNTL_DETECT; - OUTREG(TV_DAC_CNTL, reg); -} - -static void radeon_pm_setup_for_suspend(struct radeonfb_info *rinfo) -{ - /* This code is disabled. It does what is in the pm_init - * function of the MacOS driver code ATI sent me. However, - * it doesn't fix my sleep problem, and is causing other issues - * on wakeup (bascially the machine dying when switching consoles - * I haven't had time to investigate this yet - */ -#if 0 - u32 disp_misc_cntl; - u32 disp_pwr_man; - u32 temp; - - // set SPLL, MPLL, PPLL, P2PLL, TVPLL, SCLK, MCLK, PCLK, P2CLK, - // TCLK and TEST_MODE to 0 - temp = INPLL(CLK_PWRMGT_CNTL); - OUTPLL(CLK_PWRMGT_CNTL , temp & ~0xc00002ff); - - // Turn on Power Management - temp = INPLL(CLK_PWRMGT_CNTL); - OUTPLL(CLK_PWRMGT_CNTL , temp | 0x00000400); - - // Turn off display clock if using mobile chips - temp = INPLL(CLK_PWRMGT_CNTL); - OUTREG(CLK_PWRMGT_CNTL , temp | 0x00100000); - - // Force PIXCLK_ALWAYS_ON and PIXCLK_DAC_ALWAYS_ON - temp = INPLL(VCLK_ECP_CNTL); - OUTPLL(VCLK_ECP_CNTL, temp & ~0x000000c0); - - // Force ECP_FORCE_ON to 1 - temp = INPLL(VCLK_ECP_CNTL); - OUTPLL(VCLK_ECP_CNTL, temp | 0x00040000); - - // Force PIXCLK_BLEND_ALWAYS_ON and PIXCLK_GV_ALWAYS_ON - temp = INPLL(PIXCLKS_CNTL); - OUTPLL(PIXCLKS_CNTL, temp & ~0x00001800); - - // Forcing SCLK_CNTL to ON - OUTPLL(SCLK_CNTL, (INPLL(SCLK_CNTL)& 0x00000007) | 0xffff8000 ); - - // Set PM control over XTALIN pad - temp = INPLL(CLK_PIN_CNTL); - OUTPLL(CLK_PIN_CNTL, temp | 0x00080000); - - // Force MCLK and YCLK and MC as dynamic - temp = INPLL(MCLK_CNTL); - OUTPLL(MCLK_CNTL, temp & 0xffeaffff); - - // PLL_TURNOFF - temp = INPLL(PLL_PWRMGT_CNTL); - OUTPLL(PLL_PWRMGT_CNTL, temp | 0x0000001f); - - // set MOBILE_SU to 1 if M6 or DDR64 is detected - temp = INPLL(PLL_PWRMGT_CNTL); - OUTPLL(PLL_PWRMGT_CNTL, temp | 0x00010000); - - // select PM access mode (PM_MODE_SEL) (use ACPI mode) -// temp = INPLL(PLL_PWRMGT_CNTL); -// OUTPLL(PLL_PWRMGT_CNTL, temp | 0x00002000); - temp = INPLL(PLL_PWRMGT_CNTL); - OUTPLL(PLL_PWRMGT_CNTL, temp & ~0x00002000); - - // set DISP_MISC_CNTL register - disp_misc_cntl = INREG(DISP_MISC_CNTL); - disp_misc_cntl &= ~( DISP_MISC_CNTL_SOFT_RESET_GRPH_PP | - DISP_MISC_CNTL_SOFT_RESET_SUBPIC_PP | - DISP_MISC_CNTL_SOFT_RESET_OV0_PP | - DISP_MISC_CNTL_SOFT_RESET_GRPH_SCLK | - DISP_MISC_CNTL_SOFT_RESET_SUBPIC_SCLK | - DISP_MISC_CNTL_SOFT_RESET_OV0_SCLK | - DISP_MISC_CNTL_SOFT_RESET_GRPH2_PP | - DISP_MISC_CNTL_SOFT_RESET_GRPH2_SCLK | - DISP_MISC_CNTL_SOFT_RESET_LVDS | - DISP_MISC_CNTL_SOFT_RESET_TMDS | - DISP_MISC_CNTL_SOFT_RESET_DIG_TMDS | - DISP_MISC_CNTL_SOFT_RESET_TV); - OUTREG(DISP_MISC_CNTL, disp_misc_cntl); - - // set DISP_PWR_MAN register - disp_pwr_man = INREG(DISP_PWR_MAN); - // clau - 9.29.2000 - changes made to bit23:18 to set to 1 as requested by George - disp_pwr_man |= (DISP_PWR_MAN_DIG_TMDS_ENABLE_RST | - DISP_PWR_MAN_TV_ENABLE_RST | - // DISP_PWR_MAN_AUTO_PWRUP_EN | - DISP_PWR_MAN_DISP_D3_GRPH_RST | - DISP_PWR_MAN_DISP_D3_SUBPIC_RST | - DISP_PWR_MAN_DISP_D3_OV0_RST | - DISP_PWR_MAN_DISP_D1D2_GRPH_RST | - DISP_PWR_MAN_DISP_D1D2_SUBPIC_RST | - DISP_PWR_MAN_DISP_D1D2_OV0_RST); - disp_pwr_man &= ~(DISP_PWR_MAN_DISP_PWR_MAN_D3_CRTC_EN | - DISP_PWR_MAN_DISP2_PWR_MAN_D3_CRTC2_EN| - DISP_PWR_MAN_DISP_D3_RST | - DISP_PWR_MAN_DISP_D3_REG_RST); - OUTREG(DISP_PWR_MAN, disp_pwr_man); - - // clau - 10.24.2000 - // - add in setting for BUS_CNTL1 b27:26 = 0x01 and b31 = 0x1 - // - add in setting for AGP_CNTL b7:0 = 0x20 - // - add in setting for DVI_DDC_DATA_OUT_EN b17:16 = 0x0 - - // the following settings (two lines) are applied at a later part of this function, only on mobile platform - // requres -mobile flag - OUTREG(BUS_CNTL1, (INREG(BUS_CNTL1) & 0xf3ffffff) | 0x04000000); - OUTREG(BUS_CNTL1, INREG(BUS_CNTL1) | 0x80000000); - OUTREG(AGP_CNTL, (INREG(AGP_CNTL) & 0xffffff00) | 0x20); - OUTREG(GPIO_DVI_DDC, INREG(GPIO_DVI_DDC) & 0xfffcffff); - - // yulee - 12.12.2000 - // A12 only - // EN_MCLK_TRISTATE_IN_SUSPEND@MCLK_MISC = 1 - // ACCESS_REGS_IN_SUSPEND@CLK_PIN_CNTL = 0 - // only on mobile platform - OUTPLL(MCLK_MISC, INPLL(MCLK_MISC) | 0x00040000 ); - - // yulee -12.12.2000 - // AGPCLK_VALID@BUS_CNTL1 = 1 - // MOBILE_PLATFORM_SEL@BUS_CNTL1 = 01 - // CRTC_STEREO_SYNC_OUT_EN@CRTC_OFFSET_CNTL = 0 - // CG_CLK_TO_OUTPIN@CLK_PIN_CNTL = 0 - // only on mobile platform - OUTPLL(CLK_PIN_CNTL, INPLL(CLK_PIN_CNTL ) & 0xFFFFF7FF ); - OUTREG(BUS_CNTL1, (INREG(BUS_CNTL1 ) & 0xF3FFFFFF) | 0x84000000 ); - OUTREG(CRTC_OFFSET_CNTL, INREG(CRTC_OFFSET_CNTL ) & 0xFFEFFFFF ); - - mdelay(100); -#endif - - /* Disable CRTCs */ - OUTREG(CRTC_GEN_CNTL, (INREG(CRTC_GEN_CNTL) & ~CRTC_EN) | CRTC_DISP_REQ_EN_B); - OUTREG(CRTC2_GEN_CNTL, (INREG(CRTC2_GEN_CNTL) & ~CRTC2_EN) | CRTC2_DISP_REQ_EN_B); - (void)INREG(CRTC2_GEN_CNTL); - mdelay(17); -} - -static void radeon_set_suspend(struct radeonfb_info *rinfo, int suspend) -{ - u16 pwr_cmd; - - if (!rinfo->pm_reg) - return; - - /* Set the chip into appropriate suspend mode (we use D2, - * D3 would require a compete re-initialization of the chip, - * including PCI config registers, clocks, AGP conf, ...) - */ - if (suspend) { - /* According to ATI, we should program V2CLK here, I have - * to verify what's up exactly - */ - /* Save some registers */ - radeon_pm_save_regs(rinfo); - - /* Check that on M7 too, might work might not. M7 may also - * need explicit enabling of PM - */ - if (rinfo->arch == RADEON_M6) { - /* Program V2CLK */ - radeon_pm_program_v2clk(rinfo); - - /* Disable IO PADs */ - radeon_pm_disable_iopad(rinfo); - - /* Set low current */ - radeon_pm_low_current(rinfo); - - /* Prepare chip for power management */ - radeon_pm_setup_for_suspend(rinfo); - - /* Reset the MDLL */ - OUTPLL(MDLL_CKO, INPLL(MDLL_CKO) | MCKOA_RESET); - (void)INPLL(MDLL_RDCKA); - OUTPLL(MDLL_CKO, INPLL(MDLL_CKO) & ~MCKOA_RESET); - (void)INPLL(MDLL_RDCKA); - } - - /* Switch PCI power managment to D2. */ - for (;;) { - pci_read_config_word( - rinfo->pdev, rinfo->pm_reg+PCI_PM_CTRL, - &pwr_cmd); - if (pwr_cmd & 2) - break; - pci_write_config_word( - rinfo->pdev, rinfo->pm_reg+PCI_PM_CTRL, - (pwr_cmd & ~PCI_PM_CTRL_STATE_MASK) | 2); - mdelay(500); - } - } else { - /* Switch back PCI powermanagment to D0 */ - mdelay(200); - pci_write_config_word(rinfo->pdev, rinfo->pm_reg+PCI_PM_CTRL, 0); - mdelay(500); - - dbg_clk = INPLL(1); - - /* Do we need that on M7 ? */ - if (rinfo->arch == RADEON_M6) { - /* Restore the MDLL */ - OUTPLL(MDLL_CKO, INPLL(MDLL_CKO) & ~MCKOA_RESET); - (void)INPLL(MDLL_CKO); - } - - /* Restore some registers */ - radeon_pm_restore_regs(rinfo); - } -} - -/* - * Save the contents of the framebuffer when we go to sleep, - * and restore it when we wake up again. - */ - -int radeon_sleep_notify(struct pmu_sleep_notifier *self, int when) -{ - struct radeonfb_info *rinfo; - - for (rinfo = board_list; rinfo != NULL; rinfo = rinfo->next) { - struct fb_fix_screeninfo fix; - int nb; - struct display *disp; - - disp = (rinfo->currcon < 0) ? rinfo->info.disp : &fb_display[rinfo->currcon]; - - switch (rinfo->arch) { - case RADEON_M6: - case RADEON_M7: - case RADEON_M9: - break; - default: - return PBOOK_SLEEP_REFUSE; - } - - radeonfb_get_fix(&fix, fg_console, (struct fb_info *)rinfo); - nb = fb_display[fg_console].var.yres * fix.line_length; - - switch (when) { - case PBOOK_SLEEP_NOW: - acquire_console_sem(); - disp->dispsw = &fbcon_dummy; - - if (!noaccel) { - /* Make sure engine is reset */ - radeon_engine_reset(); - radeon_engine_idle(); - } - - /* Blank display and LCD */ - radeonfb_blank(VESA_POWERDOWN+1, - (struct fb_info *)rinfo); - - /* Sleep */ - rinfo->asleep = 1; - radeon_set_suspend(rinfo, 1); - release_console_sem(); - - break; - case PBOOK_WAKE: - acquire_console_sem(); - /* Wakeup */ - radeon_set_suspend(rinfo, 0); - - if (!noaccel) - radeon_engine_init(rinfo); - rinfo->asleep = 0; - radeon_set_dispsw(rinfo, disp); - radeon_load_video_mode(rinfo, &disp->var); - do_install_cmap(rinfo->currcon < 0 ? 0 : rinfo->currcon, - (struct fb_info *)rinfo); - - radeonfb_blank(0, (struct fb_info *)rinfo); - release_console_sem(); - printk("CLK_PIN_CNTL on wakeup was: %08x\n", dbg_clk); - break; - } - } - - return PBOOK_SLEEP_OK; -} - -#endif /* CONFIG_PMAC_PBOOK */ - -static int radeonfb_pci_register (struct pci_dev *pdev, - const struct pci_device_id *ent) -{ - struct radeonfb_info *rinfo; - struct radeon_chip_info *rci = &radeon_chip_info[ent->driver_data]; - u32 tmp; - - RTRACE("radeonfb_pci_register BEGIN\n"); - - /* Enable device in PCI config */ - if (pci_enable_device(pdev) != 0) { - printk(KERN_ERR "radeonfb: Cannot enable PCI device\n"); - return -ENODEV; - } - - rinfo = kmalloc (sizeof (struct radeonfb_info), GFP_KERNEL); - if (!rinfo) { - printk ("radeonfb: could not allocate memory\n"); - return -ENODEV; - } - - memset (rinfo, 0, sizeof (struct radeonfb_info)); - //info = &rinfo->info; - rinfo->pdev = pdev; - strcpy(rinfo->name, rci->name); - rinfo->arch = rci->arch; - - /* Set base addrs */ - rinfo->fb_base_phys = pci_resource_start (pdev, 0); - rinfo->mmio_base_phys = pci_resource_start (pdev, 2); - - /* request the mem regions */ - if (!request_mem_region (rinfo->fb_base_phys, - pci_resource_len(pdev, 0), "radeonfb")) { - printk ("radeonfb: cannot reserve FB region\n"); - kfree (rinfo); - return -ENODEV; - } - - if (!request_mem_region (rinfo->mmio_base_phys, - pci_resource_len(pdev, 2), "radeonfb")) { - printk ("radeonfb: cannot reserve MMIO region\n"); - release_mem_region (rinfo->fb_base_phys, - pci_resource_len(pdev, 0)); - kfree (rinfo); - return -ENODEV; - } - - /* map the regions */ - rinfo->mmio_base = ioremap (rinfo->mmio_base_phys, RADEON_REGSIZE); - if (!rinfo->mmio_base) { - printk ("radeonfb: cannot map MMIO\n"); - release_mem_region (rinfo->mmio_base_phys, - pci_resource_len(pdev, 2)); - release_mem_region (rinfo->fb_base_phys, - pci_resource_len(pdev, 0)); - kfree (rinfo); - return -ENODEV; - } - - rinfo->chipset = pdev->device; - - switch (rinfo->arch) { - case RADEON_R100: - rinfo->hasCRTC2 = 0; - break; - default: - /* all the rest have it */ - rinfo->hasCRTC2 = 1; - break; - } -#if 0 - if (rinfo->arch == RADEON_M7) { - /* - * Noticed some errors in accel with M7, will have to work these out... - */ - noaccel = 1; - } -#endif - if (mirror) - printk("radeonfb: mirroring display to CRT\n"); - - /* framebuffer size */ - tmp = INREG(CONFIG_MEMSIZE); - - /* mem size is bits [28:0], mask off the rest */ - rinfo->video_ram = tmp & CONFIG_MEMSIZE_MASK; - - /* ram type */ - tmp = INREG(MEM_SDRAM_MODE_REG); - switch ((MEM_CFG_TYPE & tmp) >> 30) { - case 0: - /* SDR SGRAM (2:1) */ - strcpy(rinfo->ram_type, "SDR SGRAM"); - rinfo->ram.ml = 4; - rinfo->ram.mb = 4; - rinfo->ram.trcd = 1; - rinfo->ram.trp = 2; - rinfo->ram.twr = 1; - rinfo->ram.cl = 2; - rinfo->ram.loop_latency = 16; - rinfo->ram.rloop = 16; - - break; - case 1: - /* DDR SGRAM */ - strcpy(rinfo->ram_type, "DDR SGRAM"); - rinfo->ram.ml = 4; - rinfo->ram.mb = 4; - rinfo->ram.trcd = 3; - rinfo->ram.trp = 3; - rinfo->ram.twr = 2; - rinfo->ram.cl = 3; - rinfo->ram.tr2w = 1; - rinfo->ram.loop_latency = 16; - rinfo->ram.rloop = 16; - - break; - default: - /* 64-bit SDR SGRAM */ - strcpy(rinfo->ram_type, "SDR SGRAM 64"); - rinfo->ram.ml = 4; - rinfo->ram.mb = 8; - rinfo->ram.trcd = 3; - rinfo->ram.trp = 3; - rinfo->ram.twr = 1; - rinfo->ram.cl = 3; - rinfo->ram.tr2w = 1; - rinfo->ram.loop_latency = 17; - rinfo->ram.rloop = 17; - - break; - } - - rinfo->bios_seg = radeon_find_rom(rinfo); - radeon_get_pllinfo(rinfo, rinfo->bios_seg); - - /* - * Hack to get around some busted production M6's - * reporting no ram - */ - if (rinfo->video_ram == 0) { - switch (pdev->device) { - case PCI_DEVICE_ID_ATI_RADEON_LY: - case PCI_DEVICE_ID_ATI_RADEON_LZ: - rinfo->video_ram = 8192 * 1024; - break; - default: - break; - } - } - - - RTRACE("radeonfb: probed %s %dk videoram\n", (rinfo->ram_type), (rinfo->video_ram/1024)); - -#if !defined(__powerpc__) - radeon_get_moninfo(rinfo); -#else - switch (pdev->device) { - case PCI_DEVICE_ID_ATI_RADEON_LW: - case PCI_DEVICE_ID_ATI_RADEON_LX: - case PCI_DEVICE_ID_ATI_RADEON_LY: - case PCI_DEVICE_ID_ATI_RADEON_LZ: - rinfo->dviDisp_type = MT_LCD; - break; - default: - radeon_get_moninfo(rinfo); - break; - } -#endif - - radeon_get_EDID(rinfo); - - if ((rinfo->dviDisp_type == MT_DFP) || (rinfo->dviDisp_type == MT_LCD) || - (rinfo->crtDisp_type == MT_DFP)) { - if (!radeon_get_dfpinfo(rinfo)) { - iounmap(rinfo->mmio_base); - release_mem_region (rinfo->mmio_base_phys, - pci_resource_len(pdev, 2)); - release_mem_region (rinfo->fb_base_phys, - pci_resource_len(pdev, 0)); - kfree (rinfo); - return -ENODEV; - } - } - - rinfo->fb_base = ioremap (rinfo->fb_base_phys, rinfo->video_ram); - if (!rinfo->fb_base) { - printk ("radeonfb: cannot map FB\n"); - iounmap(rinfo->mmio_base); - release_mem_region (rinfo->mmio_base_phys, - pci_resource_len(pdev, 2)); - release_mem_region (rinfo->fb_base_phys, - pci_resource_len(pdev, 0)); - kfree (rinfo); - return -ENODEV; - } - - /* I SHOULD FIX THAT CRAP ! I should probably mimmic XFree DRI - * driver setup here. - * - * On PPC, OF based cards setup the internal memory - * mapping in strange ways. We change it so that the - * framebuffer is mapped at 0 and given half of the card's - * address space (2Gb). AGP is mapped high (0xe0000000) and - * can use up to 512Mb. Once DRI is fully implemented, we - * will have to setup the PCI remapper to remap the agp_special_page - * memory page somewhere between those regions so that the card - * use a normal PCI bus master cycle to access the ring read ptr. - * --BenH. - */ -#ifdef CONFIG_ALL_PPC - if (rinfo->hasCRTC2) - OUTREG(CRTC2_GEN_CNTL, - (INREG(CRTC2_GEN_CNTL) & ~CRTC2_EN) | CRTC2_DISP_REQ_EN_B); - OUTREG(CRTC_EXT_CNTL, INREG(CRTC_EXT_CNTL) | CRTC_DISPLAY_DIS); - OUTREG(MC_FB_LOCATION, 0x7fff0000); - OUTREG(MC_AGP_LOCATION, 0xffffe000); - OUTREG(DISPLAY_BASE_ADDR, 0x00000000); - if (rinfo->hasCRTC2) - OUTREG(CRTC2_DISPLAY_BASE_ADDR, 0x00000000); - OUTREG(SRC_OFFSET, 0x00000000); - OUTREG(DST_OFFSET, 0x00000000); - mdelay(10); - OUTREG(CRTC_EXT_CNTL, INREG(CRTC_EXT_CNTL) & ~CRTC_DISPLAY_DIS); -#endif /* CONFIG_ALL_PPC */ - - /* save current mode regs before we switch into the new one - * so we can restore this upon __exit - */ - radeon_save_state (rinfo, &rinfo->init_state); - - /* set all the vital stuff */ - radeon_set_fbinfo (rinfo); - - pci_set_drvdata(pdev, rinfo); - rinfo->next = board_list; - board_list = rinfo; - ((struct fb_info *) rinfo)->device = &pdev->dev; - if (register_framebuffer ((struct fb_info *) rinfo) < 0) { - printk ("radeonfb: could not register framebuffer\n"); - iounmap(rinfo->fb_base); - iounmap(rinfo->mmio_base); - release_mem_region (rinfo->mmio_base_phys, - pci_resource_len(pdev, 2)); - release_mem_region (rinfo->fb_base_phys, - pci_resource_len(pdev, 0)); - kfree (rinfo); - return -ENODEV; - } - -#ifdef CONFIG_MTRR - rinfo->mtrr_hdl = nomtrr ? -1 : mtrr_add(rinfo->fb_base_phys, - rinfo->video_ram, - MTRR_TYPE_WRCOMB, 1); -#endif - -#ifdef CONFIG_PMAC_BACKLIGHT - if (rinfo->dviDisp_type == MT_LCD) - register_backlight_controller(&radeon_backlight_controller, - rinfo, "ati"); -#endif - -#ifdef CONFIG_PMAC_PBOOK - if (rinfo->dviDisp_type == MT_LCD) { - rinfo->pm_reg = pci_find_capability(pdev, PCI_CAP_ID_PM); - pmu_register_sleep_notifier(&radeon_sleep_notifier); - } -#endif - - printk ("radeonfb: ATI Radeon %s %s %d MB\n", rinfo->name, rinfo->ram_type, - (rinfo->video_ram/(1024*1024))); - - if (rinfo->hasCRTC2) { - printk("radeonfb: DVI port %s monitor connected\n", - GET_MON_NAME(rinfo->dviDisp_type)); - printk("radeonfb: CRT port %s monitor connected\n", - GET_MON_NAME(rinfo->crtDisp_type)); - } else { - printk("radeonfb: CRT port %s monitor connected\n", - GET_MON_NAME(rinfo->crtDisp_type)); - } - - RTRACE("radeonfb_pci_register END\n"); - - return 0; -} - - - -static void __devexit radeonfb_pci_unregister (struct pci_dev *pdev) -{ - struct radeonfb_info *rinfo = pci_get_drvdata(pdev); - - if (!rinfo) - return; - - /* restore original state - * - * Doesn't quite work yet, possibly because of the PPC hacking - * I do on startup, disable for now. --BenH - */ - radeon_write_mode (rinfo, &rinfo->init_state); - -#ifdef CONFIG_MTRR - if (rinfo->mtrr_hdl >= 0) - mtrr_del(rinfo->mtrr_hdl, 0, 0); -#endif - - unregister_framebuffer ((struct fb_info *) rinfo); - - iounmap(rinfo->mmio_base); - iounmap(rinfo->fb_base); - - release_mem_region (rinfo->mmio_base_phys, - pci_resource_len(pdev, 2)); - release_mem_region (rinfo->fb_base_phys, - pci_resource_len(pdev, 0)); - - kfree (rinfo); -} - - -static struct pci_driver radeonfb_driver = { - .name = "radeonfb", - .id_table = radeonfb_pci_table, - .probe = radeonfb_pci_register, - .remove = __devexit_p(radeonfb_pci_unregister), -}; - -#ifndef MODULE -static int __init radeonfb_old_setup (char *options) -{ - char *this_opt; - - if (!options || !*options) - return 0; - - while ((this_opt = strsep (&options, ",")) != NULL) { - if (!*this_opt) - continue; - if (!strncmp(this_opt, "noaccel", 7)) { - noaccel = 1; - } else if (!strncmp(this_opt, "mirror", 6)) { - mirror = 1; - } else if (!strncmp(this_opt, "dfp", 3)) { - force_dfp = 1; - } else if (!strncmp(this_opt, "panel_yres:", 11)) { - panel_yres = simple_strtoul((this_opt+11), NULL, 0); - } else if (!strncmp(this_opt, "nomtrr", 6)) { - nomtrr = 1; - } else - mode_option = this_opt; - } - - return 0; -} -#endif /* MODULE */ - -static int __init radeonfb_old_init (void) -{ -#ifndef MODULE - char *option = NULL; - - if (fb_get_options("radeonfb_old", &option)) - return -ENODEV; - radeonfb_old_setup(option); -#endif - return pci_register_driver (&radeonfb_driver); -} - - -static void __exit radeonfb_old_exit (void) -{ - pci_unregister_driver (&radeonfb_driver); -} - -module_init(radeonfb_old_init); -module_exit(radeonfb_old_exit); - - -MODULE_AUTHOR("Ani Joshi"); -MODULE_DESCRIPTION("framebuffer driver for ATI Radeon chipset"); -MODULE_LICENSE("GPL"); diff --git a/drivers/video/sticore.h b/drivers/video/sticore.h index dc93336af55..1a9a60c74be 100644 --- a/drivers/video/sticore.h +++ b/drivers/video/sticore.h @@ -34,36 +34,20 @@ * for them to fix it and steal their solution. prumpf */ -#define STI_WAIT 1 - -#include <asm/io.h> /* for USE_HPPA_IOREMAP */ - -#if USE_HPPA_IOREMAP +#include <asm/io.h> -#define STI_PTR(p) (p) -#define PTR_STI(p) (p) -static inline int STI_CALL( unsigned long func, - void *flags, void *inptr, void *outptr, void *glob_cfg ) -{ - int (*f)(void *,void *,void *,void *); - f = (void*)func; - return f(flags, inptr, outptr, glob_cfg); -} - -#else /* !USE_HPPA_IOREMAP */ +#define STI_WAIT 1 #define STI_PTR(p) ( virt_to_phys(p) ) -#define PTR_STI(p) ( phys_to_virt((long)p) ) -#define STI_CALL(func, flags, inptr, outptr, glob_cfg) \ - ({ \ - pdc_sti_call( func, (unsigned long)STI_PTR(flags), \ - (unsigned long)STI_PTR(inptr), \ - (unsigned long)STI_PTR(outptr), \ - (unsigned long)STI_PTR(glob_cfg)); \ +#define PTR_STI(p) ( phys_to_virt((unsigned long)p) ) +#define STI_CALL(func, flags, inptr, outptr, glob_cfg) \ + ({ \ + pdc_sti_call( func, STI_PTR(flags), \ + STI_PTR(inptr), \ + STI_PTR(outptr), \ + STI_PTR(glob_cfg)); \ }) -#endif /* USE_HPPA_IOREMAP */ - #define sti_onscreen_x(sti) (sti->glob_cfg->onscreen_x) #define sti_onscreen_y(sti) (sti->glob_cfg->onscreen_y) @@ -352,8 +336,9 @@ struct sti_struct { struct sti_conf_outptr outptr; /* configuration */ struct sti_conf_outptr_ext outptr_ext; - /* PCI data structures (pg. 17ff from sti.pdf) */ struct pci_dev *pd; + + /* PCI data structures (pg. 17ff from sti.pdf) */ u8 rm_entry[16]; /* pci region mapper array == pci config space offset */ /* pointer to the fb_info where this STI device is used */ diff --git a/drivers/video/stifb.c b/drivers/video/stifb.c index 56d71d6e9a7..4a292aae6eb 100644 --- a/drivers/video/stifb.c +++ b/drivers/video/stifb.c @@ -3,7 +3,7 @@ * Low level Frame buffer driver for HP workstations with * STI (standard text interface) video firmware. * - * Copyright (C) 2001-2005 Helge Deller <deller@gmx.de> + * Copyright (C) 2001-2006 Helge Deller <deller@gmx.de> * Portions Copyright (C) 2001 Thomas Bogendoerfer <tsbogend@alpha.franken.de> * * Based on: @@ -514,7 +514,7 @@ rattlerSetupPlanes(struct stifb_info *fb) SETUP_HW(fb); WRITE_BYTE(1, fb, REG_16b1); - fb_memset(fb->info.fix.smem_start, 0xff, + fb_memset((void*)fb->info.fix.smem_start, 0xff, fb->info.var.yres*fb->info.fix.line_length); CRX24_SET_OVLY_MASK(fb); @@ -908,83 +908,6 @@ SETUP_HCRX(struct stifb_info *fb) /* ------------------- driver specific functions --------------------------- */ -#define TMPBUFLEN 2048 - -static ssize_t -stifb_read(struct file *file, char *buf, size_t count, loff_t *ppos) -{ - unsigned long p = *ppos; - struct inode *inode = file->f_dentry->d_inode; - int fbidx = iminor(inode); - struct fb_info *info = registered_fb[fbidx]; - char tmpbuf[TMPBUFLEN]; - - if (!info || ! info->screen_base) - return -ENODEV; - - if (p >= info->fix.smem_len) - return 0; - if (count >= info->fix.smem_len) - count = info->fix.smem_len; - if (count + p > info->fix.smem_len) - count = info->fix.smem_len - p; - if (count > sizeof(tmpbuf)) - count = sizeof(tmpbuf); - if (count) { - char *base_addr; - - base_addr = info->screen_base; - memcpy_fromio(&tmpbuf, base_addr+p, count); - count -= copy_to_user(buf, &tmpbuf, count); - if (!count) - return -EFAULT; - *ppos += count; - } - return count; -} - -static ssize_t -stifb_write(struct file *file, const char *buf, size_t count, loff_t *ppos) -{ - struct inode *inode = file->f_dentry->d_inode; - int fbidx = iminor(inode); - struct fb_info *info = registered_fb[fbidx]; - unsigned long p = *ppos; - size_t c; - int err; - char tmpbuf[TMPBUFLEN]; - - if (!info || !info->screen_base) - return -ENODEV; - - if (p > info->fix.smem_len) - return -ENOSPC; - if (count >= info->fix.smem_len) - count = info->fix.smem_len; - err = 0; - if (count + p > info->fix.smem_len) { - count = info->fix.smem_len - p; - err = -ENOSPC; - } - - p += (unsigned long)info->screen_base; - c = count; - while (c) { - int len = c > sizeof(tmpbuf) ? sizeof(tmpbuf) : c; - err = -EFAULT; - if (copy_from_user(&tmpbuf, buf, len)) - break; - memcpy_toio(p, &tmpbuf, len); - c -= len; - p += len; - buf += len; - *ppos += len; - } - if (count-c) - return (count-c); - return err; -} - static int stifb_setcolreg(u_int regno, u_int red, u_int green, u_int blue, u_int transp, struct fb_info *info) @@ -1137,8 +1060,6 @@ stifb_init_display(struct stifb_info *fb) static struct fb_ops stifb_ops = { .owner = THIS_MODULE, - .fb_read = stifb_read, - .fb_write = stifb_write, .fb_setcolreg = stifb_setcolreg, .fb_blank = stifb_blank, .fb_fillrect = cfb_fillrect, @@ -1162,7 +1083,7 @@ stifb_init_fb(struct sti_struct *sti, int bpp_pref) char *dev_name; int bpp, xres, yres; - fb = kmalloc(sizeof(*fb), GFP_ATOMIC); + fb = kzalloc(sizeof(*fb), GFP_ATOMIC); if (!fb) { printk(KERN_ERR "stifb: Could not allocate stifb structure\n"); return -ENODEV; @@ -1171,7 +1092,6 @@ stifb_init_fb(struct sti_struct *sti, int bpp_pref) info = &fb->info; /* set struct to a known state */ - memset(fb, 0, sizeof(*fb)); fix = &info->fix; var = &info->var; @@ -1234,7 +1154,7 @@ stifb_init_fb(struct sti_struct *sti, int bpp_pref) case S9000_ID_TOMCAT: /* Dual CRX, behaves else like a CRX */ /* FIXME: TomCat supports two heads: * fb.iobase = REGION_BASE(fb_info,3); - * fb.screen_base = (void*) REGION_BASE(fb_info,2); + * fb.screen_base = ioremap_nocache(REGION_BASE(fb_info,2),xxx); * for now we only support the left one ! */ xres = fb->ngle_rom.x_size_visible; yres = fb->ngle_rom.y_size_visible; @@ -1327,7 +1247,8 @@ stifb_init_fb(struct sti_struct *sti, int bpp_pref) strcpy(fix->id, "stifb"); info->fbops = &stifb_ops; - info->screen_base = (void*) REGION_BASE(fb,1); + info->screen_base = ioremap_nocache(REGION_BASE(fb,1), fix->smem_len); + info->screen_size = fix->smem_len; info->flags = FBINFO_DEFAULT; info->pseudo_palette = &fb->pseudo_palette; @@ -1457,7 +1378,7 @@ stifb_setup(char *options) int i; if (!options || !*options) - return 0; + return 1; if (strncmp(options, "off", 3) == 0) { stifb_disabled = 1; @@ -1472,7 +1393,7 @@ stifb_setup(char *options) stifb_bpp_pref[i] = simple_strtoul(options, &options, 10); } } - return 0; + return 1; } __setup("stifb=", stifb_setup); diff --git a/drivers/video/w100fb.c b/drivers/video/w100fb.c index f6e24ee85f0..5fc86ea2069 100644 --- a/drivers/video/w100fb.c +++ b/drivers/video/w100fb.c @@ -4,8 +4,9 @@ * Frame Buffer Device for ATI Imageon w100 (Wallaby) * * Copyright (C) 2002, ATI Corp. - * Copyright (C) 2004-2005 Richard Purdie + * Copyright (C) 2004-2006 Richard Purdie * Copyright (c) 2005 Ian Molton + * Copyright (c) 2006 Alberto Mardegan * * Rewritten for 2.6 by Richard Purdie <rpurdie@rpsys.net> * @@ -14,6 +15,9 @@ * * w32xx support by Ian Molton * + * Hardware acceleration support by Alberto Mardegan + * <mardy@users.sourceforge.net> + * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. @@ -47,6 +51,7 @@ static void w100_set_dispregs(struct w100fb_par*); static void w100_update_enable(void); static void w100_update_disable(void); static void calc_hsync(struct w100fb_par *par); +static void w100_init_graphic_engine(struct w100fb_par *par); struct w100_pll_info *w100_get_xtal_table(unsigned int freq); /* Pseudo palette size */ @@ -248,6 +253,152 @@ static int w100fb_blank(int blank_mode, struct fb_info *info) } +static void w100_fifo_wait(int entries) +{ + union rbbm_status_u status; + int i; + + for (i = 0; i < 2000000; i++) { + status.val = readl(remapped_regs + mmRBBM_STATUS); + if (status.f.cmdfifo_avail >= entries) + return; + udelay(1); + } + printk(KERN_ERR "w100fb: FIFO Timeout!\n"); +} + + +static int w100fb_sync(struct fb_info *info) +{ + union rbbm_status_u status; + int i; + + for (i = 0; i < 2000000; i++) { + status.val = readl(remapped_regs + mmRBBM_STATUS); + if (!status.f.gui_active) + return 0; + udelay(1); + } + printk(KERN_ERR "w100fb: Graphic engine timeout!\n"); + return -EBUSY; +} + + +static void w100_init_graphic_engine(struct w100fb_par *par) +{ + union dp_gui_master_cntl_u gmc; + union dp_mix_u dp_mix; + union dp_datatype_u dp_datatype; + union dp_cntl_u dp_cntl; + + w100_fifo_wait(4); + writel(W100_FB_BASE, remapped_regs + mmDST_OFFSET); + writel(par->xres, remapped_regs + mmDST_PITCH); + writel(W100_FB_BASE, remapped_regs + mmSRC_OFFSET); + writel(par->xres, remapped_regs + mmSRC_PITCH); + + w100_fifo_wait(3); + writel(0, remapped_regs + mmSC_TOP_LEFT); + writel((par->yres << 16) | par->xres, remapped_regs + mmSC_BOTTOM_RIGHT); + writel(0x1fff1fff, remapped_regs + mmSRC_SC_BOTTOM_RIGHT); + + w100_fifo_wait(4); + dp_cntl.val = 0; + dp_cntl.f.dst_x_dir = 1; + dp_cntl.f.dst_y_dir = 1; + dp_cntl.f.src_x_dir = 1; + dp_cntl.f.src_y_dir = 1; + dp_cntl.f.dst_major_x = 1; + dp_cntl.f.src_major_x = 1; + writel(dp_cntl.val, remapped_regs + mmDP_CNTL); + + gmc.val = 0; + gmc.f.gmc_src_pitch_offset_cntl = 1; + gmc.f.gmc_dst_pitch_offset_cntl = 1; + gmc.f.gmc_src_clipping = 1; + gmc.f.gmc_dst_clipping = 1; + gmc.f.gmc_brush_datatype = GMC_BRUSH_NONE; + gmc.f.gmc_dst_datatype = 3; /* from DstType_16Bpp_444 */ + gmc.f.gmc_src_datatype = SRC_DATATYPE_EQU_DST; + gmc.f.gmc_byte_pix_order = 1; + gmc.f.gmc_default_sel = 0; + gmc.f.gmc_rop3 = ROP3_SRCCOPY; + gmc.f.gmc_dp_src_source = DP_SRC_MEM_RECTANGULAR; + gmc.f.gmc_clr_cmp_fcn_dis = 1; + gmc.f.gmc_wr_msk_dis = 1; + gmc.f.gmc_dp_op = DP_OP_ROP; + writel(gmc.val, remapped_regs + mmDP_GUI_MASTER_CNTL); + + dp_datatype.val = dp_mix.val = 0; + dp_datatype.f.dp_dst_datatype = gmc.f.gmc_dst_datatype; + dp_datatype.f.dp_brush_datatype = gmc.f.gmc_brush_datatype; + dp_datatype.f.dp_src2_type = 0; + dp_datatype.f.dp_src2_datatype = gmc.f.gmc_src_datatype; + dp_datatype.f.dp_src_datatype = gmc.f.gmc_src_datatype; + dp_datatype.f.dp_byte_pix_order = gmc.f.gmc_byte_pix_order; + writel(dp_datatype.val, remapped_regs + mmDP_DATATYPE); + + dp_mix.f.dp_src_source = gmc.f.gmc_dp_src_source; + dp_mix.f.dp_src2_source = 1; + dp_mix.f.dp_rop3 = gmc.f.gmc_rop3; + dp_mix.f.dp_op = gmc.f.gmc_dp_op; + writel(dp_mix.val, remapped_regs + mmDP_MIX); +} + + +static void w100fb_fillrect(struct fb_info *info, + const struct fb_fillrect *rect) +{ + union dp_gui_master_cntl_u gmc; + + if (info->state != FBINFO_STATE_RUNNING) + return; + if (info->flags & FBINFO_HWACCEL_DISABLED) { + cfb_fillrect(info, rect); + return; + } + + gmc.val = readl(remapped_regs + mmDP_GUI_MASTER_CNTL); + gmc.f.gmc_rop3 = ROP3_PATCOPY; + gmc.f.gmc_brush_datatype = GMC_BRUSH_SOLID_COLOR; + w100_fifo_wait(2); + writel(gmc.val, remapped_regs + mmDP_GUI_MASTER_CNTL); + writel(rect->color, remapped_regs + mmDP_BRUSH_FRGD_CLR); + + w100_fifo_wait(2); + writel((rect->dy << 16) | (rect->dx & 0xffff), remapped_regs + mmDST_Y_X); + writel((rect->width << 16) | (rect->height & 0xffff), + remapped_regs + mmDST_WIDTH_HEIGHT); +} + + +static void w100fb_copyarea(struct fb_info *info, + const struct fb_copyarea *area) +{ + u32 dx = area->dx, dy = area->dy, sx = area->sx, sy = area->sy; + u32 h = area->height, w = area->width; + union dp_gui_master_cntl_u gmc; + + if (info->state != FBINFO_STATE_RUNNING) + return; + if (info->flags & FBINFO_HWACCEL_DISABLED) { + cfb_copyarea(info, area); + return; + } + + gmc.val = readl(remapped_regs + mmDP_GUI_MASTER_CNTL); + gmc.f.gmc_rop3 = ROP3_SRCCOPY; + gmc.f.gmc_brush_datatype = GMC_BRUSH_NONE; + w100_fifo_wait(1); + writel(gmc.val, remapped_regs + mmDP_GUI_MASTER_CNTL); + + w100_fifo_wait(3); + writel((sy << 16) | (sx & 0xffff), remapped_regs + mmSRC_Y_X); + writel((dy << 16) | (dx & 0xffff), remapped_regs + mmDST_Y_X); + writel((w << 16) | (h & 0xffff), remapped_regs + mmDST_WIDTH_HEIGHT); +} + + /* * Change the resolution by calling the appropriate hardware functions */ @@ -265,6 +416,7 @@ static void w100fb_activate_var(struct w100fb_par *par) w100_init_lcd(par); w100_set_dispregs(par); w100_update_enable(); + w100_init_graphic_engine(par); calc_hsync(par); @@ -394,9 +546,10 @@ static struct fb_ops w100fb_ops = { .fb_set_par = w100fb_set_par, .fb_setcolreg = w100fb_setcolreg, .fb_blank = w100fb_blank, - .fb_fillrect = cfb_fillrect, - .fb_copyarea = cfb_copyarea, + .fb_fillrect = w100fb_fillrect, + .fb_copyarea = w100fb_copyarea, .fb_imageblit = cfb_imageblit, + .fb_sync = w100fb_sync, }; #ifdef CONFIG_PM @@ -543,7 +696,8 @@ int __init w100fb_probe(struct platform_device *pdev) } info->fbops = &w100fb_ops; - info->flags = FBINFO_DEFAULT; + info->flags = FBINFO_DEFAULT | FBINFO_HWACCEL_COPYAREA | + FBINFO_HWACCEL_FILLRECT; info->node = -1; info->screen_base = remapped_fbuf + (W100_FB_BASE-MEM_WINDOW_BASE); info->screen_size = REMAPPED_FB_LEN; diff --git a/drivers/video/w100fb.h b/drivers/video/w100fb.h index 7a58a1e3e42..fffae7b4f6e 100644 --- a/drivers/video/w100fb.h +++ b/drivers/video/w100fb.h @@ -122,15 +122,32 @@ /* Block DISPLAY End: */ /* Block GFX Start: */ +#define mmDST_OFFSET 0x1004 +#define mmDST_PITCH 0x1008 +#define mmDST_Y_X 0x1038 +#define mmDST_WIDTH_HEIGHT 0x1198 +#define mmDP_GUI_MASTER_CNTL 0x106C #define mmBRUSH_OFFSET 0x108C #define mmBRUSH_Y_X 0x1074 +#define mmDP_BRUSH_FRGD_CLR 0x107C +#define mmSRC_OFFSET 0x11AC +#define mmSRC_PITCH 0x11B0 +#define mmSRC_Y_X 0x1034 #define mmDEFAULT_PITCH_OFFSET 0x10A0 #define mmDEFAULT_SC_BOTTOM_RIGHT 0x10A8 #define mmDEFAULT2_SC_BOTTOM_RIGHT 0x10AC +#define mmSC_TOP_LEFT 0x11BC +#define mmSC_BOTTOM_RIGHT 0x11C0 +#define mmSRC_SC_BOTTOM_RIGHT 0x11C4 #define mmGLOBAL_ALPHA 0x1210 #define mmFILTER_COEF 0x1214 #define mmMVC_CNTL_START 0x11E0 #define mmE2_ARITHMETIC_CNTL 0x1220 +#define mmDP_CNTL 0x11C8 +#define mmDP_CNTL_DST_DIR 0x11CC +#define mmDP_DATATYPE 0x12C4 +#define mmDP_MIX 0x12C8 +#define mmDP_WRITE_MSK 0x12CC #define mmENG_CNTL 0x13E8 #define mmENG_PERF_CNT 0x13F0 /* Block GFX End: */ @@ -179,6 +196,7 @@ /* Block RBBM Start: */ #define mmWAIT_UNTIL 0x1400 #define mmISYNC_CNTL 0x1404 +#define mmRBBM_STATUS 0x0140 #define mmRBBM_CNTL 0x0144 #define mmNQWAIT_UNTIL 0x0150 /* Block RBBM End: */ @@ -225,147 +243,147 @@ /* Register structure definitions */ struct wrap_top_dir_t { - unsigned long top_addr : 23; - unsigned long : 9; + u32 top_addr : 23; + u32 : 9; } __attribute__((packed)); union wrap_top_dir_u { - unsigned long val : 32; + u32 val : 32; struct wrap_top_dir_t f; } __attribute__((packed)); struct wrap_start_dir_t { - unsigned long start_addr : 23; - unsigned long : 9; + u32 start_addr : 23; + u32 : 9; } __attribute__((packed)); union wrap_start_dir_u { - unsigned long val : 32; + u32 val : 32; struct wrap_start_dir_t f; } __attribute__((packed)); struct cif_cntl_t { - unsigned long swap_reg : 2; - unsigned long swap_fbuf_1 : 2; - unsigned long swap_fbuf_2 : 2; - unsigned long swap_fbuf_3 : 2; - unsigned long pmi_int_disable : 1; - unsigned long pmi_schmen_disable : 1; - unsigned long intb_oe : 1; - unsigned long en_wait_to_compensate_dq_prop_dly : 1; - unsigned long compensate_wait_rd_size : 2; - unsigned long wait_asserted_timeout_val : 2; - unsigned long wait_masked_val : 2; - unsigned long en_wait_timeout : 1; - unsigned long en_one_clk_setup_before_wait : 1; - unsigned long interrupt_active_high : 1; - unsigned long en_overwrite_straps : 1; - unsigned long strap_wait_active_hi : 1; - unsigned long lat_busy_count : 2; - unsigned long lat_rd_pm4_sclk_busy : 1; - unsigned long dis_system_bits : 1; - unsigned long dis_mr : 1; - unsigned long cif_spare_1 : 4; + u32 swap_reg : 2; + u32 swap_fbuf_1 : 2; + u32 swap_fbuf_2 : 2; + u32 swap_fbuf_3 : 2; + u32 pmi_int_disable : 1; + u32 pmi_schmen_disable : 1; + u32 intb_oe : 1; + u32 en_wait_to_compensate_dq_prop_dly : 1; + u32 compensate_wait_rd_size : 2; + u32 wait_asserted_timeout_val : 2; + u32 wait_masked_val : 2; + u32 en_wait_timeout : 1; + u32 en_one_clk_setup_before_wait : 1; + u32 interrupt_active_high : 1; + u32 en_overwrite_straps : 1; + u32 strap_wait_active_hi : 1; + u32 lat_busy_count : 2; + u32 lat_rd_pm4_sclk_busy : 1; + u32 dis_system_bits : 1; + u32 dis_mr : 1; + u32 cif_spare_1 : 4; } __attribute__((packed)); union cif_cntl_u { - unsigned long val : 32; + u32 val : 32; struct cif_cntl_t f; } __attribute__((packed)); struct cfgreg_base_t { - unsigned long cfgreg_base : 24; - unsigned long : 8; + u32 cfgreg_base : 24; + u32 : 8; } __attribute__((packed)); union cfgreg_base_u { - unsigned long val : 32; + u32 val : 32; struct cfgreg_base_t f; } __attribute__((packed)); struct cif_io_t { - unsigned long dq_srp : 1; - unsigned long dq_srn : 1; - unsigned long dq_sp : 4; - unsigned long dq_sn : 4; - unsigned long waitb_srp : 1; - unsigned long waitb_srn : 1; - unsigned long waitb_sp : 4; - unsigned long waitb_sn : 4; - unsigned long intb_srp : 1; - unsigned long intb_srn : 1; - unsigned long intb_sp : 4; - unsigned long intb_sn : 4; - unsigned long : 2; + u32 dq_srp : 1; + u32 dq_srn : 1; + u32 dq_sp : 4; + u32 dq_sn : 4; + u32 waitb_srp : 1; + u32 waitb_srn : 1; + u32 waitb_sp : 4; + u32 waitb_sn : 4; + u32 intb_srp : 1; + u32 intb_srn : 1; + u32 intb_sp : 4; + u32 intb_sn : 4; + u32 : 2; } __attribute__((packed)); union cif_io_u { - unsigned long val : 32; + u32 val : 32; struct cif_io_t f; } __attribute__((packed)); struct cif_read_dbg_t { - unsigned long unpacker_pre_fetch_trig_gen : 2; - unsigned long dly_second_rd_fetch_trig : 1; - unsigned long rst_rd_burst_id : 1; - unsigned long dis_rd_burst_id : 1; - unsigned long en_block_rd_when_packer_is_not_emp : 1; - unsigned long dis_pre_fetch_cntl_sm : 1; - unsigned long rbbm_chrncy_dis : 1; - unsigned long rbbm_rd_after_wr_lat : 2; - unsigned long dis_be_during_rd : 1; - unsigned long one_clk_invalidate_pulse : 1; - unsigned long dis_chnl_priority : 1; - unsigned long rst_read_path_a_pls : 1; - unsigned long rst_read_path_b_pls : 1; - unsigned long dis_reg_rd_fetch_trig : 1; - unsigned long dis_rd_fetch_trig_from_ind_addr : 1; - unsigned long dis_rd_same_byte_to_trig_fetch : 1; - unsigned long dis_dir_wrap : 1; - unsigned long dis_ring_buf_to_force_dec : 1; - unsigned long dis_addr_comp_in_16bit : 1; - unsigned long clr_w : 1; - unsigned long err_rd_tag_is_3 : 1; - unsigned long err_load_when_ful_a : 1; - unsigned long err_load_when_ful_b : 1; - unsigned long : 7; + u32 unpacker_pre_fetch_trig_gen : 2; + u32 dly_second_rd_fetch_trig : 1; + u32 rst_rd_burst_id : 1; + u32 dis_rd_burst_id : 1; + u32 en_block_rd_when_packer_is_not_emp : 1; + u32 dis_pre_fetch_cntl_sm : 1; + u32 rbbm_chrncy_dis : 1; + u32 rbbm_rd_after_wr_lat : 2; + u32 dis_be_during_rd : 1; + u32 one_clk_invalidate_pulse : 1; + u32 dis_chnl_priority : 1; + u32 rst_read_path_a_pls : 1; + u32 rst_read_path_b_pls : 1; + u32 dis_reg_rd_fetch_trig : 1; + u32 dis_rd_fetch_trig_from_ind_addr : 1; + u32 dis_rd_same_byte_to_trig_fetch : 1; + u32 dis_dir_wrap : 1; + u32 dis_ring_buf_to_force_dec : 1; + u32 dis_addr_comp_in_16bit : 1; + u32 clr_w : 1; + u32 err_rd_tag_is_3 : 1; + u32 err_load_when_ful_a : 1; + u32 err_load_when_ful_b : 1; + u32 : 7; } __attribute__((packed)); union cif_read_dbg_u { - unsigned long val : 32; + u32 val : 32; struct cif_read_dbg_t f; } __attribute__((packed)); struct cif_write_dbg_t { - unsigned long packer_timeout_count : 2; - unsigned long en_upper_load_cond : 1; - unsigned long en_chnl_change_cond : 1; - unsigned long dis_addr_comp_cond : 1; - unsigned long dis_load_same_byte_addr_cond : 1; - unsigned long dis_timeout_cond : 1; - unsigned long dis_timeout_during_rbbm : 1; - unsigned long dis_packer_ful_during_rbbm_timeout : 1; - unsigned long en_dword_split_to_rbbm : 1; - unsigned long en_dummy_val : 1; - unsigned long dummy_val_sel : 1; - unsigned long mask_pm4_wrptr_dec : 1; - unsigned long dis_mc_clean_cond : 1; - unsigned long err_two_reqi_during_ful : 1; - unsigned long err_reqi_during_idle_clk : 1; - unsigned long err_global : 1; - unsigned long en_wr_buf_dbg_load : 1; - unsigned long en_wr_buf_dbg_path : 1; - unsigned long sel_wr_buf_byte : 3; - unsigned long dis_rd_flush_wr : 1; - unsigned long dis_packer_ful_cond : 1; - unsigned long dis_invalidate_by_ops_chnl : 1; - unsigned long en_halt_when_reqi_err : 1; - unsigned long cif_spare_2 : 5; - unsigned long : 1; + u32 packer_timeout_count : 2; + u32 en_upper_load_cond : 1; + u32 en_chnl_change_cond : 1; + u32 dis_addr_comp_cond : 1; + u32 dis_load_same_byte_addr_cond : 1; + u32 dis_timeout_cond : 1; + u32 dis_timeout_during_rbbm : 1; + u32 dis_packer_ful_during_rbbm_timeout : 1; + u32 en_dword_split_to_rbbm : 1; + u32 en_dummy_val : 1; + u32 dummy_val_sel : 1; + u32 mask_pm4_wrptr_dec : 1; + u32 dis_mc_clean_cond : 1; + u32 err_two_reqi_during_ful : 1; + u32 err_reqi_during_idle_clk : 1; + u32 err_global : 1; + u32 en_wr_buf_dbg_load : 1; + u32 en_wr_buf_dbg_path : 1; + u32 sel_wr_buf_byte : 3; + u32 dis_rd_flush_wr : 1; + u32 dis_packer_ful_cond : 1; + u32 dis_invalidate_by_ops_chnl : 1; + u32 en_halt_when_reqi_err : 1; + u32 cif_spare_2 : 5; + u32 : 1; } __attribute__((packed)); union cif_write_dbg_u { - unsigned long val : 32; + u32 val : 32; struct cif_write_dbg_t f; } __attribute__((packed)); @@ -403,327 +421,327 @@ union cpu_defaults_u { } __attribute__((packed)); struct crtc_total_t { - unsigned long crtc_h_total : 10; - unsigned long : 6; - unsigned long crtc_v_total : 10; - unsigned long : 6; + u32 crtc_h_total : 10; + u32 : 6; + u32 crtc_v_total : 10; + u32 : 6; } __attribute__((packed)); union crtc_total_u { - unsigned long val : 32; + u32 val : 32; struct crtc_total_t f; } __attribute__((packed)); struct crtc_ss_t { - unsigned long ss_start : 10; - unsigned long : 6; - unsigned long ss_end : 10; - unsigned long : 2; - unsigned long ss_align : 1; - unsigned long ss_pol : 1; - unsigned long ss_run_mode : 1; - unsigned long ss_en : 1; + u32 ss_start : 10; + u32 : 6; + u32 ss_end : 10; + u32 : 2; + u32 ss_align : 1; + u32 ss_pol : 1; + u32 ss_run_mode : 1; + u32 ss_en : 1; } __attribute__((packed)); union crtc_ss_u { - unsigned long val : 32; + u32 val : 32; struct crtc_ss_t f; } __attribute__((packed)); struct active_h_disp_t { - unsigned long active_h_start : 10; - unsigned long : 6; - unsigned long active_h_end : 10; - unsigned long : 6; + u32 active_h_start : 10; + u32 : 6; + u32 active_h_end : 10; + u32 : 6; } __attribute__((packed)); union active_h_disp_u { - unsigned long val : 32; + u32 val : 32; struct active_h_disp_t f; } __attribute__((packed)); struct active_v_disp_t { - unsigned long active_v_start : 10; - unsigned long : 6; - unsigned long active_v_end : 10; - unsigned long : 6; + u32 active_v_start : 10; + u32 : 6; + u32 active_v_end : 10; + u32 : 6; } __attribute__((packed)); union active_v_disp_u { - unsigned long val : 32; + u32 val : 32; struct active_v_disp_t f; } __attribute__((packed)); struct graphic_h_disp_t { - unsigned long graphic_h_start : 10; - unsigned long : 6; - unsigned long graphic_h_end : 10; - unsigned long : 6; + u32 graphic_h_start : 10; + u32 : 6; + u32 graphic_h_end : 10; + u32 : 6; } __attribute__((packed)); union graphic_h_disp_u { - unsigned long val : 32; + u32 val : 32; struct graphic_h_disp_t f; } __attribute__((packed)); struct graphic_v_disp_t { - unsigned long graphic_v_start : 10; - unsigned long : 6; - unsigned long graphic_v_end : 10; - unsigned long : 6; + u32 graphic_v_start : 10; + u32 : 6; + u32 graphic_v_end : 10; + u32 : 6; } __attribute__((packed)); union graphic_v_disp_u{ - unsigned long val : 32; + u32 val : 32; struct graphic_v_disp_t f; } __attribute__((packed)); struct graphic_ctrl_t_w100 { - unsigned long color_depth : 3; - unsigned long portrait_mode : 2; - unsigned long low_power_on : 1; - unsigned long req_freq : 4; - unsigned long en_crtc : 1; - unsigned long en_graphic_req : 1; - unsigned long en_graphic_crtc : 1; - unsigned long total_req_graphic : 9; - unsigned long lcd_pclk_on : 1; - unsigned long lcd_sclk_on : 1; - unsigned long pclk_running : 1; - unsigned long sclk_running : 1; - unsigned long : 6; + u32 color_depth : 3; + u32 portrait_mode : 2; + u32 low_power_on : 1; + u32 req_freq : 4; + u32 en_crtc : 1; + u32 en_graphic_req : 1; + u32 en_graphic_crtc : 1; + u32 total_req_graphic : 9; + u32 lcd_pclk_on : 1; + u32 lcd_sclk_on : 1; + u32 pclk_running : 1; + u32 sclk_running : 1; + u32 : 6; } __attribute__((packed)); struct graphic_ctrl_t_w32xx { - unsigned long color_depth : 3; - unsigned long portrait_mode : 2; - unsigned long low_power_on : 1; - unsigned long req_freq : 4; - unsigned long en_crtc : 1; - unsigned long en_graphic_req : 1; - unsigned long en_graphic_crtc : 1; - unsigned long total_req_graphic : 10; - unsigned long lcd_pclk_on : 1; - unsigned long lcd_sclk_on : 1; - unsigned long pclk_running : 1; - unsigned long sclk_running : 1; - unsigned long : 5; + u32 color_depth : 3; + u32 portrait_mode : 2; + u32 low_power_on : 1; + u32 req_freq : 4; + u32 en_crtc : 1; + u32 en_graphic_req : 1; + u32 en_graphic_crtc : 1; + u32 total_req_graphic : 10; + u32 lcd_pclk_on : 1; + u32 lcd_sclk_on : 1; + u32 pclk_running : 1; + u32 sclk_running : 1; + u32 : 5; } __attribute__((packed)); union graphic_ctrl_u { - unsigned long val : 32; + u32 val : 32; struct graphic_ctrl_t_w100 f_w100; struct graphic_ctrl_t_w32xx f_w32xx; } __attribute__((packed)); struct video_ctrl_t { - unsigned long video_mode : 1; - unsigned long keyer_en : 1; - unsigned long en_video_req : 1; - unsigned long en_graphic_req_video : 1; - unsigned long en_video_crtc : 1; - unsigned long video_hor_exp : 2; - unsigned long video_ver_exp : 2; - unsigned long uv_combine : 1; - unsigned long total_req_video : 9; - unsigned long video_ch_sel : 1; - unsigned long video_portrait : 2; - unsigned long yuv2rgb_en : 1; - unsigned long yuv2rgb_option : 1; - unsigned long video_inv_hor : 1; - unsigned long video_inv_ver : 1; - unsigned long gamma_sel : 2; - unsigned long dis_limit : 1; - unsigned long en_uv_hblend : 1; - unsigned long rgb_gamma_sel : 2; + u32 video_mode : 1; + u32 keyer_en : 1; + u32 en_video_req : 1; + u32 en_graphic_req_video : 1; + u32 en_video_crtc : 1; + u32 video_hor_exp : 2; + u32 video_ver_exp : 2; + u32 uv_combine : 1; + u32 total_req_video : 9; + u32 video_ch_sel : 1; + u32 video_portrait : 2; + u32 yuv2rgb_en : 1; + u32 yuv2rgb_option : 1; + u32 video_inv_hor : 1; + u32 video_inv_ver : 1; + u32 gamma_sel : 2; + u32 dis_limit : 1; + u32 en_uv_hblend : 1; + u32 rgb_gamma_sel : 2; } __attribute__((packed)); union video_ctrl_u { - unsigned long val : 32; + u32 val : 32; struct video_ctrl_t f; } __attribute__((packed)); struct disp_db_buf_cntl_rd_t { - unsigned long en_db_buf : 1; - unsigned long update_db_buf_done : 1; - unsigned long db_buf_cntl : 6; - unsigned long : 24; + u32 en_db_buf : 1; + u32 update_db_buf_done : 1; + u32 db_buf_cntl : 6; + u32 : 24; } __attribute__((packed)); union disp_db_buf_cntl_rd_u { - unsigned long val : 32; + u32 val : 32; struct disp_db_buf_cntl_rd_t f; } __attribute__((packed)); struct disp_db_buf_cntl_wr_t { - unsigned long en_db_buf : 1; - unsigned long update_db_buf : 1; - unsigned long db_buf_cntl : 6; - unsigned long : 24; + u32 en_db_buf : 1; + u32 update_db_buf : 1; + u32 db_buf_cntl : 6; + u32 : 24; } __attribute__((packed)); union disp_db_buf_cntl_wr_u { - unsigned long val : 32; + u32 val : 32; struct disp_db_buf_cntl_wr_t f; } __attribute__((packed)); struct gamma_value1_t { - unsigned long gamma1 : 8; - unsigned long gamma2 : 8; - unsigned long gamma3 : 8; - unsigned long gamma4 : 8; + u32 gamma1 : 8; + u32 gamma2 : 8; + u32 gamma3 : 8; + u32 gamma4 : 8; } __attribute__((packed)); union gamma_value1_u { - unsigned long val : 32; + u32 val : 32; struct gamma_value1_t f; } __attribute__((packed)); struct gamma_value2_t { - unsigned long gamma5 : 8; - unsigned long gamma6 : 8; - unsigned long gamma7 : 8; - unsigned long gamma8 : 8; + u32 gamma5 : 8; + u32 gamma6 : 8; + u32 gamma7 : 8; + u32 gamma8 : 8; } __attribute__((packed)); union gamma_value2_u { - unsigned long val : 32; + u32 val : 32; struct gamma_value2_t f; } __attribute__((packed)); struct gamma_slope_t { - unsigned long slope1 : 3; - unsigned long slope2 : 3; - unsigned long slope3 : 3; - unsigned long slope4 : 3; - unsigned long slope5 : 3; - unsigned long slope6 : 3; - unsigned long slope7 : 3; - unsigned long slope8 : 3; - unsigned long : 8; + u32 slope1 : 3; + u32 slope2 : 3; + u32 slope3 : 3; + u32 slope4 : 3; + u32 slope5 : 3; + u32 slope6 : 3; + u32 slope7 : 3; + u32 slope8 : 3; + u32 : 8; } __attribute__((packed)); union gamma_slope_u { - unsigned long val : 32; + u32 val : 32; struct gamma_slope_t f; } __attribute__((packed)); struct mc_ext_mem_location_t { - unsigned long mc_ext_mem_start : 16; - unsigned long mc_ext_mem_top : 16; + u32 mc_ext_mem_start : 16; + u32 mc_ext_mem_top : 16; } __attribute__((packed)); union mc_ext_mem_location_u { - unsigned long val : 32; + u32 val : 32; struct mc_ext_mem_location_t f; } __attribute__((packed)); struct mc_fb_location_t { - unsigned long mc_fb_start : 16; - unsigned long mc_fb_top : 16; + u32 mc_fb_start : 16; + u32 mc_fb_top : 16; } __attribute__((packed)); union mc_fb_location_u { - unsigned long val : 32; + u32 val : 32; struct mc_fb_location_t f; } __attribute__((packed)); struct clk_pin_cntl_t { - unsigned long osc_en : 1; - unsigned long osc_gain : 5; - unsigned long dont_use_xtalin : 1; - unsigned long xtalin_pm_en : 1; - unsigned long xtalin_dbl_en : 1; - unsigned long : 7; - unsigned long cg_debug : 16; + u32 osc_en : 1; + u32 osc_gain : 5; + u32 dont_use_xtalin : 1; + u32 xtalin_pm_en : 1; + u32 xtalin_dbl_en : 1; + u32 : 7; + u32 cg_debug : 16; } __attribute__((packed)); union clk_pin_cntl_u { - unsigned long val : 32; + u32 val : 32; struct clk_pin_cntl_t f; } __attribute__((packed)); struct pll_ref_fb_div_t { - unsigned long pll_ref_div : 4; - unsigned long : 4; - unsigned long pll_fb_div_int : 6; - unsigned long : 2; - unsigned long pll_fb_div_frac : 3; - unsigned long : 1; - unsigned long pll_reset_time : 4; - unsigned long pll_lock_time : 8; + u32 pll_ref_div : 4; + u32 : 4; + u32 pll_fb_div_int : 6; + u32 : 2; + u32 pll_fb_div_frac : 3; + u32 : 1; + u32 pll_reset_time : 4; + u32 pll_lock_time : 8; } __attribute__((packed)); union pll_ref_fb_div_u { - unsigned long val : 32; + u32 val : 32; struct pll_ref_fb_div_t f; } __attribute__((packed)); struct pll_cntl_t { - unsigned long pll_pwdn : 1; - unsigned long pll_reset : 1; - unsigned long pll_pm_en : 1; - unsigned long pll_mode : 1; - unsigned long pll_refclk_sel : 1; - unsigned long pll_fbclk_sel : 1; - unsigned long pll_tcpoff : 1; - unsigned long pll_pcp : 3; - unsigned long pll_pvg : 3; - unsigned long pll_vcofr : 1; - unsigned long pll_ioffset : 2; - unsigned long pll_pecc_mode : 2; - unsigned long pll_pecc_scon : 2; - unsigned long pll_dactal : 4; - unsigned long pll_cp_clip : 2; - unsigned long pll_conf : 3; - unsigned long pll_mbctrl : 2; - unsigned long pll_ring_off : 1; + u32 pll_pwdn : 1; + u32 pll_reset : 1; + u32 pll_pm_en : 1; + u32 pll_mode : 1; + u32 pll_refclk_sel : 1; + u32 pll_fbclk_sel : 1; + u32 pll_tcpoff : 1; + u32 pll_pcp : 3; + u32 pll_pvg : 3; + u32 pll_vcofr : 1; + u32 pll_ioffset : 2; + u32 pll_pecc_mode : 2; + u32 pll_pecc_scon : 2; + u32 pll_dactal : 4; + u32 pll_cp_clip : 2; + u32 pll_conf : 3; + u32 pll_mbctrl : 2; + u32 pll_ring_off : 1; } __attribute__((packed)); union pll_cntl_u { - unsigned long val : 32; + u32 val : 32; struct pll_cntl_t f; } __attribute__((packed)); struct sclk_cntl_t { - unsigned long sclk_src_sel : 2; - unsigned long : 2; - unsigned long sclk_post_div_fast : 4; - unsigned long sclk_clkon_hys : 3; - unsigned long sclk_post_div_slow : 4; - unsigned long disp_cg_ok2switch_en : 1; - unsigned long sclk_force_reg : 1; - unsigned long sclk_force_disp : 1; - unsigned long sclk_force_mc : 1; - unsigned long sclk_force_extmc : 1; - unsigned long sclk_force_cp : 1; - unsigned long sclk_force_e2 : 1; - unsigned long sclk_force_e3 : 1; - unsigned long sclk_force_idct : 1; - unsigned long sclk_force_bist : 1; - unsigned long busy_extend_cp : 1; - unsigned long busy_extend_e2 : 1; - unsigned long busy_extend_e3 : 1; - unsigned long busy_extend_idct : 1; - unsigned long : 3; + u32 sclk_src_sel : 2; + u32 : 2; + u32 sclk_post_div_fast : 4; + u32 sclk_clkon_hys : 3; + u32 sclk_post_div_slow : 4; + u32 disp_cg_ok2switch_en : 1; + u32 sclk_force_reg : 1; + u32 sclk_force_disp : 1; + u32 sclk_force_mc : 1; + u32 sclk_force_extmc : 1; + u32 sclk_force_cp : 1; + u32 sclk_force_e2 : 1; + u32 sclk_force_e3 : 1; + u32 sclk_force_idct : 1; + u32 sclk_force_bist : 1; + u32 busy_extend_cp : 1; + u32 busy_extend_e2 : 1; + u32 busy_extend_e3 : 1; + u32 busy_extend_idct : 1; + u32 : 3; } __attribute__((packed)); union sclk_cntl_u { - unsigned long val : 32; + u32 val : 32; struct sclk_cntl_t f; } __attribute__((packed)); struct pclk_cntl_t { - unsigned long pclk_src_sel : 2; - unsigned long : 2; - unsigned long pclk_post_div : 4; - unsigned long : 8; - unsigned long pclk_force_disp : 1; - unsigned long : 15; + u32 pclk_src_sel : 2; + u32 : 2; + u32 pclk_post_div : 4; + u32 : 8; + u32 pclk_force_disp : 1; + u32 : 15; } __attribute__((packed)); union pclk_cntl_u { - unsigned long val : 32; + u32 val : 32; struct pclk_cntl_t f; } __attribute__((packed)); @@ -735,36 +753,176 @@ union pclk_cntl_u { #define TESTCLK_SRC_XTAL 0x06 struct clk_test_cntl_t { - unsigned long testclk_sel : 4; - unsigned long : 3; - unsigned long start_check_freq : 1; - unsigned long tstcount_rst : 1; - unsigned long : 15; - unsigned long test_count : 8; + u32 testclk_sel : 4; + u32 : 3; + u32 start_check_freq : 1; + u32 tstcount_rst : 1; + u32 : 15; + u32 test_count : 8; } __attribute__((packed)); union clk_test_cntl_u { - unsigned long val : 32; + u32 val : 32; struct clk_test_cntl_t f; } __attribute__((packed)); struct pwrmgt_cntl_t { - unsigned long pwm_enable : 1; - unsigned long : 1; - unsigned long pwm_mode_req : 2; - unsigned long pwm_wakeup_cond : 2; - unsigned long pwm_fast_noml_hw_en : 1; - unsigned long pwm_noml_fast_hw_en : 1; - unsigned long pwm_fast_noml_cond : 4; - unsigned long pwm_noml_fast_cond : 4; - unsigned long pwm_idle_timer : 8; - unsigned long pwm_busy_timer : 8; + u32 pwm_enable : 1; + u32 : 1; + u32 pwm_mode_req : 2; + u32 pwm_wakeup_cond : 2; + u32 pwm_fast_noml_hw_en : 1; + u32 pwm_noml_fast_hw_en : 1; + u32 pwm_fast_noml_cond : 4; + u32 pwm_noml_fast_cond : 4; + u32 pwm_idle_timer : 8; + u32 pwm_busy_timer : 8; } __attribute__((packed)); union pwrmgt_cntl_u { - unsigned long val : 32; + u32 val : 32; struct pwrmgt_cntl_t f; } __attribute__((packed)); +#define SRC_DATATYPE_EQU_DST 3 + +#define ROP3_SRCCOPY 0xcc +#define ROP3_PATCOPY 0xf0 + +#define GMC_BRUSH_SOLID_COLOR 13 +#define GMC_BRUSH_NONE 15 + +#define DP_SRC_MEM_RECTANGULAR 2 + +#define DP_OP_ROP 0 + +struct dp_gui_master_cntl_t { + u32 gmc_src_pitch_offset_cntl : 1; + u32 gmc_dst_pitch_offset_cntl : 1; + u32 gmc_src_clipping : 1; + u32 gmc_dst_clipping : 1; + u32 gmc_brush_datatype : 4; + u32 gmc_dst_datatype : 4; + u32 gmc_src_datatype : 3; + u32 gmc_byte_pix_order : 1; + u32 gmc_default_sel : 1; + u32 gmc_rop3 : 8; + u32 gmc_dp_src_source : 3; + u32 gmc_clr_cmp_fcn_dis : 1; + u32 : 1; + u32 gmc_wr_msk_dis : 1; + u32 gmc_dp_op : 1; +} __attribute__((packed)); + +union dp_gui_master_cntl_u { + u32 val : 32; + struct dp_gui_master_cntl_t f; +} __attribute__((packed)); + +struct rbbm_status_t { + u32 cmdfifo_avail : 7; + u32 : 1; + u32 hirq_on_rbb : 1; + u32 cprq_on_rbb : 1; + u32 cfrq_on_rbb : 1; + u32 hirq_in_rtbuf : 1; + u32 cprq_in_rtbuf : 1; + u32 cfrq_in_rtbuf : 1; + u32 cf_pipe_busy : 1; + u32 eng_ev_busy : 1; + u32 cp_cmdstrm_busy : 1; + u32 e2_busy : 1; + u32 rb2d_busy : 1; + u32 rb3d_busy : 1; + u32 se_busy : 1; + u32 re_busy : 1; + u32 tam_busy : 1; + u32 tdm_busy : 1; + u32 pb_busy : 1; + u32 : 6; + u32 gui_active : 1; +} __attribute__((packed)); + +union rbbm_status_u { + u32 val : 32; + struct rbbm_status_t f; +} __attribute__((packed)); + +struct dp_datatype_t { + u32 dp_dst_datatype : 4; + u32 : 4; + u32 dp_brush_datatype : 4; + u32 dp_src2_type : 1; + u32 dp_src2_datatype : 3; + u32 dp_src_datatype : 3; + u32 : 11; + u32 dp_byte_pix_order : 1; + u32 : 1; +} __attribute__((packed)); + +union dp_datatype_u { + u32 val : 32; + struct dp_datatype_t f; +} __attribute__((packed)); + +struct dp_mix_t { + u32 : 8; + u32 dp_src_source : 3; + u32 dp_src2_source : 3; + u32 : 2; + u32 dp_rop3 : 8; + u32 dp_op : 1; + u32 : 7; +} __attribute__((packed)); + +union dp_mix_u { + u32 val : 32; + struct dp_mix_t f; +} __attribute__((packed)); + +struct eng_cntl_t { + u32 erc_reg_rd_ws : 1; + u32 erc_reg_wr_ws : 1; + u32 erc_idle_reg_wr : 1; + u32 dis_engine_triggers : 1; + u32 dis_rop_src_uses_dst_w_h : 1; + u32 dis_src_uses_dst_dirmaj : 1; + u32 : 6; + u32 force_3dclk_when_2dclk : 1; + u32 : 19; +} __attribute__((packed)); + +union eng_cntl_u { + u32 val : 32; + struct eng_cntl_t f; +} __attribute__((packed)); + +struct dp_cntl_t { + u32 dst_x_dir : 1; + u32 dst_y_dir : 1; + u32 src_x_dir : 1; + u32 src_y_dir : 1; + u32 dst_major_x : 1; + u32 src_major_x : 1; + u32 : 26; +} __attribute__((packed)); + +union dp_cntl_u { + u32 val : 32; + struct dp_cntl_t f; +} __attribute__((packed)); + +struct dp_cntl_dst_dir_t { + u32 : 15; + u32 dst_y_dir : 1; + u32 : 15; + u32 dst_x_dir : 1; +} __attribute__((packed)); + +union dp_cntl_dst_dir_u { + u32 val : 32; + struct dp_cntl_dst_dir_t f; +} __attribute__((packed)); + #endif |