dtl1_cs.c
上传用户:jlfgdled
上传日期:2013-04-10
资源大小:33168k
文件大小:18k
源码类别:

Linux/Unix编程

开发平台:

Unix_Linux

  1. /*
  2.  *
  3.  *  A driver for Nokia Connectivity Card DTL-1 devices
  4.  *
  5.  *  Copyright (C) 2001-2002  Marcel Holtmann <marcel@holtmann.org>
  6.  *
  7.  *
  8.  *  This program is free software; you can redistribute it and/or modify
  9.  *  it under the terms of the GNU General Public License version 2 as
  10.  *  published by the Free Software Foundation;
  11.  *
  12.  *  Software distributed under the License is distributed on an "AS
  13.  *  IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
  14.  *  implied. See the License for the specific language governing
  15.  *  rights and limitations under the License.
  16.  *
  17.  *  The initial developer of the original code is David A. Hinds
  18.  *  <dahinds@users.sourceforge.net>.  Portions created by David A. Hinds
  19.  *  are Copyright (C) 1999 David A. Hinds.  All Rights Reserved.
  20.  *
  21.  */
  22. #include <linux/config.h>
  23. #include <linux/module.h>
  24. #include <linux/kernel.h>
  25. #include <linux/init.h>
  26. #include <linux/slab.h>
  27. #include <linux/types.h>
  28. #include <linux/sched.h>
  29. #include <linux/timer.h>
  30. #include <linux/errno.h>
  31. #include <linux/ptrace.h>
  32. #include <linux/ioport.h>
  33. #include <linux/spinlock.h>
  34. #include <linux/skbuff.h>
  35. #include <linux/string.h>
  36. #include <linux/serial.h>
  37. #include <linux/serial_reg.h>
  38. #include <asm/system.h>
  39. #include <asm/bitops.h>
  40. #include <asm/io.h>
  41. #include <pcmcia/version.h>
  42. #include <pcmcia/cs_types.h>
  43. #include <pcmcia/cs.h>
  44. #include <pcmcia/cistpl.h>
  45. #include <pcmcia/ciscode.h>
  46. #include <pcmcia/ds.h>
  47. #include <pcmcia/cisreg.h>
  48. #include <net/bluetooth/bluetooth.h>
  49. #include <net/bluetooth/hci_core.h>
  50. /* ======================== Module parameters ======================== */
  51. /* Bit map of interrupts to choose from */
  52. static u_int irq_mask = 0xffff;
  53. static int irq_list[4] = { -1 };
  54. MODULE_PARM(irq_mask, "i");
  55. MODULE_PARM(irq_list, "1-4i");
  56. MODULE_AUTHOR("Marcel Holtmann <marcel@holtmann.org>");
  57. MODULE_DESCRIPTION("BlueZ driver for Nokia Connectivity Card DTL-1");
  58. MODULE_LICENSE("GPL");
  59. /* ======================== Local structures ======================== */
  60. typedef struct dtl1_info_t {
  61. dev_link_t link;
  62. dev_node_t node;
  63. struct hci_dev hdev;
  64. spinlock_t lock; /* For serializing operations */
  65. unsigned long flowmask; /* HCI flow mask */
  66. int ri_latch;
  67. struct sk_buff_head txq;
  68. unsigned long tx_state;
  69. unsigned long rx_state;
  70. unsigned long rx_count;
  71. struct sk_buff *rx_skb;
  72. } dtl1_info_t;
  73. void dtl1_config(dev_link_t *link);
  74. void dtl1_release(u_long arg);
  75. int dtl1_event(event_t event, int priority, event_callback_args_t *args);
  76. static dev_info_t dev_info = "dtl1_cs";
  77. dev_link_t *dtl1_attach(void);
  78. void dtl1_detach(dev_link_t *);
  79. static dev_link_t *dev_list = NULL;
  80. /* Transmit states  */
  81. #define XMIT_SENDING  1
  82. #define XMIT_WAKEUP   2
  83. #define XMIT_WAITING  8
  84. /* Receiver States */
  85. #define RECV_WAIT_NSH   0
  86. #define RECV_WAIT_DATA  1
  87. typedef struct {
  88. u8 type;
  89. u8 zero;
  90. u16 len;
  91. } __attribute__ ((packed)) nsh_t; /* Nokia Specific Header */
  92. #define NSHL  4 /* Nokia Specific Header Length */
  93. /* ======================== Interrupt handling ======================== */
  94. static int dtl1_write(unsigned int iobase, int fifo_size, __u8 *buf, int len)
  95. {
  96. int actual = 0;
  97. /* Tx FIFO should be empty */
  98. if (!(inb(iobase + UART_LSR) & UART_LSR_THRE))
  99. return 0;
  100. /* Fill FIFO with current frame */
  101. while ((fifo_size-- > 0) && (actual < len)) {
  102. /* Transmit next byte */
  103. outb(buf[actual], iobase + UART_TX);
  104. actual++;
  105. }
  106. return actual;
  107. }
  108. static void dtl1_write_wakeup(dtl1_info_t *info)
  109. {
  110. if (!info) {
  111. printk(KERN_WARNING "dtl1_cs: Call of write_wakeup for unknown device.n");
  112. return;
  113. }
  114. if (test_bit(XMIT_WAITING, &(info->tx_state))) {
  115. set_bit(XMIT_WAKEUP, &(info->tx_state));
  116. return;
  117. }
  118. if (test_and_set_bit(XMIT_SENDING, &(info->tx_state))) {
  119. set_bit(XMIT_WAKEUP, &(info->tx_state));
  120. return;
  121. }
  122. do {
  123. register unsigned int iobase = info->link.io.BasePort1;
  124. register struct sk_buff *skb;
  125. register int len;
  126. clear_bit(XMIT_WAKEUP, &(info->tx_state));
  127. if (!(info->link.state & DEV_PRESENT))
  128. return;
  129. if (!(skb = skb_dequeue(&(info->txq))))
  130. break;
  131. /* Send frame */
  132. len = dtl1_write(iobase, 32, skb->data, skb->len);
  133. if (len == skb->len) {
  134. set_bit(XMIT_WAITING, &(info->tx_state));
  135. kfree_skb(skb);
  136. } else {
  137. skb_pull(skb, len);
  138. skb_queue_head(&(info->txq), skb);
  139. }
  140. info->hdev.stat.byte_tx += len;
  141. } while (test_bit(XMIT_WAKEUP, &(info->tx_state)));
  142. clear_bit(XMIT_SENDING, &(info->tx_state));
  143. }
  144. static void dtl1_control(dtl1_info_t *info, struct sk_buff *skb)
  145. {
  146. u8 flowmask = *(u8 *)skb->data;
  147. int i;
  148. printk(KERN_INFO "dtl1_cs: Nokia control data = ");
  149. for (i = 0; i < skb->len; i++) {
  150. printk("%02x ", skb->data[i]);
  151. }
  152. printk("n");
  153. /* transition to active state */
  154. if (((info->flowmask & 0x07) == 0) && ((flowmask & 0x07) != 0)) {
  155. clear_bit(XMIT_WAITING, &(info->tx_state));
  156. dtl1_write_wakeup(info);
  157. }
  158. info->flowmask = flowmask;
  159. kfree_skb(skb);
  160. }
  161. static void dtl1_receive(dtl1_info_t *info)
  162. {
  163. unsigned int iobase;
  164. nsh_t *nsh;
  165. int boguscount = 0;
  166. if (!info) {
  167. printk(KERN_WARNING "dtl1_cs: Call of receive for unknown device.n");
  168. return;
  169. }
  170. iobase = info->link.io.BasePort1;
  171. do {
  172. info->hdev.stat.byte_rx++;
  173. /* Allocate packet */
  174. if (info->rx_skb == NULL)
  175. if (!(info->rx_skb = bluez_skb_alloc(HCI_MAX_FRAME_SIZE, GFP_ATOMIC))) {
  176. printk(KERN_WARNING "dtl1_cs: Can't allocate mem for new packet.n");
  177. info->rx_state = RECV_WAIT_NSH;
  178. info->rx_count = NSHL;
  179. return;
  180. }
  181. *skb_put(info->rx_skb, 1) = inb(iobase + UART_RX);
  182. nsh = (nsh_t *)info->rx_skb->data;
  183. info->rx_count--;
  184. if (info->rx_count == 0) {
  185. switch (info->rx_state) {
  186. case RECV_WAIT_NSH:
  187. info->rx_state = RECV_WAIT_DATA;
  188. info->rx_count = nsh->len + (nsh->len & 0x0001);
  189. break;
  190. case RECV_WAIT_DATA:
  191. info->rx_skb->pkt_type = nsh->type;
  192. /* remove PAD byte if it exists */
  193. if (nsh->len & 0x0001) {
  194. info->rx_skb->tail--;
  195. info->rx_skb->len--;
  196. }
  197. /* remove NSH */
  198. skb_pull(info->rx_skb, NSHL);
  199. switch (info->rx_skb->pkt_type) {
  200. case 0x80:
  201. /* control data for the Nokia Card */
  202. dtl1_control(info, info->rx_skb);
  203. break;
  204. case 0x82:
  205. case 0x83:
  206. case 0x84:
  207. /* send frame to the HCI layer */
  208. info->rx_skb->dev = (void *)&(info->hdev);
  209. info->rx_skb->pkt_type &= 0x0f;
  210. hci_recv_frame(info->rx_skb);
  211. break;
  212. default:
  213. /* unknown packet */
  214. printk(KERN_WARNING "dtl1_cs: Unknown HCI packet with type 0x%02x received.n", info->rx_skb->pkt_type);
  215. kfree_skb(info->rx_skb);
  216. break;
  217. }
  218. info->rx_state = RECV_WAIT_NSH;
  219. info->rx_count = NSHL;
  220. info->rx_skb = NULL;
  221. break;
  222. }
  223. }
  224. /* Make sure we don't stay here to long */
  225. if (boguscount++ > 32)
  226. break;
  227. } while (inb(iobase + UART_LSR) & UART_LSR_DR);
  228. }
  229. void dtl1_interrupt(int irq, void *dev_inst, struct pt_regs *regs)
  230. {
  231. dtl1_info_t *info = dev_inst;
  232. unsigned int iobase;
  233. unsigned char msr;
  234. int boguscount = 0;
  235. int iir, lsr;
  236. if (!info) {
  237. printk(KERN_WARNING "dtl1_cs: Call of irq %d for unknown device.n", irq);
  238. return;
  239. }
  240. iobase = info->link.io.BasePort1;
  241. spin_lock(&(info->lock));
  242. iir = inb(iobase + UART_IIR) & UART_IIR_ID;
  243. while (iir) {
  244. /* Clear interrupt */
  245. lsr = inb(iobase + UART_LSR);
  246. switch (iir) {
  247. case UART_IIR_RLSI:
  248. printk(KERN_NOTICE "dtl1_cs: RLSIn");
  249. break;
  250. case UART_IIR_RDI:
  251. /* Receive interrupt */
  252. dtl1_receive(info);
  253. break;
  254. case UART_IIR_THRI:
  255. if (lsr & UART_LSR_THRE) {
  256. /* Transmitter ready for data */
  257. dtl1_write_wakeup(info);
  258. }
  259. break;
  260. default:
  261. printk(KERN_NOTICE "dtl1_cs: Unhandled IIR=%#xn", iir);
  262. break;
  263. }
  264. /* Make sure we don't stay here to long */
  265. if (boguscount++ > 100)
  266. break;
  267. iir = inb(iobase + UART_IIR) & UART_IIR_ID;
  268. }
  269. msr = inb(iobase + UART_MSR);
  270. if (info->ri_latch ^ (msr & UART_MSR_RI)) {
  271. info->ri_latch = msr & UART_MSR_RI;
  272. clear_bit(XMIT_WAITING, &(info->tx_state));
  273. dtl1_write_wakeup(info);
  274. }
  275. spin_unlock(&(info->lock));
  276. }
  277. /* ======================== HCI interface ======================== */
  278. static int dtl1_hci_open(struct hci_dev *hdev)
  279. {
  280. set_bit(HCI_RUNNING, &(hdev->flags));
  281. return 0;
  282. }
  283. static int dtl1_hci_flush(struct hci_dev *hdev)
  284. {
  285. dtl1_info_t *info = (dtl1_info_t *)(hdev->driver_data);
  286. /* Drop TX queue */
  287. skb_queue_purge(&(info->txq));
  288. return 0;
  289. }
  290. static int dtl1_hci_close(struct hci_dev *hdev)
  291. {
  292. if (!test_and_clear_bit(HCI_RUNNING, &(hdev->flags)))
  293. return 0;
  294. dtl1_hci_flush(hdev);
  295. return 0;
  296. }
  297. static int dtl1_hci_send_frame(struct sk_buff *skb)
  298. {
  299. dtl1_info_t *info;
  300. struct hci_dev *hdev = (struct hci_dev *)(skb->dev);
  301. struct sk_buff *s;
  302. nsh_t nsh;
  303. if (!hdev) {
  304. printk(KERN_WARNING "dtl1_cs: Frame for unknown HCI device (hdev=NULL).");
  305. return -ENODEV;
  306. }
  307. info = (dtl1_info_t *)(hdev->driver_data);
  308. switch (skb->pkt_type) {
  309. case HCI_COMMAND_PKT:
  310. hdev->stat.cmd_tx++;
  311. nsh.type = 0x81;
  312. break;
  313. case HCI_ACLDATA_PKT:
  314. hdev->stat.acl_tx++;
  315. nsh.type = 0x82;
  316. break;
  317. case HCI_SCODATA_PKT:
  318. hdev->stat.sco_tx++;
  319. nsh.type = 0x83;
  320. break;
  321. };
  322. nsh.zero = 0;
  323. nsh.len = skb->len;
  324. s = bluez_skb_alloc(NSHL + skb->len + 1, GFP_ATOMIC);
  325. skb_reserve(s, NSHL);
  326. memcpy(skb_put(s, skb->len), skb->data, skb->len);
  327. if (skb->len & 0x0001)
  328. *skb_put(s, 1) = 0; /* PAD */
  329. /* Prepend skb with Nokia frame header and queue */
  330. memcpy(skb_push(s, NSHL), &nsh, NSHL);
  331. skb_queue_tail(&(info->txq), s);
  332. dtl1_write_wakeup(info);
  333. kfree_skb(skb);
  334. return 0;
  335. }
  336. static void dtl1_hci_destruct(struct hci_dev *hdev)
  337. {
  338. }
  339. static int dtl1_hci_ioctl(struct hci_dev *hdev, unsigned int cmd,  unsigned long arg)
  340. {
  341. return -ENOIOCTLCMD;
  342. }
  343. /* ======================== Card services HCI interaction ======================== */
  344. int dtl1_open(dtl1_info_t *info)
  345. {
  346. unsigned long flags;
  347. unsigned int iobase = info->link.io.BasePort1;
  348. struct hci_dev *hdev;
  349. spin_lock_init(&(info->lock));
  350. skb_queue_head_init(&(info->txq));
  351. info->rx_state = RECV_WAIT_NSH;
  352. info->rx_count = NSHL;
  353. info->rx_skb = NULL;
  354. set_bit(XMIT_WAITING, &(info->tx_state));
  355. spin_lock_irqsave(&(info->lock), flags);
  356. /* Reset UART */
  357. outb(0, iobase + UART_MCR);
  358. /* Turn off interrupts */
  359. outb(0, iobase + UART_IER);
  360. /* Initialize UART */
  361. outb(UART_LCR_WLEN8, iobase + UART_LCR); /* Reset DLAB */
  362. outb((UART_MCR_DTR | UART_MCR_RTS | UART_MCR_OUT2), iobase + UART_MCR);
  363. info->ri_latch = inb(info->link.io.BasePort1 + UART_MSR) & UART_MSR_RI;
  364. /* Turn on interrupts */
  365. outb(UART_IER_RLSI | UART_IER_RDI | UART_IER_THRI, iobase + UART_IER);
  366. spin_unlock_irqrestore(&(info->lock), flags);
  367. /* Timeout before it is safe to send the first HCI packet */
  368. set_current_state(TASK_INTERRUPTIBLE);
  369. schedule_timeout(HZ * 2);
  370. /* Initialize and register HCI device */
  371. hdev = &(info->hdev);
  372. hdev->type = HCI_PCCARD;
  373. hdev->driver_data = info;
  374. hdev->open = dtl1_hci_open;
  375. hdev->close = dtl1_hci_close;
  376. hdev->flush = dtl1_hci_flush;
  377. hdev->send = dtl1_hci_send_frame;
  378. hdev->destruct = dtl1_hci_destruct;
  379. hdev->ioctl = dtl1_hci_ioctl;
  380. if (hci_register_dev(hdev) < 0) {
  381. printk(KERN_WARNING "dtl1_cs: Can't register HCI device %s.n", hdev->name);
  382. return -ENODEV;
  383. }
  384. return 0;
  385. }
  386. int dtl1_close(dtl1_info_t *info)
  387. {
  388. unsigned long flags;
  389. unsigned int iobase = info->link.io.BasePort1;
  390. struct hci_dev *hdev = &(info->hdev);
  391. dtl1_hci_close(hdev);
  392. spin_lock_irqsave(&(info->lock), flags);
  393. /* Reset UART */
  394. outb(0, iobase + UART_MCR);
  395. /* Turn off interrupts */
  396. outb(0, iobase + UART_IER);
  397. spin_unlock_irqrestore(&(info->lock), flags);
  398. if (hci_unregister_dev(hdev) < 0)
  399. printk(KERN_WARNING "dtl1_cs: Can't unregister HCI device %s.n", hdev->name);
  400. return 0;
  401. }
  402. /* ======================== Card services ======================== */
  403. static void cs_error(client_handle_t handle, int func, int ret)
  404. {
  405. error_info_t err = { func, ret };
  406. CardServices(ReportError, handle, &err);
  407. }
  408. dev_link_t *dtl1_attach(void)
  409. {
  410. dtl1_info_t *info;
  411. client_reg_t client_reg;
  412. dev_link_t *link;
  413. int i, ret;
  414. /* Create new info device */
  415. info = kmalloc(sizeof(*info), GFP_KERNEL);
  416. if (!info)
  417. return NULL;
  418. memset(info, 0, sizeof(*info));
  419. link = &info->link;
  420. link->priv = info;
  421. link->release.function = &dtl1_release;
  422. link->release.data = (u_long)link;
  423. link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
  424. link->io.NumPorts1 = 8;
  425. link->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_HANDLE_PRESENT;
  426. link->irq.IRQInfo1 = IRQ_INFO2_VALID | IRQ_LEVEL_ID;
  427. if (irq_list[0] == -1)
  428. link->irq.IRQInfo2 = irq_mask;
  429. else
  430. for (i = 0; i < 4; i++)
  431. link->irq.IRQInfo2 |= 1 << irq_list[i];
  432. link->irq.Handler = dtl1_interrupt;
  433. link->irq.Instance = info;
  434. link->conf.Attributes = CONF_ENABLE_IRQ;
  435. link->conf.Vcc = 50;
  436. link->conf.IntType = INT_MEMORY_AND_IO;
  437. /* Register with Card Services */
  438. link->next = dev_list;
  439. dev_list = link;
  440. client_reg.dev_info = &dev_info;
  441. client_reg.Attributes = INFO_IO_CLIENT | INFO_CARD_SHARE;
  442. client_reg.EventMask =
  443. CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL |
  444. CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET |
  445. CS_EVENT_PM_SUSPEND | CS_EVENT_PM_RESUME;
  446. client_reg.event_handler = &dtl1_event;
  447. client_reg.Version = 0x0210;
  448. client_reg.event_callback_args.client_data = link;
  449. ret = CardServices(RegisterClient, &link->handle, &client_reg);
  450. if (ret != CS_SUCCESS) {
  451. cs_error(link->handle, RegisterClient, ret);
  452. dtl1_detach(link);
  453. return NULL;
  454. }
  455. return link;
  456. }
  457. void dtl1_detach(dev_link_t *link)
  458. {
  459. dtl1_info_t *info = link->priv;
  460. dev_link_t **linkp;
  461. int ret;
  462. /* Locate device structure */
  463. for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next)
  464. if (*linkp == link)
  465. break;
  466. if (*linkp == NULL)
  467. return;
  468. del_timer(&link->release);
  469. if (link->state & DEV_CONFIG)
  470. dtl1_release((u_long)link);
  471. if (link->handle) {
  472. ret = CardServices(DeregisterClient, link->handle);
  473. if (ret != CS_SUCCESS)
  474. cs_error(link->handle, DeregisterClient, ret);
  475. }
  476. /* Unlink device structure, free bits */
  477. *linkp = link->next;
  478. kfree(info);
  479. }
  480. static int get_tuple(int fn, client_handle_t handle, tuple_t *tuple, cisparse_t *parse)
  481. {
  482. int i;
  483. i = CardServices(fn, handle, tuple);
  484. if (i != CS_SUCCESS)
  485. return CS_NO_MORE_ITEMS;
  486. i = CardServices(GetTupleData, handle, tuple);
  487. if (i != CS_SUCCESS)
  488. return i;
  489. return CardServices(ParseTuple, handle, tuple, parse);
  490. }
  491. #define first_tuple(a, b, c) get_tuple(GetFirstTuple, a, b, c)
  492. #define next_tuple(a, b, c) get_tuple(GetNextTuple, a, b, c)
  493. void dtl1_config(dev_link_t *link)
  494. {
  495. client_handle_t handle = link->handle;
  496. dtl1_info_t *info = link->priv;
  497. tuple_t tuple;
  498. u_short buf[256];
  499. cisparse_t parse;
  500. cistpl_cftable_entry_t *cf = &parse.cftable_entry;
  501. config_info_t config;
  502. int i, last_ret, last_fn;
  503. tuple.TupleData = (cisdata_t *)buf;
  504. tuple.TupleOffset = 0;
  505. tuple.TupleDataMax = 255;
  506. tuple.Attributes = 0;
  507. /* Get configuration register information */
  508. tuple.DesiredTuple = CISTPL_CONFIG;
  509. last_ret = first_tuple(handle, &tuple, &parse);
  510. if (last_ret != CS_SUCCESS) {
  511. last_fn = ParseTuple;
  512. goto cs_failed;
  513. }
  514. link->conf.ConfigBase = parse.config.base;
  515. link->conf.Present = parse.config.rmask[0];
  516. /* Configure card */
  517. link->state |= DEV_CONFIG;
  518. i = CardServices(GetConfigurationInfo, handle, &config);
  519. link->conf.Vcc = config.Vcc;
  520. tuple.TupleData = (cisdata_t *)buf;
  521. tuple.TupleOffset = 0;
  522. tuple.TupleDataMax = 255;
  523. tuple.Attributes = 0;
  524. tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
  525. /* Look for a generic full-sized window */
  526. link->io.NumPorts1 = 8;
  527. i = first_tuple(handle, &tuple, &parse);
  528. while (i != CS_NO_MORE_ITEMS) {
  529. if ((i == CS_SUCCESS) && (cf->io.nwin == 1) && (cf->io.win[0].len > 8)) {
  530. link->conf.ConfigIndex = cf->index;
  531. link->io.BasePort1 = cf->io.win[0].base;
  532. link->io.NumPorts1 = cf->io.win[0].len; /*yo */
  533. link->io.IOAddrLines = cf->io.flags & CISTPL_IO_LINES_MASK;
  534. i = CardServices(RequestIO, link->handle, &link->io);
  535. if (i == CS_SUCCESS)
  536. break;
  537. }
  538. i = next_tuple(handle, &tuple, &parse);
  539. }
  540. if (i != CS_SUCCESS) {
  541. cs_error(link->handle, RequestIO, i);
  542. goto failed;
  543. }
  544. i = CardServices(RequestIRQ, link->handle, &link->irq);
  545. if (i != CS_SUCCESS) {
  546. cs_error(link->handle, RequestIRQ, i);
  547. link->irq.AssignedIRQ = 0;
  548. }
  549. i = CardServices(RequestConfiguration, link->handle, &link->conf);
  550. if (i != CS_SUCCESS) {
  551. cs_error(link->handle, RequestConfiguration, i);
  552. goto failed;
  553. }
  554. MOD_INC_USE_COUNT;
  555. if (dtl1_open(info) != 0)
  556. goto failed;
  557. strcpy(info->node.dev_name, info->hdev.name);
  558. link->dev = &info->node;
  559. link->state &= ~DEV_CONFIG_PENDING;
  560. return;
  561. cs_failed:
  562. cs_error(link->handle, last_fn, last_ret);
  563. failed:
  564. dtl1_release((u_long)link);
  565. }
  566. void dtl1_release(u_long arg)
  567. {
  568. dev_link_t *link = (dev_link_t *)arg;
  569. dtl1_info_t *info = link->priv;
  570. if (link->state & DEV_PRESENT)
  571. dtl1_close(info);
  572. MOD_DEC_USE_COUNT;
  573. link->dev = NULL;
  574. CardServices(ReleaseConfiguration, link->handle);
  575. CardServices(ReleaseIO, link->handle, &link->io);
  576. CardServices(ReleaseIRQ, link->handle, &link->irq);
  577. link->state &= ~DEV_CONFIG;
  578. }
  579. int dtl1_event(event_t event, int priority, event_callback_args_t *args)
  580. {
  581. dev_link_t *link = args->client_data;
  582. dtl1_info_t *info = link->priv;
  583. switch (event) {
  584. case CS_EVENT_CARD_REMOVAL:
  585. link->state &= ~DEV_PRESENT;
  586. if (link->state & DEV_CONFIG) {
  587. dtl1_close(info);
  588. mod_timer(&link->release, jiffies + HZ / 20);
  589. }
  590. break;
  591. case CS_EVENT_CARD_INSERTION:
  592. link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
  593. dtl1_config(link);
  594. break;
  595. case CS_EVENT_PM_SUSPEND:
  596. link->state |= DEV_SUSPEND;
  597. /* Fall through... */
  598. case CS_EVENT_RESET_PHYSICAL:
  599. if (link->state & DEV_CONFIG)
  600. CardServices(ReleaseConfiguration, link->handle);
  601. break;
  602. case CS_EVENT_PM_RESUME:
  603. link->state &= ~DEV_SUSPEND;
  604. /* Fall through... */
  605. case CS_EVENT_CARD_RESET:
  606. if (DEV_OK(link))
  607. CardServices(RequestConfiguration, link->handle, &link->conf);
  608. break;
  609. }
  610. return 0;
  611. }
  612. /* ======================== Module initialization ======================== */
  613. int __init init_dtl1_cs(void)
  614. {
  615. servinfo_t serv;
  616. int err;
  617. CardServices(GetCardServicesInfo, &serv);
  618. if (serv.Revision != CS_RELEASE_CODE) {
  619. printk(KERN_NOTICE "dtl1_cs: Card Services release does not match!n");
  620. return -1;
  621. }
  622. err = register_pccard_driver(&dev_info, &dtl1_attach, &dtl1_detach);
  623. return err;
  624. }
  625. void __exit exit_dtl1_cs(void)
  626. {
  627. unregister_pccard_driver(&dev_info);
  628. while (dev_list != NULL)
  629. dtl1_detach(dev_list);
  630. }
  631. module_init(init_dtl1_cs);
  632. module_exit(exit_dtl1_cs);
  633. EXPORT_NO_SYMBOLS;