]>
Commit | Line | Data |
---|---|---|
f7deaa1a | 1 | /* |
bc44d920 | 2 | * "$Id: ieee1394-linux.c 6649 2007-07-11 21:46:42Z mike $" |
f7deaa1a | 3 | * |
4 | * Linux IEEE-1394 glue for the Common UNIX Printing System (CUPS). | |
5 | * | |
bc44d920 | 6 | * Copyright 2007 by Apple Inc. |
f7deaa1a | 7 | * Copyright 2002 by Easy Software Products, all rights reserved. |
8 | * | |
9 | * Redistribution and use in source and binary forms, with or | |
10 | * without modification, are permitted provided that the | |
11 | * following conditions are met: | |
12 | * | |
13 | * 1. Redistributions of source code must retain the above | |
14 | * copyright notice, this list of conditions and the | |
15 | * following disclaimer. | |
16 | * | |
17 | * 2. Redistributions in binary form must reproduce the | |
18 | * above copyright notice, this list of conditions and | |
19 | * the following disclaimer in the documentation and/or | |
20 | * other materials provided with the distribution. | |
21 | * | |
22 | * 3. All advertising materials mentioning features or use | |
23 | * of this software must display the following | |
24 | * acknowledgement: | |
25 | * | |
26 | * This product includes software developed by Easy | |
27 | * Software Products. | |
28 | * | |
29 | * 4. The name of Easy Software Products may not be used to | |
30 | * endorse or promote products derived from this software | |
31 | * without specific prior written permission. | |
32 | * | |
33 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS | |
34 | * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, | |
35 | * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF | |
36 | * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | |
37 | * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS | |
38 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | |
39 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | |
40 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | |
41 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | |
42 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | |
43 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE | |
44 | * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | |
45 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH | |
46 | * DAMAGE. | |
47 | * | |
48 | * Contents: | |
49 | * | |
50 | * get_device_id() - Get the IEEE-1284 device ID for a node... | |
51 | * get_unit_type() - Get the unit type for a node... | |
52 | * show_data() - Show a data node... | |
53 | * show_dir() - Show a directory list... | |
54 | * ieee1394_list() - List the available printer devices. | |
55 | * ieee1394_open() - Open a printer device. | |
56 | * ieee1394_close() - Close a printer device. | |
57 | * ieee1394_read() - Read from a printer device. | |
58 | * ieee1394_write() - Write data to a printer device. | |
59 | * ieee1394_error() - Return the last error. | |
60 | */ | |
61 | ||
62 | /* | |
63 | * Include necessary headers. | |
64 | */ | |
65 | ||
66 | #include "ieee1394.h" | |
67 | #include <cups/debug.h> | |
68 | #include <libraw1394/raw1394.h> | |
69 | #include <libraw1394/csr.h> | |
70 | ||
71 | ||
72 | /* | |
73 | * Limits... | |
74 | */ | |
75 | ||
76 | #define MAX_NODES 100 | |
77 | ||
78 | ||
79 | /* | |
80 | * Structures... | |
81 | */ | |
82 | ||
83 | typedef struct | |
84 | { | |
85 | char uri[HTTP_MAX_URI],/* URI for this node... */ | |
86 | description[128],/* Description of port */ | |
87 | make_model[128];/* Make and model */ | |
88 | int port, /* Port where this node is found */ | |
89 | node; /* Node number */ | |
90 | unsigned long long addr; /* Management address */ | |
91 | } linux1394_node_t; | |
92 | ||
93 | typedef struct | |
94 | { | |
95 | raw1394handle_t handle; /* Handle for printer device */ | |
96 | int node; /* Node number for printer device */ | |
97 | unsigned long long addr; /* Management address */ | |
98 | } linux1394_dev_t; | |
99 | ||
100 | ||
101 | /* | |
102 | * ORB messages for communication with the device... | |
103 | */ | |
104 | ||
105 | typedef struct /**** Login ORB Message */ | |
106 | { | |
107 | unsigned char passwd_addr[8]; /* Password address */ | |
108 | unsigned char resp_addr[8]; /* Login response address */ | |
109 | unsigned char notify_excl; /* Notify and exclusive bits */ | |
110 | unsigned char recon_func; /* Reconnect time and function */ | |
111 | unsigned char lun[2]; /* Logical unit number */ | |
112 | unsigned char passwd_len[2]; /* Length of password */ | |
113 | unsigned char resp_len[2]; /* Length of login response */ | |
114 | unsigned char fifo_addr[8]; /* Local status FIFO address */ | |
115 | } login_orb_t; | |
116 | ||
117 | typedef struct /**** Login Response Message ****/ | |
118 | { | |
119 | unsigned char length[2]; /* Length of response */ | |
120 | unsigned char login_id[2]; /* Login ID */ | |
121 | unsigned char cmd_addr[8]; /* Command block agent address */ | |
122 | unsigned char reserved[2]; /* Reserved (0) */ | |
123 | unsigned char recon_hold[2]; /* Number of seconds to hold login */ | |
124 | } login_resp_t; | |
125 | ||
126 | ||
127 | /* | |
128 | * Local globals... | |
129 | */ | |
130 | ||
131 | static char error_string[1024] = ""; | |
132 | static int num_nodes; | |
133 | static linux1394_node_t nodes[MAX_NODES]; | |
134 | ||
135 | ||
136 | /* | |
137 | * 'get_device_id()' - Get the IEEE-1284 device ID for a node... | |
138 | */ | |
139 | ||
140 | static char * /* O - Device ID */ | |
141 | get_device_id(raw1394handle_t handle,/* I - Handle for device */ | |
142 | int node, /* I - Node number */ | |
143 | unsigned long long offset,/* I - Offset to directory */ | |
144 | char *id, /* O - ID string */ | |
145 | int idlen) /* I - Size of ID string */ | |
146 | { | |
147 | unsigned char data[1024], /* Data from ROM */ | |
148 | *dataptr; /* Pointer into data */ | |
149 | int length; /* Length of directory */ | |
150 | int datalen; /* Length of data */ | |
151 | unsigned long long dataoff; /* Offset of data */ | |
152 | ||
153 | ||
154 | DEBUG_printf(("get_device_id(handle = %p, node = %d, offset = %llx, id = %p, idlen = %d)\n", | |
155 | handle, node, offset, id, idlen)); | |
156 | ||
157 | *id = '\0'; | |
158 | ||
159 | /* | |
160 | * Read the directory length from the first quadlet... | |
161 | */ | |
162 | ||
163 | if (raw1394_read(handle, 0xffc0 | node, offset, 4, (quadlet_t *)data) < 0) | |
164 | return (NULL); | |
165 | ||
166 | offset += 4; | |
167 | ||
168 | /* | |
169 | * The length is in the upper 16 bits... | |
170 | */ | |
171 | ||
172 | length = (data[0] << 8) | data[1]; | |
173 | ||
174 | DEBUG_printf((" length = %d\n", length)); | |
175 | ||
176 | /* | |
177 | * Then read the directory, looking for unit directory or device tags... | |
178 | */ | |
179 | ||
180 | while (length > 0) | |
181 | { | |
182 | if (raw1394_read(handle, 0xffc0 | node, offset, 4, (quadlet_t *)data) < 0) | |
183 | return (NULL); | |
184 | ||
185 | DEBUG_printf((" data = %02X %02X %02X %02X\n", data[0], data[1], | |
186 | data[2], data[3])); | |
187 | ||
188 | if (data[0] == 0xd1) | |
189 | { | |
190 | /* | |
191 | * Found the unit directory... | |
192 | */ | |
193 | ||
194 | offset += ((((data[1] << 8) | data[2]) << 8) | data[3]) << 2; | |
195 | ||
196 | return (get_device_id(handle, node, offset, id, idlen)); | |
197 | } | |
198 | else if (data[0] == 0x81) | |
199 | { | |
200 | /* | |
201 | * Found potential IEEE-1284 device ID... | |
202 | */ | |
203 | ||
204 | dataoff = offset + (((((data[1] << 8) | data[2]) << 8) | data[3]) << 2); | |
205 | ||
206 | if (raw1394_read(handle, 0xffc0 | node, dataoff, 4, (quadlet_t *)data) < 0) | |
207 | return (NULL); | |
208 | ||
209 | dataoff += 4; | |
210 | ||
211 | /* | |
212 | * Read the leaf value... | |
213 | */ | |
214 | ||
215 | datalen = (data[0] << 8) | data[1]; | |
216 | ||
217 | if (datalen > (sizeof(data) / 4)) | |
218 | datalen = sizeof(data) / 4; | |
219 | ||
220 | for (dataptr = data; datalen > 0; datalen --, dataptr += 4, dataoff += 4) | |
221 | if (raw1394_read(handle, 0xffc0 | node, dataoff, 4, | |
222 | (quadlet_t *)dataptr) < 0) | |
223 | return (NULL); | |
224 | ||
225 | if (data[0] == 0 && memcmp(data + 8, "MFG:", 4) == 0) | |
226 | { | |
227 | /* | |
228 | * Found the device ID... | |
229 | */ | |
230 | ||
231 | datalen = dataptr - data - 8; | |
232 | if (datalen >= idlen) | |
233 | datalen --; | |
234 | ||
235 | memcpy(id, data + 8, datalen); | |
236 | id[datalen] = '\0'; | |
237 | ||
238 | return (id); | |
239 | } | |
240 | } | |
241 | ||
242 | offset += 4; | |
243 | length --; | |
244 | } | |
245 | ||
246 | return (NULL); | |
247 | } | |
248 | ||
249 | ||
250 | /* | |
251 | * 'get_man_addr()' - Get the management address for a node... | |
252 | */ | |
253 | ||
254 | static int /* O - Unit type */ | |
255 | get_man_addr(raw1394handle_t handle, /* I - Handle for device */ | |
256 | int node, /* I - Node number */ | |
257 | unsigned long long offset) /* I - Offset to directory */ | |
258 | { | |
259 | unsigned char data[4]; /* Data from ROM */ | |
260 | int length; /* Length of directory */ | |
261 | ||
262 | ||
263 | DEBUG_printf(("get_man_addr(handle = %p, node = %d, offset = %llx)\n", | |
264 | handle, node, offset)); | |
265 | ||
266 | /* | |
267 | * Read the directory length from the first quadlet... | |
268 | */ | |
269 | ||
270 | if (raw1394_read(handle, 0xffc0 | node, offset, 4, (quadlet_t *)data) < 0) | |
271 | return (-1); | |
272 | ||
273 | offset += 4; | |
274 | ||
275 | /* | |
276 | * The length is in the upper 16 bits... | |
277 | */ | |
278 | ||
279 | length = (data[0] << 8) | data[1]; | |
280 | ||
281 | DEBUG_printf((" length = %d\n", length)); | |
282 | ||
283 | /* | |
284 | * Then read the directory, looking for unit directory or type tags... | |
285 | */ | |
286 | ||
287 | while (length > 0) | |
288 | { | |
289 | if (raw1394_read(handle, 0xffc0 | node, offset, 4, (quadlet_t *)data) < 0) | |
290 | return (-1); | |
291 | ||
292 | DEBUG_printf((" data = %02X %02X %02X %02X\n", data[0], data[1], | |
293 | data[2], data[3])); | |
294 | ||
295 | if (data[0] == 0xd1) | |
296 | { | |
297 | /* | |
298 | * Found the unit directory... | |
299 | */ | |
300 | ||
301 | offset += ((((data[1] << 8) | data[2]) << 8) | data[3]) << 2; | |
302 | ||
303 | return (get_man_addr(handle, node, offset)); | |
304 | } | |
305 | else if (data[0] == 0x54) | |
306 | { | |
307 | /* | |
308 | * Found the management address... | |
309 | */ | |
310 | ||
311 | return (((((data[1] << 8) | data[2]) << 8) | data[3]) << 2); | |
312 | } | |
313 | ||
314 | offset += 4; | |
315 | length --; | |
316 | } | |
317 | ||
318 | return (-1); | |
319 | } | |
320 | ||
321 | ||
322 | /* | |
323 | * 'get_unit_type()' - Get the unit type for a node... | |
324 | */ | |
325 | ||
326 | static int /* O - Unit type */ | |
327 | get_unit_type(raw1394handle_t handle,/* I - Handle for device */ | |
328 | int node, /* I - Node number */ | |
329 | unsigned long long offset)/* I - Offset to directory */ | |
330 | { | |
331 | unsigned char data[4]; /* Data from ROM */ | |
332 | int length; /* Length of directory */ | |
333 | ||
334 | ||
335 | DEBUG_printf(("get_unit_type(handle = %p, node = %d, offset = %llx)\n", | |
336 | handle, node, offset)); | |
337 | ||
338 | /* | |
339 | * Read the directory length from the first quadlet... | |
340 | */ | |
341 | ||
342 | if (raw1394_read(handle, 0xffc0 | node, offset, 4, (quadlet_t *)data) < 0) | |
343 | return (-1); | |
344 | ||
345 | offset += 4; | |
346 | ||
347 | /* | |
348 | * The length is in the upper 16 bits... | |
349 | */ | |
350 | ||
351 | length = (data[0] << 8) | data[1]; | |
352 | ||
353 | DEBUG_printf((" length = %d\n", length)); | |
354 | ||
355 | /* | |
356 | * Then read the directory, looking for unit directory or type tags... | |
357 | */ | |
358 | ||
359 | while (length > 0) | |
360 | { | |
361 | if (raw1394_read(handle, 0xffc0 | node, offset, 4, (quadlet_t *)data) < 0) | |
362 | return (-1); | |
363 | ||
364 | DEBUG_printf((" data = %02X %02X %02X %02X\n", data[0], data[1], | |
365 | data[2], data[3])); | |
366 | ||
367 | if (data[0] == 0xd1) | |
368 | { | |
369 | /* | |
370 | * Found the unit directory... | |
371 | */ | |
372 | ||
373 | offset += ((((data[1] << 8) | data[2]) << 8) | data[3]) << 2; | |
374 | ||
375 | return (get_unit_type(handle, node, offset)); | |
376 | } | |
377 | else if (data[0] == 0x14) | |
378 | { | |
379 | /* | |
380 | * Found the unit type... | |
381 | */ | |
382 | ||
383 | return (data[1] & 0x1f); | |
384 | } | |
385 | ||
386 | offset += 4; | |
387 | length --; | |
388 | } | |
389 | ||
390 | return (-1); | |
391 | } | |
392 | ||
393 | ||
394 | #ifdef DEBUG | |
395 | /* | |
396 | * 'show_data()' - Show a data node... | |
397 | */ | |
398 | ||
399 | static void | |
400 | show_data(raw1394handle_t handle, /* I - Handle for device */ | |
401 | int node, /* I - Node number */ | |
402 | unsigned long long offset, /* I - Offset to directory */ | |
403 | int indent) /* Amount to indent */ | |
404 | { | |
405 | int i; /* Looping var */ | |
406 | unsigned char data[4]; /* Data from ROM */ | |
407 | int length; /* Length of data */ | |
408 | ||
409 | ||
410 | /* | |
411 | * Read the data length from the first quadlet... | |
412 | */ | |
413 | ||
414 | if (raw1394_read(handle, 0xffc0 | node, offset, 4, (quadlet_t *)data) < 0) | |
415 | return; | |
416 | ||
417 | offset += 4; | |
418 | ||
419 | /* | |
420 | * The length is in the upper 16 bits... | |
421 | */ | |
422 | ||
423 | length = (data[0] << 8) | data[1]; | |
424 | ||
425 | /* | |
426 | * Then read the data... | |
427 | */ | |
428 | ||
429 | for (i = 0; i < indent; i ++) | |
430 | putchar(' '); | |
431 | ||
432 | printf("LEAF (%d quadlets)\n", length); | |
433 | ||
434 | while (length > 0) | |
435 | { | |
436 | if (raw1394_read(handle, 0xffc0 | node, offset, 4, (quadlet_t *)data) < 0) | |
437 | return; | |
438 | ||
439 | for (i = 0; i < indent; i ++) | |
440 | putchar(' '); | |
441 | ||
442 | printf("%02X %02X %02X %02X '%c%c%c%c'\n", | |
443 | data[0], data[1], data[2], data[3], | |
444 | (data[0] < ' ' || data[0] >= 0x7f) ? '.' : data[0], | |
445 | (data[1] < ' ' || data[1] >= 0x7f) ? '.' : data[1], | |
446 | (data[2] < ' ' || data[2] >= 0x7f) ? '.' : data[2], | |
447 | (data[3] < ' ' || data[3] >= 0x7f) ? '.' : data[3]); | |
448 | ||
449 | offset += 4; | |
450 | length --; | |
451 | } | |
452 | } | |
453 | ||
454 | ||
455 | /* | |
456 | * 'show_dir()' - Show a directory list... | |
457 | */ | |
458 | ||
459 | static void | |
460 | show_dir(raw1394handle_t handle, /* I - Handle for device */ | |
461 | int node, /* I - Node number */ | |
462 | unsigned long long offset, /* I - Offset to directory */ | |
463 | int indent) /* Amount to indent */ | |
464 | { | |
465 | int i; /* Looping var */ | |
466 | unsigned char data[4]; /* Data from ROM */ | |
467 | int length; /* Length of directory */ | |
468 | int value; /* Value in directory */ | |
469 | ||
470 | ||
471 | /* | |
472 | * Read the directory length from the first quadlet... | |
473 | */ | |
474 | ||
475 | if (raw1394_read(handle, 0xffc0 | node, offset, 4, (quadlet_t *)data) < 0) | |
476 | return; | |
477 | ||
478 | offset += 4; | |
479 | ||
480 | /* | |
481 | * The length is in the upper 16 bits... | |
482 | */ | |
483 | ||
484 | length = (data[0] << 8) | data[1]; | |
485 | ||
486 | /* | |
487 | * Then read the directory... | |
488 | */ | |
489 | ||
490 | while (length > 0) | |
491 | { | |
492 | if (raw1394_read(handle, 0xffc0 | node, offset, 4, (quadlet_t *)data) < 0) | |
493 | return; | |
494 | ||
495 | for (i = 0; i < indent; i ++) | |
496 | putchar(' '); | |
497 | ||
498 | printf("%02X %02X %02X %02X\n", data[0], data[1], data[2], data[3]); | |
499 | ||
500 | value = (((data[1] << 8) | data[2]) << 8) | data[3]; | |
501 | ||
502 | switch (data[0] & 0xc0) | |
503 | { | |
504 | case 0x00 : | |
505 | for (i = -4; i < indent; i ++) | |
506 | putchar(' '); | |
507 | ||
508 | printf("IMMEDIATE %d\n", value); | |
509 | break; | |
510 | ||
511 | case 0x40 : | |
512 | for (i = -4; i < indent; i ++) | |
513 | putchar(' '); | |
514 | ||
515 | printf("CSR OFFSET +%06X\n", value); | |
516 | break; | |
517 | ||
518 | case 0x80 : | |
519 | show_data(handle, node, offset + value * 4, indent + 4); | |
520 | break; | |
521 | ||
522 | case 0xc0 : | |
523 | show_dir(handle, node, offset + value * 4, indent + 4); | |
524 | break; | |
525 | } | |
526 | ||
527 | offset += 4; | |
528 | length --; | |
529 | } | |
530 | } | |
531 | #endif /* DEBUG */ | |
532 | ||
533 | ||
534 | /* | |
535 | * 'ieee1394_list()' - List the available printer devices. | |
536 | */ | |
537 | ||
538 | ieee1394_info_t * /* O - Printer information */ | |
539 | ieee1394_list(int *num_devices) /* O - Number of printers */ | |
540 | { | |
541 | int i, j; /* Looping vars */ | |
542 | raw1394handle_t handle; /* 1394 handle */ | |
543 | int num_ports; /* Number of ports */ | |
544 | struct raw1394_portinfo ports[100]; /* Port data... */ | |
545 | unsigned char guid[8]; /* Global unique ID */ | |
546 | int vendor; /* Vendor portion of GUID */ | |
547 | int unit_type; /* Unit type */ | |
548 | int addr; /* Management address offset */ | |
549 | char id[1024], /* Device ID string */ | |
550 | *idptr, /* Pointer into ID string */ | |
551 | *idsep; /* Pointer to separator */ | |
552 | ieee1394_info_t *devices; /* Device list */ | |
553 | ||
554 | ||
555 | /* | |
556 | * Connect to the user-mode driver interface... | |
557 | */ | |
558 | ||
559 | handle = raw1394_new_handle(); | |
560 | num_ports = raw1394_get_port_info(handle, ports, | |
561 | sizeof(ports) / sizeof(ports[0])); | |
562 | ||
563 | DEBUG_printf(("num_ports = %d\n", num_ports)); | |
564 | ||
565 | /* | |
566 | * Loop through the ports to discover what nodes are available. | |
567 | */ | |
568 | ||
569 | num_nodes = 0; | |
570 | ||
571 | for (i = 0; i < num_ports; i ++) | |
572 | { | |
573 | DEBUG_printf(("ports[%d] = { nodes = %d, name = \"%s\" }\n", i, | |
574 | ports[i].nodes, ports[i].name)); | |
575 | ||
576 | raw1394_set_port(handle, i); | |
577 | ||
578 | for (j = 0; j < ports[i].nodes; j ++) | |
579 | { | |
580 | if (raw1394_read(handle, 0xffc0 | j, | |
581 | CSR_REGISTER_BASE + CSR_CONFIG_ROM + 12, 4, | |
582 | (quadlet_t *)guid) < 0) | |
583 | { | |
584 | DEBUG_printf((" Node #%d: Unable to contact (%s)!\n", j, | |
585 | strerror(errno))); | |
586 | continue; | |
587 | } | |
588 | else | |
589 | { | |
590 | raw1394_read(handle, 0xffc0 | j, | |
591 | CSR_REGISTER_BASE + CSR_CONFIG_ROM + 16, 4, | |
592 | (quadlet_t *)(guid + 4)); | |
593 | ||
594 | DEBUG_printf((" Node #%d: GUID = %02X%02X%02X%02X%02X%02X%02X%02X\n", | |
595 | j, guid[0], guid[1], guid[2], guid[3], guid[4], | |
596 | guid[5], guid[6], guid[7])); | |
597 | ||
598 | vendor = (((guid[0] << 8) | guid[1]) << 8) | guid[2]; | |
599 | unit_type = get_unit_type(handle, j, | |
600 | CSR_REGISTER_BASE + CSR_CONFIG_ROM + 20); | |
601 | ||
602 | DEBUG_printf(("vendor = %x, unit_type = %d\n", vendor, unit_type)); | |
603 | ||
604 | if (unit_type == 2 && num_nodes < MAX_NODES) | |
605 | { | |
606 | /* | |
607 | * Found a printer device; add it to the nodes list... | |
608 | */ | |
609 | ||
610 | #ifdef DEBUG | |
611 | show_dir(handle, j, CSR_REGISTER_BASE + CSR_CONFIG_ROM + 20, 0); | |
612 | #endif /* DEBUG */ | |
613 | ||
614 | memset(nodes + num_nodes, 0, sizeof(linux1394_node_t)); | |
615 | ||
616 | sprintf(nodes[num_nodes].uri, "ieee1394://%02X%02X%02X%02X%02X%02X%02X%02X", | |
617 | guid[0], guid[1], guid[2], guid[3], guid[4], | |
618 | guid[5], guid[6], guid[7]); | |
619 | ||
620 | nodes[num_nodes].port = i; | |
621 | nodes[num_nodes].node = j; | |
622 | ||
623 | addr = get_man_addr(handle, j, CSR_REGISTER_BASE + CSR_CONFIG_ROM + 20); | |
624 | ||
625 | if (addr < 0) | |
626 | continue; | |
627 | ||
628 | nodes[num_nodes].addr = CSR_REGISTER_BASE + addr; | |
629 | ||
630 | DEBUG_printf(("Node address = %llx\n", nodes[num_nodes].addr)); | |
631 | ||
632 | get_device_id(handle, j, CSR_REGISTER_BASE + CSR_CONFIG_ROM + 20, | |
633 | id, sizeof(id)); | |
634 | ||
635 | if (id[0]) | |
636 | { | |
637 | /* | |
638 | * Grab the manufacturer and model name from the device ID | |
639 | * string... | |
640 | */ | |
641 | ||
642 | idptr = id + 4; | |
643 | idsep = strchr(id, ';'); | |
644 | if (idsep) | |
645 | *idsep++ = '\0'; | |
646 | else | |
647 | idsep = idptr; | |
648 | ||
649 | snprintf(nodes[num_nodes].description, | |
650 | sizeof(nodes[num_nodes].description), | |
651 | "%s Firewire Printer", idptr); | |
652 | ||
653 | if ((idptr = strstr(idsep, "DES:")) == NULL) | |
654 | idptr = strstr(idsep, "MDL:"); | |
655 | ||
656 | if (idptr == NULL) | |
657 | strcpy(nodes[num_nodes].make_model, "Unknown"); | |
658 | else | |
659 | { | |
660 | /* | |
661 | * Grab the DES or MDL code... | |
662 | */ | |
663 | ||
664 | idptr += 4; | |
665 | idsep = strchr(idptr, ';'); | |
666 | if (idsep) | |
667 | *idsep = '\0'; | |
668 | ||
669 | if (strncmp(id + 4, idptr, strlen(id + 4)) == 0) | |
670 | { | |
671 | /* | |
672 | * Use the description directly... | |
673 | */ | |
674 | ||
675 | strlcpy(nodes[num_nodes].make_model, idptr, | |
676 | sizeof(nodes[num_nodes].make_model)); | |
677 | } | |
678 | else | |
679 | { | |
680 | /* | |
681 | * Add the manufacturer to the front of the name... | |
682 | */ | |
683 | ||
684 | snprintf(nodes[num_nodes].make_model, | |
685 | sizeof(nodes[num_nodes].make_model), | |
686 | "%s %s", id + 4, idptr); | |
687 | } | |
688 | } | |
689 | } | |
690 | else | |
691 | { | |
692 | /* | |
693 | * Flag it as an unknown printer... | |
694 | */ | |
695 | ||
696 | sprintf(nodes[num_nodes].description, | |
697 | "Unknown%06X Firewire Printer", vendor); | |
698 | strcpy(nodes[num_nodes].make_model, "Unknown"); | |
699 | } | |
700 | ||
701 | num_nodes ++; | |
702 | } | |
703 | } | |
704 | } | |
705 | } | |
706 | ||
707 | /* | |
708 | * Done querying the Firewire bus... | |
709 | */ | |
710 | ||
711 | raw1394_destroy_handle(handle); | |
712 | ||
713 | /* | |
714 | * Build an array of device info structures as needed... | |
715 | */ | |
716 | ||
717 | if (num_devices == NULL) | |
718 | return (NULL); | |
719 | ||
720 | *num_devices = num_nodes; | |
721 | ||
722 | if (num_nodes) | |
723 | { | |
724 | if ((devices = calloc(sizeof(ieee1394_info_t), num_nodes)) != NULL) | |
725 | { | |
726 | for (i = 0; i < num_nodes; i ++) | |
727 | { | |
728 | strcpy(devices[i].uri, nodes[i].uri); | |
729 | strcpy(devices[i].description, nodes[i].description); | |
730 | strcpy(devices[i].make_model, nodes[i].make_model); | |
731 | } | |
732 | } | |
733 | ||
734 | return (devices); | |
735 | } | |
736 | else | |
737 | return (NULL); | |
738 | } | |
739 | ||
740 | ||
741 | /* | |
742 | * 'ieee1394_open()' - Open a printer device. | |
743 | */ | |
744 | ||
745 | ieee1394_dev_t /* O - Printer device or NULL */ | |
746 | ieee1394_open(const char *uri) /* I - Device URI */ | |
747 | { | |
748 | int i; /* Looping var */ | |
749 | linux1394_dev_t *ldev; /* Linux device */ | |
750 | ||
751 | ||
752 | /* | |
753 | * Return early if we can't see any printers... | |
754 | */ | |
755 | ||
756 | if (num_nodes == 0) | |
757 | ieee1394_list(NULL); | |
758 | ||
759 | if (num_nodes == 0) | |
760 | { | |
761 | strcpy(error_string, "No IEEE-1394 printers found!"); | |
762 | return (NULL); | |
763 | } | |
764 | ||
765 | /* | |
766 | * Look for the URI... | |
767 | */ | |
768 | ||
769 | for (i = 0; i < num_nodes; i ++) | |
770 | if (strcmp(nodes[i].uri, uri) == 0) | |
771 | break; | |
772 | ||
773 | if (i >= num_nodes) | |
774 | { | |
775 | snprintf(error_string, sizeof(error_string), "Device %s not found!", uri); | |
776 | return (NULL); | |
777 | } | |
778 | ||
779 | /* | |
780 | * Now create a new device structure... | |
781 | */ | |
782 | ||
783 | if ((ldev = calloc(sizeof(linux1394_dev_t), 1)) == NULL) | |
784 | { | |
785 | strcpy(error_string, "Out of memory!"); | |
786 | return (NULL); | |
787 | } | |
788 | ||
789 | ldev->handle = raw1394_new_handle(); | |
790 | ldev->node = nodes[i].node; | |
791 | ldev->addr = nodes[i].addr; | |
792 | ||
793 | raw1394_set_port(ldev->handle, nodes[i].port); | |
794 | ||
795 | error_string[0] = '\0'; | |
796 | ||
797 | return ((ieee1394_dev_t)ldev); | |
798 | } | |
799 | ||
800 | ||
801 | /* | |
802 | * 'ieee1394_close()' - Close a printer device. | |
803 | */ | |
804 | ||
805 | int /* O - 0 on success, -1 on failure */ | |
806 | ieee1394_close(ieee1394_dev_t dev) /* I - Printer device */ | |
807 | { | |
808 | linux1394_dev_t *ldev; /* Linux device */ | |
809 | ||
810 | ||
811 | ldev = (linux1394_dev_t *)dev; | |
812 | ||
813 | raw1394_destroy_handle(ldev->handle); | |
814 | ||
815 | free(ldev); | |
816 | ||
817 | return (0); | |
818 | } | |
819 | ||
820 | ||
821 | /* | |
822 | * 'ieee1394_read()' - Read from a printer device. | |
823 | */ | |
824 | ||
825 | int /* O - Number of bytes read or -1 */ | |
826 | ieee1394_read(ieee1394_dev_t dev, /* I - Printer device */ | |
827 | char *buffer, /* I - Read buffer */ | |
828 | int len) /* I - Max bytes to read */ | |
829 | { | |
830 | linux1394_dev_t *ldev; /* Linux device */ | |
831 | ||
832 | ||
833 | ldev = (linux1394_dev_t *)dev; | |
834 | ||
835 | ||
836 | return (0); | |
837 | } | |
838 | ||
839 | ||
840 | /* | |
841 | * 'ieee1394_write()' - Write data to a printer device. | |
842 | */ | |
843 | ||
844 | int /* O - Number of bytes written or -1 */ | |
845 | ieee1394_write(ieee1394_dev_t dev, /* I - Printer device */ | |
846 | char *buffer, /* I - Buffer to write */ | |
847 | int len) /* I - Number of bytes to write */ | |
848 | { | |
849 | linux1394_dev_t *ldev; /* Linux device */ | |
850 | ||
851 | ||
852 | ldev = (linux1394_dev_t *)dev; | |
853 | ||
854 | ||
855 | /* if (raw1394_write(handle, 0xffc0 | j, 0, , | |
856 | (quadlet_t *)guid) < 0)*/ | |
857 | ||
858 | return (len); | |
859 | } | |
860 | ||
861 | ||
862 | /* | |
863 | * 'ieee1394_error()' - Return the last error. | |
864 | */ | |
865 | ||
866 | const char * /* O - Error string or NULL */ | |
867 | ieee1394_error(void) | |
868 | { | |
869 | if (error_string[0]) | |
870 | return (error_string); | |
871 | else | |
872 | return (NULL); | |
873 | } | |
874 | ||
875 | ||
876 | /* | |
bc44d920 | 877 | * End of "$Id: ieee1394-linux.c 6649 2007-07-11 21:46:42Z mike $". |
f7deaa1a | 878 | */ |