Merge rsync://rsync.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6
[sfrench/cifs-2.6.git] / drivers / bluetooth / bt3c_cs.c
index d2a0add19cc88a52ddcd703495fdcf0584b00022..b94ac2f9f7baf2d5e9cc0641e52de23cd1536d13 100644 (file)
@@ -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,16 +88,10 @@ 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_event(event_t event, int priority, event_callback_args_t *args);
+static int bt3c_config(struct pcmcia_device *link);
+static void bt3c_release(struct pcmcia_device *link);
 
-static dev_info_t dev_info = "bt3c_cs";
-
-static dev_link_t *bt3c_attach(void);
-static void bt3c_detach(dev_link_t *);
-
-static dev_link_t *dev_list = NULL;
+static void bt3c_detach(struct pcmcia_device *p_dev);
 
 
 /* Transmit states  */
@@ -197,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;
 
 
@@ -235,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);
@@ -356,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));
 
@@ -480,18 +474,6 @@ static int bt3c_hci_ioctl(struct hci_dev *hdev, unsigned int cmd, unsigned long
 /* ======================== Card services HCI interaction ======================== */
 
 
-static struct device *bt3c_device(void)
-{
-       static struct device dev = {
-               .bus_id = "pcmcia",
-       };
-       kobject_set_name(&dev.kobj, "bt3c");
-       kobject_init(&dev.kobj);
-
-       return &dev;
-}
-
-
 static int bt3c_load_firmware(bt3c_info_t *info, unsigned char *firmware, int count)
 {
        char *ptr = (char *) firmware;
@@ -499,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);
@@ -612,7 +594,7 @@ static int bt3c_open(bt3c_info_t *info)
        hdev->owner = THIS_MODULE;
 
        /* Load firmware */
-       err = request_firmware(&firmware, "BT3CPCC.bin", bt3c_device());
+       err = request_firmware(&firmware, "BT3CPCC.bin", &info->p_dev->dev);
        if (err < 0) {
                BT_ERR("Firmware request failed");
                goto error;
@@ -663,19 +645,16 @@ static int bt3c_close(bt3c_info_t *info)
        return 0;
 }
 
-static dev_link_t *bt3c_attach(void)
+static int bt3c_probe(struct pcmcia_device *link)
 {
        bt3c_info_t *info;
-       client_reg_t client_reg;
-       dev_link_t *link;
-       int ret;
 
        /* Create new info device */
        info = kzalloc(sizeof(*info), GFP_KERNEL);
        if (!info)
-               return NULL;
+               return -ENOMEM;
 
-       link = &info->link;
+       info->p_dev = link;
        link->priv = info;
 
        link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
@@ -687,57 +666,21 @@ static dev_link_t *bt3c_attach(void)
        link->irq.Instance = info;
 
        link->conf.Attributes = CONF_ENABLE_IRQ;
-       link->conf.Vcc = 50;
        link->conf.IntType = INT_MEMORY_AND_IO;
 
-       /* Register with Card Services */
-       link->next = dev_list;
-       dev_list = link;
-       client_reg.dev_info = &dev_info;
-       client_reg.Version = 0x0210;
-       client_reg.event_callback_args.client_data = link;
-
-       ret = pcmcia_register_client(&link->handle, &client_reg);
-       if (ret != CS_SUCCESS) {
-               cs_error(link->handle, RegisterClient, ret);
-               bt3c_detach(link);
-               return NULL;
-       }
-
-       return link;
+       return bt3c_config(link);
 }
 
 
-static void bt3c_detach(dev_link_t *link)
+static void bt3c_detach(struct pcmcia_device *link)
 {
        bt3c_info_t *info = link->priv;
-       dev_link_t **linkp;
-       int ret;
-
-       /* Locate device structure */
-       for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next)
-               if (*linkp == link)
-                       break;
-
-       if (*linkp == NULL)
-               return;
-
-       if (link->state & DEV_CONFIG)
-               bt3c_release(link);
-
-       if (link->handle) {
-               ret = pcmcia_deregister_client(link->handle);
-               if (ret != CS_SUCCESS)
-                       cs_error(link->handle, DeregisterClient, ret);
-       }
-
-       /* Unlink device structure, free bits */
-       *linkp = link->next;
 
+       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;
 
@@ -748,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;
@@ -781,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;
@@ -789,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;
@@ -802,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;
        }
 
@@ -862,72 +798,29 @@ 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);
+       bt3c_close(info);
 
-       link->state &= ~DEV_CONFIG;
+       pcmcia_disable_device(link);
 }
 
 
-static int bt3c_event(event_t event, int priority, event_callback_args_t *args)
-{
-       dev_link_t *link = args->client_data;
-       bt3c_info_t *info = link->priv;
-
-       switch (event) {
-       case CS_EVENT_CARD_REMOVAL:
-               link->state &= ~DEV_PRESENT;
-               if (link->state & DEV_CONFIG) {
-                       bt3c_close(info);
-                       bt3c_release(link);
-               }
-               break;
-       case CS_EVENT_CARD_INSERTION:
-               link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
-               bt3c_config(link);
-               break;
-       case CS_EVENT_PM_SUSPEND:
-               link->state |= DEV_SUSPEND;
-               /* Fall through... */
-       case CS_EVENT_RESET_PHYSICAL:
-               if (link->state & DEV_CONFIG)
-                       pcmcia_release_configuration(link->handle);
-               break;
-       case CS_EVENT_PM_RESUME:
-               link->state &= ~DEV_SUSPEND;
-               /* Fall through... */
-       case CS_EVENT_CARD_RESET:
-               if (DEV_OK(link))
-                       pcmcia_request_configuration(link->handle, &link->conf);
-               break;
-       }
-
-       return 0;
-}
-
 static struct pcmcia_device_id bt3c_ids[] = {
        PCMCIA_DEVICE_PROD_ID13("3COM", "Bluetooth PC Card", 0xefce0a31, 0xd4ce9b02),
        PCMCIA_DEVICE_NULL
@@ -939,9 +832,8 @@ static struct pcmcia_driver bt3c_driver = {
        .drv            = {
                .name   = "bt3c_cs",
        },
-       .attach         = bt3c_attach,
-       .event          = bt3c_event,
-       .detach         = bt3c_detach,
+       .probe          = bt3c_probe,
+       .remove         = bt3c_detach,
        .id_table       = bt3c_ids,
 };
 
@@ -954,7 +846,6 @@ static int __init init_bt3c_cs(void)
 static void __exit exit_bt3c_cs(void)
 {
        pcmcia_unregister_driver(&bt3c_driver);
-       BUG_ON(dev_list != NULL);
 }
 
 module_init(init_bt3c_cs);