123
124
#define UW_PACKET_DATA ((uw4c_t){ 0x02, 0x00, 0xff, 0x9f })
124
125
#define UW_PACKET_STAT ((uw4c_t){ 0x03, 0x00, 0xff, 0x9f })
127
#define UW_MAGIC_OUT ((uw4c_t){ 'U','S','B','C' })
128
#define UW_MAGIC_IN ((uw4c_t){ 'U','S','B','S' })
131
/* This is linux/include/linux/usb/storage.h, struct bulk_cb_wrap
135
uw4c_t magic; /* The letters U S B C for packets sent to camera */
136
uw32_t tag; /* The SCSI command tag */
137
uw32_t rw_length; /* Length of data to be read or written next */
138
unsigned char flags; /* in / out flag mostly */
139
unsigned char lun; /* 0 here */
140
unsigned char length; /* of the CDB... but 0x0c is used here in the traces */
141
unsigned char cdb[16];
145
* This is the end response block from the camera looks like this:
147
* This is the generic bulk style USB Storage response block.
149
* linux/include/linux/usb/storage.h, struct bulk_cs_wrap */
152
uw4c_t magic; /* The letters U S B S for packets from camera */
153
uw32_t tag; /* A copy of whatever value the host made up */
154
uw32_t residue; /* residual read? */
155
char status; /* status byte */
128
159
* Data packet sent along with a UW_REQUEST_RDY:
208
static int ums_tag = 0x42424242;
212
GPPort *dev, int todev,
213
char *cmd, unsigned int cmdlen,
214
char *sense, unsigned int senselen,
215
char *data, unsigned int size
223
ret = gp_port_get_info (dev, &info);
224
if (ret != GP_OK) return ret;
226
ret = gp_port_info_get_type (info, &type);
227
if (ret != GP_OK) return ret;
229
if (type == GP_PORT_USB_SCSI)
230
/* just send it to the generic SCSI stack */
231
return gp_port_send_scsi_cmd (
238
/* Assuming plain USB, emulating SCSI ... */
240
memset(&hdr, 0, sizeof(hdr));
241
hdr.magic = UW_MAGIC_OUT;
242
hdr.tag = uw_value(ums_tag);
244
hdr.rw_length = uw_value(size);
245
hdr.length = 12; /* seems to be always 12, even as we send 16 byte CDBs */
246
hdr.flags = todev?0:(1<<7);
249
memcpy(hdr.cdb, cmd, cmdlen);
251
/* WRITE scsi header / cdb */
252
if ((ret=gp_port_write(dev, (char*)&hdr, sizeof(hdr))) < GP_OK) {
253
GP_DEBUG( "scsi_wrap_cmd *** FAILED to write scsi cmd" );
256
/* WRITE / READ data blob */
258
if ((ret=gp_port_write(dev, (char*)data, size)) < GP_OK) {
259
GP_DEBUG( "scsi_wrap_cmd *** FAILED to write scsi data" );
263
if ((ret=gp_port_read(dev, (char*)data, size)) < GP_OK) {
264
GP_DEBUG( "scsi_wrap_cmd *** FAILED to read scsi data" );
270
memset(&rsp, 0, sizeof(rsp));
272
GP_DEBUG( "usb_wrap_OK" );
273
if ((ret = gp_port_read(dev, (char*)&rsp, sizeof(rsp))) != sizeof(rsp)) {
274
gp_log (GP_LOG_DEBUG, GP_MODULE, "scsi_wrap_cmd *** FAILED (%d vs %d bytes)", (int)sizeof(rsp), ret );
279
if ( !UW_EQUAL(rsp.magic, UW_MAGIC_IN) ||
280
!UW_EQUAL(rsp.tag, hdr.tag))
282
GP_DEBUG( "scsi_wrap_cmd wrong session *** FAILED" );
286
* 32bit residual length (0) and 8 bit status (0) are good.
288
if ( rsp.residue.c1 != 0 ||
289
rsp.residue.c2 != 0 ||
290
rsp.residue.c3 != 0 ||
291
rsp.residue.c4 != 0 ||
293
GP_DEBUG( "Error: scsi_wrap_cmd - residual non-0 or status %x", rsp.status);
299
#define gp_port_send_scsi_cmd scsi_wrap_cmd
188
302
usb_wrap_RDY(gp_port* dev, unsigned int type)