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