dev_name.c 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268
  1. /*
  2. * Mach Operating System
  3. * Copyright (c) 1991,1990,1989 Carnegie Mellon University
  4. * All Rights Reserved.
  5. *
  6. * Permission to use, copy, modify and distribute this software and its
  7. * documentation is hereby granted, provided that both the copyright
  8. * notice and this permission notice appear in all copies of the
  9. * software, derivative works or modified versions, and any portions
  10. * thereof, and that both notices appear in supporting documentation.
  11. *
  12. * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
  13. * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
  14. * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
  15. *
  16. * Carnegie Mellon requests users of this software to return to
  17. *
  18. * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
  19. * School of Computer Science
  20. * Carnegie Mellon University
  21. * Pittsburgh PA 15213-3890
  22. *
  23. * any improvements or extensions that they make and grant Carnegie Mellon
  24. * the rights to redistribute these changes.
  25. */
  26. /*
  27. * Author: David B. Golub, Carnegie Mellon University
  28. * Date: 8/89
  29. */
  30. #include <kern/printf.h>
  31. #include <string.h>
  32. #include <device/device_types.h>
  33. #include <device/dev_hdr.h>
  34. #include <device/conf.h>
  35. /*
  36. * Routines placed in empty entries in the device tables
  37. */
  38. int nulldev(void)
  39. {
  40. return (D_SUCCESS);
  41. }
  42. int nulldev_open(dev_t dev, int flags, io_req_t ior)
  43. {
  44. return (D_SUCCESS);
  45. }
  46. void nulldev_close(dev_t dev, int flags)
  47. {
  48. }
  49. int nulldev_read(dev_t dev, io_req_t ior)
  50. {
  51. return (D_SUCCESS);
  52. }
  53. int nulldev_write(dev_t dev, io_req_t ior)
  54. {
  55. return (D_SUCCESS);
  56. }
  57. io_return_t nulldev_getstat(dev_t dev, int flavor, int *data, natural_t *count)
  58. {
  59. return (D_SUCCESS);
  60. }
  61. io_return_t nulldev_setstat(dev_t dev, int flavor, int *data, natural_t count)
  62. {
  63. return (D_SUCCESS);
  64. }
  65. int nulldev_portdeath(dev_t dev, mach_port_t port)
  66. {
  67. return (D_SUCCESS);
  68. }
  69. int nodev(void)
  70. {
  71. return (D_INVALID_OPERATION);
  72. }
  73. int
  74. nomap(dev_t dev, vm_offset_t off, int prot)
  75. {
  76. return (D_INVALID_OPERATION);
  77. }
  78. /*
  79. * Name comparison routine.
  80. * Compares first 'len' characters of 'src'
  81. * with 'target', which is zero-terminated.
  82. * Returns TRUE if strings are equal:
  83. * src and target are equal in first 'len' characters
  84. * next character of target is 0 (end of string).
  85. */
  86. boolean_t __attribute__ ((pure))
  87. name_equal(src, len, target)
  88. const char *src;
  89. int len;
  90. const char *target;
  91. {
  92. while (--len >= 0)
  93. if (*src++ != *target++)
  94. return FALSE;
  95. return *target == 0;
  96. }
  97. /*
  98. * device name lookup
  99. */
  100. boolean_t dev_name_lookup(
  101. char *name,
  102. dev_ops_t *ops, /* out */
  103. int *unit) /* out */
  104. {
  105. /*
  106. * Assume that block device names are of the form
  107. *
  108. * <device_name><unit_number>[[<slice num>]<partition>]
  109. *
  110. * where
  111. * <device_name> is the name in the device table
  112. * <unit_number> is an integer
  113. * <slice num> * is 's' followed by a number (disks only!)
  114. * <partition> is a letter in [a-h] (disks only?)
  115. */
  116. char *cp = name;
  117. int len;
  118. int j = 0;
  119. int c;
  120. dev_ops_t dev;
  121. boolean_t found;
  122. int slice_num = 0;
  123. /*
  124. * Find device type name (characters before digit)
  125. */
  126. while ((c = *cp) != '\0' &&
  127. !(c >= '0' && c <= '9'))
  128. cp++;
  129. len = cp - name;
  130. if (c != '\0') {
  131. /*
  132. * Find unit number
  133. */
  134. while ((c = *cp) != '\0' &&
  135. c >= '0' && c <= '9') {
  136. j = j * 10 + (c - '0');
  137. cp++;
  138. }
  139. }
  140. found = FALSE;
  141. dev_search(dev) {
  142. if (name_equal(name, len, dev->d_name)) {
  143. found = TRUE;
  144. break;
  145. }
  146. }
  147. if (!found) {
  148. /* name not found - try indirection list */
  149. dev_indirect_t di;
  150. dev_indirect_search(di) {
  151. if (name_equal(name, len, di->d_name)) {
  152. /*
  153. * Return device and unit from indirect vector.
  154. */
  155. *ops = di->d_ops;
  156. *unit = di->d_unit;
  157. return (TRUE);
  158. }
  159. }
  160. /* Not found in either list. */
  161. return (FALSE);
  162. }
  163. *ops = dev;
  164. *unit = j;
  165. /*
  166. * Find sub-device number
  167. */
  168. j = dev->d_subdev;
  169. if (j > 0) {
  170. /* if no slice string, slice num = 0 */
  171. /* <subdev_count>*unit + <slice_number>*16 -- I know it's bad */
  172. *unit *= j;
  173. /* find slice ? */
  174. if (c == 's') {
  175. cp++;
  176. while ((c = *cp) != '\0' &&
  177. c >= '0' && c <= '9') {
  178. slice_num = slice_num * 10 + (c - '0');
  179. cp++;
  180. }
  181. }
  182. *unit += (slice_num << 4);
  183. /* if slice==0, it is either compatibility or whole device */
  184. if (c >= 'a' && c < 'a' + j) { /* note: w/o this -> whole slice */
  185. /*
  186. * Minor number is <subdev_count>*unit + letter.
  187. * NOW it is slice result + letter
  188. */
  189. *unit += (c - 'a' +1);
  190. }
  191. }
  192. return (TRUE);
  193. }
  194. /*
  195. * Change an entry in the indirection list.
  196. */
  197. void
  198. dev_set_indirection(name, ops, unit)
  199. const char *name;
  200. dev_ops_t ops;
  201. int unit;
  202. {
  203. dev_indirect_t di;
  204. dev_indirect_search(di) {
  205. if (!strcmp(di->d_name, name)) {
  206. di->d_ops = ops;
  207. di->d_unit = unit;
  208. break;
  209. }
  210. }
  211. }
  212. boolean_t dev_change_indirect(iname, dname, unit)
  213. const char *iname;
  214. const char *dname;
  215. int unit;
  216. {
  217. struct dev_ops *dp;
  218. struct dev_indirect *di;
  219. boolean_t found = FALSE;
  220. dev_search(dp) {
  221. if (!strcmp(dp->d_name, dname)) {
  222. found = TRUE;
  223. break;
  224. }
  225. }
  226. if (!found) return FALSE;
  227. dev_indirect_search(di) {
  228. if (!strcmp(di->d_name, iname)) {
  229. di->d_ops = dp;
  230. di->d_unit = unit;
  231. return TRUE;
  232. }
  233. }
  234. return FALSE;
  235. }