Load cups into easysw/current.
[thirdparty/cups.git] / backend / ieee1394-linux.c
1 /*
2  * "$Id: ieee1394-linux.c 4703 2005-09-26 19:33:58Z mike $"
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 /*
876  * End of "$Id: ieee1394-linux.c 4703 2005-09-26 19:33:58Z mike $".
877  */