aboutsummaryrefslogtreecommitdiff
path: root/drivers/bluetooth/bluecard_cs.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/bluetooth/bluecard_cs.c')
-rw-r--r--drivers/bluetooth/bluecard_cs.c306
1 files changed, 81 insertions, 225 deletions
diff --git a/drivers/bluetooth/bluecard_cs.c b/drivers/bluetooth/bluecard_cs.c
index 9888bc15175..dfa5043e68b 100644
--- a/drivers/bluetooth/bluecard_cs.c
+++ b/drivers/bluetooth/bluecard_cs.c
@@ -20,7 +20,6 @@
*
*/
-#include <linux/config.h>
#include <linux/module.h>
#include <linux/kernel.h>
@@ -38,10 +37,8 @@
#include <linux/wait.h>
#include <linux/skbuff.h>
-#include <asm/io.h>
+#include <linux/io.h>
-#include <pcmcia/cs_types.h>
-#include <pcmcia/cs.h>
#include <pcmcia/cistpl.h>
#include <pcmcia/ciscode.h>
#include <pcmcia/ds.h>
@@ -65,8 +62,7 @@ MODULE_LICENSE("GPL");
typedef struct bluecard_info_t {
- dev_link_t link;
- dev_node_t node;
+ struct pcmcia_device *p_dev;
struct hci_dev *hdev;
@@ -85,8 +81,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 +158,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->resource[0]->start;
if (!test_bit(CARD_HAS_PCCARD_ID, &(info->hw_state)))
return;
@@ -179,7 +175,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->resource[0]->start;
if (!test_bit(CARD_HAS_PCCARD_ID, &(info->hw_state)))
return;
@@ -235,16 +231,16 @@ static void bluecard_write_wakeup(bluecard_info_t *info)
}
do {
- register unsigned int iobase = info->link.io.BasePort1;
- register unsigned int offset;
- register unsigned char command;
- register unsigned long ready_bit;
+ unsigned int iobase = info->p_dev->resource[0]->start;
+ unsigned int offset;
+ unsigned char command;
+ unsigned long ready_bit;
register struct sk_buff *skb;
- register int len;
+ int len;
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))) {
@@ -261,7 +257,8 @@ static void bluecard_write_wakeup(bluecard_info_t *info)
ready_bit = XMIT_BUF_ONE_READY;
}
- if (!(skb = skb_dequeue(&(info->txq))))
+ skb = skb_dequeue(&(info->txq));
+ if (!skb)
break;
if (bt_cb(skb)->pkt_type & 0x80) {
@@ -283,7 +280,7 @@ static void bluecard_write_wakeup(bluecard_info_t *info)
clear_bit(ready_bit, &(info->tx_state));
if (bt_cb(skb)->pkt_type & 0x80) {
- DECLARE_WAIT_QUEUE_HEAD(wq);
+ DECLARE_WAIT_QUEUE_HEAD_ONSTACK(wq);
DEFINE_WAIT(wait);
unsigned char baud_reg;
@@ -382,7 +379,7 @@ static void bluecard_receive(bluecard_info_t *info, unsigned int offset)
return;
}
- iobase = info->link.io.BasePort1;
+ iobase = info->p_dev->resource[0]->start;
if (test_bit(XMIT_SENDING_READY, &(info->tx_state)))
bluecard_enable_activity_led(info);
@@ -395,7 +392,8 @@ static void bluecard_receive(bluecard_info_t *info, unsigned int offset)
if (info->rx_skb == NULL) {
info->rx_state = RECV_WAIT_PACKET_TYPE;
info->rx_count = 0;
- if (!(info->rx_skb = bt_skb_alloc(HCI_MAX_FRAME_SIZE, GFP_ATOMIC))) {
+ info->rx_skb = bt_skb_alloc(HCI_MAX_FRAME_SIZE, GFP_ATOMIC);
+ if (!info->rx_skb) {
BT_ERR("Can't allocate mem for new packet");
return;
}
@@ -403,7 +401,6 @@ static void bluecard_receive(bluecard_info_t *info, unsigned int offset)
if (info->rx_state == RECV_WAIT_PACKET_TYPE) {
- info->rx_skb->dev = (void *) info->hdev;
bt_cb(info->rx_skb)->pkt_type = buf[i];
switch (bt_cb(info->rx_skb)->pkt_type) {
@@ -462,26 +459,26 @@ static void bluecard_receive(bluecard_info_t *info, unsigned int offset)
switch (info->rx_state) {
case RECV_WAIT_EVENT_HEADER:
- eh = (struct hci_event_hdr *)(info->rx_skb->data);
+ eh = hci_event_hdr(info->rx_skb);
info->rx_state = RECV_WAIT_DATA;
info->rx_count = eh->plen;
break;
case RECV_WAIT_ACL_HEADER:
- ah = (struct hci_acl_hdr *)(info->rx_skb->data);
+ ah = hci_acl_hdr(info->rx_skb);
dlen = __le16_to_cpu(ah->dlen);
info->rx_state = RECV_WAIT_DATA;
info->rx_count = dlen;
break;
case RECV_WAIT_SCO_HEADER:
- sh = (struct hci_sco_hdr *)(info->rx_skb->data);
+ sh = hci_sco_hdr(info->rx_skb);
info->rx_state = RECV_WAIT_DATA;
info->rx_count = sh->dlen;
break;
case RECV_WAIT_DATA:
- hci_recv_frame(info->rx_skb);
+ hci_recv_frame(info->hdev, info->rx_skb);
info->rx_skb = NULL;
break;
@@ -498,21 +495,20 @@ static void bluecard_receive(bluecard_info_t *info, unsigned int offset)
}
-static irqreturn_t bluecard_interrupt(int irq, void *dev_inst, struct pt_regs *regs)
+static irqreturn_t bluecard_interrupt(int irq, void *dev_inst)
{
bluecard_info_t *info = dev_inst;
unsigned int iobase;
unsigned char reg;
- if (!info || !info->hdev) {
- BT_ERR("Call of irq %d for unknown device", irq);
+ if (!info || !info->hdev)
+ /* our irq handler is shared */
return IRQ_NONE;
- }
if (!test_bit(CARD_READY, &(info->hw_state)))
return IRQ_HANDLED;
- iobase = info->link.io.BasePort1;
+ iobase = info->p_dev->resource[0]->start;
spin_lock(&(info->lock));
@@ -566,13 +562,14 @@ static irqreturn_t bluecard_interrupt(int irq, void *dev_inst, struct pt_regs *r
static int bluecard_hci_set_baud_rate(struct hci_dev *hdev, int baud)
{
- bluecard_info_t *info = (bluecard_info_t *)(hdev->driver_data);
+ bluecard_info_t *info = hci_get_drvdata(hdev);
struct sk_buff *skb;
/* Ericsson baud rate command */
unsigned char cmd[] = { HCI_COMMAND_PKT, 0x09, 0xfc, 0x01, 0x03 };
- if (!(skb = bt_skb_alloc(HCI_MAX_FRAME_SIZE, GFP_ATOMIC))) {
+ skb = bt_skb_alloc(HCI_MAX_FRAME_SIZE, GFP_ATOMIC);
+ if (!skb) {
BT_ERR("Can't allocate mem for new packet");
return -1;
}
@@ -614,7 +611,7 @@ static int bluecard_hci_set_baud_rate(struct hci_dev *hdev, int baud)
static int bluecard_hci_flush(struct hci_dev *hdev)
{
- bluecard_info_t *info = (bluecard_info_t *)(hdev->driver_data);
+ bluecard_info_t *info = hci_get_drvdata(hdev);
/* Drop TX queue */
skb_queue_purge(&(info->txq));
@@ -625,8 +622,7 @@ static int bluecard_hci_flush(struct hci_dev *hdev)
static int bluecard_hci_open(struct hci_dev *hdev)
{
- bluecard_info_t *info = (bluecard_info_t *)(hdev->driver_data);
- unsigned int iobase = info->link.io.BasePort1;
+ bluecard_info_t *info = hci_get_drvdata(hdev);
if (test_bit(CARD_HAS_PCCARD_ID, &(info->hw_state)))
bluecard_hci_set_baud_rate(hdev, DEFAULT_BAUD_RATE);
@@ -635,6 +631,8 @@ static int bluecard_hci_open(struct hci_dev *hdev)
return 0;
if (test_bit(CARD_HAS_PCCARD_ID, &(info->hw_state))) {
+ unsigned int iobase = info->p_dev->resource[0]->start;
+
/* Enable LED */
outb(0x08 | 0x20, iobase + 0x30);
}
@@ -645,8 +643,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;
+ bluecard_info_t *info = hci_get_drvdata(hdev);
if (!test_and_clear_bit(HCI_RUNNING, &(hdev->flags)))
return 0;
@@ -654,6 +651,8 @@ static int bluecard_hci_close(struct hci_dev *hdev)
bluecard_hci_flush(hdev);
if (test_bit(CARD_HAS_PCCARD_ID, &(info->hw_state))) {
+ unsigned int iobase = info->p_dev->resource[0]->start;
+
/* Disable LED */
outb(0x00, iobase + 0x30);
}
@@ -662,17 +661,9 @@ static int bluecard_hci_close(struct hci_dev *hdev)
}
-static int bluecard_hci_send_frame(struct sk_buff *skb)
+static int bluecard_hci_send_frame(struct hci_dev *hdev, struct sk_buff *skb)
{
- bluecard_info_t *info;
- struct hci_dev *hdev = (struct hci_dev *)(skb->dev);
-
- if (!hdev) {
- BT_ERR("Frame for unknown HCI device (hdev=NULL)");
- return -ENODEV;
- }
-
- info = (bluecard_info_t *)(hdev->driver_data);
+ bluecard_info_t *info = hci_get_drvdata(hdev);
switch (bt_cb(skb)->pkt_type) {
case HCI_COMMAND_PKT:
@@ -684,7 +675,7 @@ static int bluecard_hci_send_frame(struct sk_buff *skb)
case HCI_SCODATA_PKT:
hdev->stat.sco_tx++;
break;
- };
+ }
/* Prepend skb with frame type */
memcpy(skb_push(skb, 1), &bt_cb(skb)->pkt_type, 1);
@@ -696,24 +687,13 @@ static int bluecard_hci_send_frame(struct sk_buff *skb)
}
-static void bluecard_hci_destruct(struct hci_dev *hdev)
-{
-}
-
-
-static int bluecard_hci_ioctl(struct hci_dev *hdev, unsigned int cmd, unsigned long arg)
-{
- return -ENOIOCTLCMD;
-}
-
-
/* ======================== Card services HCI interaction ======================== */
static int bluecard_open(bluecard_info_t *info)
{
- unsigned int iobase = info->link.io.BasePort1;
+ unsigned int iobase = info->p_dev->resource[0]->start;
struct hci_dev *hdev;
unsigned char id;
@@ -738,17 +718,14 @@ static int bluecard_open(bluecard_info_t *info)
info->hdev = hdev;
- hdev->type = HCI_PCCARD;
- hdev->driver_data = info;
-
- hdev->open = bluecard_hci_open;
- hdev->close = bluecard_hci_close;
- hdev->flush = bluecard_hci_flush;
- hdev->send = bluecard_hci_send_frame;
- hdev->destruct = bluecard_hci_destruct;
- hdev->ioctl = bluecard_hci_ioctl;
+ hdev->bus = HCI_PCCARD;
+ hci_set_drvdata(hdev, info);
+ SET_HCIDEV_DEV(hdev, &info->p_dev->dev);
- hdev->owner = THIS_MODULE;
+ hdev->open = bluecard_hci_open;
+ hdev->close = bluecard_hci_close;
+ hdev->flush = bluecard_hci_flush;
+ hdev->send = bluecard_hci_send_frame;
id = inb(iobase + 0x30);
@@ -831,7 +808,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->resource[0]->start;
struct hci_dev *hdev = info->hdev;
if (!hdev)
@@ -848,192 +825,88 @@ static int bluecard_close(bluecard_info_t *info)
/* Turn FPGA off */
outb(0x80, iobase + 0x30);
- if (hci_unregister_dev(hdev) < 0)
- BT_ERR("Can't unregister HCI device %s", hdev->name);
-
+ hci_unregister_dev(hdev);
hci_free_dev(hdev);
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);
+ info = devm_kzalloc(&link->dev, 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;
- link->io.NumPorts1 = 8;
- link->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_HANDLE_PRESENT;
- link->irq.IRQInfo1 = IRQ_LEVEL_ID;
-
- link->irq.Handler = bluecard_interrupt;
- link->irq.Instance = info;
+ link->config_flags |= CONF_ENABLE_IRQ;
- 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);
-
- kfree(info);
+ bluecard_release(link);
}
-static int first_tuple(client_handle_t handle, tuple_t *tuple, cisparse_t *parse)
+static int bluecard_config(struct pcmcia_device *link)
{
- int i;
-
- i = pcmcia_get_first_tuple(handle, tuple);
- if (i != CS_SUCCESS)
- return CS_NO_MORE_ITEMS;
-
- i = pcmcia_get_tuple_data(handle, tuple);
- if (i != CS_SUCCESS)
- return i;
-
- return pcmcia_parse_tuple(handle, tuple, parse);
-}
-
-static void bluecard_config(dev_link_t *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;
- tuple.TupleOffset = 0;
- tuple.TupleDataMax = 255;
- tuple.Attributes = 0;
-
- /* Get configuration register information */
- tuple.DesiredTuple = CISTPL_CONFIG;
- last_ret = first_tuple(handle, &tuple, &parse);
- if (last_ret != CS_SUCCESS) {
- last_fn = ParseTuple;
- goto cs_failed;
- }
- link->conf.ConfigBase = parse.config.base;
- link->conf.Present = parse.config.rmask[0];
+ int i, n;
- /* Configure card */
- link->state |= DEV_CONFIG;
- i = pcmcia_get_configuration_info(handle, &config);
- link->conf.Vcc = config.Vcc;
+ link->config_index = 0x20;
- link->conf.ConfigIndex = 0x20;
- link->io.NumPorts1 = 64;
- link->io.IOAddrLines = 6;
+ link->resource[0]->flags |= IO_DATA_PATH_WIDTH_8;
+ link->resource[0]->end = 64;
+ link->io_lines = 6;
for (n = 0; n < 0x400; n += 0x40) {
- link->io.BasePort1 = n ^ 0x300;
- i = pcmcia_request_io(link->handle, &link->io);
- if (i == CS_SUCCESS)
+ link->resource[0]->start = n ^ 0x300;
+ i = pcmcia_request_io(link);
+ if (i == 0)
break;
}
- if (i != CS_SUCCESS) {
- cs_error(link->handle, RequestIO, i);
+ if (i != 0)
goto failed;
- }
- i = pcmcia_request_irq(link->handle, &link->irq);
- if (i != CS_SUCCESS) {
- cs_error(link->handle, RequestIRQ, i);
- link->irq.AssignedIRQ = 0;
- }
+ i = pcmcia_request_irq(link, bluecard_interrupt);
+ if (i != 0)
+ goto failed;
- i = pcmcia_request_configuration(link->handle, &link->conf);
- if (i != CS_SUCCESS) {
- cs_error(link->handle, RequestConfiguration, i);
+ i = pcmcia_enable_device(link);
+ if (i != 0)
goto failed;
- }
if (bluecard_open(info) != 0)
goto failed;
- strcpy(info->node.dev_name, info->hdev->name);
- link->dev = &info->node;
- link->state &= ~DEV_CONFIG_PENDING;
-
- return;
-
-cs_failed:
- cs_error(link->handle, last_fn, last_ret);
+ return 0;
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);
-
- 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);
+ bluecard_close(info);
- link->state &= ~DEV_SUSPEND;
- if (DEV_OK(link))
- pcmcia_request_configuration(link->handle, &link->conf);
+ del_timer_sync(&(info->timer));
- return 0;
+ pcmcia_disable_device(link);
}
-static struct pcmcia_device_id bluecard_ids[] = {
+static const struct pcmcia_device_id bluecard_ids[] = {
PCMCIA_DEVICE_PROD_ID12("BlueCard", "LSE041", 0xbaf16fbf, 0x657cc15e),
PCMCIA_DEVICE_PROD_ID12("BTCFCARD", "LSE139", 0xe3987764, 0x2524b59c),
PCMCIA_DEVICE_PROD_ID12("WSS", "LSE039", 0x0a0736ec, 0x24e6dfab),
@@ -1043,26 +916,9 @@ MODULE_DEVICE_TABLE(pcmcia, bluecard_ids);
static struct pcmcia_driver bluecard_driver = {
.owner = THIS_MODULE,
- .drv = {
- .name = "bluecard_cs",
- },
- .probe = bluecard_attach,
+ .name = "bluecard_cs",
+ .probe = bluecard_probe,
.remove = bluecard_detach,
.id_table = bluecard_ids,
- .suspend = bluecard_suspend,
- .resume = bluecard_resume,
};
-
-static int __init init_bluecard_cs(void)
-{
- return pcmcia_register_driver(&bluecard_driver);
-}
-
-
-static void __exit exit_bluecard_cs(void)
-{
- pcmcia_unregister_driver(&bluecard_driver);
-}
-
-module_init(init_bluecard_cs);
-module_exit(exit_bluecard_cs);
+module_pcmcia_driver(bluecard_driver);