summaryrefslogtreecommitdiff
path: root/graphics/sane-frontends/files/patch-ae
blob: c880e73f2c0c2323ca33ed62fe18ceba6fcce39e (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
--- sanei/sanei_scsi.c.orig	Sat Aug 12 23:54:15 2000
+++ sanei/sanei_scsi.c	Fri Sep  8 22:38:49 2000
@@ -2424,6 +2424,169 @@
    cam_freeccb(ccb);
    return SANE_STATUS_GOOD;
 }
+
+#define WE_HAVE_FIND_DEVICES
+
+int
+cam_compare_inquiry(int fd, path_id_t path_id,
+		    target_id_t target_id, lun_id_t target_lun,
+		    const char *vendor, const char *product, const char *type)
+{
+  struct ccb_dev_match	cdm;
+  struct device_match_pattern *pattern;
+  struct scsi_inquiry_data *inq;
+  int retval = 0;
+
+  /* build ccb for device match */
+  bzero(&cdm, sizeof(cdm));
+  cdm.ccb_h.func_code = XPT_DEV_MATCH;
+
+  /* result buffer */
+  cdm.match_buf_len = sizeof(struct dev_match_result);
+  cdm.matches = (struct dev_match_result *)malloc(cdm.match_buf_len);
+  cdm.num_matches = 0;
+
+  /* pattern buffer */
+  cdm.num_patterns = 1;
+  cdm.pattern_buf_len = sizeof(struct dev_match_pattern);
+  cdm.patterns = (struct dev_match_pattern *)malloc(cdm.pattern_buf_len);
+
+  /* assemble conditions */
+  cdm.patterns[0].type = DEV_MATCH_DEVICE;
+  pattern = &cdm.patterns[0].pattern.device_pattern;
+  pattern->flags = DEV_MATCH_PATH | DEV_MATCH_TARGET | DEV_MATCH_LUN;
+  pattern->path_id = path_id;
+  pattern->target_id = target_id;
+  pattern->target_lun = target_lun;
+  
+  if (ioctl(fd, CAMIOCOMMAND, &cdm) == -1) {
+    DBG (1, "error sending CAMIOCOMMAND ioctl");
+    retval = -1;
+    goto ret;
+  }
+
+  if ((cdm.ccb_h.status != CAM_REQ_CMP)
+      || ((cdm.status != CAM_DEV_MATCH_LAST)
+	  && (cdm.status != CAM_DEV_MATCH_MORE))) {
+    DBG (1, "got CAM error %#x, CDM error %d\n",
+	 cdm.ccb_h.status, cdm.status);
+    retval = -1;
+    goto ret;
+  }
+
+  if (cdm.num_matches == 0) {
+    DBG (1, "not found\n");
+    retval = -1;
+    goto ret;
+  }
+	    
+  if (cdm.matches[0].type != DEV_MATCH_DEVICE) {
+    DBG (1, "no device match\n");
+    retval = -1;
+    goto ret;
+  }
+
+  inq = &cdm.matches[0].result.device_result.inq_data;
+  if ((vendor && cam_strmatch(inq->vendor, vendor, SID_VENDOR_SIZE)) ||
+      (product && cam_strmatch(inq->product, product, SID_PRODUCT_SIZE)))
+    retval = 1;
+ 
+ ret:
+  free(cdm.patterns);
+  free(cdm.matches);
+  return(retval);
+}
+
+void
+sanei_scsi_find_devices (const char *findvendor, const char *findmodel,
+			 const char *findtype,
+			 int findbus, int findchannel, int findid, int findlun,
+			 SANE_Status (*attach) (const char *dev))
+{
+  int		fd;
+  struct ccb_dev_match	cdm;
+  struct periph_match_pattern *pattern;
+  struct periph_match_result *result;
+  int		i;
+  char devname[16];
+
+  DBG_INIT();
+
+  if ((fd = open(XPT_DEVICE, O_RDWR)) == -1) {
+    DBG (1, "could not open %s\n", XPT_DEVICE);
+    return;
+  }
+
+  /* build ccb for device match */
+  bzero(&cdm, sizeof(cdm));
+  cdm.ccb_h.func_code = XPT_DEV_MATCH;
+
+  /* result buffer */
+  cdm.match_buf_len = sizeof(struct dev_match_result) * 100;
+  cdm.matches = (struct dev_match_result *)malloc(cdm.match_buf_len);
+  cdm.num_matches = 0;
+
+  /* pattern buffer */
+  cdm.num_patterns = 1;
+  cdm.pattern_buf_len = sizeof(struct dev_match_pattern);
+  cdm.patterns = (struct dev_match_pattern *)malloc(cdm.pattern_buf_len);
+
+  /* assemble conditions ... findchannel is ignored */
+  cdm.patterns[0].type = DEV_MATCH_PERIPH;
+  pattern = &cdm.patterns[0].pattern.periph_pattern;
+  pattern->flags = PERIPH_MATCH_NAME;
+  strcpy(pattern->periph_name, "pass");
+  if (findbus != -1) {
+    pattern->path_id = findbus;
+    pattern->flags |= PERIPH_MATCH_PATH;
+  }    
+  if (findid != -1) {
+    pattern->target_id = findid;
+    pattern->flags |= PERIPH_MATCH_TARGET;
+  }
+  if (findlun != -1) {
+    pattern->target_lun = findlun;
+    pattern->flags |= PERIPH_MATCH_LUN;
+  }
+
+  /* result loop */
+  do {
+    if (ioctl(fd, CAMIOCOMMAND, &cdm) == -1) {
+      DBG (1, "error sending CAMIOCOMMAND ioctl");
+      break;
+    }
+
+    if ((cdm.ccb_h.status != CAM_REQ_CMP)
+	|| ((cdm.status != CAM_DEV_MATCH_LAST)
+	    && (cdm.status != CAM_DEV_MATCH_MORE))) {
+      DBG (1, "got CAM error %#x, CDM error %d\n", 
+	   cdm.ccb_h.status, cdm.status);
+      break;
+    }
+    
+    for (i = 0; i < cdm.num_matches; i++) {
+      if (cdm.matches[i].type != DEV_MATCH_PERIPH)
+	continue;
+      result = &cdm.matches[i].result.periph_result;
+      DBG (4, "%s%d on scbus%d %d:%d\n",
+	      result->periph_name, result->unit_number,
+	      result->path_id, result->target_id, result->target_lun);
+      if (cam_compare_inquiry(fd, result->path_id,
+			      result->target_id, result->target_lun,
+			      findvendor, findmodel, findtype) == 0) {
+	sprintf(devname, "/dev/%s%d", result->periph_name, result->unit_number);
+	(*attach) (devname);
+      }
+    }
+  } while ((cdm.ccb_h.status == CAM_REQ_CMP)
+	   && (cdm.status == CAM_DEV_MATCH_MORE));
+
+  free(cdm.patterns);
+  free(cdm.matches);
+  close(fd);
+  return;
+}
+
 #endif
 
 
@@ -3722,6 +3885,7 @@
 			 int findbus, int findchannel, int findid, int findlun,
 			 SANE_Status (*attach) (const char *dev))
 {
+  DBG_INIT();
   DBG (1, "sanei_scsi_find_devices: not implemented for this platform\n");
 }