*
*/
-#include <linux/config.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/types.h>
-#include <linux/sched.h>
#include <linux/delay.h>
#include <linux/errno.h>
#include <linux/ptrace.h>
} dtl1_info_t;
-static void dtl1_config(struct pcmcia_device *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);
clear_bit(XMIT_WAKEUP, &(info->tx_state));
- if (!(info->p_dev->state & DEV_PRESENT))
+ if (!pcmcia_dev_present(info->p_dev))
return;
if (!(skb = skb_dequeue(&(info->txq))))
}
-static irqreturn_t dtl1_interrupt(int irq, void *dev_inst, struct pt_regs *regs)
+static irqreturn_t dtl1_interrupt(int irq, void *dev_inst)
{
dtl1_info_t *info = dev_inst;
unsigned int iobase;
unsigned char msr;
int boguscount = 0;
int iir, lsr;
+ irqreturn_t r = IRQ_NONE;
- if (!info || !info->hdev) {
- BT_ERR("Call of irq %d for unknown device", irq);
- return IRQ_NONE;
- }
+ BUG_ON(!info->hdev);
iobase = info->p_dev->io.BasePort1;
iir = inb(iobase + UART_IIR) & UART_IIR_ID;
while (iir) {
+ r = IRQ_HANDLED;
/* Clear interrupt */
lsr = inb(iobase + UART_LSR);
info->ri_latch = msr & UART_MSR_RI;
clear_bit(XMIT_WAITING, &(info->tx_state));
dtl1_write_wakeup(info);
+ r = IRQ_HANDLED;
}
spin_unlock(&(info->lock));
- return IRQ_HANDLED;
+ return r;
}
hdev->stat.sco_tx++;
nsh.type = 0x83;
break;
+ default:
+ return -EILSEQ;
};
nsh.zero = 0;
nsh.len = skb->len;
s = bt_skb_alloc(NSHL + skb->len + 1, GFP_ATOMIC);
+ if (!s)
+ return -ENOMEM;
+
skb_reserve(s, NSHL);
- memcpy(skb_put(s, skb->len), skb->data, skb->len);
+ skb_copy_from_linear_data(skb, skb_put(s, skb->len), skb->len);
if (skb->len & 0x0001)
*skb_put(s, 1) = 0; /* PAD */
hdev->type = HCI_PCCARD;
hdev->driver_data = info;
+ SET_HCIDEV_DEV(hdev, &info->p_dev->dev);
hdev->open = dtl1_hci_open;
hdev->close = dtl1_hci_close;
return 0;
}
-static int dtl1_attach(struct pcmcia_device *link)
+static int dtl1_probe(struct pcmcia_device *link)
{
dtl1_info_t *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.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
link->irq.Handler = dtl1_interrupt;
- link->irq.Instance = info;
link->conf.Attributes = CONF_ENABLE_IRQ;
link->conf.IntType = INT_MEMORY_AND_IO;
- link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
- dtl1_config(link);
-
- return 0;
+ return dtl1_config(link);
}
{
dtl1_info_t *info = link->priv;
- if (link->state & DEV_CONFIG)
- dtl1_release(link);
+ dtl1_release(link);
kfree(info);
}
-static int get_tuple(struct pcmcia_device *handle, tuple_t *tuple, cisparse_t *parse)
-{
- int i;
-
- i = pcmcia_get_tuple_data(handle, tuple);
- if (i != CS_SUCCESS)
- return i;
-
- return pcmcia_parse_tuple(handle, tuple, 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(struct pcmcia_device *handle, tuple_t *tuple, cisparse_t *parse)
+static int dtl1_confcheck(struct pcmcia_device *p_dev,
+ cistpl_cftable_entry_t *cf,
+ cistpl_cftable_entry_t *dflt,
+ unsigned int vcc,
+ void *priv_data)
{
- if (pcmcia_get_next_tuple(handle, tuple) != CS_SUCCESS)
- return CS_NO_MORE_ITEMS;
- return get_tuple(handle, tuple, parse);
+ if ((cf->io.nwin == 1) && (cf->io.win[0].len > 8)) {
+ p_dev->io.BasePort1 = cf->io.win[0].base;
+ p_dev->io.NumPorts1 = cf->io.win[0].len; /*yo */
+ p_dev->io.IOAddrLines = cf->io.flags & CISTPL_IO_LINES_MASK;
+ if (!pcmcia_request_io(p_dev, &p_dev->io))
+ return 0;
+ }
+ return -ENODEV;
}
-static void dtl1_config(struct pcmcia_device *link)
+static int dtl1_config(struct pcmcia_device *link)
{
dtl1_info_t *info = link->priv;
- tuple_t tuple;
- u_short buf[256];
- cisparse_t parse;
- cistpl_cftable_entry_t *cf = &parse.cftable_entry;
- int i, 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(link, &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];
-
- /* 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;
+ int i;
/* Look for a generic full-sized window */
link->io.NumPorts1 = 8;
- 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, &link->io);
- if (i == CS_SUCCESS)
- break;
- }
- i = next_tuple(link, &tuple, &parse);
- }
-
- if (i != CS_SUCCESS) {
- cs_error(link, RequestIO, i);
+ if (pcmcia_loop_config(link, dtl1_confcheck, NULL) < 0)
goto failed;
- }
i = pcmcia_request_irq(link, &link->irq);
- if (i != CS_SUCCESS) {
- cs_error(link, RequestIRQ, i);
+ if (i != 0)
link->irq.AssignedIRQ = 0;
- }
i = pcmcia_request_configuration(link, &link->conf);
- if (i != CS_SUCCESS) {
- cs_error(link, RequestConfiguration, i);
+ if (i != 0)
goto failed;
- }
if (dtl1_open(info) != 0)
goto failed;
strcpy(info->node.dev_name, info->hdev->name);
link->dev_node = &info->node;
- link->state &= ~DEV_CONFIG_PENDING;
-
- return;
-cs_failed:
- cs_error(link, last_fn, last_ret);
+ return 0;
failed:
dtl1_release(link);
+ return -ENODEV;
}
{
dtl1_info_t *info = link->priv;
- if (link->state & DEV_PRESENT)
- dtl1_close(info);
+ dtl1_close(info);
pcmcia_disable_device(link);
}
static struct pcmcia_device_id dtl1_ids[] = {
PCMCIA_DEVICE_PROD_ID12("Nokia Mobile Phones", "DTL-1", 0xe1bfdd64, 0xe168480d),
+ PCMCIA_DEVICE_PROD_ID12("Nokia Mobile Phones", "DTL-4", 0xe1bfdd64, 0x9102bc82),
PCMCIA_DEVICE_PROD_ID12("Socket", "CF", 0xb38bcc2e, 0x44ebf863),
PCMCIA_DEVICE_PROD_ID12("Socket", "CF+ Personal Network Card", 0xb38bcc2e, 0xe732bae3),
PCMCIA_DEVICE_NULL
.drv = {
.name = "dtl1_cs",
},
- .probe = dtl1_attach,
+ .probe = dtl1_probe,
.remove = dtl1_detach,
.id_table = dtl1_ids,
};