probe.c 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283
  1. /*
  2. * Parallel port device probing code
  3. *
  4. * Authors: Carsten Gross, carsten@sol.wohnheim.uni-ulm.de
  5. * Philip Blundell <philb@gnu.org>
  6. */
  7. #include <linux/module.h>
  8. #include <linux/parport.h>
  9. #include <linux/ctype.h>
  10. #include <linux/string.h>
  11. #include <linux/slab.h>
  12. #include <asm/uaccess.h>
  13. static const struct {
  14. const char *token;
  15. const char *descr;
  16. } classes[] = {
  17. { "", "Legacy device" },
  18. { "PRINTER", "Printer" },
  19. { "MODEM", "Modem" },
  20. { "NET", "Network device" },
  21. { "HDC", "Hard disk" },
  22. { "PCMCIA", "PCMCIA" },
  23. { "MEDIA", "Multimedia device" },
  24. { "FDC", "Floppy disk" },
  25. { "PORTS", "Ports" },
  26. { "SCANNER", "Scanner" },
  27. { "DIGICAM", "Digital camera" },
  28. { "", "Unknown device" },
  29. { "", "Unspecified" },
  30. { "SCSIADAPTER", "SCSI adapter" },
  31. { NULL, NULL }
  32. };
  33. static void pretty_print(struct parport *port, int device)
  34. {
  35. struct parport_device_info *info = &port->probe_info[device + 1];
  36. printk(KERN_INFO "%s", port->name);
  37. if (device >= 0)
  38. printk (" (addr %d)", device);
  39. printk (": %s", classes[info->class].descr);
  40. if (info->class)
  41. printk(", %s %s", info->mfr, info->model);
  42. printk("\n");
  43. }
  44. static void parse_data(struct parport *port, int device, char *str)
  45. {
  46. char *txt = kmalloc(strlen(str)+1, GFP_KERNEL);
  47. char *p = txt, *q;
  48. int guessed_class = PARPORT_CLASS_UNSPEC;
  49. struct parport_device_info *info = &port->probe_info[device + 1];
  50. if (!txt) {
  51. printk(KERN_WARNING "%s probe: memory squeeze\n", port->name);
  52. return;
  53. }
  54. strcpy(txt, str);
  55. while (p) {
  56. char *sep;
  57. q = strchr(p, ';');
  58. if (q) *q = 0;
  59. sep = strchr(p, ':');
  60. if (sep) {
  61. char *u;
  62. *(sep++) = 0;
  63. /* Get rid of trailing blanks */
  64. u = sep + strlen (sep) - 1;
  65. while (u >= p && *u == ' ')
  66. *u-- = '\0';
  67. u = p;
  68. while (*u) {
  69. *u = toupper(*u);
  70. u++;
  71. }
  72. if (!strcmp(p, "MFG") || !strcmp(p, "MANUFACTURER")) {
  73. kfree(info->mfr);
  74. info->mfr = kstrdup(sep, GFP_KERNEL);
  75. } else if (!strcmp(p, "MDL") || !strcmp(p, "MODEL")) {
  76. kfree(info->model);
  77. info->model = kstrdup(sep, GFP_KERNEL);
  78. } else if (!strcmp(p, "CLS") || !strcmp(p, "CLASS")) {
  79. int i;
  80. kfree(info->class_name);
  81. info->class_name = kstrdup(sep, GFP_KERNEL);
  82. for (u = sep; *u; u++)
  83. *u = toupper(*u);
  84. for (i = 0; classes[i].token; i++) {
  85. if (!strcmp(classes[i].token, sep)) {
  86. info->class = i;
  87. goto rock_on;
  88. }
  89. }
  90. printk(KERN_WARNING "%s probe: warning, class '%s' not understood.\n", port->name, sep);
  91. info->class = PARPORT_CLASS_OTHER;
  92. } else if (!strcmp(p, "CMD") ||
  93. !strcmp(p, "COMMAND SET")) {
  94. kfree(info->cmdset);
  95. info->cmdset = kstrdup(sep, GFP_KERNEL);
  96. /* if it speaks printer language, it's
  97. probably a printer */
  98. if (strstr(sep, "PJL") || strstr(sep, "PCL"))
  99. guessed_class = PARPORT_CLASS_PRINTER;
  100. } else if (!strcmp(p, "DES") || !strcmp(p, "DESCRIPTION")) {
  101. kfree(info->description);
  102. info->description = kstrdup(sep, GFP_KERNEL);
  103. }
  104. }
  105. rock_on:
  106. if (q)
  107. p = q + 1;
  108. else
  109. p = NULL;
  110. }
  111. /* If the device didn't tell us its class, maybe we have managed to
  112. guess one from the things it did say. */
  113. if (info->class == PARPORT_CLASS_UNSPEC)
  114. info->class = guessed_class;
  115. pretty_print (port, device);
  116. kfree(txt);
  117. }
  118. /* Read up to count-1 bytes of device id. Terminate buffer with
  119. * '\0'. Buffer begins with two Device ID length bytes as given by
  120. * device. */
  121. static ssize_t parport_read_device_id (struct parport *port, char *buffer,
  122. size_t count)
  123. {
  124. unsigned char length[2];
  125. unsigned lelen, belen;
  126. size_t idlens[4];
  127. unsigned numidlens;
  128. unsigned current_idlen;
  129. ssize_t retval;
  130. size_t len;
  131. /* First two bytes are MSB,LSB of inclusive length. */
  132. retval = parport_read (port, length, 2);
  133. if (retval < 0)
  134. return retval;
  135. if (retval != 2)
  136. return -EIO;
  137. if (count < 2)
  138. return 0;
  139. memcpy(buffer, length, 2);
  140. len = 2;
  141. /* Some devices wrongly send LE length, and some send it two
  142. * bytes short. Construct a sorted array of lengths to try. */
  143. belen = (length[0] << 8) + length[1];
  144. lelen = (length[1] << 8) + length[0];
  145. idlens[0] = min(belen, lelen);
  146. idlens[1] = idlens[0]+2;
  147. if (belen != lelen) {
  148. int off = 2;
  149. /* Don't try lengths of 0x100 and 0x200 as 1 and 2 */
  150. if (idlens[0] <= 2)
  151. off = 0;
  152. idlens[off] = max(belen, lelen);
  153. idlens[off+1] = idlens[off]+2;
  154. numidlens = off+2;
  155. }
  156. else {
  157. /* Some devices don't truly implement Device ID, but
  158. * just return constant nibble forever. This catches
  159. * also those cases. */
  160. if (idlens[0] == 0 || idlens[0] > 0xFFF) {
  161. printk (KERN_DEBUG "%s: reported broken Device ID"
  162. " length of %#zX bytes\n",
  163. port->name, idlens[0]);
  164. return -EIO;
  165. }
  166. numidlens = 2;
  167. }
  168. /* Try to respect the given ID length despite all the bugs in
  169. * the ID length. Read according to shortest possible ID
  170. * first. */
  171. for (current_idlen = 0; current_idlen < numidlens; ++current_idlen) {
  172. size_t idlen = idlens[current_idlen];
  173. if (idlen+1 >= count)
  174. break;
  175. retval = parport_read (port, buffer+len, idlen-len);
  176. if (retval < 0)
  177. return retval;
  178. len += retval;
  179. if (port->physport->ieee1284.phase != IEEE1284_PH_HBUSY_DAVAIL) {
  180. if (belen != len) {
  181. printk (KERN_DEBUG "%s: Device ID was %zd bytes"
  182. " while device told it would be %d"
  183. " bytes\n",
  184. port->name, len, belen);
  185. }
  186. goto done;
  187. }
  188. /* This might end reading the Device ID too
  189. * soon. Hopefully the needed fields were already in
  190. * the first 256 bytes or so that we must have read so
  191. * far. */
  192. if (buffer[len-1] == ';') {
  193. printk (KERN_DEBUG "%s: Device ID reading stopped"
  194. " before device told data not available. "
  195. "Current idlen %u of %u, len bytes %02X %02X\n",
  196. port->name, current_idlen, numidlens,
  197. length[0], length[1]);
  198. goto done;
  199. }
  200. }
  201. if (current_idlen < numidlens) {
  202. /* Buffer not large enough, read to end of buffer. */
  203. size_t idlen, len2;
  204. if (len+1 < count) {
  205. retval = parport_read (port, buffer+len, count-len-1);
  206. if (retval < 0)
  207. return retval;
  208. len += retval;
  209. }
  210. /* Read the whole ID since some devices would not
  211. * otherwise give back the Device ID from beginning
  212. * next time when asked. */
  213. idlen = idlens[current_idlen];
  214. len2 = len;
  215. while(len2 < idlen && retval > 0) {
  216. char tmp[4];
  217. retval = parport_read (port, tmp,
  218. min(sizeof tmp, idlen-len2));
  219. if (retval < 0)
  220. return retval;
  221. len2 += retval;
  222. }
  223. }
  224. /* In addition, there are broken devices out there that don't
  225. even finish off with a semi-colon. We do not need to care
  226. about those at this time. */
  227. done:
  228. buffer[len] = '\0';
  229. return len;
  230. }
  231. /* Get Std 1284 Device ID. */
  232. ssize_t parport_device_id (int devnum, char *buffer, size_t count)
  233. {
  234. ssize_t retval = -ENXIO;
  235. struct pardevice *dev = parport_open (devnum, "Device ID probe");
  236. if (!dev)
  237. return -ENXIO;
  238. parport_claim_or_block (dev);
  239. /* Negotiate to compatibility mode, and then to device ID
  240. * mode. (This so that we start form beginning of device ID if
  241. * already in device ID mode.) */
  242. parport_negotiate (dev->port, IEEE1284_MODE_COMPAT);
  243. retval = parport_negotiate (dev->port,
  244. IEEE1284_MODE_NIBBLE | IEEE1284_DEVICEID);
  245. if (!retval) {
  246. retval = parport_read_device_id (dev->port, buffer, count);
  247. parport_negotiate (dev->port, IEEE1284_MODE_COMPAT);
  248. if (retval > 2)
  249. parse_data (dev->port, dev->daisy, buffer+2);
  250. }
  251. parport_release (dev);
  252. parport_close (dev);
  253. return retval;
  254. }