probe.c 7.5 KB

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