1 /*
2 * SANE backend for Xerox Phaser 3200MFP
3 * Copyright 2008 ABC <abc@telekom.ru>
4 *
5 * This program is licensed under GPL + SANE exception.
6 * More info at http://www.sane-project.org/license.html
7 */
8
9 #undef BACKEND_NAME
10 #define BACKEND_NAME xerox_mfp
11 #define DEBUG_DECLARE_ONLY
12 #define DEBUG_NOT_STATIC
13 #include "sane/config.h"
14 #include "sane/saneopts.h"
15 #include "sane/sanei_config.h"
16 #include "sane/sanei_backend.h"
17 #include "sane/sanei_debug.h"
18 #include "sane/sanei_usb.h"
19 #include "xerox_mfp.h"
20
21
22 extern int sanei_debug_xerox_mfp;
23
24 static int
xerox_need_clear_halt()25 xerox_need_clear_halt()
26 {
27 char *env;
28 int workaround = 0;
29
30 env = getenv("SANE_XEROX_USB_HALT_WORKAROUND");
31 if (env) {
32 workaround = atoi(env);
33 DBG(5, "xerox_need_clear_halt: workaround: %d\n", workaround);
34 return workaround;
35 }
36 return 0;
37 }
38
39 int
usb_dev_request(struct device * dev,SANE_Byte * cmd,size_t cmdlen,SANE_Byte * resp,size_t * resplen)40 usb_dev_request(struct device *dev,
41 SANE_Byte *cmd, size_t cmdlen,
42 SANE_Byte *resp, size_t *resplen)
43 {
44 SANE_Status status;
45 size_t len = cmdlen;
46
47 if (cmd && cmdlen) {
48 status = sanei_usb_write_bulk(dev->dn, cmd, &cmdlen);
49 if (status != SANE_STATUS_GOOD) {
50 DBG(1, "%s: sanei_usb_write_bulk: %s\n", __func__,
51 sane_strstatus(status));
52 return SANE_STATUS_IO_ERROR;
53 }
54
55 if (cmdlen != len) {
56 DBG(1, "%s: sanei_usb_write_bulk: wanted %lu bytes, wrote %lu bytes\n",
57 __func__, (size_t)len, (size_t)cmdlen);
58 return SANE_STATUS_IO_ERROR;
59 }
60 }
61
62 if (resp && resplen) {
63 status = sanei_usb_read_bulk(dev->dn, resp, resplen);
64 if (status != SANE_STATUS_GOOD) {
65 DBG(1, "%s: sanei_usb_read_bulk: %s\n", __func__,
66 sane_strstatus(status));
67 return SANE_STATUS_IO_ERROR;
68 }
69 }
70
71 return SANE_STATUS_GOOD;
72 }
73
74
75 SANE_Status
usb_dev_open(struct device * dev)76 usb_dev_open(struct device *dev)
77 {
78 SANE_Status status;
79
80 DBG(3, "%s: open %p\n", __func__, (void *)dev);
81 status = sanei_usb_open(dev->sane.name, &dev->dn);
82 if (status != SANE_STATUS_GOOD) {
83 DBG(1, "%s: sanei_usb_open(%s): %s\n", __func__,
84 dev->sane.name, sane_strstatus(status));
85 dev->dn = -1;
86 return status;
87 }
88 if (xerox_need_clear_halt()) {
89 sanei_usb_clear_halt(dev->dn);
90 }
91 return SANE_STATUS_GOOD;
92 }
93
94 void
usb_dev_close(struct device * dev)95 usb_dev_close(struct device *dev)
96 {
97 if (!dev)
98 return;
99 DBG(3, "%s: closing dev %p\n", __func__, (void *)dev);
100
101 /* finish all operations */
102 if (dev->scanning) {
103 dev->cancel = 1;
104 /* flush READ_IMAGE data */
105 if (dev->reading)
106 sane_read(dev, NULL, 1, NULL);
107 /* send cancel if not sent before */
108 if (dev->state != SANE_STATUS_CANCELLED)
109 ret_cancel(dev, 0);
110 }
111
112 if (xerox_need_clear_halt()) {
113 sanei_usb_clear_halt(dev->dn); /* unstall for next users */
114 }
115 sanei_usb_close(dev->dn);
116 dev->dn = -1;
117 }
118
119
120 /* SANE API ignores return code of this callback */
121 SANE_Status
usb_configure_device(const char * devname,SANE_Status (* attach)(const char * dev))122 usb_configure_device(const char *devname, SANE_Status(*attach)(const char *dev))
123 {
124 sanei_usb_set_timeout(1000);
125 sanei_usb_attach_matching_devices(devname, attach);
126 sanei_usb_set_timeout(30000);
127 return SANE_STATUS_GOOD;
128 }
129
130
131 /* xerox_mfp-usb.c */
132