drivers.c 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864
  1. /*
  2. module/drivers.c
  3. functions for manipulating drivers
  4. COMEDI - Linux Control and Measurement Device Interface
  5. Copyright (C) 1997-2000 David A. Schleef <ds@schleef.org>
  6. Copyright (C) 2002 Frank Mori Hess <fmhess@users.sourceforge.net>
  7. This program is free software; you can redistribute it and/or modify
  8. it under the terms of the GNU General Public License as published by
  9. the Free Software Foundation; either version 2 of the License, or
  10. (at your option) any later version.
  11. This program is distributed in the hope that it will be useful,
  12. but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. GNU General Public License for more details.
  15. */
  16. #include <linux/device.h>
  17. #include <linux/module.h>
  18. #include <linux/errno.h>
  19. #include <linux/kconfig.h>
  20. #include <linux/kernel.h>
  21. #include <linux/sched.h>
  22. #include <linux/fcntl.h>
  23. #include <linux/ioport.h>
  24. #include <linux/mm.h>
  25. #include <linux/slab.h>
  26. #include <linux/highmem.h> /* for SuSE brokenness */
  27. #include <linux/vmalloc.h>
  28. #include <linux/cdev.h>
  29. #include <linux/dma-mapping.h>
  30. #include <linux/io.h>
  31. #include <linux/interrupt.h>
  32. #include <linux/firmware.h>
  33. #include "comedidev.h"
  34. #include "comedi_internal.h"
  35. struct comedi_driver *comedi_drivers;
  36. /* protects access to comedi_drivers */
  37. DEFINE_MUTEX(comedi_drivers_list_lock);
  38. int comedi_set_hw_dev(struct comedi_device *dev, struct device *hw_dev)
  39. {
  40. if (hw_dev == dev->hw_dev)
  41. return 0;
  42. if (dev->hw_dev != NULL)
  43. return -EEXIST;
  44. dev->hw_dev = get_device(hw_dev);
  45. return 0;
  46. }
  47. EXPORT_SYMBOL_GPL(comedi_set_hw_dev);
  48. static void comedi_clear_hw_dev(struct comedi_device *dev)
  49. {
  50. put_device(dev->hw_dev);
  51. dev->hw_dev = NULL;
  52. }
  53. /**
  54. * comedi_alloc_devpriv() - Allocate memory for the device private data.
  55. * @dev: comedi_device struct
  56. * @size: size of the memory to allocate
  57. */
  58. void *comedi_alloc_devpriv(struct comedi_device *dev, size_t size)
  59. {
  60. dev->private = kzalloc(size, GFP_KERNEL);
  61. return dev->private;
  62. }
  63. EXPORT_SYMBOL_GPL(comedi_alloc_devpriv);
  64. int comedi_alloc_subdevices(struct comedi_device *dev, int num_subdevices)
  65. {
  66. struct comedi_subdevice *s;
  67. int i;
  68. if (num_subdevices < 1)
  69. return -EINVAL;
  70. s = kcalloc(num_subdevices, sizeof(*s), GFP_KERNEL);
  71. if (!s)
  72. return -ENOMEM;
  73. dev->subdevices = s;
  74. dev->n_subdevices = num_subdevices;
  75. for (i = 0; i < num_subdevices; ++i) {
  76. s = &dev->subdevices[i];
  77. s->device = dev;
  78. s->index = i;
  79. s->async_dma_dir = DMA_NONE;
  80. spin_lock_init(&s->spin_lock);
  81. s->minor = -1;
  82. }
  83. return 0;
  84. }
  85. EXPORT_SYMBOL_GPL(comedi_alloc_subdevices);
  86. /**
  87. * comedi_alloc_subdev_readback() - Allocate memory for the subdevice readback.
  88. * @s: comedi_subdevice struct
  89. */
  90. int comedi_alloc_subdev_readback(struct comedi_subdevice *s)
  91. {
  92. if (!s->n_chan)
  93. return -EINVAL;
  94. s->readback = kcalloc(s->n_chan, sizeof(*s->readback), GFP_KERNEL);
  95. if (!s->readback)
  96. return -ENOMEM;
  97. return 0;
  98. }
  99. EXPORT_SYMBOL_GPL(comedi_alloc_subdev_readback);
  100. static void comedi_device_detach_cleanup(struct comedi_device *dev)
  101. {
  102. int i;
  103. struct comedi_subdevice *s;
  104. if (dev->subdevices) {
  105. for (i = 0; i < dev->n_subdevices; i++) {
  106. s = &dev->subdevices[i];
  107. if (s->runflags & SRF_FREE_SPRIV)
  108. kfree(s->private);
  109. comedi_free_subdevice_minor(s);
  110. if (s->async) {
  111. comedi_buf_alloc(dev, s, 0);
  112. kfree(s->async);
  113. }
  114. kfree(s->readback);
  115. }
  116. kfree(dev->subdevices);
  117. dev->subdevices = NULL;
  118. dev->n_subdevices = 0;
  119. }
  120. kfree(dev->private);
  121. dev->private = NULL;
  122. dev->driver = NULL;
  123. dev->board_name = NULL;
  124. dev->board_ptr = NULL;
  125. dev->mmio = NULL;
  126. dev->iobase = 0;
  127. dev->iolen = 0;
  128. dev->ioenabled = false;
  129. dev->irq = 0;
  130. dev->read_subdev = NULL;
  131. dev->write_subdev = NULL;
  132. dev->open = NULL;
  133. dev->close = NULL;
  134. comedi_clear_hw_dev(dev);
  135. }
  136. void comedi_device_detach(struct comedi_device *dev)
  137. {
  138. comedi_device_cancel_all(dev);
  139. down_write(&dev->attach_lock);
  140. dev->attached = false;
  141. dev->detach_count++;
  142. if (dev->driver)
  143. dev->driver->detach(dev);
  144. comedi_device_detach_cleanup(dev);
  145. up_write(&dev->attach_lock);
  146. }
  147. static int poll_invalid(struct comedi_device *dev, struct comedi_subdevice *s)
  148. {
  149. return -EINVAL;
  150. }
  151. int insn_inval(struct comedi_device *dev, struct comedi_subdevice *s,
  152. struct comedi_insn *insn, unsigned int *data)
  153. {
  154. return -EINVAL;
  155. }
  156. /**
  157. * comedi_readback_insn_read() - A generic (*insn_read) for subdevice readback.
  158. * @dev: comedi_device struct
  159. * @s: comedi_subdevice struct
  160. * @insn: comedi_insn struct
  161. * @data: pointer to return the readback data
  162. */
  163. int comedi_readback_insn_read(struct comedi_device *dev,
  164. struct comedi_subdevice *s,
  165. struct comedi_insn *insn,
  166. unsigned int *data)
  167. {
  168. unsigned int chan = CR_CHAN(insn->chanspec);
  169. int i;
  170. if (!s->readback)
  171. return -EINVAL;
  172. for (i = 0; i < insn->n; i++)
  173. data[i] = s->readback[chan];
  174. return insn->n;
  175. }
  176. EXPORT_SYMBOL_GPL(comedi_readback_insn_read);
  177. /**
  178. * comedi_timeout() - busy-wait for a driver condition to occur.
  179. * @dev: comedi_device struct
  180. * @s: comedi_subdevice struct
  181. * @insn: comedi_insn struct
  182. * @cb: callback to check for the condition
  183. * @context: private context from the driver
  184. */
  185. int comedi_timeout(struct comedi_device *dev,
  186. struct comedi_subdevice *s,
  187. struct comedi_insn *insn,
  188. int (*cb)(struct comedi_device *dev,
  189. struct comedi_subdevice *s,
  190. struct comedi_insn *insn,
  191. unsigned long context),
  192. unsigned long context)
  193. {
  194. unsigned long timeout = jiffies + msecs_to_jiffies(COMEDI_TIMEOUT_MS);
  195. int ret;
  196. while (time_before(jiffies, timeout)) {
  197. ret = cb(dev, s, insn, context);
  198. if (ret != -EBUSY)
  199. return ret; /* success (0) or non EBUSY errno */
  200. cpu_relax();
  201. }
  202. return -ETIMEDOUT;
  203. }
  204. EXPORT_SYMBOL_GPL(comedi_timeout);
  205. /**
  206. * comedi_dio_insn_config() - boilerplate (*insn_config) for DIO subdevices.
  207. * @dev: comedi_device struct
  208. * @s: comedi_subdevice struct
  209. * @insn: comedi_insn struct
  210. * @data: parameters for the @insn
  211. * @mask: io_bits mask for grouped channels
  212. */
  213. int comedi_dio_insn_config(struct comedi_device *dev,
  214. struct comedi_subdevice *s,
  215. struct comedi_insn *insn,
  216. unsigned int *data,
  217. unsigned int mask)
  218. {
  219. unsigned int chan_mask = 1 << CR_CHAN(insn->chanspec);
  220. if (!mask)
  221. mask = chan_mask;
  222. switch (data[0]) {
  223. case INSN_CONFIG_DIO_INPUT:
  224. s->io_bits &= ~mask;
  225. break;
  226. case INSN_CONFIG_DIO_OUTPUT:
  227. s->io_bits |= mask;
  228. break;
  229. case INSN_CONFIG_DIO_QUERY:
  230. data[1] = (s->io_bits & mask) ? COMEDI_OUTPUT : COMEDI_INPUT;
  231. return insn->n;
  232. default:
  233. return -EINVAL;
  234. }
  235. return 0;
  236. }
  237. EXPORT_SYMBOL_GPL(comedi_dio_insn_config);
  238. /**
  239. * comedi_dio_update_state() - update the internal state of DIO subdevices.
  240. * @s: comedi_subdevice struct
  241. * @data: the channel mask and bits to update
  242. */
  243. unsigned int comedi_dio_update_state(struct comedi_subdevice *s,
  244. unsigned int *data)
  245. {
  246. unsigned int chanmask = (s->n_chan < 32) ? ((1 << s->n_chan) - 1)
  247. : 0xffffffff;
  248. unsigned int mask = data[0] & chanmask;
  249. unsigned int bits = data[1];
  250. if (mask) {
  251. s->state &= ~mask;
  252. s->state |= (bits & mask);
  253. }
  254. return mask;
  255. }
  256. EXPORT_SYMBOL_GPL(comedi_dio_update_state);
  257. /**
  258. * comedi_bytes_per_scan - get length of asynchronous command "scan" in bytes
  259. * @s: comedi_subdevice struct
  260. *
  261. * Determines the overall scan length according to the subdevice type and the
  262. * number of channels in the scan.
  263. *
  264. * For digital input, output or input/output subdevices, samples for multiple
  265. * channels are assumed to be packed into one or more unsigned short or
  266. * unsigned int values according to the subdevice's SDF_LSAMPL flag. For other
  267. * types of subdevice, samples are assumed to occupy a whole unsigned short or
  268. * unsigned int according to the SDF_LSAMPL flag.
  269. *
  270. * Returns the overall scan length in bytes.
  271. */
  272. unsigned int comedi_bytes_per_scan(struct comedi_subdevice *s)
  273. {
  274. struct comedi_cmd *cmd = &s->async->cmd;
  275. unsigned int num_samples;
  276. unsigned int bits_per_sample;
  277. switch (s->type) {
  278. case COMEDI_SUBD_DI:
  279. case COMEDI_SUBD_DO:
  280. case COMEDI_SUBD_DIO:
  281. bits_per_sample = 8 * bytes_per_sample(s);
  282. num_samples = (cmd->chanlist_len + bits_per_sample - 1) /
  283. bits_per_sample;
  284. break;
  285. default:
  286. num_samples = cmd->chanlist_len;
  287. break;
  288. }
  289. return num_samples * bytes_per_sample(s);
  290. }
  291. EXPORT_SYMBOL_GPL(comedi_bytes_per_scan);
  292. /**
  293. * comedi_inc_scan_progress - update scan progress in asynchronous command
  294. * @s: comedi_subdevice struct
  295. * @num_bytes: amount of data in bytes to increment scan progress
  296. *
  297. * Increments the scan progress by the number of bytes specified by num_bytes.
  298. * If the scan progress reaches or exceeds the scan length in bytes, reduce
  299. * it modulo the scan length in bytes and set the "end of scan" asynchronous
  300. * event flag to be processed later.
  301. */
  302. void comedi_inc_scan_progress(struct comedi_subdevice *s,
  303. unsigned int num_bytes)
  304. {
  305. struct comedi_async *async = s->async;
  306. unsigned int scan_length = comedi_bytes_per_scan(s);
  307. async->scan_progress += num_bytes;
  308. if (async->scan_progress >= scan_length) {
  309. async->scan_progress %= scan_length;
  310. async->events |= COMEDI_CB_EOS;
  311. }
  312. }
  313. EXPORT_SYMBOL_GPL(comedi_inc_scan_progress);
  314. /**
  315. * comedi_handle_events - handle events and possibly stop acquisition
  316. * @dev: comedi_device struct
  317. * @s: comedi_subdevice struct
  318. *
  319. * Handles outstanding asynchronous acquisition event flags associated
  320. * with the subdevice. Call the subdevice's "->cancel()" handler if the
  321. * "end of acquisition", "error" or "overflow" event flags are set in order
  322. * to stop the acquisition at the driver level.
  323. *
  324. * Calls comedi_event() to further process the event flags, which may mark
  325. * the asynchronous command as no longer running, possibly terminated with
  326. * an error, and may wake up tasks.
  327. *
  328. * Return a bit-mask of the handled events.
  329. */
  330. unsigned int comedi_handle_events(struct comedi_device *dev,
  331. struct comedi_subdevice *s)
  332. {
  333. unsigned int events = s->async->events;
  334. if (events == 0)
  335. return events;
  336. if (events & (COMEDI_CB_EOA | COMEDI_CB_ERROR | COMEDI_CB_OVERFLOW))
  337. s->cancel(dev, s);
  338. comedi_event(dev, s);
  339. return events;
  340. }
  341. EXPORT_SYMBOL_GPL(comedi_handle_events);
  342. static int insn_rw_emulate_bits(struct comedi_device *dev,
  343. struct comedi_subdevice *s,
  344. struct comedi_insn *insn, unsigned int *data)
  345. {
  346. struct comedi_insn new_insn;
  347. int ret;
  348. static const unsigned channels_per_bitfield = 32;
  349. unsigned chan = CR_CHAN(insn->chanspec);
  350. const unsigned base_bitfield_channel =
  351. (chan < channels_per_bitfield) ? 0 : chan;
  352. unsigned int new_data[2];
  353. memset(new_data, 0, sizeof(new_data));
  354. memset(&new_insn, 0, sizeof(new_insn));
  355. new_insn.insn = INSN_BITS;
  356. new_insn.chanspec = base_bitfield_channel;
  357. new_insn.n = 2;
  358. new_insn.subdev = insn->subdev;
  359. if (insn->insn == INSN_WRITE) {
  360. if (!(s->subdev_flags & SDF_WRITABLE))
  361. return -EINVAL;
  362. new_data[0] = 1 << (chan - base_bitfield_channel); /* mask */
  363. new_data[1] = data[0] ? (1 << (chan - base_bitfield_channel))
  364. : 0; /* bits */
  365. }
  366. ret = s->insn_bits(dev, s, &new_insn, new_data);
  367. if (ret < 0)
  368. return ret;
  369. if (insn->insn == INSN_READ)
  370. data[0] = (new_data[1] >> (chan - base_bitfield_channel)) & 1;
  371. return 1;
  372. }
  373. static int __comedi_device_postconfig_async(struct comedi_device *dev,
  374. struct comedi_subdevice *s)
  375. {
  376. struct comedi_async *async;
  377. unsigned int buf_size;
  378. int ret;
  379. if ((s->subdev_flags & (SDF_CMD_READ | SDF_CMD_WRITE)) == 0) {
  380. dev_warn(dev->class_dev,
  381. "async subdevices must support SDF_CMD_READ or SDF_CMD_WRITE\n");
  382. return -EINVAL;
  383. }
  384. if (!s->do_cmdtest) {
  385. dev_warn(dev->class_dev,
  386. "async subdevices must have a do_cmdtest() function\n");
  387. return -EINVAL;
  388. }
  389. async = kzalloc(sizeof(*async), GFP_KERNEL);
  390. if (!async)
  391. return -ENOMEM;
  392. init_waitqueue_head(&async->wait_head);
  393. s->async = async;
  394. async->max_bufsize = comedi_default_buf_maxsize_kb * 1024;
  395. buf_size = comedi_default_buf_size_kb * 1024;
  396. if (buf_size > async->max_bufsize)
  397. buf_size = async->max_bufsize;
  398. if (comedi_buf_alloc(dev, s, buf_size) < 0) {
  399. dev_warn(dev->class_dev, "Buffer allocation failed\n");
  400. return -ENOMEM;
  401. }
  402. if (s->buf_change) {
  403. ret = s->buf_change(dev, s);
  404. if (ret < 0)
  405. return ret;
  406. }
  407. comedi_alloc_subdevice_minor(s);
  408. return 0;
  409. }
  410. static int __comedi_device_postconfig(struct comedi_device *dev)
  411. {
  412. struct comedi_subdevice *s;
  413. int ret;
  414. int i;
  415. for (i = 0; i < dev->n_subdevices; i++) {
  416. s = &dev->subdevices[i];
  417. if (s->type == COMEDI_SUBD_UNUSED)
  418. continue;
  419. if (s->type == COMEDI_SUBD_DO) {
  420. if (s->n_chan < 32)
  421. s->io_bits = (1 << s->n_chan) - 1;
  422. else
  423. s->io_bits = 0xffffffff;
  424. }
  425. if (s->len_chanlist == 0)
  426. s->len_chanlist = 1;
  427. if (s->do_cmd) {
  428. ret = __comedi_device_postconfig_async(dev, s);
  429. if (ret)
  430. return ret;
  431. }
  432. if (!s->range_table && !s->range_table_list)
  433. s->range_table = &range_unknown;
  434. if (!s->insn_read && s->insn_bits)
  435. s->insn_read = insn_rw_emulate_bits;
  436. if (!s->insn_write && s->insn_bits)
  437. s->insn_write = insn_rw_emulate_bits;
  438. if (!s->insn_read)
  439. s->insn_read = insn_inval;
  440. if (!s->insn_write)
  441. s->insn_write = insn_inval;
  442. if (!s->insn_bits)
  443. s->insn_bits = insn_inval;
  444. if (!s->insn_config)
  445. s->insn_config = insn_inval;
  446. if (!s->poll)
  447. s->poll = poll_invalid;
  448. }
  449. return 0;
  450. }
  451. /* do a little post-config cleanup */
  452. static int comedi_device_postconfig(struct comedi_device *dev)
  453. {
  454. int ret;
  455. ret = __comedi_device_postconfig(dev);
  456. if (ret < 0)
  457. return ret;
  458. down_write(&dev->attach_lock);
  459. dev->attached = true;
  460. up_write(&dev->attach_lock);
  461. return 0;
  462. }
  463. /*
  464. * Generic recognize function for drivers that register their supported
  465. * board names.
  466. *
  467. * 'driv->board_name' points to a 'const char *' member within the
  468. * zeroth element of an array of some private board information
  469. * structure, say 'struct foo_board' containing a member 'const char
  470. * *board_name' that is initialized to point to a board name string that
  471. * is one of the candidates matched against this function's 'name'
  472. * parameter.
  473. *
  474. * 'driv->offset' is the size of the private board information
  475. * structure, say 'sizeof(struct foo_board)', and 'driv->num_names' is
  476. * the length of the array of private board information structures.
  477. *
  478. * If one of the board names in the array of private board information
  479. * structures matches the name supplied to this function, the function
  480. * returns a pointer to the pointer to the board name, otherwise it
  481. * returns NULL. The return value ends up in the 'board_ptr' member of
  482. * a 'struct comedi_device' that the low-level comedi driver's
  483. * 'attach()' hook can convert to a point to a particular element of its
  484. * array of private board information structures by subtracting the
  485. * offset of the member that points to the board name. (No subtraction
  486. * is required if the board name pointer is the first member of the
  487. * private board information structure, which is generally the case.)
  488. */
  489. static void *comedi_recognize(struct comedi_driver *driv, const char *name)
  490. {
  491. char **name_ptr = (char **)driv->board_name;
  492. int i;
  493. for (i = 0; i < driv->num_names; i++) {
  494. if (strcmp(*name_ptr, name) == 0)
  495. return name_ptr;
  496. name_ptr = (void *)name_ptr + driv->offset;
  497. }
  498. return NULL;
  499. }
  500. static void comedi_report_boards(struct comedi_driver *driv)
  501. {
  502. unsigned int i;
  503. const char *const *name_ptr;
  504. pr_info("comedi: valid board names for %s driver are:\n",
  505. driv->driver_name);
  506. name_ptr = driv->board_name;
  507. for (i = 0; i < driv->num_names; i++) {
  508. pr_info(" %s\n", *name_ptr);
  509. name_ptr = (const char **)((char *)name_ptr + driv->offset);
  510. }
  511. if (driv->num_names == 0)
  512. pr_info(" %s\n", driv->driver_name);
  513. }
  514. /**
  515. * comedi_load_firmware() - Request and load firmware for a device.
  516. * @dev: comedi_device struct
  517. * @hw_device: device struct for the comedi_device
  518. * @name: the name of the firmware image
  519. * @cb: callback to the upload the firmware image
  520. * @context: private context from the driver
  521. */
  522. int comedi_load_firmware(struct comedi_device *dev,
  523. struct device *device,
  524. const char *name,
  525. int (*cb)(struct comedi_device *dev,
  526. const u8 *data, size_t size,
  527. unsigned long context),
  528. unsigned long context)
  529. {
  530. const struct firmware *fw;
  531. int ret;
  532. if (!cb)
  533. return -EINVAL;
  534. ret = request_firmware(&fw, name, device);
  535. if (ret == 0) {
  536. ret = cb(dev, fw->data, fw->size, context);
  537. release_firmware(fw);
  538. }
  539. return ret < 0 ? ret : 0;
  540. }
  541. EXPORT_SYMBOL_GPL(comedi_load_firmware);
  542. /**
  543. * __comedi_request_region() - Request an I/O reqion for a legacy driver.
  544. * @dev: comedi_device struct
  545. * @start: base address of the I/O reqion
  546. * @len: length of the I/O region
  547. */
  548. int __comedi_request_region(struct comedi_device *dev,
  549. unsigned long start, unsigned long len)
  550. {
  551. if (!start) {
  552. dev_warn(dev->class_dev,
  553. "%s: a I/O base address must be specified\n",
  554. dev->board_name);
  555. return -EINVAL;
  556. }
  557. if (!request_region(start, len, dev->board_name)) {
  558. dev_warn(dev->class_dev, "%s: I/O port conflict (%#lx,%lu)\n",
  559. dev->board_name, start, len);
  560. return -EIO;
  561. }
  562. return 0;
  563. }
  564. EXPORT_SYMBOL_GPL(__comedi_request_region);
  565. /**
  566. * comedi_request_region() - Request an I/O reqion for a legacy driver.
  567. * @dev: comedi_device struct
  568. * @start: base address of the I/O reqion
  569. * @len: length of the I/O region
  570. */
  571. int comedi_request_region(struct comedi_device *dev,
  572. unsigned long start, unsigned long len)
  573. {
  574. int ret;
  575. ret = __comedi_request_region(dev, start, len);
  576. if (ret == 0) {
  577. dev->iobase = start;
  578. dev->iolen = len;
  579. }
  580. return ret;
  581. }
  582. EXPORT_SYMBOL_GPL(comedi_request_region);
  583. /**
  584. * comedi_legacy_detach() - A generic (*detach) function for legacy drivers.
  585. * @dev: comedi_device struct
  586. */
  587. void comedi_legacy_detach(struct comedi_device *dev)
  588. {
  589. if (dev->irq) {
  590. free_irq(dev->irq, dev);
  591. dev->irq = 0;
  592. }
  593. if (dev->iobase && dev->iolen) {
  594. release_region(dev->iobase, dev->iolen);
  595. dev->iobase = 0;
  596. dev->iolen = 0;
  597. }
  598. }
  599. EXPORT_SYMBOL_GPL(comedi_legacy_detach);
  600. int comedi_device_attach(struct comedi_device *dev, struct comedi_devconfig *it)
  601. {
  602. struct comedi_driver *driv;
  603. int ret;
  604. if (dev->attached)
  605. return -EBUSY;
  606. mutex_lock(&comedi_drivers_list_lock);
  607. for (driv = comedi_drivers; driv; driv = driv->next) {
  608. if (!try_module_get(driv->module))
  609. continue;
  610. if (driv->num_names) {
  611. dev->board_ptr = comedi_recognize(driv, it->board_name);
  612. if (dev->board_ptr)
  613. break;
  614. } else if (strcmp(driv->driver_name, it->board_name) == 0) {
  615. break;
  616. }
  617. module_put(driv->module);
  618. }
  619. if (driv == NULL) {
  620. /* recognize has failed if we get here */
  621. /* report valid board names before returning error */
  622. for (driv = comedi_drivers; driv; driv = driv->next) {
  623. if (!try_module_get(driv->module))
  624. continue;
  625. comedi_report_boards(driv);
  626. module_put(driv->module);
  627. }
  628. ret = -EIO;
  629. goto out;
  630. }
  631. if (driv->attach == NULL) {
  632. /* driver does not support manual configuration */
  633. dev_warn(dev->class_dev,
  634. "driver '%s' does not support attach using comedi_config\n",
  635. driv->driver_name);
  636. module_put(driv->module);
  637. ret = -ENOSYS;
  638. goto out;
  639. }
  640. dev->driver = driv;
  641. dev->board_name = dev->board_ptr ? *(const char **)dev->board_ptr
  642. : dev->driver->driver_name;
  643. ret = driv->attach(dev, it);
  644. if (ret >= 0)
  645. ret = comedi_device_postconfig(dev);
  646. if (ret < 0) {
  647. comedi_device_detach(dev);
  648. module_put(driv->module);
  649. }
  650. /* On success, the driver module count has been incremented. */
  651. out:
  652. mutex_unlock(&comedi_drivers_list_lock);
  653. return ret;
  654. }
  655. int comedi_auto_config(struct device *hardware_device,
  656. struct comedi_driver *driver, unsigned long context)
  657. {
  658. struct comedi_device *dev;
  659. int ret;
  660. if (!hardware_device) {
  661. pr_warn("BUG! comedi_auto_config called with NULL hardware_device\n");
  662. return -EINVAL;
  663. }
  664. if (!driver) {
  665. dev_warn(hardware_device,
  666. "BUG! comedi_auto_config called with NULL comedi driver\n");
  667. return -EINVAL;
  668. }
  669. if (!driver->auto_attach) {
  670. dev_warn(hardware_device,
  671. "BUG! comedi driver '%s' has no auto_attach handler\n",
  672. driver->driver_name);
  673. return -EINVAL;
  674. }
  675. dev = comedi_alloc_board_minor(hardware_device);
  676. if (IS_ERR(dev)) {
  677. dev_warn(hardware_device,
  678. "driver '%s' could not create device.\n",
  679. driver->driver_name);
  680. return PTR_ERR(dev);
  681. }
  682. /* Note: comedi_alloc_board_minor() locked dev->mutex. */
  683. dev->driver = driver;
  684. dev->board_name = dev->driver->driver_name;
  685. ret = driver->auto_attach(dev, context);
  686. if (ret >= 0)
  687. ret = comedi_device_postconfig(dev);
  688. mutex_unlock(&dev->mutex);
  689. if (ret < 0) {
  690. dev_warn(hardware_device,
  691. "driver '%s' failed to auto-configure device.\n",
  692. driver->driver_name);
  693. comedi_release_hardware_device(hardware_device);
  694. } else {
  695. /*
  696. * class_dev should be set properly here
  697. * after a successful auto config
  698. */
  699. dev_info(dev->class_dev,
  700. "driver '%s' has successfully auto-configured '%s'.\n",
  701. driver->driver_name, dev->board_name);
  702. }
  703. return ret;
  704. }
  705. EXPORT_SYMBOL_GPL(comedi_auto_config);
  706. void comedi_auto_unconfig(struct device *hardware_device)
  707. {
  708. if (hardware_device == NULL)
  709. return;
  710. comedi_release_hardware_device(hardware_device);
  711. }
  712. EXPORT_SYMBOL_GPL(comedi_auto_unconfig);
  713. int comedi_driver_register(struct comedi_driver *driver)
  714. {
  715. mutex_lock(&comedi_drivers_list_lock);
  716. driver->next = comedi_drivers;
  717. comedi_drivers = driver;
  718. mutex_unlock(&comedi_drivers_list_lock);
  719. return 0;
  720. }
  721. EXPORT_SYMBOL_GPL(comedi_driver_register);
  722. void comedi_driver_unregister(struct comedi_driver *driver)
  723. {
  724. struct comedi_driver *prev;
  725. int i;
  726. /* unlink the driver */
  727. mutex_lock(&comedi_drivers_list_lock);
  728. if (comedi_drivers == driver) {
  729. comedi_drivers = driver->next;
  730. } else {
  731. for (prev = comedi_drivers; prev->next; prev = prev->next) {
  732. if (prev->next == driver) {
  733. prev->next = driver->next;
  734. break;
  735. }
  736. }
  737. }
  738. mutex_unlock(&comedi_drivers_list_lock);
  739. /* check for devices using this driver */
  740. for (i = 0; i < COMEDI_NUM_BOARD_MINORS; i++) {
  741. struct comedi_device *dev = comedi_dev_get_from_minor(i);
  742. if (!dev)
  743. continue;
  744. mutex_lock(&dev->mutex);
  745. if (dev->attached && dev->driver == driver) {
  746. if (dev->use_count)
  747. dev_warn(dev->class_dev,
  748. "BUG! detaching device with use_count=%d\n",
  749. dev->use_count);
  750. comedi_device_detach(dev);
  751. }
  752. mutex_unlock(&dev->mutex);
  753. comedi_dev_put(dev);
  754. }
  755. }
  756. EXPORT_SYMBOL_GPL(comedi_driver_unregister);