1 /*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21 /*
22 * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
24 */
25
26
27 /*
28 * scsa2usb bridge nexus driver:
29 *
30 * This driver supports the following wire transports:
31 * a. Bulk Only transport (see usb_ms_bulkonly.c)
32 * b. CB transport (see usb_ms_cbi.c)
33 * c. CBI transport with interrupt status completion (see usb_ms_cbi.c)
34 *
35 * It handles the following command sets:
36 * a. SCSI
37 * b. ATAPI command set (subset of SCSI command set)
38 * c. UFI command set (
39 * http://www.usb.org/developers/devclass_docs/usbmass-ufi10.pdf)
40 *
41 * For details on USB Mass Storage Class overview:
42 * http://www.usb.org/developers/devclass_docs/usbmassover_11.pdf
43 */
44 #if defined(lint) && !defined(DEBUG)
45 #define DEBUG 1
46 #endif
47
48 #include <sys/usb/usba/usbai_version.h>
49 #include <sys/scsi/scsi.h>
50 #include <sys/cdio.h>
51 #include <sys/sunndi.h>
52 #include <sys/esunddi.h>
53 #include <sys/callb.h>
54 #include <sys/kobj.h>
55 #include <sys/kobj_lex.h>
56 #include <sys/strsubr.h>
57 #include <sys/strsun.h>
58 #include <sys/sysmacros.h>
59
60 #include <sys/usb/usba.h>
61 #include <sys/usb/clients/ugen/usb_ugen.h>
62 #include <sys/usb/usba/usba_ugen.h>
63
64 #include <sys/usb/usba/usba_private.h>
65 #include <sys/usb/usba/usba_ugend.h>
66 #include <sys/usb/clients/mass_storage/usb_bulkonly.h>
67 #include <sys/usb/scsa2usb/scsa2usb.h>
68
69 /*
70 * Function Prototypes
71 */
72 static int scsa2usb_attach(dev_info_t *, ddi_attach_cmd_t);
73 static int scsa2usb_info(dev_info_t *, ddi_info_cmd_t, void *,
74 void **);
75 static int scsa2usb_detach(dev_info_t *, ddi_detach_cmd_t);
76 static int scsa2usb_cleanup(dev_info_t *, scsa2usb_state_t *);
77 static void scsa2usb_validate_attrs(scsa2usb_state_t *);
78 static void scsa2usb_create_luns(scsa2usb_state_t *);
79 static int scsa2usb_is_usb(dev_info_t *);
80 static void scsa2usb_fake_inquiry(scsa2usb_state_t *,
81 struct scsi_inquiry *);
82 static void scsa2usb_do_inquiry(scsa2usb_state_t *,
83 uint_t, uint_t);
84 static int scsa2usb_do_tur(scsa2usb_state_t *, struct scsi_address *);
85
86 /* override property handling */
87 static void scsa2usb_override(scsa2usb_state_t *);
88 static int scsa2usb_parse_input_str(char *, scsa2usb_ov_t *,
89 scsa2usb_state_t *);
90 static void scsa2usb_override_error(char *, scsa2usb_state_t *);
91 static char *scsa2usb_strtok_r(char *, char *, char **);
92
93
94 /* PANIC callback handling */
95 static void scsa2usb_panic_callb_init(scsa2usb_state_t *);
96 static void scsa2usb_panic_callb_fini(scsa2usb_state_t *);
97 static boolean_t scsa2usb_panic_callb(void *, int);
98
99 /* SCSA support */
100 static int scsa2usb_scsi_tgt_probe(struct scsi_device *, int (*)(void));
101 static int scsa2usb_scsi_tgt_init(dev_info_t *, dev_info_t *,
102 scsi_hba_tran_t *, struct scsi_device *);
103 static void scsa2usb_scsi_tgt_free(dev_info_t *, dev_info_t *,
104 scsi_hba_tran_t *, struct scsi_device *);
105 static struct scsi_pkt *scsa2usb_scsi_init_pkt(struct scsi_address *,
106 struct scsi_pkt *, struct buf *, int, int,
107 int, int, int (*)(), caddr_t);
108 static void scsa2usb_scsi_destroy_pkt(struct scsi_address *,
109 struct scsi_pkt *);
110 static int scsa2usb_scsi_start(struct scsi_address *, struct scsi_pkt *);
111 static int scsa2usb_scsi_abort(struct scsi_address *, struct scsi_pkt *);
112 static int scsa2usb_scsi_reset(struct scsi_address *, int);
113 static int scsa2usb_scsi_getcap(struct scsi_address *, char *, int);
114 static int scsa2usb_scsi_setcap(struct scsi_address *, char *, int, int);
115 static int scsa2usb_scsi_bus_config(dev_info_t *, uint_t,
116 ddi_bus_config_op_t, void *, dev_info_t **);
117 static int scsa2usb_scsi_bus_unconfig(dev_info_t *, uint_t,
118 ddi_bus_config_op_t, void *);
119
120 /* functions for command and transport support */
121 static void scsa2usb_prepare_pkt(scsa2usb_state_t *, struct scsi_pkt *);
122 static int scsa2usb_cmd_transport(scsa2usb_state_t *, scsa2usb_cmd_t *);
123 static int scsa2usb_check_bulkonly_blacklist_attrs(scsa2usb_state_t *,
124 scsa2usb_cmd_t *, uchar_t);
125 static int scsa2usb_check_ufi_blacklist_attrs(scsa2usb_state_t *, uchar_t,
126 scsa2usb_cmd_t *);
127 static int scsa2usb_handle_scsi_cmd_sub_class(scsa2usb_state_t *,
128 scsa2usb_cmd_t *, struct scsi_pkt *);
129 static int scsa2usb_handle_ufi_subclass_cmd(scsa2usb_state_t *,
130 scsa2usb_cmd_t *, struct scsi_pkt *);
131
132 /* waitQ handling */
133 static void scsa2usb_work_thread(void *);
134 static void scsa2usb_transport_request(scsa2usb_state_t *, uint_t);
135 static void scsa2usb_flush_waitQ(scsa2usb_state_t *, uint_t, uchar_t);
136 static int scsa2usb_all_waitQs_empty(scsa2usb_state_t *);
137
138 /* auto request sense handling */
139 static int scsa2usb_create_arq_pkt(scsa2usb_state_t *,
140 struct scsi_address *);
141 static void scsa2usb_delete_arq_pkt(scsa2usb_state_t *);
142 static void scsa2usb_complete_arq_pkt(scsa2usb_state_t *, struct scsi_pkt *,
143 scsa2usb_cmd_t *, struct buf *);
144
145 /* utility functions for any transport */
146 static int scsa2usb_open_usb_pipes(scsa2usb_state_t *);
147 void scsa2usb_close_usb_pipes(scsa2usb_state_t *);
148
149 static void scsa2usb_fill_up_cdb_len(scsa2usb_cmd_t *, int);
150 static void scsa2usb_fill_up_cdb_lba(scsa2usb_cmd_t *, int);
151 static void scsa2usb_fill_up_ReadCD_cdb_len(scsa2usb_cmd_t *, int, int);
152 static void scsa2usb_fill_up_12byte_cdb_len(scsa2usb_cmd_t *, int, int);
153 static int scsa2usb_read_cd_blk_size(uchar_t);
154 int scsa2usb_rw_transport(scsa2usb_state_t *, struct scsi_pkt *);
155 void scsa2usb_setup_next_xfer(scsa2usb_state_t *, scsa2usb_cmd_t *);
156
157 static mblk_t *scsa2usb_bp_to_mblk(scsa2usb_state_t *);
158 int scsa2usb_handle_data_start(scsa2usb_state_t *,
159 scsa2usb_cmd_t *, usb_bulk_req_t *);
160 void scsa2usb_handle_data_done(scsa2usb_state_t *,
161 scsa2usb_cmd_t *cmd, usb_bulk_req_t *);
162
163 usb_bulk_req_t *scsa2usb_init_bulk_req(scsa2usb_state_t *,
164 size_t, uint_t, usb_req_attrs_t, usb_flags_t);
165 int scsa2usb_bulk_timeout(int);
166 int scsa2usb_clear_ept_stall(scsa2usb_state_t *, uint_t,
167 usb_pipe_handle_t, char *);
168 static void scsa2usb_pkt_completion(scsa2usb_state_t *, struct scsi_pkt *);
169
170 /* event handling */
171 static int scsa2usb_reconnect_event_cb(dev_info_t *);
172 static int scsa2usb_disconnect_event_cb(dev_info_t *);
173 static int scsa2usb_cpr_suspend(dev_info_t *);
174 static void scsa2usb_cpr_resume(dev_info_t *);
175 static void scsa2usb_restore_device_state(dev_info_t *, scsa2usb_state_t *);
176
177 /* PM handling */
178 static void scsa2usb_create_pm_components(dev_info_t *, scsa2usb_state_t *);
179 static void scsa2usb_raise_power(scsa2usb_state_t *);
180 static int scsa2usb_pwrlvl0(scsa2usb_state_t *);
181 static int scsa2usb_pwrlvl1(scsa2usb_state_t *);
182 static int scsa2usb_pwrlvl2(scsa2usb_state_t *);
183 static int scsa2usb_pwrlvl3(scsa2usb_state_t *);
184 static int scsa2usb_power(dev_info_t *, int comp, int level);
185 static void scsa2usb_pm_busy_component(scsa2usb_state_t *);
186 static void scsa2usb_pm_idle_component(scsa2usb_state_t *);
187
188 /* external functions for Bulk only (BO) support */
189 extern int scsa2usb_bulk_only_transport(scsa2usb_state_t *,
190 scsa2usb_cmd_t *);
191 extern int scsa2usb_bulk_only_get_max_lun(scsa2usb_state_t *);
192
193 /* external functions for CB/CBI support */
194 extern int scsa2usb_cbi_transport(scsa2usb_state_t *, scsa2usb_cmd_t *);
195 extern void scsa2usb_cbi_stop_intr_polling(scsa2usb_state_t *);
196
197
198 /* cmd decoding */
199 static char *scsa2usb_cmds[] = {
200 "\000tur",
201 "\001rezero",
202 "\003rqsense",
203 "\004format",
204 "\014cartprot",
205 "\022inquiry",
206 "\026tranlba",
207 "\030fmtverify",
208 "\032modesense",
209 "\033start",
210 "\035snddiag",
211 "\036doorlock",
212 "\043formatcap",
213 "\045readcap",
214 "\050read10",
215 "\052write10",
216 "\053seek10",
217 "\056writeverify",
218 "\057verify",
219 "\065synchcache",
220 "\076readlong",
221 "\077writelong",
222 "\102readsubchan",
223 "\103readtoc",
224 "\104readhdr",
225 "\105playaudio10",
226 "\107playaudio_msf",
227 "\110playaudio_ti",
228 "\111playtrk_r10",
229 "\112geteventnotify",
230 "\113pause_resume",
231 "\116stop/play_scan",
232 "\121readdiscinfo",
233 "\122readtrkinfo",
234 "\123reservedtrk",
235 "\124sendopcinfo",
236 "\125modeselect",
237 "\132modesense",
238 "\133closetrksession",
239 "\135sendcuesheet",
240 "\136prin",
241 "\137prout",
242 "\241blankcd",
243 "\245playaudio12",
244 "\250read12",
245 "\251playtrk12",
246 "\252write12",
247 "\254getperf",
248 "\271readcdmsf",
249 "\273setcdspeed",
250 "\275mechanism_sts",
251 "\276readcd",
252 NULL
253 };
254
255
256 /*
257 * Mass-Storage devices masquerade as "sd" disks.
258 *
259 * These devices may not support all SCSI CDBs in their
260 * entirety due to their hardware implementation limitations.
261 *
262 * As such, following is a list of some of the black-listed
263 * devices w/ the attributes that they do not support.
264 * (See scsa2usb.h for description on each attribute)
265 */
266 #define X ((uint16_t)(-1))
267
268 static struct blacklist {
269 uint16_t idVendor; /* vendor ID */
270 uint16_t idProduct; /* product ID */
271 uint16_t bcdDevice; /* device release number in bcd */
272 uint16_t attributes; /* attributes to blacklist */
273 } scsa2usb_blacklist[] = {
274 /* Iomega Zip100 drive (prototype) with flaky bridge */
275 {MS_IOMEGA_VID, MS_IOMEGA_PID1_ZIP100, 0,
276 SCSA2USB_ATTRS_GET_LUN | SCSA2USB_ATTRS_PM},
277
278 /* Iomega Zip100 drive (newer model) with flaky bridge */
279 {MS_IOMEGA_VID, MS_IOMEGA_PID2_ZIP100, 0,
280 SCSA2USB_ATTRS_GET_LUN | SCSA2USB_ATTRS_PM},
281
282 /* Iomega Zip100 drive (newer model) with flaky bridge */
283 {MS_IOMEGA_VID, MS_IOMEGA_PID3_ZIP100, 0,
284 SCSA2USB_ATTRS_GET_LUN | SCSA2USB_ATTRS_PM},
285
286 /* Iomega Zip250 drive */
287 {MS_IOMEGA_VID, MS_IOMEGA_PID_ZIP250, 0, SCSA2USB_ATTRS_GET_LUN},
288
289 /* Iomega Clik! drive */
290 {MS_IOMEGA_VID, MS_IOMEGA_PID_CLIK, 0,
291 SCSA2USB_ATTRS_GET_LUN | SCSA2USB_ATTRS_START_STOP},
292
293 /* Kingston DataTraveler Stick / PNY Attache Stick */
294 {MS_TOSHIBA_VID, MS_TOSHIBA_PID0, 0,
295 SCSA2USB_ATTRS_GET_LUN},
296
297 /* PNY Floppy drive */
298 {MS_PNY_VID, MS_PNY_PID0, 0,
299 SCSA2USB_ATTRS_GET_LUN},
300
301 /* SMSC floppy Device - and its clones */
302 {MS_SMSC_VID, X, 0, SCSA2USB_ATTRS_START_STOP},
303
304 /* Hagiwara SmartMedia Device */
305 {MS_HAGIWARA_SYS_COM_VID, MS_HAGIWARA_SYSCOM_PID1, 0,
306 SCSA2USB_ATTRS_GET_LUN | SCSA2USB_ATTRS_START_STOP},
307
308 /* Hagiwara CompactFlash Device */
309 {MS_HAGIWARA_SYS_COM_VID, MS_HAGIWARA_SYSCOM_PID2, 0,
310 SCSA2USB_ATTRS_GET_LUN | SCSA2USB_ATTRS_START_STOP},
311
312 /* Hagiwara SmartMedia/CompactFlash Combo Device */
313 {MS_HAGIWARA_SYS_COM_VID, MS_HAGIWARA_SYSCOM_PID3, 0,
314 SCSA2USB_ATTRS_START_STOP},
315
316 /* Hagiwara new SM Device */
317 {MS_HAGIWARA_SYS_COM_VID, MS_HAGIWARA_SYSCOM_PID4, 0,
318 SCSA2USB_ATTRS_GET_LUN | SCSA2USB_ATTRS_START_STOP},
319
320 /* Hagiwara new CF Device */
321 {MS_HAGIWARA_SYS_COM_VID, MS_HAGIWARA_SYSCOM_PID5, 0,
322 SCSA2USB_ATTRS_GET_LUN | SCSA2USB_ATTRS_START_STOP},
323
324 /* Mitsumi CD-RW Device(s) */
325 {MS_MITSUMI_VID, X, X, SCSA2USB_ATTRS_BIG_TIMEOUT |
326 SCSA2USB_ATTRS_GET_CONF | SCSA2USB_ATTRS_GET_PERF},
327
328 /* Neodio Technologies Corporation SM/CF/MS/SD Combo Device */
329 {MS_NEODIO_VID, MS_NEODIO_DEVICE_3050, 0,
330 SCSA2USB_ATTRS_MODE_SENSE },
331
332 /* dumb flash devices */
333 {MS_SONY_FLASH_VID, MS_SONY_FLASH_PID, 0,
334 SCSA2USB_ATTRS_REDUCED_CMD},
335
336 {MS_TREK_FLASH_VID, MS_TREK_FLASH_PID, 0,
337 SCSA2USB_ATTRS_REDUCED_CMD},
338
339 {MS_PENN_FLASH_VID, MS_PENN_FLASH_PID, 0,
340 SCSA2USB_ATTRS_REDUCED_CMD},
341
342 /* SimpleTech UCF-100 CF Device */
343 {MS_SIMPLETECH_VID, MS_SIMPLETECH_PID1, 0,
344 SCSA2USB_ATTRS_REDUCED_CMD},
345
346 {MS_ADDONICS_CARD_READER_VID, MS_ADDONICS_CARD_READER_PID,
347 0, SCSA2USB_ATTRS_REDUCED_CMD},
348
349 /* Acomdata 80GB USB/1394 Hard Disk */
350 {MS_ACOMDATA_VID, MS_ACOMDATA_PID1, 0,
351 SCSA2USB_ATTRS_USE_CSW_RESIDUE},
352
353 /* OTi6828 Flash Disk */
354 {MS_OTI_VID, MS_OTI_DEVICE_6828, 0,
355 SCSA2USB_ATTRS_USE_CSW_RESIDUE},
356
357 /* AMI Virtual Floppy */
358 {MS_AMI_VID, MS_AMI_VIRTUAL_FLOPPY, 0,
359 SCSA2USB_ATTRS_NO_MEDIA_CHECK},
360
361 /* ScanLogic USB Storage Device */
362 {MS_SCANLOGIC_VID, MS_SCANLOGIC_PID1, 0,
363 SCSA2USB_ATTRS_NO_CAP_ADJUST},
364
365 /* Super Top USB 2.0 IDE Device */
366 {MS_SUPERTOP_VID, MS_SUPERTOP_DEVICE_6600, 0,
367 SCSA2USB_ATTRS_USE_CSW_RESIDUE},
368
369 /* Aigo Miniking Device NEHFSP14 */
370 {MS_AIGO_VID, MS_AIGO_DEVICE_6981, 0,
371 SCSA2USB_ATTRS_USE_CSW_RESIDUE},
372
373 /* Alcor Micro Corp 6387 flash disk */
374 {MS_ALCOR_VID, MS_ALCOR_PID0, 0,
375 SCSA2USB_ATTRS_GET_LUN | SCSA2USB_ATTRS_USE_CSW_RESIDUE},
376
377 /* Western Digital External HDD */
378 {MS_WD_VID, MS_WD_PID, 0,
379 SCSA2USB_ATTRS_INQUIRY_EVPD}
380 };
381
382
383 #define N_SCSA2USB_BLACKLIST (sizeof (scsa2usb_blacklist))/ \
384 sizeof (struct blacklist)
385
386 /*
387 * Attribute values can be overridden by values
388 * contained in the scsa2usb.conf file.
389 * These arrays define possible user input values.
390 */
391
392 struct scsa2usb_subclass_protocol_override {
393 char *name;
394 int value;
395 };
396
397 static struct scsa2usb_subclass_protocol_override scsa2usb_protocol[] = {
398 {"CB", SCSA2USB_CB_PROTOCOL},
399 {"CBI", SCSA2USB_CBI_PROTOCOL},
400 {"BO", SCSA2USB_BULK_ONLY_PROTOCOL}
401 };
402
403 static struct scsa2usb_subclass_protocol_override scsa2usb_subclass[] = {
404 {"SCSI", SCSA2USB_SCSI_CMDSET},
405 {"ATAPI", SCSA2USB_ATAPI_CMDSET},
406 {"UFI", SCSA2USB_UFI_CMDSET}
407 };
408
409
410 #define N_SCSA2USB_SUBC_OVERRIDE (sizeof (scsa2usb_subclass))/ \
411 sizeof (struct scsa2usb_subclass_protocol_override)
412
413 #define N_SCSA2USB_PROT_OVERRIDE (sizeof (scsa2usb_protocol))/ \
414 sizeof (struct scsa2usb_subclass_protocol_override)
415
416 /* global variables */
417 static void *scsa2usb_statep; /* for soft state */
418 static boolean_t scsa2usb_sync_message = B_TRUE; /* for syncing */
419
420 /* for debug messages */
421 uint_t scsa2usb_errmask = (uint_t)DPRINT_MASK_ALL;
422 uint_t scsa2usb_errlevel = USB_LOG_L4;
423 uint_t scsa2usb_instance_debug = (uint_t)-1;
424 uint_t scsa2usb_scsi_bus_config_debug = 0;
425 uint_t scsa2usb_long_timeout = 50 * SCSA2USB_BULK_PIPE_TIMEOUT;
426
427
428 /*
429 * Some devices have problems with big bulk transfers,
430 * transfers >= 128kbytes hang the device. This tunable allows to
431 * limit the maximum bulk transfers rate.
432 */
433 uint_t scsa2usb_max_bulk_xfer_size = SCSA2USB_MAX_BULK_XFER_SIZE;
434
435
436 #ifdef SCSA2USB_BULK_ONLY_TEST
437 /*
438 * Test BO 13 cases. (See USB Mass Storage Class - Bulk Only Transport).
439 * We are not covering test cases 1, 6, and 12 as these are the "good"
440 * test cases and are tested as part of the normal drive access operations.
441 *
442 * NOTE: This is for testing only. It will be replaced by a uscsi test.
443 * Some are listed here while; other test cases are moved to usb_bulkonly.c
444 */
445 static int scsa2usb_test_case_5 = 0;
446 int scsa2usb_test_case_8 = 0;
447 int scsa2usb_test_case_10 = 0;
448 static int scsa2usb_test_case_11 = 0;
449
450 static void scsa2usb_test_mblk(scsa2usb_state_t *, boolean_t);
451 #endif /* SCSA2USB_BULK_ONLY_TEST */
452
453 static int scsa2usb_ugen_open(dev_t *, int, int, cred_t *);
454 static int scsa2usb_ugen_close(dev_t, int, int, cred_t *);
455 static int scsa2usb_ugen_read(dev_t, struct uio *, cred_t *);
456 static int scsa2usb_ugen_write(dev_t, struct uio *, cred_t *);
457 static int scsa2usb_ugen_poll(dev_t, short, int, short *,
458 struct pollhead **);
459
460 /* scsa2usb cb_ops */
461 static struct cb_ops scsa2usb_cbops = {
462 scsa2usb_ugen_open, /* open */
463 scsa2usb_ugen_close, /* close */
464 nodev, /* strategy */
465 nodev, /* print */
466 nodev, /* dump */
467 scsa2usb_ugen_read, /* read */
468 scsa2usb_ugen_write, /* write */
469 nodev, /* ioctl */
470 nodev, /* devmap */
471 nodev, /* mmap */
472 nodev, /* segmap */
473 scsa2usb_ugen_poll, /* poll */
474 ddi_prop_op, /* prop_op */
475 NULL, /* stream */
476 D_MP, /* cb_flag */
477 CB_REV, /* rev */
478 nodev, /* int (*cb_aread)() */
479 nodev /* int (*cb_awrite)() */
480 };
481
482 /* modloading support */
483 static struct dev_ops scsa2usb_ops = {
484 DEVO_REV, /* devo_rev, */
485 0, /* refcnt */
486 scsa2usb_info, /* info */
487 nulldev, /* identify */
488 nulldev, /* probe */
489 scsa2usb_attach, /* attach */
490 scsa2usb_detach, /* detach */
491 nodev, /* reset */
492 &scsa2usb_cbops, /* driver operations */
493 NULL, /* bus operations */
494 scsa2usb_power, /* power */
495 ddi_quiesce_not_needed, /* quiesce */
496 };
497
498 static struct modldrv modldrv = {
499 &mod_driverops, /* Module type. This one is a driver */
500 "SCSA to USB Driver", /* Name of the module. */
501 &scsa2usb_ops, /* driver ops */
502 };
503
504 static struct modlinkage modlinkage = {
505 MODREV_1, (void *)&modldrv, NULL
506 };
507
508 /* event support */
509 static usb_event_t scsa2usb_events = {
510 scsa2usb_disconnect_event_cb,
511 scsa2usb_reconnect_event_cb,
512 NULL, NULL
513 };
514
515 int
_init(void)516 _init(void)
517 {
518 int rval;
519
520 if (((rval = ddi_soft_state_init(&scsa2usb_statep,
521 sizeof (scsa2usb_state_t), SCSA2USB_INITIAL_ALLOC)) != 0)) {
522
523 return (rval);
524 }
525
526 if ((rval = scsi_hba_init(&modlinkage)) != 0) {
527 ddi_soft_state_fini(&scsa2usb_statep);
528
529 return (rval);
530 }
531
532 if ((rval = mod_install(&modlinkage)) != 0) {
533 scsi_hba_fini(&modlinkage);
534 ddi_soft_state_fini(&scsa2usb_statep);
535
536 return (rval);
537 }
538
539 return (rval);
540 }
541
542
543 int
_fini(void)544 _fini(void)
545 {
546 int rval;
547
548 if ((rval = mod_remove(&modlinkage)) == 0) {
549 scsi_hba_fini(&modlinkage);
550 ddi_soft_state_fini(&scsa2usb_statep);
551 }
552
553 return (rval);
554 }
555
556
557 int
_info(struct modinfo * modinfop)558 _info(struct modinfo *modinfop)
559 {
560 return (mod_info(&modlinkage, modinfop));
561 }
562
563
564 /*
565 * scsa2usb_info :
566 * Get minor number, soft state structure etc.
567 */
568 /*ARGSUSED*/
569 static int
scsa2usb_info(dev_info_t * dip,ddi_info_cmd_t infocmd,void * arg,void ** result)570 scsa2usb_info(dev_info_t *dip, ddi_info_cmd_t infocmd,
571 void *arg, void **result)
572 {
573 scsa2usb_state_t *scsa2usbp = NULL;
574 int error = DDI_FAILURE;
575 int instance = SCSA2USB_MINOR_TO_INSTANCE(getminor((dev_t)arg));
576
577 switch (infocmd) {
578 case DDI_INFO_DEVT2DEVINFO:
579 if (((scsa2usbp = ddi_get_soft_state(scsa2usb_statep,
580 instance)) != NULL) &&
581 scsa2usbp->scsa2usb_dip) {
582 *result = scsa2usbp->scsa2usb_dip;
583 error = DDI_SUCCESS;
584 } else {
585 *result = NULL;
586 }
587 break;
588 case DDI_INFO_DEVT2INSTANCE:
589 *result = (void *)(uintptr_t)instance;
590 error = DDI_SUCCESS;
591 break;
592 default:
593 break;
594 }
595
596 return (error);
597 }
598
599
600 /*
601 * scsa2usb_attach:
602 * Attach driver
603 * Allocate a "scsi_hba_tran" - call scsi_hba_tran_alloc()
604 * Invoke scsi_hba_attach_setup
605 * Get the serialno of the device
606 * Open bulk pipes
607 * Create disk child(ren)
608 * Register events
609 * Create and register panic callback
610 *
611 * NOTE: Replaced CBW_DIR_OUT with USB_EP_DIR_OUT and CBW_DIR_IN with
612 * USB_EP_DIR_IN as they are the same #defines.
613 */
614 static int
scsa2usb_attach(dev_info_t * dip,ddi_attach_cmd_t cmd)615 scsa2usb_attach(dev_info_t *dip, ddi_attach_cmd_t cmd)
616 {
617 int instance = ddi_get_instance(dip);
618 int interface;
619 uint_t lun;
620 boolean_t ept_check = B_TRUE;
621 scsi_hba_tran_t *tran; /* scsi transport */
622 scsa2usb_state_t *scsa2usbp;
623 usb_log_handle_t log_handle;
624 usb_ep_data_t *ep_data;
625 usb_client_dev_data_t *dev_data;
626 usb_alt_if_data_t *altif_data;
627 usb_ugen_info_t usb_ugen_info;
628
629 USB_DPRINTF_L4(DPRINT_MASK_SCSA, NULL,
630 "scsa2usb_attach: dip = 0x%p", (void *)dip);
631
632 switch (cmd) {
633 case DDI_ATTACH:
634 break;
635 case DDI_RESUME:
636 scsa2usb_cpr_resume(dip);
637
638 return (DDI_SUCCESS);
639 default:
640 USB_DPRINTF_L2(DPRINT_MASK_SCSA, NULL,
641 "scsa2usb_attach: failed");
642
643 return (DDI_FAILURE);
644 }
645
646 /* Allocate softc information */
647 if (ddi_soft_state_zalloc(scsa2usb_statep, instance) != DDI_SUCCESS) {
648 ddi_prop_remove_all(dip);
649
650 return (DDI_FAILURE);
651 }
652
653 /* get soft state space and initialize */
654 if ((scsa2usbp = ddi_get_soft_state(scsa2usb_statep,
655 instance)) == NULL) {
656 USB_DPRINTF_L2(DPRINT_MASK_SCSA, NULL,
657 "scsa2usb%d: bad soft state", instance);
658 ddi_prop_remove_all(dip);
659
660 return (DDI_FAILURE);
661 }
662
663 scsa2usbp->scsa2usb_dip = dip;
664 scsa2usbp->scsa2usb_instance = instance;
665
666 /* allocate a log handle for debug/error messages */
667 scsa2usbp->scsa2usb_log_handle = log_handle =
668 usb_alloc_log_hdl(dip, "s2u",
669 &scsa2usb_errlevel,
670 &scsa2usb_errmask, &scsa2usb_instance_debug,
671 0);
672
673 /* attach to USBA */
674 if (usb_client_attach(dip, USBDRV_VERSION, 0) != USB_SUCCESS) {
675 USB_DPRINTF_L2(DPRINT_MASK_SCSA, log_handle,
676 "usb_client_attach failed");
677
678 goto fail;
679 }
680 if (usb_get_dev_data(dip, &dev_data, USB_PARSE_LVL_IF, 0) !=
681 USB_SUCCESS) {
682 USB_DPRINTF_L2(DPRINT_MASK_SCSA, log_handle,
683 "usb_get_dev_data failed");
684
685 goto fail;
686 }
687
688 /* initialize the mutex with the right cookie */
689 mutex_init(&scsa2usbp->scsa2usb_mutex, NULL, MUTEX_DRIVER,
690 dev_data->dev_iblock_cookie);
691 cv_init(&scsa2usbp->scsa2usb_transport_busy_cv, NULL, CV_DRIVER, NULL);
692
693 for (lun = 0; lun < SCSA2USB_MAX_LUNS; lun++) {
694 usba_init_list(&scsa2usbp->scsa2usb_waitQ[lun], NULL,
695 dev_data->dev_iblock_cookie);
696 }
697 mutex_enter(&scsa2usbp->scsa2usb_mutex);
698 scsa2usbp->scsa2usb_dip = dip;
699 scsa2usbp->scsa2usb_instance = instance;
700 scsa2usbp->scsa2usb_attrs = SCSA2USB_ALL_ATTRS;
701 scsa2usbp->scsa2usb_dev_data = dev_data;
702
703
704 /* save the default pipe handle */
705 scsa2usbp->scsa2usb_default_pipe = dev_data->dev_default_ph;
706
707 /* basic inits are done */
708 scsa2usbp->scsa2usb_flags |= SCSA2USB_FLAGS_LOCKS_INIT;
709
710 USB_DPRINTF_L4(DPRINT_MASK_SCSA, log_handle,
711 "curr_cfg=%ld, curr_if=%d",
712 (long)(dev_data->dev_curr_cfg - &dev_data->dev_cfg[0]),
713 dev_data->dev_curr_if);
714
715 interface = dev_data->dev_curr_if;
716 scsa2usbp->scsa2usb_intfc_num = dev_data->dev_curr_if;
717
718 /* now find out relevant descriptors for alternate 0 */
719 altif_data = &dev_data->dev_curr_cfg->cfg_if[interface].if_alt[0];
720
721 if (altif_data->altif_n_ep == 0) {
722 USB_DPRINTF_L2(DPRINT_MASK_SCSA, log_handle,
723 "invalid alt 0 for interface %d", interface);
724 mutex_exit(&scsa2usbp->scsa2usb_mutex);
725
726 goto fail;
727 }
728
729 /* All CB/CBI, BO devices should have this value set */
730 if (altif_data->altif_descr.bInterfaceClass !=
731 USB_CLASS_MASS_STORAGE) {
732 USB_DPRINTF_L2(DPRINT_MASK_SCSA, log_handle,
733 "invalid interface class (0x%x)",
734 altif_data->altif_descr.bInterfaceClass);
735 }
736 scsa2usbp->scsa2usb_intfc_descr = altif_data->altif_descr;
737
738 /* figure out the endpoints and copy the descr */
739 if ((ep_data = usb_lookup_ep_data(dip, dev_data, interface, 0, 0,
740 USB_EP_ATTR_BULK, USB_EP_DIR_OUT)) != NULL) {
741 scsa2usbp->scsa2usb_bulkout_ept = ep_data->ep_descr;
742 }
743 if ((ep_data = usb_lookup_ep_data(dip, dev_data, interface, 0, 0,
744 USB_EP_ATTR_BULK, USB_EP_DIR_IN)) != NULL) {
745 scsa2usbp->scsa2usb_bulkin_ept = ep_data->ep_descr;
746 }
747 if ((ep_data = usb_lookup_ep_data(dip, dev_data, interface, 0, 0,
748 USB_EP_ATTR_INTR, USB_EP_DIR_IN)) != NULL) {
749 scsa2usbp->scsa2usb_intr_ept = ep_data->ep_descr;
750 }
751
752 /*
753 * check here for protocol and subclass supported by this driver
754 *
755 * first check if conf file has override values
756 * Note: override values are not used if supplied values are legal
757 */
758 scsa2usb_override(scsa2usbp);
759
760 USB_DPRINTF_L3(DPRINT_MASK_SCSA, log_handle,
761 "protocol=0x%x override=0x%x subclass=0x%x override=0x%x",
762 scsa2usbp->scsa2usb_intfc_descr.bInterfaceProtocol,
763 scsa2usbp->scsa2usb_protocol_override,
764 scsa2usbp->scsa2usb_intfc_descr.bInterfaceSubClass,
765 scsa2usbp->scsa2usb_subclass_override);
766
767 switch (scsa2usbp->scsa2usb_intfc_descr.bInterfaceProtocol) {
768 case USB_PROTO_MS_CBI:
769 scsa2usbp->scsa2usb_cmd_protocol |= SCSA2USB_CB_PROTOCOL;
770 break;
771 case USB_PROTO_MS_CBI_WC:
772 scsa2usbp->scsa2usb_cmd_protocol |= SCSA2USB_CBI_PROTOCOL;
773 break;
774 case USB_PROTO_MS_ISD_1999_SILICN:
775 case USB_PROTO_MS_BULK_ONLY:
776 scsa2usbp->scsa2usb_cmd_protocol |= SCSA2USB_BULK_ONLY_PROTOCOL;
777 break;
778 default:
779 if (scsa2usbp->scsa2usb_protocol_override) {
780 scsa2usbp->scsa2usb_cmd_protocol |=
781 scsa2usbp->scsa2usb_protocol_override;
782 USB_DPRINTF_L2(DPRINT_MASK_SCSA, log_handle,
783 "overriding protocol %x",
784 scsa2usbp->scsa2usb_intfc_descr.bInterfaceProtocol);
785 break;
786 }
787
788 USB_DPRINTF_L2(DPRINT_MASK_SCSA, log_handle,
789 "unsupported protocol = %x",
790 scsa2usbp->scsa2usb_intfc_descr.bInterfaceProtocol);
791 mutex_exit(&scsa2usbp->scsa2usb_mutex);
792
793 goto fail;
794 }
795
796 switch (scsa2usbp->scsa2usb_intfc_descr.bInterfaceSubClass) {
797 case USB_SUBCLS_MS_SCSI: /* transparent SCSI */
798 scsa2usbp->scsa2usb_cmd_protocol |= SCSA2USB_SCSI_CMDSET;
799 break;
800 case USB_SUBCLS_MS_SFF8020I:
801 case USB_SUBCLS_MS_SFF8070I:
802 scsa2usbp->scsa2usb_cmd_protocol |= SCSA2USB_ATAPI_CMDSET;
803 break;
804 case USB_SUBCLS_MS_UFI: /* UFI */
805 scsa2usbp->scsa2usb_cmd_protocol |= SCSA2USB_UFI_CMDSET;
806 break;
807 default:
808 if (scsa2usbp->scsa2usb_subclass_override) {
809 scsa2usbp->scsa2usb_cmd_protocol |=
810 scsa2usbp->scsa2usb_subclass_override;
811 USB_DPRINTF_L2(DPRINT_MASK_SCSA, log_handle,
812 "overriding subclass %x",
813 scsa2usbp->scsa2usb_intfc_descr.bInterfaceSubClass);
814 break;
815 }
816
817 USB_DPRINTF_L2(DPRINT_MASK_SCSA, log_handle,
818 "unsupported subclass = %x",
819 scsa2usbp->scsa2usb_intfc_descr.bInterfaceSubClass);
820 mutex_exit(&scsa2usbp->scsa2usb_mutex);
821
822 goto fail;
823 }
824
825 /* check that we have the right set of endpoint descriptors */
826 if (SCSA2USB_IS_BULK_ONLY(scsa2usbp) || SCSA2USB_IS_CB(scsa2usbp)) {
827 if ((scsa2usbp->scsa2usb_bulkout_ept.bLength == 0) ||
828 (scsa2usbp->scsa2usb_bulkin_ept.bLength == 0)) {
829 ept_check = B_FALSE;
830 }
831 } else if (SCSA2USB_IS_CBI(scsa2usbp)) {
832 if ((scsa2usbp->scsa2usb_bulkout_ept.bLength == 0) ||
833 (scsa2usbp->scsa2usb_bulkin_ept.bLength == 0) ||
834 (scsa2usbp->scsa2usb_intr_ept.bLength == 0)) {
835 ept_check = B_FALSE;
836 }
837 }
838
839 if (ept_check == B_FALSE) {
840 USB_DPRINTF_L2(DPRINT_MASK_SCSA, log_handle,
841 "scsa2usb%d doesn't support minimum required endpoints",
842 instance);
843 mutex_exit(&scsa2usbp->scsa2usb_mutex);
844
845 goto fail;
846 }
847
848 /*
849 * Validate the black-listed attributes
850 */
851 scsa2usb_validate_attrs(scsa2usbp);
852
853 /* Print the serial number from the registration data */
854 if (scsa2usbp->scsa2usb_dev_data->dev_serial) {
855 USB_DPRINTF_L4(DPRINT_MASK_SCSA,
856 scsa2usbp->scsa2usb_log_handle, "Serial Number = %s",
857 scsa2usbp->scsa2usb_dev_data->dev_serial);
858 }
859
860 /*
861 * Allocate a SCSA transport structure
862 */
863 tran = scsi_hba_tran_alloc(dip, SCSI_HBA_CANSLEEP);
864 scsa2usbp->scsa2usb_tran = tran;
865
866 /*
867 * initialize transport structure
868 */
869 tran->tran_hba_private = scsa2usbp;
870 tran->tran_tgt_private = NULL;
871 tran->tran_tgt_init = scsa2usb_scsi_tgt_init;
872 tran->tran_tgt_probe = scsa2usb_scsi_tgt_probe;
873 tran->tran_tgt_free = scsa2usb_scsi_tgt_free;
874 tran->tran_start = scsa2usb_scsi_start;
875 tran->tran_abort = scsa2usb_scsi_abort;
876 tran->tran_reset = scsa2usb_scsi_reset;
877 tran->tran_getcap = scsa2usb_scsi_getcap;
878 tran->tran_setcap = scsa2usb_scsi_setcap;
879 tran->tran_init_pkt = scsa2usb_scsi_init_pkt;
880 tran->tran_destroy_pkt = scsa2usb_scsi_destroy_pkt;
881 tran->tran_dmafree = NULL;
882 tran->tran_sync_pkt = NULL;
883 tran->tran_reset_notify = NULL;
884 tran->tran_get_bus_addr = NULL;
885 tran->tran_get_name = NULL;
886 tran->tran_quiesce = NULL;
887 tran->tran_unquiesce = NULL;
888 tran->tran_bus_reset = NULL;
889 tran->tran_add_eventcall = NULL;
890 tran->tran_get_eventcookie = NULL;
891 tran->tran_post_event = NULL;
892 tran->tran_remove_eventcall = NULL;
893 tran->tran_bus_config = scsa2usb_scsi_bus_config;
894 tran->tran_bus_unconfig = scsa2usb_scsi_bus_unconfig;
895
896 /*
897 * register with SCSA as an HBA
898 * Note that the dma attributes are from parent nexus
899 */
900 if (scsi_hba_attach_setup(dip, usba_get_hc_dma_attr(dip), tran, 0)) {
901 USB_DPRINTF_L2(DPRINT_MASK_SCSA, log_handle,
902 "scsi_hba_attach_setup failed");
903 mutex_exit(&scsa2usbp->scsa2usb_mutex);
904
905 goto fail;
906 }
907
908 scsa2usbp->scsa2usb_flags |= SCSA2USB_FLAGS_HBA_ATTACH_SETUP;
909
910 /* create minor node */
911 if (ddi_create_minor_node(dip, "scsa2usb", S_IFCHR,
912 instance << SCSA2USB_MINOR_INSTANCE_SHIFT,
913 DDI_NT_SCSI_NEXUS, 0) != DDI_SUCCESS) {
914 USB_DPRINTF_L2(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
915 "scsi_attach: ddi_create_minor_node failed");
916 mutex_exit(&scsa2usbp->scsa2usb_mutex);
917
918 goto fail;
919 }
920
921 /* open pipes and set scsa2usb_flags */
922 if (scsa2usb_open_usb_pipes(scsa2usbp) == USB_FAILURE) {
923 USB_DPRINTF_L2(DPRINT_MASK_SCSA, log_handle,
924 "error opening pipes");
925 mutex_exit(&scsa2usbp->scsa2usb_mutex);
926
927 goto fail;
928 }
929
930 /* set default block size. updated after read cap cmd */
931 for (lun = 0; lun < SCSA2USB_MAX_LUNS; lun++) {
932 scsa2usbp->scsa2usb_lbasize[lun] = DEV_BSIZE;
933 }
934
935 mutex_exit(&scsa2usbp->scsa2usb_mutex);
936
937 /* initialize PANIC callback */
938 scsa2usb_panic_callb_init(scsa2usbp);
939
940 /* finally we are all done 'initializing' the device */
941 mutex_enter(&scsa2usbp->scsa2usb_mutex);
942 scsa2usbp->scsa2usb_dev_state = USB_DEV_ONLINE;
943
944 /* enable PM, mutex needs to be held across this */
945 scsa2usb_create_pm_components(dip, scsa2usbp);
946 mutex_exit(&scsa2usbp->scsa2usb_mutex);
947
948 /* register for connect/disconnect events */
949 if (usb_register_event_cbs(scsa2usbp->scsa2usb_dip, &scsa2usb_events,
950 0) != USB_SUCCESS) {
951 USB_DPRINTF_L2(DPRINT_MASK_SCSA, log_handle,
952 "error cb registering");
953 goto fail;
954 }
955
956 /* free the dev_data tree, we no longer need it */
957 usb_free_descr_tree(dip, dev_data);
958
959 scsa2usb_pm_idle_component(scsa2usbp);
960
961 /* log the conf file override string if there is one */
962 if (scsa2usbp->scsa2usb_override_str) {
963 USB_DPRINTF_L2(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
964 "scsa2usb.conf override: %s",
965 scsa2usbp->scsa2usb_override_str);
966 }
967
968 if (usb_owns_device(dip)) {
969 /* get a ugen handle */
970 bzero(&usb_ugen_info, sizeof (usb_ugen_info));
971 usb_ugen_info.usb_ugen_flags = 0;
972 usb_ugen_info.usb_ugen_minor_node_ugen_bits_mask =
973 (dev_t)SCSA2USB_MINOR_UGEN_BITS_MASK;
974 usb_ugen_info.usb_ugen_minor_node_instance_mask =
975 (dev_t)~SCSA2USB_MINOR_UGEN_BITS_MASK;
976 scsa2usbp->scsa2usb_ugen_hdl =
977 usb_ugen_get_hdl(dip, &usb_ugen_info);
978
979 if (usb_ugen_attach(scsa2usbp->scsa2usb_ugen_hdl, cmd) !=
980 USB_SUCCESS) {
981 USB_DPRINTF_L2(DPRINT_MASK_SCSA,
982 scsa2usbp->scsa2usb_log_handle,
983 "usb_ugen_attach failed");
984
985 usb_ugen_release_hdl(scsa2usbp->scsa2usb_ugen_hdl);
986 scsa2usbp->scsa2usb_ugen_hdl = NULL;
987 }
988 }
989
990 /* report device */
991 ddi_report_dev(dip);
992
993 return (DDI_SUCCESS);
994
995 fail:
996 if (scsa2usbp) {
997 (void) scsa2usb_cleanup(dip, scsa2usbp);
998 }
999
1000 return (DDI_FAILURE);
1001 }
1002
1003
1004 /*
1005 * scsa2usb_detach:
1006 * detach or suspend driver instance
1007 */
1008 static int
scsa2usb_detach(dev_info_t * dip,ddi_detach_cmd_t cmd)1009 scsa2usb_detach(dev_info_t *dip, ddi_detach_cmd_t cmd)
1010 {
1011 scsi_hba_tran_t *tran;
1012 scsa2usb_state_t *scsa2usbp;
1013 int rval;
1014
1015 tran = ddi_get_driver_private(dip);
1016 ASSERT(tran != NULL);
1017
1018 scsa2usbp = (scsa2usb_state_t *)tran->tran_hba_private;
1019 ASSERT(scsa2usbp);
1020
1021 USB_DPRINTF_L4(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
1022 "scsa2usb_detach: dip = 0x%p, cmd = %d", (void *)dip, cmd);
1023
1024 switch (cmd) {
1025 case DDI_DETACH:
1026
1027 if (scsa2usb_cleanup(dip, scsa2usbp) != USB_SUCCESS) {
1028
1029 return (DDI_FAILURE);
1030 }
1031
1032 return (DDI_SUCCESS);
1033 case DDI_SUSPEND:
1034 rval = scsa2usb_cpr_suspend(dip);
1035
1036 return ((rval == USB_SUCCESS) ? DDI_SUCCESS : DDI_FAILURE);
1037 default:
1038
1039 return (DDI_FAILURE);
1040 }
1041 }
1042
1043 /*
1044 * ugen support
1045 */
1046 /*
1047 * scsa2usb_ugen_open()
1048 * (all ugen opens and pipe opens are by definition exclusive so it is OK
1049 * to count opens)
1050 */
1051 static int
scsa2usb_ugen_open(dev_t * devp,int flag,int sflag,cred_t * cr)1052 scsa2usb_ugen_open(dev_t *devp, int flag, int sflag, cred_t *cr)
1053 {
1054 scsa2usb_state_t *scsa2usbp;
1055 int rval;
1056
1057 if ((scsa2usbp = ddi_get_soft_state(scsa2usb_statep,
1058 SCSA2USB_MINOR_TO_INSTANCE(getminor(*devp)))) == NULL) {
1059 /* deferred detach */
1060
1061 return (ENXIO);
1062 }
1063
1064 USB_DPRINTF_L4(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
1065 "scsa2usb_ugen_open: dev_t=0x%lx", *devp);
1066
1067 mutex_enter(&scsa2usbp->scsa2usb_mutex);
1068
1069 /* if this is the first ugen open, check on transport busy */
1070 if (scsa2usbp->scsa2usb_busy_proc != curproc) {
1071 while (scsa2usbp->scsa2usb_transport_busy ||
1072 (scsa2usb_all_waitQs_empty(scsa2usbp) !=
1073 USB_SUCCESS)) {
1074 rval = cv_wait_sig(
1075 &scsa2usbp->scsa2usb_transport_busy_cv,
1076 &scsa2usbp->scsa2usb_mutex);
1077 if (rval == 0) {
1078 mutex_exit(&scsa2usbp->scsa2usb_mutex);
1079
1080 return (EINTR);
1081 }
1082 }
1083 scsa2usbp->scsa2usb_transport_busy++;
1084 scsa2usbp->scsa2usb_busy_proc = curproc;
1085 }
1086
1087 scsa2usbp->scsa2usb_ugen_open_count++;
1088
1089 scsa2usb_raise_power(scsa2usbp);
1090
1091 scsa2usb_close_usb_pipes(scsa2usbp);
1092
1093 mutex_exit(&scsa2usbp->scsa2usb_mutex);
1094
1095 rval = usb_ugen_open(scsa2usbp->scsa2usb_ugen_hdl, devp, flag,
1096 sflag, cr);
1097 if (!rval) {
1098 /*
1099 * if usb_ugen_open() succeeded, we'll change the minor number
1100 * so that we can keep track of every open()/close() issued by
1101 * the userland processes. We need to pick a minor number that
1102 * is not used by the ugen framework
1103 */
1104
1105 usb_ugen_hdl_impl_t *usb_ugen_hdl_impl;
1106 ugen_state_t *ugenp;
1107 int ugen_minor, clone;
1108
1109 mutex_enter(&scsa2usbp->scsa2usb_mutex);
1110
1111 usb_ugen_hdl_impl =
1112 (usb_ugen_hdl_impl_t *)scsa2usbp->scsa2usb_ugen_hdl;
1113 ugenp = usb_ugen_hdl_impl->hdl_ugenp;
1114
1115 /* 'clone' is bigger than any ugen minor in use */
1116 for (clone = ugenp->ug_minor_node_table_index + 1;
1117 clone < SCSA2USB_MAX_CLONE; clone++) {
1118 if (!scsa2usbp->scsa2usb_clones[clone])
1119 break;
1120 }
1121
1122 if (clone >= SCSA2USB_MAX_CLONE) {
1123 cmn_err(CE_WARN, "scsa2usb_ugen_open: too many clones");
1124 rval = EBUSY;
1125 mutex_exit(&scsa2usbp->scsa2usb_mutex);
1126 goto open_done;
1127 }
1128
1129 ugen_minor = getminor(*devp) & SCSA2USB_MINOR_UGEN_BITS_MASK;
1130 *devp = makedevice(getmajor(*devp),
1131 (scsa2usbp->scsa2usb_instance
1132 << SCSA2USB_MINOR_INSTANCE_SHIFT)
1133 + clone);
1134
1135 /* save the ugen minor */
1136 scsa2usbp->scsa2usb_clones[clone] = (uint8_t)ugen_minor;
1137 USB_DPRINTF_L4(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
1138 "scsa2usb_ugen_open: new dev=%lx, old minor=%x",
1139 *devp, ugen_minor);
1140
1141 mutex_exit(&scsa2usbp->scsa2usb_mutex);
1142 }
1143
1144 open_done:
1145
1146 if (rval) {
1147 mutex_enter(&scsa2usbp->scsa2usb_mutex);
1148
1149 /* reopen the pipes */
1150 if (--scsa2usbp->scsa2usb_ugen_open_count == 0) {
1151 scsa2usbp->scsa2usb_transport_busy--;
1152 scsa2usbp->scsa2usb_busy_proc = NULL;
1153 cv_signal(&scsa2usbp->scsa2usb_transport_busy_cv);
1154 }
1155 mutex_exit(&scsa2usbp->scsa2usb_mutex);
1156
1157 scsa2usb_pm_idle_component(scsa2usbp);
1158 }
1159
1160 return (rval);
1161 }
1162
1163
1164 /*
1165 * scsa2usb_ugen_close()
1166 */
1167 static int
scsa2usb_ugen_close(dev_t dev,int flag,int otype,cred_t * cr)1168 scsa2usb_ugen_close(dev_t dev, int flag, int otype, cred_t *cr)
1169 {
1170 int rval;
1171 int ugen_minor, clone;
1172
1173 scsa2usb_state_t *scsa2usbp = ddi_get_soft_state(scsa2usb_statep,
1174 SCSA2USB_MINOR_TO_INSTANCE(getminor(dev)));
1175
1176 if (scsa2usbp == NULL) {
1177
1178 return (ENXIO);
1179 }
1180
1181 USB_DPRINTF_L4(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
1182 "scsa2usb_ugen_close: dev_t=0x%lx", dev);
1183
1184 clone = getminor(dev) & SCSA2USB_MINOR_UGEN_BITS_MASK;
1185 ugen_minor = scsa2usbp->scsa2usb_clones[clone];
1186 dev = makedevice(getmajor(dev),
1187 (scsa2usbp->scsa2usb_instance << SCSA2USB_MINOR_INSTANCE_SHIFT)
1188 + ugen_minor);
1189 USB_DPRINTF_L4(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
1190 "scsa2usb_ugen_close: old dev=%lx", dev);
1191 rval = usb_ugen_close(scsa2usbp->scsa2usb_ugen_hdl, dev, flag,
1192 otype, cr);
1193
1194 if (rval == 0) {
1195 mutex_enter(&scsa2usbp->scsa2usb_mutex);
1196
1197 scsa2usbp->scsa2usb_clones[clone] = 0;
1198 /* reopen the pipes */
1199 if (--scsa2usbp->scsa2usb_ugen_open_count == 0) {
1200 scsa2usbp->scsa2usb_transport_busy--;
1201 scsa2usbp->scsa2usb_busy_proc = NULL;
1202 cv_signal(&scsa2usbp->scsa2usb_transport_busy_cv);
1203 }
1204 mutex_exit(&scsa2usbp->scsa2usb_mutex);
1205
1206 scsa2usb_pm_idle_component(scsa2usbp);
1207 }
1208
1209 return (rval);
1210 }
1211
1212
1213 /*
1214 * scsa2usb_ugen_read/write()
1215 */
1216 /*ARGSUSED*/
1217 static int
scsa2usb_ugen_read(dev_t dev,struct uio * uiop,cred_t * credp)1218 scsa2usb_ugen_read(dev_t dev, struct uio *uiop, cred_t *credp)
1219 {
1220 int clone, ugen_minor;
1221 scsa2usb_state_t *scsa2usbp = ddi_get_soft_state(scsa2usb_statep,
1222 SCSA2USB_MINOR_TO_INSTANCE(getminor(dev)));
1223
1224 if (scsa2usbp == NULL) {
1225
1226 return (ENXIO);
1227 }
1228
1229 USB_DPRINTF_L4(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
1230 "scsa2usb_ugen_read: dev_t=0x%lx", dev);
1231
1232 clone = getminor(dev) & SCSA2USB_MINOR_UGEN_BITS_MASK;
1233 ugen_minor = scsa2usbp->scsa2usb_clones[clone];
1234 dev = makedevice(getmajor(dev),
1235 (scsa2usbp->scsa2usb_instance << SCSA2USB_MINOR_INSTANCE_SHIFT)
1236 + ugen_minor);
1237
1238 return (usb_ugen_read(scsa2usbp->scsa2usb_ugen_hdl, dev,
1239 uiop, credp));
1240 }
1241
1242
1243 /*ARGSUSED*/
1244 static int
scsa2usb_ugen_write(dev_t dev,struct uio * uiop,cred_t * credp)1245 scsa2usb_ugen_write(dev_t dev, struct uio *uiop, cred_t *credp)
1246 {
1247 int clone, ugen_minor;
1248 scsa2usb_state_t *scsa2usbp = ddi_get_soft_state(scsa2usb_statep,
1249 SCSA2USB_MINOR_TO_INSTANCE(getminor(dev)));
1250
1251 if (scsa2usbp == NULL) {
1252
1253 return (ENXIO);
1254 }
1255
1256 USB_DPRINTF_L4(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
1257 "scsa2usb_ugen_write: dev_t=0x%lx", dev);
1258
1259 clone = getminor(dev) & SCSA2USB_MINOR_UGEN_BITS_MASK;
1260 ugen_minor = scsa2usbp->scsa2usb_clones[clone];
1261 dev = makedevice(getmajor(dev),
1262 (scsa2usbp->scsa2usb_instance << SCSA2USB_MINOR_INSTANCE_SHIFT)
1263 + ugen_minor);
1264
1265 return (usb_ugen_write(scsa2usbp->scsa2usb_ugen_hdl,
1266 dev, uiop, credp));
1267 }
1268
1269
1270 /*
1271 * scsa2usb_ugen_poll
1272 */
1273 static int
scsa2usb_ugen_poll(dev_t dev,short events,int anyyet,short * reventsp,struct pollhead ** phpp)1274 scsa2usb_ugen_poll(dev_t dev, short events,
1275 int anyyet, short *reventsp, struct pollhead **phpp)
1276 {
1277 int clone, ugen_minor;
1278 scsa2usb_state_t *scsa2usbp = ddi_get_soft_state(scsa2usb_statep,
1279 SCSA2USB_MINOR_TO_INSTANCE(getminor(dev)));
1280
1281 if (scsa2usbp == NULL) {
1282
1283 return (ENXIO);
1284 }
1285
1286 USB_DPRINTF_L4(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
1287 "scsa2usb_ugen_poll: dev_t=0x%lx", dev);
1288
1289 clone = getminor(dev) & SCSA2USB_MINOR_UGEN_BITS_MASK;
1290 ugen_minor = scsa2usbp->scsa2usb_clones[clone];
1291 dev = makedevice(getmajor(dev),
1292 (scsa2usbp->scsa2usb_instance << SCSA2USB_MINOR_INSTANCE_SHIFT)
1293 + ugen_minor);
1294
1295 return (usb_ugen_poll(scsa2usbp->scsa2usb_ugen_hdl, dev, events,
1296 anyyet, reventsp, phpp));
1297 }
1298
1299
1300 /*
1301 * scsa2usb_cleanup:
1302 * cleanup whatever attach has setup
1303 */
1304 static int
scsa2usb_cleanup(dev_info_t * dip,scsa2usb_state_t * scsa2usbp)1305 scsa2usb_cleanup(dev_info_t *dip, scsa2usb_state_t *scsa2usbp)
1306 {
1307 int rval, i;
1308 scsa2usb_power_t *pm;
1309 uint_t lun;
1310
1311 USB_DPRINTF_L4(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
1312 "scsa2usb_cleanup:");
1313
1314 /* wait till the work thread is done */
1315 mutex_enter(&scsa2usbp->scsa2usb_mutex);
1316 for (i = 0; i < SCSA2USB_DRAIN_TIMEOUT; i++) {
1317 if (scsa2usbp->scsa2usb_work_thread_id == NULL) {
1318
1319 break;
1320 }
1321 mutex_exit(&scsa2usbp->scsa2usb_mutex);
1322 delay(drv_usectohz(1000000));
1323 mutex_enter(&scsa2usbp->scsa2usb_mutex);
1324 }
1325 mutex_exit(&scsa2usbp->scsa2usb_mutex);
1326
1327 if (i >= SCSA2USB_DRAIN_TIMEOUT) {
1328
1329 return (USB_FAILURE);
1330 }
1331
1332 /*
1333 * Disable the event callbacks first, after this point, event
1334 * callbacks will never get called. Note we shouldn't hold
1335 * mutex while unregistering events because there may be a
1336 * competing event callback thread. Event callbacks are done
1337 * with ndi mutex held and this can cause a potential deadlock.
1338 */
1339 usb_unregister_event_cbs(scsa2usbp->scsa2usb_dip, &scsa2usb_events);
1340
1341 if (scsa2usbp->scsa2usb_flags & SCSA2USB_FLAGS_LOCKS_INIT) {
1342 /*
1343 * if a waitQ exists, get rid of it before destroying it
1344 */
1345 for (lun = 0; lun < SCSA2USB_MAX_LUNS; lun++) {
1346 scsa2usb_flush_waitQ(scsa2usbp, lun, CMD_TRAN_ERR);
1347 usba_destroy_list(&scsa2usbp->scsa2usb_waitQ[lun]);
1348 }
1349
1350 mutex_enter(&scsa2usbp->scsa2usb_mutex);
1351 if (scsa2usbp->scsa2usb_flags &
1352 SCSA2USB_FLAGS_HBA_ATTACH_SETUP) {
1353 (void) scsi_hba_detach(dip);
1354 scsi_hba_tran_free(scsa2usbp->scsa2usb_tran);
1355 }
1356
1357 if (scsa2usbp->scsa2usb_flags &
1358 SCSA2USB_FLAGS_PIPES_OPENED) {
1359 scsa2usb_close_usb_pipes(scsa2usbp);
1360 }
1361
1362 /* Lower the power */
1363 pm = scsa2usbp->scsa2usb_pm;
1364
1365 if (pm && (scsa2usbp->scsa2usb_dev_state !=
1366 USB_DEV_DISCONNECTED)) {
1367 if (pm->scsa2usb_wakeup_enabled) {
1368 mutex_exit(&scsa2usbp->scsa2usb_mutex);
1369 (void) pm_raise_power(dip, 0,
1370 USB_DEV_OS_FULL_PWR);
1371
1372 if ((rval = usb_handle_remote_wakeup(dip,
1373 USB_REMOTE_WAKEUP_DISABLE)) !=
1374 USB_SUCCESS) {
1375 USB_DPRINTF_L2(DPRINT_MASK_SCSA,
1376 scsa2usbp->scsa2usb_log_handle,
1377 "disable remote wakeup failed "
1378 "(%d)", rval);
1379 }
1380 } else {
1381 mutex_exit(&scsa2usbp->scsa2usb_mutex);
1382 }
1383
1384 (void) pm_lower_power(dip, 0, USB_DEV_OS_PWR_OFF);
1385
1386 mutex_enter(&scsa2usbp->scsa2usb_mutex);
1387 }
1388
1389 if (pm) {
1390 kmem_free(pm, sizeof (scsa2usb_power_t));
1391 }
1392
1393 if (scsa2usbp->scsa2usb_override_str) {
1394 kmem_free(scsa2usbp->scsa2usb_override_str,
1395 strlen(scsa2usbp->scsa2usb_override_str) + 1);
1396 scsa2usbp->scsa2usb_override_str = NULL;
1397 }
1398
1399 /* remove the minor nodes */
1400 ddi_remove_minor_node(dip, NULL);
1401
1402 /* Cancel the registered panic callback */
1403 scsa2usb_panic_callb_fini(scsa2usbp);
1404
1405 mutex_exit(&scsa2usbp->scsa2usb_mutex);
1406
1407 mutex_destroy(&scsa2usbp->scsa2usb_mutex);
1408 cv_destroy(&scsa2usbp->scsa2usb_transport_busy_cv);
1409 }
1410
1411 usb_client_detach(scsa2usbp->scsa2usb_dip,
1412 scsa2usbp->scsa2usb_dev_data);
1413
1414 if (scsa2usbp->scsa2usb_ugen_hdl) {
1415 (void) usb_ugen_detach(scsa2usbp->scsa2usb_ugen_hdl,
1416 DDI_DETACH);
1417 usb_ugen_release_hdl(scsa2usbp->scsa2usb_ugen_hdl);
1418 }
1419
1420 usb_free_log_hdl(scsa2usbp->scsa2usb_log_handle);
1421
1422 ddi_prop_remove_all(dip);
1423
1424 ddi_soft_state_free(scsa2usb_statep, ddi_get_instance(dip));
1425
1426 return (USB_SUCCESS);
1427 }
1428
1429
1430 /*
1431 * scsa2usb_override:
1432 * some devices may be attached even though their subclass or
1433 * protocol info is not according to spec.
1434 * these can be determined by the 'subclass-protocol-override'
1435 * property set in the conf file.
1436 */
1437 static void
scsa2usb_override(scsa2usb_state_t * scsa2usbp)1438 scsa2usb_override(scsa2usb_state_t *scsa2usbp)
1439 {
1440 scsa2usb_ov_t ov;
1441 char **override_str = NULL;
1442 char *override_str_cpy;
1443 uint_t override_str_len, override_str_cpy_len;
1444 uint_t i;
1445 usb_dev_descr_t *descr = scsa2usbp->scsa2usb_dev_data->dev_descr;
1446
1447 ASSERT(mutex_owned(&scsa2usbp->scsa2usb_mutex));
1448
1449 scsa2usbp->scsa2usb_subclass_override =
1450 scsa2usbp->scsa2usb_protocol_override = 0;
1451
1452 if (ddi_prop_lookup_string_array(DDI_DEV_T_ANY, scsa2usbp->scsa2usb_dip,
1453 DDI_PROP_DONTPASS, "attribute-override-list",
1454 &override_str, &override_str_len) != DDI_PROP_SUCCESS) {
1455
1456 return;
1457 }
1458
1459 /* parse each string in the subclass-protocol-override property */
1460 for (i = 0; i < override_str_len; i++) {
1461
1462 USB_DPRINTF_L4(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
1463 "override_str[%d] = %s", i, override_str[i]);
1464
1465 /*
1466 * save a copy of the override string for possible
1467 * inclusion in soft state later
1468 */
1469 override_str_cpy_len = strlen(override_str[i]) + 1;
1470 override_str_cpy = kmem_zalloc(override_str_cpy_len, KM_SLEEP);
1471 (void) strcpy(override_str_cpy, override_str[i]);
1472
1473 bzero(&ov, sizeof (scsa2usb_ov_t));
1474
1475 if (scsa2usb_parse_input_str(override_str[i], &ov,
1476 scsa2usbp) == USB_FAILURE) {
1477 kmem_free(override_str_cpy, override_str_cpy_len);
1478 continue;
1479 }
1480
1481 /*
1482 * see if subclass/protocol needs to be overridden for device
1483 * or if device should not be power managed
1484 * if there'a a match, save the override string in soft state
1485 */
1486 if (((descr->idVendor == (uint16_t)ov.vid) || (ov.vid == 0)) &&
1487 ((descr->idProduct == (uint16_t)ov.pid) || (ov.pid == 0)) &&
1488 ((descr->bcdDevice == (uint16_t)ov.rev) || (ov.rev == 0))) {
1489 scsa2usbp->scsa2usb_subclass_override = ov.subclass;
1490 scsa2usbp->scsa2usb_protocol_override = ov.protocol;
1491
1492 USB_DPRINTF_L2(DPRINT_MASK_SCSA,
1493 scsa2usbp->scsa2usb_log_handle,
1494 "vid=0x%x pid=0x%x rev=0x%x subclass=0x%x "
1495 "protocol=0x%x "
1496 "pmoff=%d fake_removable=%d modesense=%d "
1497 "reduced-cmd-support=%d",
1498 ov.vid, ov.pid, ov.rev, ov.subclass, ov.protocol,
1499 ov.pmoff, ov.fake_removable, ov.no_modesense,
1500 ov.reduced_cmd_support);
1501
1502 if (ov.pmoff) {
1503 scsa2usbp->scsa2usb_attrs &= ~SCSA2USB_ATTRS_PM;
1504 }
1505 if (ov.fake_removable) {
1506 scsa2usbp->scsa2usb_attrs &=
1507 ~SCSA2USB_ATTRS_RMB;
1508 }
1509 if (ov.no_modesense) {
1510 scsa2usbp->scsa2usb_attrs &=
1511 ~SCSA2USB_ATTRS_MODE_SENSE;
1512 }
1513 if (ov.reduced_cmd_support) {
1514 scsa2usbp->scsa2usb_attrs &=
1515 ~SCSA2USB_ATTRS_REDUCED_CMD;
1516 }
1517 scsa2usbp->scsa2usb_override_str = override_str_cpy;
1518 break;
1519 } else {
1520 kmem_free(override_str_cpy, override_str_cpy_len);
1521 }
1522 }
1523
1524 ddi_prop_free(override_str);
1525 }
1526
1527
1528 /*
1529 * scsa2usb_parse_input_str:
1530 * parse one conf file subclass-protocol-override string
1531 * return vendor id, product id, revision, subclass, protocol
1532 * function return is success or failure
1533 */
1534 static int
scsa2usb_parse_input_str(char * str,scsa2usb_ov_t * ovp,scsa2usb_state_t * scsa2usbp)1535 scsa2usb_parse_input_str(char *str, scsa2usb_ov_t *ovp,
1536 scsa2usb_state_t *scsa2usbp)
1537 {
1538 char *input_field, *input_value;
1539 char *lasts;
1540 uint_t i;
1541 u_longlong_t value;
1542
1543 /* parse all the input pairs in the string */
1544 for (input_field = scsa2usb_strtok_r(str, "=", &lasts);
1545 input_field != NULL;
1546 input_field = scsa2usb_strtok_r(lasts, "=", &lasts)) {
1547
1548 if ((input_value = scsa2usb_strtok_r(lasts, " ", &lasts)) ==
1549 NULL) {
1550 scsa2usb_override_error("format", scsa2usbp);
1551
1552 return (USB_FAILURE);
1553 }
1554 /* if input value is a 'don't care', skip to the next pair */
1555 if (strcmp(input_value, "*") == 0) {
1556 continue;
1557 }
1558 if (strcasecmp(input_field, "vid") == 0) {
1559 if (kobj_getvalue(input_value, &value) == -1) {
1560 scsa2usb_override_error("vendor id", scsa2usbp);
1561
1562 return (USB_FAILURE);
1563 }
1564 ovp->vid = (int)value;
1565 } else if (strcasecmp(input_field, "pid") == 0) {
1566 if (kobj_getvalue(input_value, &value) == -1) {
1567 scsa2usb_override_error("product id",
1568 scsa2usbp);
1569
1570 return (USB_FAILURE);
1571 }
1572 ovp->pid = (int)value;
1573 } else if (strcasecmp(input_field, "rev") == 0) {
1574 if (kobj_getvalue(input_value, &value) == -1) {
1575 scsa2usb_override_error("revision id",
1576 scsa2usbp);
1577
1578 return (USB_FAILURE);
1579 }
1580 ovp->rev = (int)value;
1581 } else if (strcasecmp(input_field, "subclass") == 0) {
1582 for (i = 0; i < N_SCSA2USB_SUBC_OVERRIDE; i++) {
1583 if (strcasecmp(input_value,
1584 scsa2usb_subclass[i].name) == 0) {
1585 ovp->subclass =
1586 scsa2usb_subclass[i].value;
1587 break;
1588 }
1589 }
1590 if (ovp->subclass == 0) {
1591 scsa2usb_override_error("subclass", scsa2usbp);
1592
1593 return (USB_FAILURE);
1594 }
1595 } else if (strcasecmp(input_field, "protocol") == 0) {
1596 for (i = 0; i < N_SCSA2USB_PROT_OVERRIDE; i++) {
1597 if (strcasecmp(input_value,
1598 scsa2usb_protocol[i].name) == 0) {
1599 ovp->protocol =
1600 scsa2usb_protocol[i].value;
1601 break;
1602 }
1603 }
1604 if (ovp->protocol == 0) {
1605 scsa2usb_override_error("protocol", scsa2usbp);
1606
1607 return (USB_FAILURE);
1608 }
1609 } else if (strcasecmp(input_field, "pm") == 0) {
1610 if (strcasecmp(input_value, "off") == 0) {
1611 ovp->pmoff = 1;
1612 break;
1613 } else {
1614 scsa2usb_override_error("pm", scsa2usbp);
1615
1616 return (USB_FAILURE);
1617 }
1618 } else if (strcasecmp(input_field, "removable") == 0) {
1619 if (strcasecmp(input_value, "true") == 0) {
1620 ovp->fake_removable = 1;
1621 break;
1622 } else {
1623 scsa2usb_override_error("removable", scsa2usbp);
1624
1625 return (USB_FAILURE);
1626 }
1627 } else if (strcasecmp(input_field, "modesense") == 0) {
1628 if (strcasecmp(input_value, "false") == 0) {
1629 ovp->no_modesense = 1;
1630 break;
1631 } else {
1632 scsa2usb_override_error("modesense",
1633 scsa2usbp);
1634
1635 return (USB_FAILURE);
1636 }
1637 } else if (strcasecmp(input_field,
1638 "reduced-cmd-support") == 0) {
1639 if (strcasecmp(input_value, "true") == 0) {
1640 ovp->reduced_cmd_support = 1;
1641 break;
1642 } else {
1643 scsa2usb_override_error(
1644 "reduced-cmd-support", scsa2usbp);
1645
1646 return (USB_FAILURE);
1647 }
1648 } else {
1649 scsa2usb_override_error(input_field, scsa2usbp);
1650
1651 return (USB_FAILURE);
1652 }
1653 }
1654
1655 return (USB_SUCCESS);
1656 }
1657
1658
1659 /*
1660 * scsa2usb_override_error:
1661 * print an error message if conf file string is bad format
1662 */
1663 static void
scsa2usb_override_error(char * input_field,scsa2usb_state_t * scsa2usbp)1664 scsa2usb_override_error(char *input_field, scsa2usb_state_t *scsa2usbp)
1665 {
1666 USB_DPRINTF_L1(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
1667 "invalid %s in scsa2usb.conf file entry", input_field);
1668 }
1669
1670 /*
1671 * scsa2usb_strtok_r:
1672 * parse a list of tokens
1673 */
1674 static char *
scsa2usb_strtok_r(char * p,char * sep,char ** lasts)1675 scsa2usb_strtok_r(char *p, char *sep, char **lasts)
1676 {
1677 char *e;
1678 char *tok = NULL;
1679
1680 if (p == 0 || *p == 0) {
1681
1682 return (NULL);
1683 }
1684
1685 e = p+strlen(p);
1686
1687 do {
1688 if (strchr(sep, *p) != NULL) {
1689 if (tok != NULL) {
1690 *p = 0;
1691 *lasts = p+1;
1692
1693 return (tok);
1694 }
1695 } else if (tok == NULL) {
1696 tok = p;
1697 }
1698 } while (++p < e);
1699
1700 *lasts = NULL;
1701
1702 return (tok);
1703 }
1704
1705
1706 /*
1707 * scsa2usb_validate_attrs:
1708 * many devices have BO/CB/CBI protocol support issues.
1709 * use vendor/product info to reset the
1710 * individual erroneous attributes
1711 *
1712 * NOTE: we look at only device at a time (at attach time)
1713 */
1714 static void
scsa2usb_validate_attrs(scsa2usb_state_t * scsa2usbp)1715 scsa2usb_validate_attrs(scsa2usb_state_t *scsa2usbp)
1716 {
1717 int i, mask;
1718 usb_dev_descr_t *desc = scsa2usbp->scsa2usb_dev_data->dev_descr;
1719
1720 if (!SCSA2USB_IS_BULK_ONLY(scsa2usbp)) {
1721 scsa2usbp->scsa2usb_attrs &= ~SCSA2USB_ATTRS_GET_LUN;
1722 }
1723
1724 /* determine if this device is on the blacklist */
1725 for (i = 0; i < N_SCSA2USB_BLACKLIST; i++) {
1726 if ((scsa2usb_blacklist[i].idVendor == desc->idVendor) &&
1727 ((scsa2usb_blacklist[i].idProduct == desc->idProduct) ||
1728 (scsa2usb_blacklist[i].idProduct == X))) {
1729 scsa2usbp->scsa2usb_attrs &=
1730 ~(scsa2usb_blacklist[i].attributes);
1731 break;
1732 }
1733 }
1734
1735 /*
1736 * Mitsumi's CD-RW drives subclass isn't UFI.
1737 * But they support UFI command-set (this code ensures that)
1738 * NOTE: This is a special case, and is being called out so.
1739 */
1740 if (desc->idVendor == MS_MITSUMI_VID) {
1741 mask = scsa2usbp->scsa2usb_cmd_protocol & SCSA2USB_CMDSET_MASK;
1742 if (mask) {
1743 scsa2usbp->scsa2usb_cmd_protocol &= ~mask;
1744 }
1745 scsa2usbp->scsa2usb_cmd_protocol |= SCSA2USB_UFI_CMDSET;
1746 }
1747
1748 if (scsa2usbp->scsa2usb_attrs != SCSA2USB_ALL_ATTRS) {
1749 USB_DPRINTF_L2(DPRINT_MASK_SCSA,
1750 scsa2usbp->scsa2usb_log_handle,
1751 "scsa2usb attributes modified: 0x%x",
1752 scsa2usbp->scsa2usb_attrs);
1753 }
1754 }
1755
1756
1757 /*
1758 * scsa2usb_create_luns:
1759 * check the number of luns but continue if the check fails,
1760 * create child nodes for each lun
1761 */
1762 static void
scsa2usb_create_luns(scsa2usb_state_t * scsa2usbp)1763 scsa2usb_create_luns(scsa2usb_state_t *scsa2usbp)
1764 {
1765 int lun, rval;
1766 char *compatible[MAX_COMPAT_NAMES]; /* compatible names */
1767 dev_info_t *cdip;
1768 uchar_t dtype;
1769 char *node_name;
1770 char *driver_name = NULL;
1771
1772 USB_DPRINTF_L4(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
1773 "scsa2usb_create_luns:");
1774
1775 mutex_enter(&scsa2usbp->scsa2usb_mutex);
1776
1777 /* Set n_luns to 1 by default (for floppies and other devices) */
1778 scsa2usbp->scsa2usb_n_luns = 1;
1779
1780 /*
1781 * Check if there are any device out there which don't
1782 * support the GET_MAX_LUN command. If so, don't issue
1783 * control request to them.
1784 */
1785 if ((scsa2usbp->scsa2usb_attrs & SCSA2USB_ATTRS_GET_LUN) == 0) {
1786 USB_DPRINTF_L2(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
1787 "get_max_lun cmd not supported");
1788 } else {
1789 if (SCSA2USB_IS_BULK_ONLY(scsa2usbp)) {
1790 scsa2usbp->scsa2usb_n_luns =
1791 scsa2usb_bulk_only_get_max_lun(scsa2usbp);
1792 }
1793 }
1794
1795 USB_DPRINTF_L3(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
1796 "scsa2usb_create_luns: %d luns found", scsa2usbp->scsa2usb_n_luns);
1797
1798 /*
1799 * create disk child for each lun
1800 */
1801 for (lun = 0; lun < scsa2usbp->scsa2usb_n_luns; lun++) {
1802 ASSERT(scsa2usbp->scsa2usb_lun_dip[lun] == NULL);
1803
1804 /* do an inquiry to get the dtype of this lun */
1805 scsa2usb_do_inquiry(scsa2usbp, 0, lun);
1806
1807 dtype = scsa2usbp->scsa2usb_lun_inquiry[lun].
1808 inq_dtype & DTYPE_MASK;
1809
1810 USB_DPRINTF_L3(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
1811 "dtype[%d]=0x%x", lun, dtype);
1812
1813 driver_name = NULL;
1814
1815 switch (dtype) {
1816 case DTYPE_DIRECT:
1817 case DTYPE_RODIRECT:
1818 case DTYPE_OPTICAL:
1819 node_name = "disk";
1820 driver_name = "sd";
1821
1822 break;
1823 case DTYPE_SEQUENTIAL:
1824 node_name = "tape";
1825 driver_name = "st";
1826
1827 break;
1828 case DTYPE_PRINTER:
1829 node_name = "printer";
1830
1831 break;
1832 case DTYPE_PROCESSOR:
1833 node_name = "processor";
1834
1835 break;
1836 case DTYPE_WORM:
1837 node_name = "worm";
1838
1839 break;
1840 case DTYPE_SCANNER:
1841 node_name = "scanner";
1842
1843 break;
1844 case DTYPE_CHANGER:
1845 node_name = "changer";
1846
1847 break;
1848 case DTYPE_COMM:
1849 node_name = "comm";
1850
1851 break;
1852 case DTYPE_ARRAY_CTRL:
1853 node_name = "array_ctrl";
1854
1855 break;
1856 case DTYPE_ESI:
1857 node_name = "esi";
1858 driver_name = "ses";
1859
1860 break;
1861 default:
1862 node_name = "generic";
1863
1864 break;
1865 }
1866
1867 if (driver_name) {
1868 compatible[0] = driver_name;
1869 }
1870
1871 ndi_devi_alloc_sleep(scsa2usbp->scsa2usb_dip, node_name,
1872 (pnode_t)DEVI_SID_NODEID, &cdip);
1873
1874 /* attach target & lun properties */
1875 rval = ndi_prop_update_int(DDI_DEV_T_NONE, cdip, "target", 0);
1876 if (rval != DDI_PROP_SUCCESS) {
1877 USB_DPRINTF_L2(DPRINT_MASK_SCSA,
1878 scsa2usbp->scsa2usb_log_handle,
1879 "ndi_prop_update_int target failed %d", rval);
1880 (void) ndi_devi_free(cdip);
1881 continue;
1882 }
1883
1884 rval = ndi_prop_create_boolean(DDI_DEV_T_NONE, cdip,
1885 "hotpluggable");
1886 if (rval != DDI_PROP_SUCCESS) {
1887 USB_DPRINTF_L2(DPRINT_MASK_SCSA,
1888 scsa2usbp->scsa2usb_log_handle,
1889 "ndi_prop_create_boolean hotpluggable failed %d",
1890 rval);
1891 ddi_prop_remove_all(cdip);
1892 (void) ndi_devi_free(cdip);
1893 continue;
1894 }
1895 /*
1896 * Some devices don't support LOG SENSE, so tells
1897 * sd driver not to send this command.
1898 */
1899 rval = ndi_prop_update_int(DDI_DEV_T_NONE, cdip,
1900 "pm-capable", 1);
1901 if (rval != DDI_PROP_SUCCESS) {
1902 USB_DPRINTF_L2(DPRINT_MASK_SCSA,
1903 scsa2usbp->scsa2usb_log_handle,
1904 "ndi_prop_update_int pm-capable failed %d", rval);
1905 ddi_prop_remove_all(cdip);
1906 (void) ndi_devi_free(cdip);
1907 continue;
1908 }
1909
1910 rval = ndi_prop_update_int(DDI_DEV_T_NONE, cdip, "lun", lun);
1911 if (rval != DDI_PROP_SUCCESS) {
1912 USB_DPRINTF_L2(DPRINT_MASK_SCSA,
1913 scsa2usbp->scsa2usb_log_handle,
1914 "ndi_prop_update_int lun failed %d", rval);
1915 ddi_prop_remove_all(cdip);
1916 (void) ndi_devi_free(cdip);
1917 continue;
1918 }
1919
1920 if (driver_name) {
1921 rval = ndi_prop_update_string_array(DDI_DEV_T_NONE,
1922 cdip, "compatible", (char **)compatible,
1923 MAX_COMPAT_NAMES);
1924 if (rval != DDI_PROP_SUCCESS) {
1925 USB_DPRINTF_L2(DPRINT_MASK_SCSA,
1926 scsa2usbp->scsa2usb_log_handle,
1927 "ndi_prop_update_string_array failed %d",
1928 rval);
1929 ddi_prop_remove_all(cdip);
1930 (void) ndi_devi_free(cdip);
1931 continue;
1932 }
1933 }
1934
1935 /*
1936 * add property "usb" so we always verify that it is our child
1937 */
1938 rval = ndi_prop_create_boolean(DDI_DEV_T_NONE, cdip, "usb");
1939 if (rval != DDI_PROP_SUCCESS) {
1940 USB_DPRINTF_L2(DPRINT_MASK_SCSA,
1941 scsa2usbp->scsa2usb_log_handle,
1942 "ndi_prop_create_boolean failed %d", rval);
1943 ddi_prop_remove_all(cdip);
1944 (void) ndi_devi_free(cdip);
1945 continue;
1946 }
1947
1948 mutex_exit(&scsa2usbp->scsa2usb_mutex);
1949 (void) ddi_initchild(scsa2usbp->scsa2usb_dip, cdip);
1950 mutex_enter(&scsa2usbp->scsa2usb_mutex);
1951
1952 usba_set_usba_device(cdip,
1953 usba_get_usba_device(scsa2usbp->scsa2usb_dip));
1954 }
1955 mutex_exit(&scsa2usbp->scsa2usb_mutex);
1956 }
1957
1958
1959 /*
1960 * scsa2usb_is_usb:
1961 * scsa2usb gets called for all possible sd children.
1962 * we can only accept usb children
1963 */
1964 static int
scsa2usb_is_usb(dev_info_t * dip)1965 scsa2usb_is_usb(dev_info_t *dip)
1966 {
1967 if (dip) {
1968 return (ddi_prop_exists(DDI_DEV_T_ANY, dip,
1969 DDI_PROP_DONTPASS, "usb"));
1970 }
1971 return (0);
1972 }
1973
1974
1975 /*
1976 * Panic Stuff
1977 * scsa2usb_panic_callb_init:
1978 * initialize PANIC callb and free allocated resources
1979 */
1980 static void
scsa2usb_panic_callb_init(scsa2usb_state_t * scsa2usbp)1981 scsa2usb_panic_callb_init(scsa2usb_state_t *scsa2usbp)
1982 {
1983 /*
1984 * In case the system panics, the sync command flushes
1985 * dirty FS pages or buffers. This would cause a hang
1986 * in USB.
1987 * The reason for the failure is that we enter
1988 * polled mode (interrupts disabled) and HCD gets stuck
1989 * trying to execute bulk requests
1990 * The panic_callback registered below provides a warning
1991 * that a panic has occurred and from that point onwards, we
1992 * complete each request successfully and immediately. This
1993 * will fake successful syncing so at least the rest of the
1994 * filesystems complete syncing.
1995 */
1996 scsa2usbp->scsa2usb_panic_info =
1997 kmem_zalloc(sizeof (scsa2usb_cpr_t), KM_SLEEP);
1998 mutex_init(&scsa2usbp->scsa2usb_panic_info->lockp,
1999 NULL, MUTEX_DRIVER,
2000 scsa2usbp->scsa2usb_dev_data->dev_iblock_cookie);
2001 scsa2usbp->scsa2usb_panic_info->statep = scsa2usbp;
2002 scsa2usbp->scsa2usb_panic_info->cpr.cc_lockp =
2003 &scsa2usbp->scsa2usb_panic_info->lockp;
2004 scsa2usbp->scsa2usb_panic_info->cpr.cc_id =
2005 callb_add(scsa2usb_panic_callb,
2006 (void *)scsa2usbp->scsa2usb_panic_info,
2007 CB_CL_PANIC, "scsa2usb");
2008 }
2009
2010
2011 /*
2012 * scsa2usb_panic_callb_fini:
2013 * cancel out PANIC callb and free allocated resources
2014 */
2015 static void
scsa2usb_panic_callb_fini(scsa2usb_state_t * scsa2usbp)2016 scsa2usb_panic_callb_fini(scsa2usb_state_t *scsa2usbp)
2017 {
2018 if (scsa2usbp->scsa2usb_panic_info) {
2019 SCSA2USB_CANCEL_CB(scsa2usbp->scsa2usb_panic_info->cpr.cc_id);
2020 mutex_destroy(&scsa2usbp->scsa2usb_panic_info->lockp);
2021 scsa2usbp->scsa2usb_panic_info->statep = NULL;
2022 kmem_free(scsa2usbp->scsa2usb_panic_info,
2023 sizeof (scsa2usb_cpr_t));
2024 scsa2usbp->scsa2usb_panic_info = NULL;
2025 }
2026 }
2027
2028
2029 /*
2030 * scsa2usb_panic_callb:
2031 * This routine is called when there is a system panic.
2032 */
2033 /* ARGSUSED */
2034 static boolean_t
scsa2usb_panic_callb(void * arg,int code)2035 scsa2usb_panic_callb(void *arg, int code)
2036 {
2037 scsa2usb_cpr_t *cpr_infop;
2038 scsa2usb_state_t *scsa2usbp;
2039 uint_t lun;
2040
2041 _NOTE(NO_COMPETING_THREADS_NOW);
2042 cpr_infop = (scsa2usb_cpr_t *)arg;
2043 scsa2usbp = (scsa2usb_state_t *)cpr_infop->statep;
2044
2045 USB_DPRINTF_L4(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
2046 "scsa2usb_panic_callb: code=%d", code);
2047
2048 /*
2049 * If we return error here, "sd" prints lots of error
2050 * messages and could retry the same pkt over and over again.
2051 * The sync recovery isn't "smooth" in that case. By faking
2052 * a success return, instead, we force sync to complete.
2053 */
2054 if (scsa2usbp->scsa2usb_cur_pkt) {
2055 /*
2056 * Do not print the "no sync" warning here. it will then be
2057 * displayed before we actually start syncing. Also we don't
2058 * replace this code with a call to scsa2usb_pkt_completion().
2059 * NOTE: mutexes are disabled during panic.
2060 */
2061 scsa2usbp->scsa2usb_cur_pkt->pkt_reason = CMD_CMPLT;
2062 mutex_enter(&scsa2usbp->scsa2usb_mutex);
2063 scsa2usb_pkt_completion(scsa2usbp, scsa2usbp->scsa2usb_cur_pkt);
2064 mutex_exit(&scsa2usbp->scsa2usb_mutex);
2065 }
2066
2067 /* get rid of waitQ */
2068 for (lun = 0; lun < SCSA2USB_MAX_LUNS; lun++) {
2069 scsa2usb_flush_waitQ(scsa2usbp, lun, CMD_CMPLT);
2070 }
2071
2072 #ifndef lint
2073 _NOTE(COMPETING_THREADS_NOW);
2074 #endif
2075
2076 return (B_TRUE);
2077 }
2078
2079 /*
2080 * scsa2usb_cpr_suspend
2081 * determine if the device's state can be changed to SUSPENDED
2082 * close pipes if there is no activity
2083 */
2084 /* ARGSUSED */
2085 static int
scsa2usb_cpr_suspend(dev_info_t * dip)2086 scsa2usb_cpr_suspend(dev_info_t *dip)
2087 {
2088 scsa2usb_state_t *scsa2usbp;
2089 int prev_state;
2090 int rval = USB_FAILURE;
2091
2092 scsa2usbp = ddi_get_soft_state(scsa2usb_statep, ddi_get_instance(dip));
2093
2094 ASSERT(scsa2usbp != NULL);
2095
2096 USB_DPRINTF_L4(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
2097 "scsa2usb_cpr_suspend:");
2098
2099 mutex_enter(&scsa2usbp->scsa2usb_mutex);
2100 switch (scsa2usbp->scsa2usb_dev_state) {
2101 case USB_DEV_ONLINE:
2102 case USB_DEV_PWRED_DOWN:
2103 case USB_DEV_DISCONNECTED:
2104 prev_state = scsa2usbp->scsa2usb_dev_state;
2105 scsa2usbp->scsa2usb_dev_state = USB_DEV_SUSPENDED;
2106
2107 /*
2108 * If the device is busy, we cannot suspend
2109 */
2110 if (SCSA2USB_BUSY(scsa2usbp)) {
2111 USB_DPRINTF_L3(DPRINT_MASK_SCSA,
2112 scsa2usbp->scsa2usb_log_handle,
2113 "scsa2usb_cpr_suspend: I/O active");
2114
2115 /* fall back to previous state */
2116 scsa2usbp->scsa2usb_dev_state = prev_state;
2117 } else {
2118 rval = USB_SUCCESS;
2119 }
2120
2121 break;
2122 case USB_DEV_SUSPENDED:
2123 default:
2124 USB_DPRINTF_L2(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
2125 "scsa2usb_cpr_suspend: Illegal dev state: %d",
2126 scsa2usbp->scsa2usb_dev_state);
2127
2128 break;
2129 }
2130 mutex_exit(&scsa2usbp->scsa2usb_mutex);
2131
2132 if ((rval == USB_SUCCESS) && scsa2usbp->scsa2usb_ugen_hdl) {
2133 rval = usb_ugen_detach(scsa2usbp->scsa2usb_ugen_hdl,
2134 DDI_SUSPEND);
2135 }
2136
2137 return (rval);
2138 }
2139
2140
2141 /*
2142 * scsa2usb_cpr_resume:
2143 * restore device's state
2144 */
2145 static void
scsa2usb_cpr_resume(dev_info_t * dip)2146 scsa2usb_cpr_resume(dev_info_t *dip)
2147 {
2148 scsa2usb_state_t *scsa2usbp =
2149 ddi_get_soft_state(scsa2usb_statep, ddi_get_instance(dip));
2150
2151 ASSERT(scsa2usbp != NULL);
2152
2153 USB_DPRINTF_L4(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
2154 "scsa2usb_cpr_resume: dip = 0x%p", (void *)dip);
2155
2156 scsa2usb_restore_device_state(dip, scsa2usbp);
2157
2158 if (scsa2usbp->scsa2usb_ugen_hdl) {
2159 (void) usb_ugen_attach(scsa2usbp->scsa2usb_ugen_hdl,
2160 DDI_RESUME);
2161 }
2162 }
2163
2164
2165 /*
2166 * scsa2usb_restore_device_state:
2167 * - raise the device's power
2168 * - reopen all the pipes
2169 */
2170 static void
scsa2usb_restore_device_state(dev_info_t * dip,scsa2usb_state_t * scsa2usbp)2171 scsa2usb_restore_device_state(dev_info_t *dip, scsa2usb_state_t *scsa2usbp)
2172 {
2173 uint_t prev_state;
2174
2175 USB_DPRINTF_L4(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
2176 "scsa2usb_restore_device_state:");
2177
2178 mutex_enter(&scsa2usbp->scsa2usb_mutex);
2179 prev_state = scsa2usbp->scsa2usb_dev_state;
2180
2181 scsa2usb_raise_power(scsa2usbp);
2182
2183 ASSERT((prev_state == USB_DEV_DISCONNECTED) ||
2184 (prev_state == USB_DEV_SUSPENDED));
2185
2186 mutex_exit(&scsa2usbp->scsa2usb_mutex);
2187
2188 /* Check for the same device */
2189 if (usb_check_same_device(dip, scsa2usbp->scsa2usb_log_handle,
2190 USB_LOG_L0, DPRINT_MASK_ALL, USB_CHK_ALL, NULL) != USB_SUCCESS) {
2191
2192 /* change the flags to active */
2193 mutex_enter(&scsa2usbp->scsa2usb_mutex);
2194 scsa2usbp->scsa2usb_dev_state = USB_DEV_DISCONNECTED;
2195 mutex_exit(&scsa2usbp->scsa2usb_mutex);
2196
2197 scsa2usb_pm_idle_component(scsa2usbp);
2198
2199 return;
2200 }
2201
2202 /*
2203 * if the device had remote wakeup earlier,
2204 * enable it again
2205 */
2206 mutex_enter(&scsa2usbp->scsa2usb_mutex);
2207 if (scsa2usbp->scsa2usb_pm &&
2208 scsa2usbp->scsa2usb_pm->scsa2usb_wakeup_enabled) {
2209 mutex_exit(&scsa2usbp->scsa2usb_mutex);
2210 (void) usb_handle_remote_wakeup(scsa2usbp->scsa2usb_dip,
2211 USB_REMOTE_WAKEUP_ENABLE);
2212 mutex_enter(&scsa2usbp->scsa2usb_mutex);
2213 }
2214
2215 scsa2usbp->scsa2usb_dev_state = USB_DEV_ONLINE;
2216 scsa2usbp->scsa2usb_pkt_state = SCSA2USB_PKT_NONE;
2217 mutex_exit(&scsa2usbp->scsa2usb_mutex);
2218
2219 scsa2usb_pm_idle_component(scsa2usbp);
2220 }
2221
2222
2223 /*
2224 * SCSA entry points:
2225 *
2226 * scsa2usb_scsi_tgt_probe:
2227 * scsa functions are exported by means of the transport table
2228 * Issue a probe to get the inquiry data.
2229 */
2230 /* ARGSUSED */
2231 static int
scsa2usb_scsi_tgt_probe(struct scsi_device * sd,int (* waitfunc)(void))2232 scsa2usb_scsi_tgt_probe(struct scsi_device *sd, int (*waitfunc)(void))
2233 {
2234 scsi_hba_tran_t *tran;
2235 scsa2usb_state_t *scsa2usbp;
2236 dev_info_t *dip = ddi_get_parent(sd->sd_dev);
2237 int rval;
2238
2239 ASSERT(dip);
2240
2241 tran = ddi_get_driver_private(dip);
2242 ASSERT(tran != NULL);
2243 scsa2usbp = (scsa2usb_state_t *)tran->tran_hba_private;
2244 ASSERT(scsa2usbp);
2245
2246 USB_DPRINTF_L4(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
2247 "scsa2usb_scsi_tgt_probe:");
2248
2249 /* if device is disconnected (ie. pipes closed), fail immediately */
2250 mutex_enter(&scsa2usbp->scsa2usb_mutex);
2251 if (!(SCSA2USB_DEVICE_ACCESS_OK(scsa2usbp))) {
2252 mutex_exit(&scsa2usbp->scsa2usb_mutex);
2253
2254 return (SCSIPROBE_FAILURE);
2255 }
2256 mutex_exit(&scsa2usbp->scsa2usb_mutex);
2257
2258 USB_DPRINTF_L4(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
2259 "scsa2usb_scsi_tgt_probe: scsi_device = 0x%p", (void *)sd);
2260
2261 if ((rval = scsi_hba_probe(sd, waitfunc)) == SCSIPROBE_EXISTS) {
2262 /*
2263 * respect the removable bit on all USB storage devices
2264 * unless overridden by a scsa2usb.conf entry
2265 */
2266 mutex_enter(&scsa2usbp->scsa2usb_mutex);
2267 if (!(scsa2usbp->scsa2usb_attrs & SCSA2USB_ATTRS_RMB)) {
2268 _NOTE(SCHEME_PROTECTS_DATA("unshared", scsi_inquiry))
2269 sd->sd_inq->inq_rmb = 1;
2270 }
2271 mutex_exit(&scsa2usbp->scsa2usb_mutex);
2272 }
2273
2274 return (rval);
2275 }
2276
2277
2278 /*
2279 * scsa2usb_scsi_tgt_init:
2280 * check whether we created this child ourselves
2281 */
2282 /* ARGSUSED */
2283 static int
scsa2usb_scsi_tgt_init(dev_info_t * dip,dev_info_t * cdip,scsi_hba_tran_t * tran,struct scsi_device * sd)2284 scsa2usb_scsi_tgt_init(dev_info_t *dip, dev_info_t *cdip,
2285 scsi_hba_tran_t *tran, struct scsi_device *sd)
2286 {
2287 scsa2usb_state_t *scsa2usbp = (scsa2usb_state_t *)
2288 tran->tran_hba_private;
2289 int lun;
2290 int t_len = sizeof (lun);
2291
2292 if (ddi_prop_op(DDI_DEV_T_ANY, cdip, PROP_LEN_AND_VAL_BUF,
2293 DDI_PROP_DONTPASS|DDI_PROP_CANSLEEP, "lun", (caddr_t)&lun,
2294 &t_len) != DDI_PROP_SUCCESS) {
2295
2296 return (DDI_FAILURE);
2297 }
2298
2299 USB_DPRINTF_L4(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
2300 "scsa2usb_scsi_tgt_init: %s, lun%d", ddi_driver_name(cdip), lun);
2301
2302 /* is this a child we created? */
2303 if (scsa2usb_is_usb(cdip) == 0) {
2304
2305 USB_DPRINTF_L2(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
2306 "scsa2usb_scsi_tgt_init: new child %s%d",
2307 ddi_driver_name(cdip), ddi_get_instance(cdip));
2308
2309 /*
2310 * add property "usb" so we can always verify that it
2311 * is our child
2312 */
2313 if (ndi_prop_create_boolean(DDI_DEV_T_NONE, cdip, "usb") !=
2314 DDI_PROP_SUCCESS) {
2315 USB_DPRINTF_L2(DPRINT_MASK_SCSA,
2316 scsa2usbp->scsa2usb_log_handle,
2317 "ndi_prop_create_boolean failed");
2318
2319 return (DDI_FAILURE);
2320 }
2321
2322 usba_set_usba_device(cdip,
2323 usba_get_usba_device(scsa2usbp->scsa2usb_dip));
2324
2325 /*
2326 * we don't store this dip in scsa2usb_lun_dip, there
2327 * might be multiple dips for the same device
2328 */
2329
2330 return (DDI_SUCCESS);
2331 }
2332
2333 mutex_enter(&scsa2usbp->scsa2usb_mutex);
2334 if ((lun >= scsa2usbp->scsa2usb_n_luns) ||
2335 (scsa2usbp->scsa2usb_lun_dip[lun] != NULL)) {
2336 mutex_exit(&scsa2usbp->scsa2usb_mutex);
2337
2338 return (DDI_FAILURE);
2339 }
2340
2341 scsa2usbp->scsa2usb_lun_dip[lun] = cdip;
2342 mutex_exit(&scsa2usbp->scsa2usb_mutex);
2343
2344 return (DDI_SUCCESS);
2345 }
2346
2347
2348 /*
2349 * scsa2usb_scsi_tgt_free:
2350 */
2351 /* ARGSUSED */
2352 static void
scsa2usb_scsi_tgt_free(dev_info_t * hba_dip,dev_info_t * cdip,scsi_hba_tran_t * tran,struct scsi_device * sd)2353 scsa2usb_scsi_tgt_free(dev_info_t *hba_dip, dev_info_t *cdip,
2354 scsi_hba_tran_t *tran, struct scsi_device *sd)
2355 {
2356 scsa2usb_state_t *scsa2usbp = (scsa2usb_state_t *)
2357 tran->tran_hba_private;
2358 int lun;
2359 int t_len = sizeof (lun);
2360
2361 /* is this our child? */
2362 if (scsa2usb_is_usb(cdip) == 0) {
2363
2364 return;
2365 }
2366
2367 if (ddi_prop_op(DDI_DEV_T_ANY, cdip, PROP_LEN_AND_VAL_BUF,
2368 DDI_PROP_DONTPASS|DDI_PROP_CANSLEEP, "lun", (caddr_t)&lun,
2369 &t_len) != DDI_PROP_SUCCESS) {
2370
2371 return;
2372 }
2373
2374 USB_DPRINTF_L4(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
2375 "scsa2usb_scsi_tgt_free: %s lun%d", ddi_driver_name(cdip), lun);
2376
2377 mutex_enter(&scsa2usbp->scsa2usb_mutex);
2378 if (lun < scsa2usbp->scsa2usb_n_luns) {
2379 if (scsa2usbp->scsa2usb_lun_dip[lun] == cdip) {
2380 scsa2usbp->scsa2usb_lun_dip[lun] = NULL;
2381 }
2382 }
2383 mutex_exit(&scsa2usbp->scsa2usb_mutex);
2384 }
2385
2386
2387 /*
2388 * bus enumeration entry points
2389 */
2390 static int
scsa2usb_scsi_bus_config(dev_info_t * dip,uint_t flag,ddi_bus_config_op_t op,void * arg,dev_info_t ** child)2391 scsa2usb_scsi_bus_config(dev_info_t *dip, uint_t flag, ddi_bus_config_op_t op,
2392 void *arg, dev_info_t **child)
2393 {
2394 int circ;
2395 int rval;
2396
2397 scsa2usb_state_t *scsa2usbp =
2398 ddi_get_soft_state(scsa2usb_statep, ddi_get_instance(dip));
2399
2400 ASSERT(scsa2usbp != NULL);
2401
2402 USB_DPRINTF_L2(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
2403 "scsa2usb_scsi_bus_config: op=%d", op);
2404
2405 if (scsa2usb_scsi_bus_config_debug) {
2406 flag |= NDI_DEVI_DEBUG;
2407 }
2408
2409 ndi_devi_enter(dip, &circ);
2410 /* create children if necessary */
2411 if (DEVI(dip)->devi_child == NULL) {
2412 scsa2usb_create_luns(scsa2usbp);
2413 }
2414
2415 rval = ndi_busop_bus_config(dip, flag, op, arg, child, 0);
2416
2417 ndi_devi_exit(dip, circ);
2418
2419 return (rval);
2420 }
2421
2422
2423 static int
scsa2usb_scsi_bus_unconfig(dev_info_t * dip,uint_t flag,ddi_bus_config_op_t op,void * arg)2424 scsa2usb_scsi_bus_unconfig(dev_info_t *dip, uint_t flag, ddi_bus_config_op_t op,
2425 void *arg)
2426 {
2427 scsa2usb_state_t *scsa2usbp =
2428 ddi_get_soft_state(scsa2usb_statep, ddi_get_instance(dip));
2429
2430 int circular_count;
2431 int rval = NDI_SUCCESS;
2432 uint_t save_flag = flag;
2433
2434 ASSERT(scsa2usbp != NULL);
2435
2436 USB_DPRINTF_L4(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
2437 "scsa2usb_scsi_bus_unconfig: op=%d", op);
2438
2439 if (scsa2usb_scsi_bus_config_debug) {
2440 flag |= NDI_DEVI_DEBUG;
2441 }
2442
2443 /*
2444 * first offline and if offlining successful, then
2445 * remove children
2446 */
2447 if (op == BUS_UNCONFIG_ALL) {
2448 flag &= ~(NDI_DEVI_REMOVE | NDI_UNCONFIG);
2449 }
2450
2451 ndi_devi_enter(dip, &circular_count);
2452 rval = ndi_busop_bus_unconfig(dip, flag, op, arg);
2453
2454 /*
2455 * If unconfig is successful and not part of modunload
2456 * daemon, attempt to remove children.
2457 */
2458 if (op == BUS_UNCONFIG_ALL && rval == NDI_SUCCESS &&
2459 (flag & NDI_AUTODETACH) == 0) {
2460 flag |= NDI_DEVI_REMOVE;
2461 rval = ndi_busop_bus_unconfig(dip, flag, op, arg);
2462 }
2463 ndi_devi_exit(dip, circular_count);
2464
2465 if ((rval != NDI_SUCCESS) && (op == BUS_UNCONFIG_ALL) &&
2466 (save_flag & NDI_DEVI_REMOVE)) {
2467 mutex_enter(&scsa2usbp->scsa2usb_mutex);
2468 if (scsa2usbp->scsa2usb_warning_given != B_TRUE) {
2469 USB_DPRINTF_L2(DPRINT_MASK_SCSA,
2470 scsa2usbp->scsa2usb_log_handle,
2471 "Disconnected device was busy, "
2472 "please reconnect.");
2473 scsa2usbp->scsa2usb_warning_given = B_TRUE;
2474 }
2475 mutex_exit(&scsa2usbp->scsa2usb_mutex);
2476 }
2477
2478 USB_DPRINTF_L4(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
2479 "scsa2usb_scsi_bus_unconfig: rval=%d", rval);
2480
2481 return (rval);
2482 }
2483
2484
2485 /*
2486 * scsa2usb_scsi_init_pkt:
2487 * Set up the scsi_pkt for transport. Also initialize
2488 * scsa2usb_cmd struct for the transport.
2489 * NOTE: We do not do any DMA setup here as USBA framework
2490 * does that for us.
2491 */
2492 static struct scsi_pkt *
scsa2usb_scsi_init_pkt(struct scsi_address * ap,struct scsi_pkt * pkt,struct buf * bp,int cmdlen,int statuslen,int tgtlen,int flags,int (* callback)(),caddr_t arg)2493 scsa2usb_scsi_init_pkt(struct scsi_address *ap,
2494 struct scsi_pkt *pkt, struct buf *bp, int cmdlen, int statuslen,
2495 int tgtlen, int flags, int (*callback)(), caddr_t arg)
2496 {
2497 scsa2usb_cmd_t *cmd;
2498 scsa2usb_state_t *scsa2usbp;
2499 struct scsi_pkt *in_pkt = pkt;
2500
2501 ASSERT(callback == NULL_FUNC || callback == SLEEP_FUNC);
2502
2503 scsa2usbp = (scsa2usb_state_t *)ADDR2SCSA2USB(ap);
2504
2505 /* Print sync message */
2506 if (ddi_in_panic()) {
2507 mutex_enter(&scsa2usbp->scsa2usb_mutex);
2508 SCSA2USB_PRINT_SYNC_MSG(scsa2usb_sync_message, scsa2usbp);
2509 mutex_exit(&scsa2usbp->scsa2usb_mutex);
2510 /* continue so caller will not hang or complain */
2511 }
2512
2513 /* allocate a pkt, if none already allocated */
2514 if (pkt == NULL) {
2515 if (statuslen < sizeof (struct scsi_arq_status)) {
2516 statuslen = sizeof (struct scsi_arq_status);
2517 }
2518
2519 pkt = scsi_hba_pkt_alloc(scsa2usbp->scsa2usb_dip, ap, cmdlen,
2520 statuslen, tgtlen, sizeof (scsa2usb_cmd_t),
2521 callback, arg);
2522 if (pkt == NULL) {
2523
2524 return (NULL);
2525 }
2526
2527 cmd = PKT2CMD(pkt);
2528 cmd->cmd_pkt = pkt; /* back link to pkt */
2529 cmd->cmd_scblen = statuslen;
2530 cmd->cmd_cdblen = (uchar_t)cmdlen;
2531
2532 mutex_enter(&scsa2usbp->scsa2usb_mutex);
2533 cmd->cmd_tag = scsa2usbp->scsa2usb_tag++;
2534 mutex_exit(&scsa2usbp->scsa2usb_mutex);
2535
2536 cmd->cmd_bp = bp;
2537 /*
2538 * The buffer size of cmd->cmd_scb is constrained
2539 * to sizeof (struct scsi_arq_status), if the scblen
2540 * is bigger than that, we use pkt->pkt_scbp directly.
2541 */
2542 if (cmd->cmd_scblen == sizeof (struct scsi_arq_status)) {
2543 pkt->pkt_scbp = (opaque_t)&cmd->cmd_scb;
2544 }
2545
2546 usba_init_list(&cmd->cmd_waitQ, (usb_opaque_t)cmd,
2547 scsa2usbp->scsa2usb_dev_data->dev_iblock_cookie);
2548 } else {
2549 USB_DPRINTF_L2(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
2550 "scsa2usb: pkt != NULL");
2551
2552 /* nothing to do */
2553 }
2554
2555 if (bp && (bp->b_bcount != 0)) {
2556 if ((bp_mapin_common(bp, (callback == SLEEP_FUNC) ?
2557 VM_SLEEP : VM_NOSLEEP)) == NULL) {
2558 if (pkt != in_pkt) {
2559 scsi_hba_pkt_free(ap, pkt);
2560 }
2561
2562 return (NULL);
2563 }
2564
2565 USB_DPRINTF_L3(DPRINT_MASK_SCSA,
2566 scsa2usbp->scsa2usb_log_handle,
2567 "scsa2usb_scsi_init_pkt: mapped in 0x%p, addr=0x%p",
2568 (void *)bp, (void *)bp->b_un.b_addr);
2569 }
2570
2571 USB_DPRINTF_L4(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
2572 "scsa2usb_scsi_init_pkt: ap = 0x%p pkt: 0x%p\n\t"
2573 "bp = 0x%p cmdlen = %x stlen = 0x%x tlen = 0x%x flags = 0x%x",
2574 (void *)ap, (void *)pkt, (void *)bp, cmdlen, statuslen,
2575 tgtlen, flags);
2576
2577 return (pkt);
2578 }
2579
2580
2581 /*
2582 * scsa2usb_scsi_destroy_pkt:
2583 * We are done with the packet. Get rid of it.
2584 */
2585 static void
scsa2usb_scsi_destroy_pkt(struct scsi_address * ap,struct scsi_pkt * pkt)2586 scsa2usb_scsi_destroy_pkt(struct scsi_address *ap, struct scsi_pkt *pkt)
2587 {
2588 scsa2usb_cmd_t *cmd = PKT2CMD(pkt);
2589 scsa2usb_state_t *scsa2usbp = ADDR2SCSA2USB(ap);
2590
2591 USB_DPRINTF_L4(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
2592 "scsa2usb_scsi_destroy_pkt: pkt=0x%p", (void *)pkt);
2593
2594 usba_destroy_list(&cmd->cmd_waitQ);
2595 scsi_hba_pkt_free(ap, pkt);
2596 }
2597
2598
2599 /*
2600 * scsa2usb_scsi_start:
2601 * For each command being issued, build up the CDB
2602 * and call scsi_transport to issue the command. This
2603 * function is based on the assumption that USB allows
2604 * a subset of SCSI commands. Other SCSI commands we fail.
2605 */
2606 static int
scsa2usb_scsi_start(struct scsi_address * ap,struct scsi_pkt * pkt)2607 scsa2usb_scsi_start(struct scsi_address *ap, struct scsi_pkt *pkt)
2608 {
2609 scsa2usb_cmd_t *cmd;
2610 scsa2usb_state_t *scsa2usbp = ADDR2SCSA2USB(ap);
2611 uint_t lun = ap->a_lun;
2612
2613 mutex_enter(&scsa2usbp->scsa2usb_mutex);
2614
2615 cmd = PKT2CMD(pkt);
2616 USB_DPRINTF_L3(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
2617 "scsa2usb_scsi_start:\n\t"
2618 "bp: 0x%p ap: 0x%p pkt: 0x%p flag: 0x%x time: 0x%x\n\tcdb0: 0x%x "
2619 "dev_state: 0x%x pkt_state: 0x%x flags: 0x%x pipe_state: 0x%x",
2620 (void *)cmd->cmd_bp, (void *)ap, (void *)pkt, pkt->pkt_flags,
2621 pkt->pkt_time, pkt->pkt_cdbp[0], scsa2usbp->scsa2usb_dev_state,
2622 scsa2usbp->scsa2usb_pkt_state, scsa2usbp->scsa2usb_flags,
2623 scsa2usbp->scsa2usb_pipe_state);
2624
2625 if (pkt->pkt_time == 0) {
2626 USB_DPRINTF_L1(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
2627 "pkt submitted with 0 timeout which may cause indefinite "
2628 "hangs");
2629 }
2630
2631 /*
2632 * if we are in panic, we are in polled mode, so we can just
2633 * accept the request, drop it and return
2634 * if we fail this request, the rest of the file systems do not
2635 * get synced
2636 */
2637 if (ddi_in_panic()) {
2638 extern int do_polled_io;
2639
2640 ASSERT(do_polled_io);
2641 scsa2usb_prepare_pkt(scsa2usbp, pkt);
2642 SCSA2USB_PRINT_SYNC_MSG(scsa2usb_sync_message, scsa2usbp);
2643 mutex_exit(&scsa2usbp->scsa2usb_mutex);
2644
2645 return (TRAN_ACCEPT);
2646 }
2647
2648 /* we cannot do polling, this should not happen */
2649 if (pkt->pkt_flags & FLAG_NOINTR) {
2650 USB_DPRINTF_L2(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
2651 "NOINTR packet: opcode = 0%x", pkt->pkt_cdbp[0]);
2652 mutex_exit(&scsa2usbp->scsa2usb_mutex);
2653
2654 return (TRAN_BADPKT);
2655 }
2656
2657 /* prepare packet */
2658 scsa2usb_prepare_pkt(scsa2usbp, pkt);
2659
2660 /* just queue up the requests in the waitQ if below max */
2661 if (usba_list_entry_count(&scsa2usbp->scsa2usb_waitQ[lun]) >
2662 SCSA2USB_MAX_REQ_PER_LUN) {
2663 USB_DPRINTF_L2(DPRINT_MASK_SCSA,
2664 scsa2usbp->scsa2usb_log_handle,
2665 "scsa2usb_scsi_start: limit (%d) exceeded",
2666 SCSA2USB_MAX_REQ_PER_LUN);
2667 mutex_exit(&scsa2usbp->scsa2usb_mutex);
2668
2669 return (TRAN_BUSY);
2670 }
2671
2672 usba_add_to_list(&scsa2usbp->scsa2usb_waitQ[lun], &cmd->cmd_waitQ);
2673
2674 USB_DPRINTF_L3(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
2675 "scsa2usb_work_thread_id=0x%p, count=%d, lun=%d",
2676 (void *)scsa2usbp->scsa2usb_work_thread_id,
2677 usba_list_entry_count(&scsa2usbp->scsa2usb_waitQ[lun]), lun);
2678
2679 /* fire up a thread to start executing the protocol */
2680 if (scsa2usbp->scsa2usb_work_thread_id == 0) {
2681 if ((usb_async_req(scsa2usbp->scsa2usb_dip,
2682 scsa2usb_work_thread,
2683 (void *)scsa2usbp, USB_FLAGS_SLEEP)) != USB_SUCCESS) {
2684 USB_DPRINTF_L2(DPRINT_MASK_SCSA,
2685 scsa2usbp->scsa2usb_log_handle,
2686 "no work thread started");
2687
2688 if (usba_rm_from_list(
2689 &scsa2usbp->scsa2usb_waitQ[lun],
2690 &cmd->cmd_waitQ) == USB_SUCCESS) {
2691 mutex_exit(&scsa2usbp->scsa2usb_mutex);
2692
2693 return (TRAN_BUSY);
2694 } else {
2695
2696 mutex_exit(&scsa2usbp->scsa2usb_mutex);
2697
2698 return (TRAN_ACCEPT);
2699 }
2700 }
2701 scsa2usbp->scsa2usb_work_thread_id = (kthread_t *)1;
2702 }
2703
2704 mutex_exit(&scsa2usbp->scsa2usb_mutex);
2705
2706 return (TRAN_ACCEPT);
2707 }
2708
2709
2710 /*
2711 * scsa2usb_scsi_abort:
2712 * Issue SCSI abort command. This function is a NOP.
2713 */
2714 /* ARGSUSED */
2715 static int
scsa2usb_scsi_abort(struct scsi_address * ap,struct scsi_pkt * pkt)2716 scsa2usb_scsi_abort(struct scsi_address *ap, struct scsi_pkt *pkt)
2717 {
2718 scsa2usb_state_t *scsa2usbp = (scsa2usb_state_t *)ADDR2SCSA2USB(ap);
2719
2720 USB_DPRINTF_L4(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
2721 "scsa2usb_scsi_abort: pkt = %p", (void *)pkt);
2722
2723 /* if device is disconnected (ie. pipes closed), fail immediately */
2724 mutex_enter(&scsa2usbp->scsa2usb_mutex);
2725 if (!(SCSA2USB_DEVICE_ACCESS_OK(scsa2usbp))) {
2726 mutex_exit(&scsa2usbp->scsa2usb_mutex);
2727
2728 return (0);
2729 }
2730
2731 /* flush waitQ if target and lun match */
2732 if ((ap->a_target == pkt->pkt_address.a_target) &&
2733 (ap->a_lun == pkt->pkt_address.a_lun)) {
2734 mutex_exit(&scsa2usbp->scsa2usb_mutex);
2735 scsa2usb_flush_waitQ(scsa2usbp, ap->a_lun, CMD_ABORTED);
2736 mutex_enter(&scsa2usbp->scsa2usb_mutex);
2737 }
2738 mutex_exit(&scsa2usbp->scsa2usb_mutex);
2739
2740 return (0);
2741 }
2742
2743
2744 /*
2745 * scsa2usb_scsi_reset:
2746 * device reset may turn the device into a brick and bus reset
2747 * is not applicable.
2748 * just flush the waitQ
2749 * We return success, always.
2750 */
2751 /* ARGSUSED */
2752 static int
scsa2usb_scsi_reset(struct scsi_address * ap,int level)2753 scsa2usb_scsi_reset(struct scsi_address *ap, int level)
2754 {
2755 scsa2usb_state_t *scsa2usbp = (scsa2usb_state_t *)ADDR2SCSA2USB(ap);
2756
2757 USB_DPRINTF_L4(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
2758 "scsa2usb_scsi_reset: ap = 0x%p, level = %d", (void *)ap, level);
2759
2760 /* flush waitQ */
2761 scsa2usb_flush_waitQ(scsa2usbp, ap->a_lun, CMD_RESET);
2762
2763 return (1);
2764 }
2765
2766
2767 /*
2768 * scsa2usb_scsi_getcap:
2769 * Get SCSI capabilities.
2770 */
2771 /* ARGSUSED */
2772 static int
scsa2usb_scsi_getcap(struct scsi_address * ap,char * cap,int whom)2773 scsa2usb_scsi_getcap(struct scsi_address *ap, char *cap, int whom)
2774 {
2775 int rval = -1;
2776 uint_t cidx;
2777 size_t dev_bsize_cap;
2778 scsa2usb_state_t *scsa2usbp = (scsa2usb_state_t *)ADDR2SCSA2USB(ap);
2779 ASSERT(scsa2usbp);
2780
2781 if (cap == NULL) {
2782 USB_DPRINTF_L2(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
2783 "scsa2usb_scsi_getcap: invalid arg, "
2784 "cap = 0x%p whom = %d", (void *)cap, whom);
2785
2786 return (rval);
2787 }
2788
2789 USB_DPRINTF_L4(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
2790 "scsa2usb_scsi_getcap: cap = %s", cap);
2791
2792 mutex_enter(&scsa2usbp->scsa2usb_mutex);
2793
2794 /* if device is disconnected (ie. pipes closed), fail immediately */
2795 if (!(SCSA2USB_DEVICE_ACCESS_OK(scsa2usbp))) {
2796
2797 mutex_exit(&scsa2usbp->scsa2usb_mutex);
2798
2799 return (rval);
2800 }
2801
2802 cidx = scsi_hba_lookup_capstr(cap);
2803 switch (cidx) {
2804 case SCSI_CAP_GEOMETRY:
2805 /* Just check and fail immediately if zero, rarely happens */
2806 if (scsa2usbp->scsa2usb_secsz[ap->a_lun] == 0) {
2807 USB_DPRINTF_L2(DPRINT_MASK_SCSA,
2808 scsa2usbp->scsa2usb_log_handle,
2809 "scsa2usb_scsi_getcap failed:"
2810 "scsa2usbp->scsa2usb_secsz[ap->a_lun] == 0");
2811 mutex_exit(&scsa2usbp->scsa2usb_mutex);
2812
2813 return (rval);
2814 }
2815
2816 dev_bsize_cap = scsa2usbp->scsa2usb_totalsec[ap->a_lun];
2817
2818 if (scsa2usbp->scsa2usb_secsz[ap->a_lun] > DEV_BSIZE) {
2819 dev_bsize_cap *=
2820 scsa2usbp->scsa2usb_secsz[ap->a_lun] / DEV_BSIZE;
2821 } else if (scsa2usbp->scsa2usb_secsz[ap->a_lun] <
2822 DEV_BSIZE) {
2823 dev_bsize_cap /=
2824 DEV_BSIZE / scsa2usbp->scsa2usb_secsz[ap->a_lun];
2825 }
2826
2827 if (dev_bsize_cap < 65536 * 2 * 18) { /* < ~1GB */
2828 /* unlabeled floppy, 18k per cylinder */
2829 rval = ((2 << 16) | 18);
2830 } else if (dev_bsize_cap < 65536 * 64 * 32) { /* < 64GB */
2831 /* 1024k per cylinder */
2832 rval = ((64 << 16) | 32);
2833 } else if (dev_bsize_cap < 65536 * 255 * 63) { /* < ~500GB */
2834 /* ~8m per cylinder */
2835 rval = ((255 << 16) | 63);
2836 } else { /* .. 8TB */
2837 /* 64m per cylinder */
2838 rval = ((512 << 16) | 256);
2839 }
2840 break;
2841
2842 case SCSI_CAP_DMA_MAX:
2843 rval = scsa2usbp->scsa2usb_max_bulk_xfer_size;
2844 break;
2845 case SCSI_CAP_SCSI_VERSION:
2846 rval = SCSI_VERSION_2;
2847 break;
2848 case SCSI_CAP_INTERCONNECT_TYPE:
2849 rval = INTERCONNECT_USB;
2850 break;
2851 case SCSI_CAP_ARQ:
2852 /* FALLTHRU */
2853 case SCSI_CAP_UNTAGGED_QING:
2854 rval = 1;
2855 break;
2856 default:
2857 USB_DPRINTF_L2(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
2858 "scsa2usb_scsi_getcap: unsupported cap = %s", cap);
2859 break;
2860 }
2861
2862 USB_DPRINTF_L4(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
2863 "scsa2usb_scsi_getcap: cap = %s, returned = %d", cap, rval);
2864
2865 mutex_exit(&scsa2usbp->scsa2usb_mutex);
2866
2867 return (rval);
2868 }
2869
2870
2871 /*
2872 * scsa2usb_scsi_setcap:
2873 * Set SCSI capabilities.
2874 */
2875 /* ARGSUSED */
2876 static int
scsa2usb_scsi_setcap(struct scsi_address * ap,char * cap,int value,int whom)2877 scsa2usb_scsi_setcap(struct scsi_address *ap, char *cap, int value, int whom)
2878 {
2879 int rval = -1; /* default is cap undefined */
2880 uint_t cidx;
2881 scsa2usb_state_t *scsa2usbp = (scsa2usb_state_t *)ADDR2SCSA2USB(ap);
2882 ASSERT(scsa2usbp);
2883
2884 if (cap == NULL || whom == 0) {
2885 USB_DPRINTF_L2(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
2886 "scsa2usb_scsi_setcap: invalid arg");
2887
2888 return (rval);
2889 }
2890
2891 mutex_enter(&scsa2usbp->scsa2usb_mutex);
2892 /* if device is disconnected (ie. pipes closed), fail immediately */
2893 if (!(SCSA2USB_DEVICE_ACCESS_OK(scsa2usbp))) {
2894 mutex_exit(&scsa2usbp->scsa2usb_mutex);
2895
2896 return (rval);
2897 }
2898
2899 cidx = scsi_hba_lookup_capstr(cap);
2900 USB_DPRINTF_L2(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
2901 "scsa2usb_scsi_setcap: ap = 0x%p value = 0x%x whom = 0x%x "
2902 "cidx = 0x%x", (void *)ap, value, whom, cidx);
2903
2904 switch (cidx) {
2905 case SCSI_CAP_SECTOR_SIZE:
2906 if (value) {
2907 scsa2usbp->scsa2usb_secsz[ap->a_lun] = value;
2908 }
2909 break;
2910 case SCSI_CAP_TOTAL_SECTORS:
2911 if (value) {
2912 scsa2usbp->scsa2usb_totalsec[ap->a_lun] = value;
2913 }
2914 break;
2915 case SCSI_CAP_ARQ:
2916 rval = 1;
2917 break;
2918 case SCSI_CAP_DMA_MAX:
2919 case SCSI_CAP_SCSI_VERSION:
2920 case SCSI_CAP_INTERCONNECT_TYPE:
2921 case SCSI_CAP_UNTAGGED_QING:
2922 /* supported but not settable */
2923 rval = 0;
2924 break;
2925 default:
2926 USB_DPRINTF_L2(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
2927 "scsa2usb_scsi_setcap: unsupported cap = %s", cap);
2928 break;
2929 }
2930
2931 mutex_exit(&scsa2usbp->scsa2usb_mutex);
2932
2933 return (rval);
2934 }
2935
2936
2937 /*
2938 * scsa2usb - cmd and transport stuff
2939 */
2940 /*
2941 * scsa2usb_prepare_pkt:
2942 * initialize some fields of the pkt and cmd
2943 * (the pkt may have been resubmitted/retried)
2944 */
2945 static void
scsa2usb_prepare_pkt(scsa2usb_state_t * scsa2usbp,struct scsi_pkt * pkt)2946 scsa2usb_prepare_pkt(scsa2usb_state_t *scsa2usbp, struct scsi_pkt *pkt)
2947 {
2948 scsa2usb_cmd_t *cmd = PKT2CMD(pkt);
2949
2950 USB_DPRINTF_L3(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
2951 "scsa2usb_prepare_pkt: pkt=0x%p cdb: 0x%x (%s)",
2952 (void *)pkt, pkt->pkt_cdbp[0],
2953 scsi_cname(pkt->pkt_cdbp[0], scsa2usb_cmds));
2954
2955 pkt->pkt_reason = CMD_CMPLT; /* Set reason to pkt_complete */
2956 pkt->pkt_state = 0; /* Reset next three fields */
2957 pkt->pkt_statistics = 0;
2958 pkt->pkt_resid = 0;
2959 bzero(pkt->pkt_scbp, cmd->cmd_scblen); /* Set status to good */
2960
2961 if (cmd) {
2962 cmd->cmd_timeout = pkt->pkt_time;
2963 cmd->cmd_xfercount = 0; /* Reset the fields */
2964 cmd->cmd_total_xfercount = 0;
2965 cmd->cmd_lba = 0;
2966 cmd->cmd_done = 0;
2967 cmd->cmd_dir = 0;
2968 cmd->cmd_offset = 0;
2969 cmd->cmd_actual_len = cmd->cmd_cdblen;
2970 }
2971 }
2972
2973
2974 /*
2975 * scsa2usb_force_invalid_request
2976 */
2977 static void
scsa2usb_force_invalid_request(scsa2usb_state_t * scsa2usbp,scsa2usb_cmd_t * cmd)2978 scsa2usb_force_invalid_request(scsa2usb_state_t *scsa2usbp,
2979 scsa2usb_cmd_t *cmd)
2980 {
2981 struct scsi_arq_status *arqp;
2982
2983 USB_DPRINTF_L3(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
2984 "scsa2usb_force_invalid_request: pkt = 0x%p", (void *)cmd->cmd_pkt);
2985
2986 if (cmd->cmd_scblen >= sizeof (struct scsi_arq_status)) {
2987 arqp = (struct scsi_arq_status *)cmd->cmd_pkt->pkt_scbp;
2988 bzero(arqp, cmd->cmd_scblen);
2989
2990 arqp->sts_status.sts_chk = 1;
2991 arqp->sts_rqpkt_reason = CMD_CMPLT;
2992 arqp->sts_rqpkt_state = STATE_XFERRED_DATA |
2993 STATE_GOT_BUS | STATE_GOT_STATUS;
2994 arqp->sts_sensedata.es_valid = 1;
2995 arqp->sts_sensedata.es_class = 7;
2996 arqp->sts_sensedata.es_key = KEY_ILLEGAL_REQUEST;
2997
2998 cmd->cmd_pkt->pkt_state = STATE_ARQ_DONE |
2999 STATE_GOT_BUS | STATE_GOT_BUS | STATE_GOT_BUS |
3000 STATE_GOT_STATUS;
3001 #ifdef DEBUG
3002 {
3003 uchar_t *p = (uchar_t *)(&arqp->sts_sensedata);
3004 USB_DPRINTF_L2(DPRINT_MASK_SCSA,
3005 scsa2usbp->scsa2usb_log_handle,
3006 "cdb: %x rqsense: "
3007 "%x %x %x %x %x %x %x %x %x %x "
3008 "%x %x %x %x %x %x %x %x %x %x",
3009 cmd->cmd_pkt->pkt_cdbp[0],
3010 p[0], p[1], p[2], p[3], p[4],
3011 p[5], p[6], p[7], p[8], p[9],
3012 p[10], p[11], p[12], p[13], p[14],
3013 p[15], p[16], p[17], p[18], p[19]);
3014 }
3015 #endif
3016
3017 }
3018 }
3019
3020
3021 /*
3022 * scsa2usb_cmd_transport:
3023 */
3024 static int
scsa2usb_cmd_transport(scsa2usb_state_t * scsa2usbp,scsa2usb_cmd_t * cmd)3025 scsa2usb_cmd_transport(scsa2usb_state_t *scsa2usbp, scsa2usb_cmd_t *cmd)
3026 {
3027 int rval, transport;
3028 struct scsi_pkt *pkt;
3029
3030 USB_DPRINTF_L3(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
3031 "scsa2usb_cmd_transport: pkt: 0x%p, cur_pkt = 0x%p",
3032 (void *)cmd->cmd_pkt, (void *)scsa2usbp->scsa2usb_cur_pkt);
3033
3034 ASSERT(mutex_owned(&scsa2usbp->scsa2usb_mutex));
3035 ASSERT(scsa2usbp->scsa2usb_cur_pkt == NULL);
3036
3037 pkt = scsa2usbp->scsa2usb_cur_pkt = cmd->cmd_pkt;
3038
3039 /* check black-listed attrs first */
3040 if (SCSA2USB_IS_BULK_ONLY(scsa2usbp)) {
3041 transport = scsa2usb_check_bulkonly_blacklist_attrs(scsa2usbp,
3042 cmd, pkt->pkt_cdbp[0]);
3043 } else if (SCSA2USB_IS_CB(scsa2usbp) || SCSA2USB_IS_CBI(scsa2usbp)) {
3044 transport = scsa2usb_check_ufi_blacklist_attrs(scsa2usbp,
3045 pkt->pkt_cdbp[0], cmd);
3046 }
3047
3048 /* just accept the command or return error */
3049 if (transport == SCSA2USB_JUST_ACCEPT) {
3050 SCSA2USB_SET_PKT_DO_COMP_STATE(scsa2usbp);
3051
3052 return (TRAN_ACCEPT);
3053 } else if (transport == SCSA2USB_REJECT) {
3054 return (TRAN_FATAL_ERROR);
3055 }
3056
3057 /* check command set next */
3058 if (SCSA2USB_IS_SCSI_CMDSET(scsa2usbp) ||
3059 SCSA2USB_IS_ATAPI_CMDSET(scsa2usbp)) {
3060 transport =
3061 scsa2usb_handle_scsi_cmd_sub_class(scsa2usbp, cmd, pkt);
3062 } else if (SCSA2USB_IS_UFI_CMDSET(scsa2usbp)) {
3063 transport =
3064 scsa2usb_handle_ufi_subclass_cmd(scsa2usbp, cmd, pkt);
3065 } else {
3066 transport = SCSA2USB_REJECT;
3067 }
3068
3069 switch (transport) {
3070 case SCSA2USB_TRANSPORT:
3071 if (SCSA2USB_IS_BULK_ONLY(scsa2usbp)) {
3072 rval = scsa2usb_bulk_only_transport(scsa2usbp, cmd);
3073 } else if (SCSA2USB_IS_CB(scsa2usbp) ||
3074 SCSA2USB_IS_CBI(scsa2usbp)) {
3075 rval = scsa2usb_cbi_transport(scsa2usbp, cmd);
3076 } else {
3077 rval = TRAN_FATAL_ERROR;
3078 }
3079 break;
3080 case SCSA2USB_JUST_ACCEPT:
3081 SCSA2USB_SET_PKT_DO_COMP_STATE(scsa2usbp);
3082 rval = TRAN_ACCEPT;
3083 break;
3084 default:
3085 rval = TRAN_FATAL_ERROR;
3086 }
3087
3088 return (rval);
3089 }
3090
3091
3092 /*
3093 * scsa2usb_check_bulkonly_blacklist_attrs:
3094 * validate "scsa2usb_blacklist_attrs" (see scsa2usb.h)
3095 * if blacklisted attrs match accept the request
3096 * attributes checked are:-
3097 * SCSA2USB_ATTRS_START_STOP
3098 */
3099 int
scsa2usb_check_bulkonly_blacklist_attrs(scsa2usb_state_t * scsa2usbp,scsa2usb_cmd_t * cmd,uchar_t opcode)3100 scsa2usb_check_bulkonly_blacklist_attrs(scsa2usb_state_t *scsa2usbp,
3101 scsa2usb_cmd_t *cmd, uchar_t opcode)
3102 {
3103 struct scsi_inquiry *inq =
3104 &scsa2usbp->scsa2usb_lun_inquiry[cmd->cmd_pkt->pkt_address.a_lun];
3105
3106 USB_DPRINTF_L4(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
3107 "scsa2usb_check_bulkonly_blacklist_attrs: opcode = %s",
3108 scsi_cname(opcode, scsa2usb_cmds));
3109
3110 ASSERT(mutex_owned(&scsa2usbp->scsa2usb_mutex));
3111
3112 /*
3113 * decode and convert the packet
3114 * for most cmds, we can bcopy the cdb
3115 */
3116 switch (opcode) {
3117 case SCMD_DOORLOCK:
3118 if (!(scsa2usbp->scsa2usb_attrs & SCSA2USB_ATTRS_DOORLOCK)) {
3119
3120 return (SCSA2USB_JUST_ACCEPT);
3121
3122 /*
3123 * only lock the door for CD and DVD drives
3124 */
3125 } else if ((inq->inq_dtype == DTYPE_RODIRECT) ||
3126 (inq->inq_dtype == DTYPE_OPTICAL)) {
3127
3128 if (inq->inq_rmb) {
3129
3130 break;
3131 }
3132 }
3133
3134 return (SCSA2USB_JUST_ACCEPT);
3135
3136 case SCMD_START_STOP: /* SCMD_LOAD for sequential devices */
3137 /*
3138 * these devices don't have mechanics that spin the
3139 * media up and down. So, it doesn't make much sense
3140 * to issue this cmd.
3141 *
3142 * Furthermore, Hagiwara devices do not handle these
3143 * cmds well. just accept this command as success.
3144 */
3145 if (!(scsa2usbp->scsa2usb_attrs & SCSA2USB_ATTRS_START_STOP)) {
3146
3147 return (SCSA2USB_JUST_ACCEPT);
3148
3149 } else if (inq->inq_dtype == DTYPE_SEQUENTIAL) {
3150 /*
3151 * In case of USB tape device, we need to send the
3152 * command to the device to unload the media.
3153 */
3154 break;
3155
3156 } else if (cmd->cmd_pkt->pkt_cdbp[4] & LOEJECT) {
3157 /*
3158 * if the device is really a removable then
3159 * pass it on to the device, else just accept
3160 */
3161 if (inq->inq_rmb) {
3162
3163 break;
3164 }
3165
3166 return (SCSA2USB_JUST_ACCEPT);
3167
3168 } else if (!scsa2usbp->scsa2usb_rcvd_not_ready) {
3169 /*
3170 * if we have not received a NOT READY condition,
3171 * just accept since some device choke on this too.
3172 * we do have to let EJECT get through though
3173 */
3174 return (SCSA2USB_JUST_ACCEPT);
3175 }
3176
3177 break;
3178 case SCMD_INQUIRY:
3179 /*
3180 * Some devices do not handle the inquiry cmd well
3181 * so build an inquiry and accept this command as
3182 * success.
3183 */
3184 if (!(scsa2usbp->scsa2usb_attrs & SCSA2USB_ATTRS_INQUIRY)) {
3185 uchar_t evpd = 0x01;
3186 unsigned int bufsize;
3187 int count;
3188
3189 if (cmd->cmd_pkt->pkt_cdbp[1] & evpd)
3190 return (SCSA2USB_REJECT);
3191
3192 scsa2usb_fake_inquiry(scsa2usbp, inq);
3193
3194 /* Copy no more than requested */
3195 count = MIN(cmd->cmd_bp->b_bcount,
3196 sizeof (struct scsi_inquiry));
3197 bufsize = cmd->cmd_pkt->pkt_cdbp[4];
3198 count = MIN(count, bufsize);
3199 bcopy(inq, cmd->cmd_bp->b_un.b_addr, count);
3200
3201 cmd->cmd_pkt->pkt_resid = bufsize - count;
3202 cmd->cmd_pkt->pkt_state |= STATE_XFERRED_DATA;
3203
3204 return (SCSA2USB_JUST_ACCEPT);
3205 } else if (!(scsa2usbp->scsa2usb_attrs &
3206 SCSA2USB_ATTRS_INQUIRY_EVPD)) {
3207 /*
3208 * Some devices do not handle the inquiry cmd with
3209 * evpd bit set well, e.g. some devices return the
3210 * same page 0x83 data which will cause the generated
3211 * devid by sd is not unique, thus return CHECK
3212 * CONDITION directly to sd.
3213 */
3214 uchar_t evpd = 0x01;
3215
3216 if (!(cmd->cmd_pkt->pkt_cdbp[1] & evpd))
3217 break;
3218
3219 if (cmd->cmd_bp) {
3220 cmd->cmd_pkt->pkt_resid = cmd->cmd_bp->
3221 b_bcount;
3222 }
3223 scsa2usb_force_invalid_request(scsa2usbp, cmd);
3224
3225 return (SCSA2USB_JUST_ACCEPT);
3226 }
3227 break;
3228 /*
3229 * Fake accepting the following Opcodes
3230 * (as most drives don't support these)
3231 * These are needed by format command.
3232 */
3233 case SCMD_RESERVE:
3234 case SCMD_RELEASE:
3235 case SCMD_PERSISTENT_RESERVE_IN:
3236 case SCMD_PERSISTENT_RESERVE_OUT:
3237
3238 return (SCSA2USB_JUST_ACCEPT);
3239
3240 case SCMD_MODE_SENSE:
3241 case SCMD_MODE_SELECT:
3242 case SCMD_MODE_SENSE_G1:
3243 case SCMD_MODE_SELECT_G1:
3244 if (!(scsa2usbp->scsa2usb_attrs & SCSA2USB_ATTRS_MODE_SENSE)) {
3245 if (cmd->cmd_bp) {
3246 cmd->cmd_pkt->pkt_resid = cmd->cmd_bp->
3247 b_bcount;
3248 }
3249 scsa2usb_force_invalid_request(scsa2usbp, cmd);
3250
3251 return (SCSA2USB_JUST_ACCEPT);
3252 }
3253
3254 break;
3255 default:
3256
3257 break;
3258 }
3259
3260 return (SCSA2USB_TRANSPORT);
3261 }
3262
3263
3264 /*
3265 * scsa2usb_handle_scsi_cmd_sub_class:
3266 * prepare a scsi cmd
3267 * returns SCSA2USB_TRANSPORT, SCSA2USB_REJECT, SCSA2USB_JUST_ACCEPT
3268 */
3269 int
scsa2usb_handle_scsi_cmd_sub_class(scsa2usb_state_t * scsa2usbp,scsa2usb_cmd_t * cmd,struct scsi_pkt * pkt)3270 scsa2usb_handle_scsi_cmd_sub_class(scsa2usb_state_t *scsa2usbp,
3271 scsa2usb_cmd_t *cmd, struct scsi_pkt *pkt)
3272 {
3273 uchar_t evpd = 0x01;
3274 USB_DPRINTF_L4(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
3275 "scsa2usb_handle_scsi_cmd_sub_class: cmd = 0x%p pkt = 0x%p",
3276 (void *)cmd, (void *)pkt);
3277
3278 ASSERT(mutex_owned(&scsa2usbp->scsa2usb_mutex));
3279
3280 bzero(&cmd->cmd_cdb, SCSI_CDB_SIZE);
3281 cmd->cmd_cdb[SCSA2USB_OPCODE] = pkt->pkt_cdbp[0]; /* Set the opcode */
3282 cmd->cmd_cdb[SCSA2USB_LUN] = pkt->pkt_cdbp[1];
3283
3284 /*
3285 * decode and convert the packet
3286 * for most cmds, we can bcopy the cdb
3287 */
3288 switch (pkt->pkt_cdbp[0]) {
3289 case SCMD_FORMAT:
3290 /*
3291 * SCMD_FORMAT used to limit cmd->cmd_xfercount
3292 * to 4 bytes, but this hangs
3293 * formatting dvd media using cdrecord (that is,
3294 * a SCSI FORMAT UNIT command with a parameter list > 4 bytes)
3295 * (bit 4 in cdb1 is the Fmtdata bit)
3296 */
3297 if ((pkt->pkt_cdbp[1] & 0x10) && cmd->cmd_bp) {
3298 cmd->cmd_xfercount = cmd->cmd_bp->b_bcount;
3299 } else {
3300 cmd->cmd_xfercount = 4;
3301 }
3302 cmd->cmd_dir = CBW_DIR_OUT;
3303 cmd->cmd_actual_len = CDB_GROUP0;
3304 bcopy(pkt->pkt_cdbp, &cmd->cmd_cdb, cmd->cmd_cdblen);
3305 break;
3306
3307 case SCMD_INQUIRY:
3308 cmd->cmd_dir = CBW_DIR_IN;
3309 cmd->cmd_actual_len = CDB_GROUP0;
3310 cmd->cmd_cdb[SCSA2USB_LBA_0] = pkt->pkt_cdbp[2];
3311
3312 /*
3313 * If vpd pages data is limited to maximum SCSA2USB_MAX_INQ_LEN,
3314 * the page data may be truncated, which may cause some issues
3315 * such as making the unique page 0x83 or 0x80 data from
3316 * different devices become the same. So don't limit return
3317 * length for vpd page inquiry cmd.
3318 * Another, in order to maintain compatibility, the original
3319 * length limitation for standard inquiry retains here. It
3320 * can be removed in future if it is verified that enough
3321 * devices can work well.
3322 */
3323 if (pkt->pkt_cdbp[1] & evpd) {
3324 cmd->cmd_cdb[SCSA2USB_LBA_2] = cmd->cmd_xfercount =
3325 (cmd->cmd_bp ? cmd->cmd_bp->b_bcount : 0);
3326 } else {
3327 cmd->cmd_cdb[SCSA2USB_LBA_2] = cmd->cmd_xfercount =
3328 min(SCSA2USB_MAX_INQ_LEN,
3329 cmd->cmd_bp ? cmd->cmd_bp->b_bcount : 0);
3330 }
3331 break;
3332
3333 case SCMD_READ_CAPACITY:
3334 cmd->cmd_dir = CBW_DIR_IN;
3335 bcopy(pkt->pkt_cdbp, &cmd->cmd_cdb, cmd->cmd_cdblen);
3336 cmd->cmd_xfercount = sizeof (scsa2usb_read_cap_t);
3337 break;
3338
3339 /*
3340 * SCMD_READ/SCMD_WRITE are converted to G1 cmds
3341 * (as ATAPI devices don't recognize G0 commands)
3342 *
3343 * SCMD_READ_LONG/SCMD_WRITE_LONG are handled in
3344 * scsa2usb_rw_transport() along with other commands.
3345 *
3346 * USB Host Controllers cannot handle large (read/write)
3347 * xfers. We split the large request to chunks of
3348 * smaller ones to meet the HCD limitations.
3349 */
3350 case SCMD_READ:
3351 case SCMD_WRITE:
3352 case SCMD_READ_G1:
3353 case SCMD_WRITE_G1:
3354 case SCMD_READ_G5:
3355 case SCMD_WRITE_G5:
3356 case SCMD_READ_LONG:
3357 case SCMD_WRITE_LONG:
3358 case SCMD_READ_CD:
3359 switch (scsa2usbp->
3360 scsa2usb_lun_inquiry[pkt->pkt_address.a_lun].
3361 inq_dtype & DTYPE_MASK) {
3362 case DTYPE_DIRECT:
3363 case DTYPE_RODIRECT:
3364 case DTYPE_OPTICAL:
3365 return (scsa2usb_rw_transport(
3366 scsa2usbp, pkt));
3367 default:
3368 bcopy(pkt->pkt_cdbp, &cmd->cmd_cdb, cmd->cmd_cdblen);
3369 if (cmd->cmd_bp) {
3370 cmd->cmd_dir =
3371 (cmd->cmd_bp->b_flags & B_READ) ?
3372 CBW_DIR_IN : CBW_DIR_OUT;
3373 cmd->cmd_xfercount =
3374 cmd->cmd_bp->b_bcount;
3375 }
3376 break;
3377 }
3378 break;
3379
3380 case SCMD_REQUEST_SENSE:
3381 cmd->cmd_dir = CBW_DIR_IN;
3382 cmd->cmd_xfercount = pkt->pkt_cdbp[4];
3383 cmd->cmd_cdb[SCSA2USB_LBA_2] = pkt->pkt_cdbp[4];
3384 cmd->cmd_actual_len = CDB_GROUP0;
3385 break;
3386
3387 case SCMD_DOORLOCK:
3388 case SCMD_START_STOP:
3389 case SCMD_TEST_UNIT_READY:
3390 bcopy(pkt->pkt_cdbp, &cmd->cmd_cdb, cmd->cmd_cdblen);
3391 break;
3392
3393 /*
3394 * Needed by zip protocol to reset the device
3395 */
3396 case SCMD_SDIAG:
3397 case SCMD_REZERO_UNIT:
3398 bcopy(pkt->pkt_cdbp, &cmd->cmd_cdb, cmd->cmd_cdblen);
3399 cmd->cmd_actual_len = CDB_GROUP1;
3400 break;
3401
3402 case SCMD_WRITE_VERIFY:
3403 bcopy(pkt->pkt_cdbp, &cmd->cmd_cdb, cmd->cmd_cdblen);
3404 cmd->cmd_dir = CBW_DIR_OUT;
3405 cmd->cmd_xfercount = (pkt->pkt_cdbp[7] << 8) | pkt->pkt_cdbp[8];
3406 cmd->cmd_actual_len = CDB_GROUP1;
3407 break;
3408
3409 /*
3410 * Next command does not have a SCSI equivalent as
3411 * it is vendor specific.
3412 * It was listed in the vendor's ATAPI Zip specs.
3413 */
3414 case SCMD_READ_FORMAT_CAP:
3415 bcopy(pkt->pkt_cdbp, &cmd->cmd_cdb, cmd->cmd_cdblen);
3416 cmd->cmd_dir = CBW_DIR_IN;
3417 cmd->cmd_xfercount = (pkt->pkt_cdbp[7] << 8) | pkt->pkt_cdbp[8];
3418 cmd->cmd_actual_len = CDB_GROUP1;
3419 break;
3420 case IOMEGA_CMD_CARTRIDGE_PROTECT:
3421 cmd->cmd_dir = CBW_DIR_OUT;
3422 cmd->cmd_cdb[SCSA2USB_LBA_2] = pkt->pkt_cdbp[4];
3423 cmd->cmd_cdb[SCSA2USB_LBA_2] &= ~1; /* Make it even */
3424 cmd->cmd_cdb[SCSA2USB_LUN] = pkt->pkt_cdbp[1];
3425 cmd->cmd_actual_len = CDB_GROUP0;
3426 cmd->cmd_xfercount = pkt->pkt_cdbp[4]; /* Length of password */
3427 break;
3428
3429 /*
3430 * Do not convert SCMD_MODE_SENSE/SELECT to G1 cmds because
3431 * the mode header is different as well. USB devices don't
3432 * support 0x03 & 0x04 mode pages, which are already obsoleted
3433 * by SPC-2 specification.
3434 */
3435 case SCMD_MODE_SENSE:
3436 case SCMD_MODE_SELECT:
3437 if (((pkt->pkt_cdbp[2] & SD_MODE_SENSE_PAGE_MASK)
3438 == SD_MODE_SENSE_PAGE3_CODE) ||
3439 ((pkt->pkt_cdbp[2] & SD_MODE_SENSE_PAGE_MASK)
3440 == SD_MODE_SENSE_PAGE4_CODE)) {
3441 if (cmd->cmd_bp) {
3442 cmd->cmd_pkt->pkt_resid = cmd->cmd_bp->b_bcount;
3443 }
3444 scsa2usb_force_invalid_request(scsa2usbp, cmd);
3445 return (SCSA2USB_JUST_ACCEPT);
3446 }
3447 /* FALLTHROUGH */
3448
3449 default:
3450 /*
3451 * an unknown command may be a uscsi cmd which we
3452 * should let go thru without mapping
3453 */
3454 bcopy(pkt->pkt_cdbp, &cmd->cmd_cdb, cmd->cmd_cdblen);
3455 if (cmd->cmd_bp) {
3456 cmd->cmd_dir = (cmd->cmd_bp->b_flags & B_READ) ?
3457 CBW_DIR_IN : CBW_DIR_OUT;
3458 cmd->cmd_xfercount = cmd->cmd_bp->b_bcount;
3459 }
3460
3461 break;
3462 } /* end of switch */
3463
3464 USB_DPRINTF_L2(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
3465 "scsa2usb_handle_scsi_cmd_sub_class: opcode = 0x%x count = 0x%lx",
3466 pkt->pkt_cdbp[SCSA2USB_OPCODE], cmd->cmd_xfercount);
3467
3468 cmd->cmd_total_xfercount = cmd->cmd_xfercount;
3469
3470 return (SCSA2USB_TRANSPORT);
3471 }
3472
3473
3474 /*
3475 * scsa2usb_do_tur is performed before READ CAPACITY command is issued.
3476 * It returns media status, 0 for media ready, -1 for media not ready
3477 * or other errors.
3478 */
3479 static int
scsa2usb_do_tur(scsa2usb_state_t * scsa2usbp,struct scsi_address * ap)3480 scsa2usb_do_tur(scsa2usb_state_t *scsa2usbp, struct scsi_address *ap)
3481 {
3482 struct scsi_pkt *pkt;
3483 scsa2usb_cmd_t *turcmd;
3484 int rval = -1;
3485
3486 USB_DPRINTF_L4(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
3487 "scsa2usb_do_tur:");
3488
3489 ASSERT(mutex_owned(&scsa2usbp->scsa2usb_mutex));
3490
3491 mutex_exit(&scsa2usbp->scsa2usb_mutex);
3492 if ((pkt = scsi_init_pkt(ap, NULL, NULL, CDB_GROUP0, 1,
3493 PKT_PRIV_LEN, PKT_CONSISTENT, SLEEP_FUNC, NULL)) == NULL) {
3494 mutex_enter(&scsa2usbp->scsa2usb_mutex);
3495 USB_DPRINTF_L2(DPRINT_MASK_SCSA,
3496 scsa2usbp->scsa2usb_log_handle,
3497 "scsa2usb_do_tur: init pkt failed");
3498
3499 return (rval);
3500 }
3501
3502 RQ_MAKECOM_G0(pkt, FLAG_HEAD | FLAG_NODISCON,
3503 (char)SCMD_TEST_UNIT_READY, 0, 0);
3504
3505 pkt->pkt_comp = NULL;
3506 pkt->pkt_time = PKT_DEFAULT_TIMEOUT;
3507 turcmd = PKT2CMD(pkt);
3508
3509 mutex_enter(&scsa2usbp->scsa2usb_mutex);
3510 scsa2usb_prepare_pkt(scsa2usbp, turcmd->cmd_pkt);
3511
3512 if (scsa2usb_cmd_transport(scsa2usbp, turcmd) != TRAN_ACCEPT) {
3513 USB_DPRINTF_L2(DPRINT_MASK_SCSA,
3514 scsa2usbp->scsa2usb_log_handle,
3515 "scsa2usb_do_tur: cmd transport failed, "
3516 "pkt_reason=0x%x", turcmd->cmd_pkt->pkt_reason);
3517 } else if (*(turcmd->cmd_pkt->pkt_scbp) != STATUS_GOOD) {
3518 /*
3519 * Theoretically, the sense data should be retrieved and
3520 * sense key be checked when check condition happens. If
3521 * the sense key is UNIT ATTENTION, TEST UNIT READY cmd
3522 * needs to be sent again to clear the UNIT ATTENTION and
3523 * another TUR to be sent to get the real media status.
3524 * But the AMI virtual floppy device simply cannot recover
3525 * from UNIT ATTENTION by re-sending a TUR cmd, so it
3526 * doesn't make any difference whether to check sense key
3527 * or not. Just ignore sense key checking here and assume
3528 * the device is NOT READY.
3529 */
3530 USB_DPRINTF_L2(DPRINT_MASK_SCSA,
3531 scsa2usbp->scsa2usb_log_handle,
3532 "scsa2usb_do_tur: media not ready");
3533 } else {
3534 rval = 0;
3535 }
3536
3537 mutex_exit(&scsa2usbp->scsa2usb_mutex);
3538 scsi_destroy_pkt(pkt);
3539 mutex_enter(&scsa2usbp->scsa2usb_mutex);
3540
3541 return (rval);
3542 }
3543
3544
3545 /*
3546 * scsa2usb_check_ufi_blacklist_attrs:
3547 * validate "scsa2usb_blacklist_attrs" (see scsa2usb.h)
3548 * if blacklisted attrs match accept the request
3549 * attributes checked are:-
3550 * SCSA2USB_ATTRS_GET_CONF
3551 * SCSA2USB_ATTRS_GET_PERF
3552 * SCSA2USB_ATTRS_GET_START_STOP
3553 */
3554 static int
scsa2usb_check_ufi_blacklist_attrs(scsa2usb_state_t * scsa2usbp,uchar_t opcode,scsa2usb_cmd_t * cmd)3555 scsa2usb_check_ufi_blacklist_attrs(scsa2usb_state_t *scsa2usbp, uchar_t opcode,
3556 scsa2usb_cmd_t *cmd)
3557 {
3558 int rval = SCSA2USB_TRANSPORT;
3559
3560 ASSERT(mutex_owned(&scsa2usbp->scsa2usb_mutex));
3561
3562 switch (opcode) {
3563 case SCMD_PRIN:
3564 case SCMD_PROUT:
3565 rval = SCSA2USB_JUST_ACCEPT;
3566 break;
3567 case SCMD_MODE_SENSE:
3568 case SCMD_MODE_SELECT:
3569 if (cmd->cmd_bp) {
3570 cmd->cmd_pkt->pkt_resid = cmd->cmd_bp->b_bcount;
3571 }
3572 scsa2usb_force_invalid_request(scsa2usbp, cmd);
3573 rval = SCSA2USB_JUST_ACCEPT;
3574 break;
3575 case SCMD_GET_CONFIGURATION:
3576 if (!(scsa2usbp->scsa2usb_attrs & SCSA2USB_ATTRS_GET_CONF)) {
3577 rval = SCSA2USB_JUST_ACCEPT;
3578 }
3579 break;
3580 case SCMD_GET_PERFORMANCE:
3581 if (!(scsa2usbp->scsa2usb_attrs & SCSA2USB_ATTRS_GET_PERF)) {
3582 rval = SCSA2USB_JUST_ACCEPT;
3583 }
3584 break;
3585 case SCMD_START_STOP:
3586 /*
3587 * some CB/CBI devices don't have mechanics that spin the
3588 * media up and down. So, it doesn't make much sense
3589 * to issue this cmd to those devices.
3590 */
3591 if (!(scsa2usbp->scsa2usb_attrs & SCSA2USB_ATTRS_START_STOP)) {
3592 rval = SCSA2USB_JUST_ACCEPT;
3593 }
3594 break;
3595 case SCMD_READ_CAPACITY:
3596 /*
3597 * Some devices don't support READ CAPACITY command
3598 * when media is not ready. Need to check media status
3599 * before issuing the cmd to such device.
3600 */
3601 if (!(scsa2usbp->scsa2usb_attrs &
3602 SCSA2USB_ATTRS_NO_MEDIA_CHECK)) {
3603 struct scsi_pkt *pkt = cmd->cmd_pkt;
3604
3605 ASSERT(scsa2usbp->scsa2usb_cur_pkt == pkt);
3606 scsa2usbp->scsa2usb_cur_pkt = NULL;
3607
3608 if (scsa2usb_do_tur(scsa2usbp,
3609 &pkt->pkt_address) != 0) {
3610 /* media not ready, force cmd invalid */
3611 if (cmd->cmd_bp) {
3612 cmd->cmd_pkt->pkt_resid =
3613 cmd->cmd_bp->b_bcount;
3614 }
3615 scsa2usb_force_invalid_request(scsa2usbp, cmd);
3616 rval = SCSA2USB_JUST_ACCEPT;
3617 }
3618
3619 scsa2usbp->scsa2usb_cur_pkt = pkt;
3620 }
3621 break;
3622 default:
3623 break;
3624 }
3625
3626 return (rval);
3627 }
3628
3629
3630 /*
3631 * scsa2usb_handle_ufi_subclass_cmd:
3632 * prepare a UFI cmd
3633 * returns SCSA2USB_TRANSPORT, SCSA2USB_REJECT
3634 */
3635 int
scsa2usb_handle_ufi_subclass_cmd(scsa2usb_state_t * scsa2usbp,scsa2usb_cmd_t * cmd,struct scsi_pkt * pkt)3636 scsa2usb_handle_ufi_subclass_cmd(scsa2usb_state_t *scsa2usbp,
3637 scsa2usb_cmd_t *cmd, struct scsi_pkt *pkt)
3638 {
3639 uchar_t opcode = pkt->pkt_cdbp[0];
3640
3641 USB_DPRINTF_L4(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
3642 "scsa2usb_handle_ufi_subclass_cmd: cmd = 0x%p pkt = 0x%p",
3643 (void *)cmd, (void *)pkt);
3644
3645 ASSERT(mutex_owned(&scsa2usbp->scsa2usb_mutex));
3646
3647 bzero(&cmd->cmd_cdb, SCSI_CDB_SIZE);
3648 cmd->cmd_cdb[SCSA2USB_OPCODE] = opcode; /* Set the opcode */
3649 cmd->cmd_cdb[SCSA2USB_LUN] = pkt->pkt_cdbp[1];
3650
3651 /*
3652 * decode and convert the packet if necessary
3653 * for most cmds, we can bcopy the cdb
3654 */
3655 switch (opcode) {
3656 case SCMD_FORMAT:
3657 /* if parameter list is specified */
3658 if (pkt->pkt_cdbp[1] & 0x10) {
3659 cmd->cmd_xfercount =
3660 (pkt->pkt_cdbp[7] << 8) | pkt->pkt_cdbp[8];
3661 cmd->cmd_dir = USB_EP_DIR_OUT;
3662 cmd->cmd_actual_len = CDB_GROUP5;
3663 }
3664 bcopy(pkt->pkt_cdbp, &cmd->cmd_cdb, cmd->cmd_cdblen);
3665 break;
3666 case SCMD_INQUIRY:
3667 cmd->cmd_dir = USB_EP_DIR_IN;
3668 cmd->cmd_actual_len = CDB_GROUP0;
3669 cmd->cmd_cdb[SCSA2USB_LBA_0] = pkt->pkt_cdbp[2];
3670 cmd->cmd_cdb[SCSA2USB_LBA_2] = cmd->cmd_xfercount =
3671 min(SCSA2USB_MAX_INQ_LEN,
3672 cmd->cmd_bp ? cmd->cmd_bp->b_bcount : 0);
3673 break;
3674 case SCMD_READ_CAPACITY:
3675 cmd->cmd_dir = USB_EP_DIR_IN;
3676 bcopy(pkt->pkt_cdbp, &cmd->cmd_cdb, cmd->cmd_cdblen);
3677 cmd->cmd_xfercount = sizeof (scsa2usb_read_cap_t);
3678 break;
3679 case SCMD_REQUEST_SENSE:
3680 cmd->cmd_dir = USB_EP_DIR_IN;
3681 cmd->cmd_xfercount = pkt->pkt_cdbp[4];
3682 cmd->cmd_cdb[SCSA2USB_LBA_2] = pkt->pkt_cdbp[4];
3683 cmd->cmd_actual_len = CDB_GROUP0;
3684 break;
3685
3686 /*
3687 * do not convert SCMD_MODE_SENSE/SELECT because the
3688 * mode header is different as well
3689 */
3690
3691 /*
3692 * see usb_bulkonly.c for comments on the next set of commands
3693 */
3694 case SCMD_READ:
3695 case SCMD_WRITE:
3696 case SCMD_READ_G1:
3697 case SCMD_WRITE_G1:
3698 case SCMD_READ_G5:
3699 case SCMD_WRITE_G5:
3700 case SCMD_READ_LONG:
3701 case SCMD_WRITE_LONG:
3702 case SCMD_READ_CD:
3703
3704 return (scsa2usb_rw_transport(scsa2usbp, pkt));
3705
3706 case SCMD_TEST_UNIT_READY:
3707 /*
3708 * Some CB/CBI devices may not support TUR.
3709 */
3710 bcopy(pkt->pkt_cdbp, &cmd->cmd_cdb, cmd->cmd_cdblen);
3711 break;
3712 case SCMD_READ_FORMAT_CAP:
3713 bcopy(pkt->pkt_cdbp, &cmd->cmd_cdb, cmd->cmd_cdblen);
3714 cmd->cmd_dir = USB_EP_DIR_IN;
3715 cmd->cmd_actual_len = CDB_GROUP1;
3716 cmd->cmd_xfercount = (pkt->pkt_cdbp[7] << 8) | pkt->pkt_cdbp[8];
3717 break;
3718 case SCMD_WRITE_VERIFY:
3719 bcopy(pkt->pkt_cdbp, &cmd->cmd_cdb, cmd->cmd_cdblen);
3720 cmd->cmd_dir = USB_EP_DIR_OUT;
3721 cmd->cmd_actual_len = CDB_GROUP1;
3722 cmd->cmd_xfercount = (pkt->pkt_cdbp[7] << 8) | pkt->pkt_cdbp[8];
3723 break;
3724 case SCMD_START_STOP:
3725 /* A larger timeout is needed for 'flaky' CD-RW devices */
3726 if (!(scsa2usbp->scsa2usb_attrs & SCSA2USB_ATTRS_BIG_TIMEOUT)) {
3727 cmd->cmd_timeout = max(cmd->cmd_timeout,
3728 20 * SCSA2USB_BULK_PIPE_TIMEOUT);
3729 }
3730 /* FALLTHRU */
3731 default:
3732 /*
3733 * all other commands don't need special mapping
3734 */
3735 bcopy(pkt->pkt_cdbp, &cmd->cmd_cdb, cmd->cmd_cdblen);
3736 if (cmd->cmd_bp) {
3737 cmd->cmd_dir = (cmd->cmd_bp->b_flags & B_READ) ?
3738 CBW_DIR_IN : CBW_DIR_OUT;
3739 cmd->cmd_xfercount = cmd->cmd_bp->b_bcount;
3740 }
3741 break;
3742
3743 } /* end of switch */
3744
3745 USB_DPRINTF_L4(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
3746 "scsa2usb_handle_ufi_subclass_cmd: opcode = 0x%x count = 0x%lx",
3747 opcode, cmd->cmd_xfercount);
3748
3749 cmd->cmd_total_xfercount = cmd->cmd_xfercount;
3750
3751 return (SCSA2USB_TRANSPORT);
3752 }
3753
3754
3755 /*
3756 * scsa2usb_rw_transport:
3757 * Handle splitting READ and WRITE requests to the
3758 * device to a size that the host controller allows.
3759 *
3760 * returns TRAN_* values and not USB_SUCCESS/FAILURE
3761 *
3762 * To support CD-R/CD-RW/DVD media, we need to support a
3763 * variety of block sizes for the different types of CD
3764 * data (audio, data, video, CD-XA, yellowbook, redbook etc.)
3765 *
3766 * Some of the block sizes used are:- 512, 1k, 2k, 2056, 2336
3767 * 2340, 2352, 2368, 2448, 2646, 2647 etc.
3768 *
3769 * NOTE: the driver could be entertaining a SCSI CDB that uses
3770 * any of the above listed block sizes at a given time, and a
3771 * totally different block size at any other given time for a
3772 * different CDB.
3773 *
3774 * We need to compute block size every time and figure out
3775 * matching LBA and LEN accordingly.
3776 *
3777 * Also UHCI has a limitation that it can only xfer 32k at a
3778 * given time. So, with "odd" sized blocks and a limitation of
3779 * how much we can xfer per shot, we need to compute xfer_count
3780 * as well each time.
3781 *
3782 * The same computation is also done in the function
3783 * scsa2usb_setup_next_xfer(). To save computing block_size in
3784 * this function, I am saving block_size in "cmd" now.
3785 */
3786 int
scsa2usb_rw_transport(scsa2usb_state_t * scsa2usbp,struct scsi_pkt * pkt)3787 scsa2usb_rw_transport(scsa2usb_state_t *scsa2usbp, struct scsi_pkt *pkt)
3788 {
3789 scsa2usb_cmd_t *cmd = PKT2CMD(pkt);
3790 int lba, dir, opcode;
3791 struct buf *bp = cmd->cmd_bp;
3792 size_t len, xfer_count;
3793 size_t blk_size; /* calculate the block size to be used */
3794 int sz;
3795
3796 USB_DPRINTF_L4(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
3797 "scsa2usb_rw_transport:");
3798
3799 ASSERT(mutex_owned(&scsa2usbp->scsa2usb_mutex));
3800
3801 opcode = pkt->pkt_cdbp[0];
3802 blk_size = scsa2usbp->scsa2usb_lbasize[pkt->pkt_address.a_lun];
3803 /* set to default */
3804
3805 switch (opcode) {
3806 case SCMD_READ:
3807 /*
3808 * Note that READ/WRITE(6) are not supported by the drive.
3809 * convert it into a 10 byte read/write.
3810 */
3811 lba = SCSA2USB_LBA_6BYTE(pkt);
3812 len = SCSA2USB_LEN_6BYTE(pkt);
3813 opcode = SCMD_READ_G1; /* Overwrite it w/ byte 10 cmd val */
3814 dir = USB_EP_DIR_IN;
3815 break;
3816 case SCMD_WRITE:
3817 lba = SCSA2USB_LBA_6BYTE(pkt);
3818 len = SCSA2USB_LEN_6BYTE(pkt);
3819 opcode = SCMD_WRITE_G1; /* Overwrite it w/ byte 10 cmd val */
3820 dir = USB_EP_DIR_OUT;
3821 break;
3822 case SCMD_READ_G1:
3823 case SCMD_READ_LONG:
3824 lba = SCSA2USB_LBA_10BYTE(pkt);
3825 len = SCSA2USB_LEN_10BYTE(pkt);
3826 dir = USB_EP_DIR_IN;
3827 break;
3828 case SCMD_WRITE_G1:
3829 case SCMD_WRITE_LONG:
3830 lba = SCSA2USB_LBA_10BYTE(pkt);
3831 len = SCSA2USB_LEN_10BYTE(pkt);
3832 dir = USB_EP_DIR_OUT;
3833 if (len) {
3834 sz = SCSA2USB_CDRW_BLKSZ(bp ? bp->b_bcount : 0, len);
3835 if (SCSA2USB_VALID_CDRW_BLKSZ(sz)) {
3836 blk_size = sz; /* change it accordingly */
3837 }
3838 }
3839 break;
3840 case SCMD_READ_CD:
3841 lba = SCSA2USB_LBA_10BYTE(pkt);
3842 len = SCSA2USB_LEN_READ_CD(pkt);
3843 dir = USB_EP_DIR_IN;
3844
3845 /* Figure out the block size */
3846 blk_size = scsa2usb_read_cd_blk_size(pkt->pkt_cdbp[1] >> 2);
3847 break;
3848 case SCMD_READ_G5:
3849 lba = SCSA2USB_LBA_12BYTE(pkt);
3850 len = SCSA2USB_LEN_12BYTE(pkt);
3851 dir = USB_EP_DIR_IN;
3852 break;
3853 case SCMD_WRITE_G5:
3854 lba = SCSA2USB_LBA_12BYTE(pkt);
3855 len = SCSA2USB_LEN_12BYTE(pkt);
3856 dir = USB_EP_DIR_OUT;
3857 break;
3858 }
3859
3860 cmd->cmd_total_xfercount = xfer_count = len * blk_size;
3861
3862 /* reduce xfer count if necessary */
3863 if (blk_size &&
3864 (xfer_count > scsa2usbp->scsa2usb_max_bulk_xfer_size)) {
3865 /*
3866 * For CD-RW devices reduce the xfer count based
3867 * on the block size used by these devices. The
3868 * block size could change for READ_CD and WRITE
3869 * opcodes.
3870 *
3871 * Also as UHCI allows a max xfer of 32k at a time;
3872 * compute the xfer_count based on the new block_size.
3873 *
3874 * The len part of the cdb changes as a result of that.
3875 */
3876 if (SCSA2USB_VALID_CDRW_BLKSZ(blk_size)) {
3877 xfer_count = ((scsa2usbp->scsa2usb_max_bulk_xfer_size/
3878 blk_size) * blk_size);
3879 len = xfer_count/blk_size;
3880 xfer_count = blk_size * len;
3881 } else {
3882 xfer_count = scsa2usbp->scsa2usb_max_bulk_xfer_size;
3883 len = xfer_count/blk_size;
3884 }
3885 }
3886
3887 cmd->cmd_xfercount = xfer_count;
3888 cmd->cmd_dir = (uchar_t)dir;
3889 cmd->cmd_blksize = (int)blk_size;
3890
3891 /*
3892 * Having figure out the 'partial' xfer len based on he
3893 * block size; fill it in to the cmd->cmd_cdb
3894 */
3895 cmd->cmd_cdb[SCSA2USB_OPCODE] = (uchar_t)opcode;
3896 switch (opcode) {
3897 case SCMD_READ_CD:
3898 bcopy(pkt->pkt_cdbp, &cmd->cmd_cdb, cmd->cmd_cdblen);
3899 scsa2usb_fill_up_ReadCD_cdb_len(cmd, len, CDB_GROUP5);
3900 break;
3901 case SCMD_WRITE_G5:
3902 case SCMD_READ_G5:
3903 scsa2usb_fill_up_12byte_cdb_len(cmd, len, CDB_GROUP5);
3904 break;
3905 default:
3906 scsa2usb_fill_up_cdb_len(cmd, len);
3907 cmd->cmd_actual_len = CDB_GROUP1;
3908 break;
3909 }
3910
3911 scsa2usb_fill_up_cdb_lba(cmd, lba);
3912
3913 USB_DPRINTF_L3(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
3914 "bcount=0x%lx lba=0x%x len=0x%lx xfercount=0x%lx total=0x%lx",
3915 bp ? bp->b_bcount : 0, lba, len, cmd->cmd_xfercount,
3916 cmd->cmd_total_xfercount);
3917
3918 /* Set the timeout value as per command request */
3919 if ((opcode == SCMD_WRITE_G1) && SCSA2USB_VALID_CDRW_BLKSZ(blk_size)) {
3920 /*
3921 * We increase the time as CD-RW writes have two things
3922 * to do. After writing out the data to the media, a
3923 * TOC needs to be filled up at the beginning of the media
3924 * This is when the write gets "finalized".
3925 * Hence the actual write could take longer than the
3926 * value specified in cmd->cmd_timeout.
3927 */
3928 cmd->cmd_timeout *= 4;
3929
3930 USB_DPRINTF_L4(DPRINT_MASK_SCSA,
3931 scsa2usbp->scsa2usb_log_handle,
3932 "new timeout value = 0x%x", cmd->cmd_timeout);
3933 }
3934
3935 USB_DPRINTF_L4(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
3936 "lba 0x%x len 0x%lx xfercount 0x%lx total 0x%lx",
3937 lba, len, cmd->cmd_xfercount, cmd->cmd_total_xfercount);
3938
3939 return (SCSA2USB_TRANSPORT);
3940 }
3941
3942
3943 /*
3944 * scsa2usb_setup_next_xfer:
3945 * For READs and WRITEs we split up the transfer in terms of
3946 * HCD understood units. This function handles the split transfers.
3947 *
3948 * See comments in the previous function scsa2usb_rw_transport
3949 *
3950 * The lba computation was being done based on scsa2usb_max_bulk_xfer_size
3951 * earlier. With CD-RW devices, the xfer_count and the block_size may
3952 * no longer be a multiple of scsa2usb_max_bulk_xfer_size. So compute
3953 * xfer_count all over again. Adjust lba, based on the previous requests'
3954 * len. Find out the len and add it to cmd->cmd_lba to get the new lba
3955 */
3956 void
scsa2usb_setup_next_xfer(scsa2usb_state_t * scsa2usbp,scsa2usb_cmd_t * cmd)3957 scsa2usb_setup_next_xfer(scsa2usb_state_t *scsa2usbp, scsa2usb_cmd_t *cmd)
3958 {
3959 int xfer_len = min(scsa2usbp->scsa2usb_max_bulk_xfer_size,
3960 cmd->cmd_total_xfercount);
3961 int cdb_len;
3962 size_t blk_size;
3963
3964 ASSERT(mutex_owned(&scsa2usbp->scsa2usb_mutex));
3965
3966 USB_DPRINTF_L4(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
3967 "scsa2usb_setup_next_xfer: opcode = 0x%x lba = 0x%x "
3968 "total count = 0x%lx", cmd->cmd_cdb[SCSA2USB_OPCODE],
3969 cmd->cmd_lba, cmd->cmd_total_xfercount);
3970
3971 ASSERT(cmd->cmd_total_xfercount > 0);
3972 cmd->cmd_xfercount = xfer_len;
3973 blk_size = scsa2usbp->scsa2usb_lbasize[
3974 cmd->cmd_pkt->pkt_address.a_lun];
3975
3976 /*
3977 * For CD-RW devices reduce the xfer count based on the
3978 * block_size used by these devices. See changes below
3979 * where xfer_count is being adjusted.
3980 *
3981 * Also adjust len/lba based on the block_size and xfer_count.
3982 * NOTE: Always calculate lba first, as it based on previous
3983 * commands' values.
3984 */
3985 switch (cmd->cmd_cdb[SCSA2USB_OPCODE]) {
3986 case SCMD_READ_CD:
3987 /* calculate lba = current_lba + len_of_prev_cmd */
3988 cmd->cmd_lba += (cmd->cmd_cdb[6] << 16) +
3989 (cmd->cmd_cdb[7] << 8) + cmd->cmd_cdb[8];
3990 cdb_len = xfer_len/cmd->cmd_blksize;
3991 cmd->cmd_cdb[SCSA2USB_READ_CD_LEN_2] = (uchar_t)cdb_len;
3992 /* re-adjust xfer count */
3993 cmd->cmd_xfercount = cdb_len * cmd->cmd_blksize;
3994 break;
3995 case SCMD_WRITE_G5:
3996 case SCMD_READ_G5:
3997 /* calculate lba = current_lba + len_of_prev_cmd */
3998 cmd->cmd_lba += (cmd->cmd_cdb[6] << 24) +
3999 (cmd->cmd_cdb[7] << 16) + (cmd->cmd_cdb[8] << 8) +
4000 cmd->cmd_cdb[9];
4001 if (blk_size) {
4002 xfer_len /= blk_size;
4003 }
4004 scsa2usb_fill_up_12byte_cdb_len(cmd, xfer_len, CDB_GROUP5);
4005 break;
4006 case SCMD_WRITE_G1:
4007 case SCMD_WRITE_LONG:
4008 /* calculate lba = current_lba + len_of_prev_cmd */
4009 cmd->cmd_lba += (cmd->cmd_cdb[7] << 8) + cmd->cmd_cdb[8];
4010 if (SCSA2USB_VALID_CDRW_BLKSZ(cmd->cmd_blksize)) {
4011 blk_size = cmd->cmd_blksize;
4012 }
4013 cdb_len = xfer_len/blk_size;
4014 scsa2usb_fill_up_cdb_len(cmd, cdb_len);
4015 /* re-adjust xfer count */
4016 cmd->cmd_xfercount = cdb_len * blk_size;
4017 break;
4018 default:
4019 if (blk_size) {
4020 xfer_len /= blk_size;
4021 }
4022 scsa2usb_fill_up_cdb_len(cmd, xfer_len);
4023 cmd->cmd_lba += scsa2usbp->scsa2usb_max_bulk_xfer_size/blk_size;
4024 }
4025
4026 /* fill in the lba */
4027 scsa2usb_fill_up_cdb_lba(cmd, cmd->cmd_lba);
4028
4029 USB_DPRINTF_L4(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
4030 "scsa2usb_setup_next_xfer:\n\tlba = 0x%x xfer_len = 0x%x "
4031 "xfercount = 0x%lx total = 0x%lx", cmd->cmd_lba, xfer_len,
4032 cmd->cmd_xfercount, cmd->cmd_total_xfercount);
4033 }
4034
4035
4036 /*
4037 * take one request from the lun's waitQ and transport it
4038 */
4039 static void
scsa2usb_transport_request(scsa2usb_state_t * scsa2usbp,uint_t lun)4040 scsa2usb_transport_request(scsa2usb_state_t *scsa2usbp, uint_t lun)
4041 {
4042 int rval;
4043 struct scsi_pkt *pkt;
4044 struct scsa2usb_cmd *cmd, *arqcmd;
4045
4046 if ((cmd = (scsa2usb_cmd_t *)
4047 usba_rm_first_pvt_from_list(
4048 &scsa2usbp->scsa2usb_waitQ[lun])) == NULL) {
4049
4050 return;
4051 }
4052 pkt = cmd->cmd_pkt;
4053
4054 /*
4055 * if device has been disconnected, just complete it
4056 */
4057 if (scsa2usbp->scsa2usb_dev_state == USB_DEV_DISCONNECTED) {
4058 USB_DPRINTF_L2(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
4059 "device not accessible");
4060 pkt->pkt_reason = CMD_DEV_GONE;
4061 SCSA2USB_SET_PKT_DO_COMP_STATE(scsa2usbp);
4062 scsa2usb_pkt_completion(scsa2usbp, pkt);
4063
4064 return;
4065 }
4066
4067 USB_DPRINTF_L4(DPRINT_MASK_SCSA,
4068 scsa2usbp->scsa2usb_log_handle,
4069 "scsa2usb_transport_request: cmd=0x%p bp=0x%p addr=0x%p",
4070 (void *)cmd, (void *)cmd->cmd_bp,
4071 (void *)(cmd->cmd_bp ? cmd->cmd_bp->b_un.b_addr : NULL));
4072
4073 rval = scsa2usb_cmd_transport(scsa2usbp, cmd);
4074
4075 USB_DPRINTF_L3(DPRINT_MASK_SCSA,
4076 scsa2usbp->scsa2usb_log_handle,
4077 "scsa2usb_transport_request: transport rval = %d",
4078 rval);
4079
4080 if (scsa2usbp->scsa2usb_cur_pkt == NULL) {
4081
4082 return;
4083 }
4084
4085 ASSERT(pkt == scsa2usbp->scsa2usb_cur_pkt);
4086
4087 if (ddi_in_panic()) {
4088 pkt->pkt_reason = CMD_CMPLT;
4089 scsa2usb_pkt_completion(scsa2usbp, pkt);
4090
4091 return;
4092 }
4093
4094 /*
4095 * start an auto-request sense iff
4096 * there was a check condition, we have enough
4097 * space in the status block, and we have not
4098 * faked an auto request sense
4099 */
4100 if ((*(pkt->pkt_scbp) == STATUS_CHECK) &&
4101 (cmd->cmd_scblen >= sizeof (struct scsi_arq_status)) &&
4102 ((pkt->pkt_state & STATE_ARQ_DONE) == 0) &&
4103 (scsa2usb_create_arq_pkt(scsa2usbp,
4104 &pkt->pkt_address) == USB_SUCCESS)) {
4105 arqcmd = scsa2usbp->scsa2usb_arq_cmd;
4106
4107 /*
4108 * copy the timeout from the
4109 * original packet
4110 * for lack of a better value
4111 */
4112 arqcmd->cmd_pkt->pkt_time = pkt->pkt_time;
4113 scsa2usb_prepare_pkt(scsa2usbp,
4114 arqcmd->cmd_pkt);
4115
4116 scsa2usbp->scsa2usb_cur_pkt = NULL;
4117 if (scsa2usb_cmd_transport(
4118 scsa2usbp, arqcmd) == TRAN_ACCEPT) {
4119
4120 /* finish w/ this packet */
4121 scsa2usb_complete_arq_pkt(
4122 scsa2usbp, arqcmd->cmd_pkt, cmd,
4123 scsa2usbp->scsa2usb_arq_bp);
4124
4125 /*
4126 * we have valid request sense
4127 * data so clear the pkt_reason
4128 */
4129 pkt->pkt_reason = CMD_CMPLT;
4130 }
4131 scsa2usbp->scsa2usb_cur_pkt = pkt;
4132 scsa2usb_delete_arq_pkt(scsa2usbp);
4133 }
4134
4135 if ((rval != TRAN_ACCEPT) &&
4136 (pkt->pkt_reason == CMD_CMPLT)) {
4137 pkt->pkt_reason = CMD_TRAN_ERR;
4138 }
4139
4140 SCSA2USB_SET_PKT_DO_COMP_STATE(scsa2usbp);
4141 scsa2usb_pkt_completion(scsa2usbp, pkt);
4142
4143 ASSERT(scsa2usbp->scsa2usb_cur_pkt == NULL);
4144 }
4145
4146
4147 /*
4148 * scsa2usb_work_thread:
4149 * The taskq thread that kicks off the transport (BO and CB/CBI)
4150 */
4151 static void
scsa2usb_work_thread(void * arg)4152 scsa2usb_work_thread(void *arg)
4153 {
4154 scsa2usb_state_t *scsa2usbp = (scsa2usb_state_t *)arg;
4155 uint_t lun;
4156 uint_t count;
4157
4158 mutex_enter(&scsa2usbp->scsa2usb_mutex);
4159 USB_DPRINTF_L4(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
4160 "scsa2usb_work_thread start: thread_id=0x%p",
4161 (void *)scsa2usbp->scsa2usb_work_thread_id);
4162
4163 ASSERT(scsa2usbp->scsa2usb_work_thread_id == (kthread_t *)1);
4164 scsa2usbp->scsa2usb_work_thread_id = curthread;
4165
4166 /* exclude ugen accesses */
4167 while (scsa2usbp->scsa2usb_transport_busy) {
4168 cv_wait(&scsa2usbp->scsa2usb_transport_busy_cv,
4169 &scsa2usbp->scsa2usb_mutex);
4170 }
4171 ASSERT(scsa2usbp->scsa2usb_ugen_open_count == 0);
4172 scsa2usbp->scsa2usb_transport_busy++;
4173 scsa2usbp->scsa2usb_busy_proc = curproc;
4174
4175 scsa2usb_raise_power(scsa2usbp);
4176
4177 /* reopen the pipes if necessary */
4178 (void) scsa2usb_open_usb_pipes(scsa2usbp);
4179
4180 for (;;) {
4181 ASSERT(scsa2usbp->scsa2usb_ugen_open_count == 0);
4182 for (lun = 0; lun < scsa2usbp->scsa2usb_n_luns; lun++) {
4183 scsa2usb_transport_request(scsa2usbp, lun);
4184 }
4185 count = 0;
4186 for (lun = 0; lun < SCSA2USB_MAX_LUNS; lun++) {
4187 count += usba_list_entry_count(
4188 &scsa2usbp->scsa2usb_waitQ[lun]);
4189 }
4190
4191 if (count == 0) {
4192
4193 break;
4194 }
4195 }
4196
4197 scsa2usbp->scsa2usb_work_thread_id = 0;
4198
4199 ASSERT(scsa2usbp->scsa2usb_ugen_open_count == 0);
4200
4201 scsa2usbp->scsa2usb_transport_busy--;
4202 scsa2usbp->scsa2usb_busy_proc = NULL;
4203 cv_signal(&scsa2usbp->scsa2usb_transport_busy_cv);
4204
4205 USB_DPRINTF_L4(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
4206 "scsa2usb_work_thread: exit");
4207
4208 mutex_exit(&scsa2usbp->scsa2usb_mutex);
4209
4210 scsa2usb_pm_idle_component(scsa2usbp);
4211 }
4212
4213
4214 /*
4215 * scsa2usb_flush_waitQ:
4216 * empties the entire waitQ with errors asap.
4217 *
4218 * It is called from scsa2usb_scsi_reset and scsa2usb_panic_callb.
4219 * If the device is reset; we should empty the waitQ right away.
4220 * If the system has paniced; we should empty the waitQ right away.
4221 *
4222 * CPR suspend will only succeed if device is idle. No need to call
4223 * this function for CPR suspend case.
4224 */
4225 static void
scsa2usb_flush_waitQ(scsa2usb_state_t * scsa2usbp,uint_t lun,uchar_t error)4226 scsa2usb_flush_waitQ(scsa2usb_state_t *scsa2usbp, uint_t lun,
4227 uchar_t error)
4228 {
4229 struct scsi_pkt *pkt;
4230 struct scsa2usb_cmd *cmd;
4231 usba_list_entry_t head;
4232
4233 mutex_enter(&scsa2usbp->scsa2usb_mutex);
4234
4235 usba_move_list(&scsa2usbp->scsa2usb_waitQ[lun], &head,
4236 scsa2usbp->scsa2usb_dev_data->dev_iblock_cookie);
4237 mutex_exit(&scsa2usbp->scsa2usb_mutex);
4238
4239 while ((cmd = (scsa2usb_cmd_t *)usba_rm_first_pvt_from_list(&head)) !=
4240 NULL) {
4241 pkt = cmd->cmd_pkt;
4242 pkt->pkt_reason = error; /* set error */
4243
4244 mutex_enter(&scsa2usbp->scsa2usb_mutex);
4245 scsa2usbp->scsa2usb_pkt_state = SCSA2USB_PKT_DO_COMP;
4246 scsa2usb_pkt_completion(scsa2usbp, pkt);
4247 mutex_exit(&scsa2usbp->scsa2usb_mutex);
4248 } /* end of while */
4249 }
4250
4251
4252 /*
4253 * scsa2usb_do_inquiry is performed before INIT CHILD and we have
4254 * to fake a few things normally done by SCSA
4255 */
4256 static void
scsa2usb_do_inquiry(scsa2usb_state_t * scsa2usbp,uint_t target,uint_t lun)4257 scsa2usb_do_inquiry(scsa2usb_state_t *scsa2usbp, uint_t target, uint_t lun)
4258 {
4259 struct buf *bp;
4260 struct scsi_pkt *pkt;
4261 struct scsi_address ap;
4262 int len = SCSA2USB_MAX_INQ_LEN;
4263
4264 USB_DPRINTF_L4(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
4265 "scsa2usb_do_inquiry: %d bytes", len);
4266
4267 /* is it inquiry-challenged? */
4268 if (!(scsa2usbp->scsa2usb_attrs & SCSA2USB_ATTRS_INQUIRY)) {
4269 scsa2usb_fake_inquiry(scsa2usbp,
4270 &scsa2usbp->scsa2usb_lun_inquiry[lun]);
4271 return;
4272 }
4273
4274 ASSERT(mutex_owned(&scsa2usbp->scsa2usb_mutex));
4275
4276 bzero(&ap, sizeof (struct scsi_address));
4277 ap.a_hba_tran = scsa2usbp->scsa2usb_tran;
4278 ap.a_target = (ushort_t)target;
4279 ap.a_lun = (uchar_t)lun;
4280
4281 /* limit inquiry to 36 bytes */
4282 mutex_exit(&scsa2usbp->scsa2usb_mutex);
4283 if ((bp = scsi_alloc_consistent_buf(&ap, (struct buf *)NULL,
4284 len, B_READ, SLEEP_FUNC, NULL)) == NULL) {
4285 mutex_enter(&scsa2usbp->scsa2usb_mutex);
4286 USB_DPRINTF_L2(DPRINT_MASK_SCSA,
4287 scsa2usbp->scsa2usb_log_handle,
4288 "scsa2usb_do_inquiry: failed");
4289
4290 return;
4291 }
4292
4293 pkt = scsi_init_pkt(&ap, NULL, bp, CDB_GROUP0, 1,
4294 PKT_PRIV_LEN, PKT_CONSISTENT, SLEEP_FUNC, NULL);
4295
4296 RQ_MAKECOM_G0(pkt, FLAG_NOINTR, (char)SCMD_INQUIRY, 0, (char)len);
4297
4298 pkt->pkt_comp = NULL;
4299 pkt->pkt_time = 5;
4300 bzero(bp->b_un.b_addr, len);
4301
4302 USB_DPRINTF_L3(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
4303 "scsa2usb_do_inquiry:INQUIRY");
4304
4305 (void) scsi_transport(pkt);
4306
4307 if (pkt->pkt_reason) {
4308 USB_DPRINTF_L2(DPRINT_MASK_SCSA,
4309 scsa2usbp->scsa2usb_log_handle,
4310 "INQUIRY failed, cannot determine device type, "
4311 "pkt_reason=0x%x", pkt->pkt_reason);
4312
4313 /* not much hope for other cmds, reduce */
4314 mutex_enter(&scsa2usbp->scsa2usb_mutex);
4315 scsa2usbp->scsa2usb_attrs &=
4316 ~SCSA2USB_ATTRS_REDUCED_CMD;
4317 scsa2usb_fake_inquiry(scsa2usbp,
4318 &scsa2usbp->scsa2usb_lun_inquiry[lun]);
4319 mutex_exit(&scsa2usbp->scsa2usb_mutex);
4320 }
4321
4322 scsi_destroy_pkt(pkt);
4323 scsi_free_consistent_buf(bp);
4324
4325 mutex_enter(&scsa2usbp->scsa2usb_mutex);
4326 }
4327
4328
4329 /*
4330 * scsa2usb_fake_inquiry:
4331 * build an inquiry for a given device that doesnt like inquiry
4332 * commands.
4333 */
4334 static void
scsa2usb_fake_inquiry(scsa2usb_state_t * scsa2usbp,struct scsi_inquiry * inqp)4335 scsa2usb_fake_inquiry(scsa2usb_state_t *scsa2usbp, struct scsi_inquiry *inqp)
4336 {
4337 usb_client_dev_data_t *dev_data = scsa2usbp->scsa2usb_dev_data;
4338 int len;
4339
4340 USB_DPRINTF_L4(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
4341 "scsa2usb_fake_inquiry:");
4342
4343 bzero(inqp, sizeof (struct scsi_inquiry));
4344 for (len = 0; len < sizeof (inqp->inq_vid); len++) {
4345 *(inqp->inq_vid + len) = ' ';
4346 }
4347
4348 for (len = 0; len < sizeof (inqp->inq_pid); len++) {
4349 *(inqp->inq_pid + len) = ' ';
4350 }
4351
4352 inqp->inq_dtype = DTYPE_DIRECT;
4353 inqp->inq_rmb = 1;
4354 inqp->inq_ansi = 2;
4355 inqp->inq_rdf = RDF_SCSI2;
4356 inqp->inq_len = sizeof (struct scsi_inquiry)-4;
4357
4358 /* Fill in the Vendor id/Product id strings */
4359 if (dev_data->dev_mfg) {
4360 if ((len = strlen(dev_data->dev_mfg)) >
4361 sizeof (inqp->inq_vid)) {
4362 len = sizeof (inqp->inq_vid);
4363 }
4364 bcopy(dev_data->dev_mfg, inqp->inq_vid, len);
4365 }
4366
4367 if (dev_data->dev_product) {
4368 if ((len = strlen(dev_data->dev_product)) >
4369 sizeof (inqp->inq_pid)) {
4370 len = sizeof (inqp->inq_pid);
4371 }
4372 bcopy(dev_data->dev_product, inqp->inq_pid, len);
4373 }
4374
4375 /* Set the Revision to the Device */
4376 inqp->inq_revision[0] = 0x30 +
4377 ((dev_data->dev_descr->bcdDevice>>12) & 0xF);
4378 inqp->inq_revision[1] = 0x30 +
4379 ((dev_data->dev_descr->bcdDevice>>8) & 0xF);
4380 inqp->inq_revision[2] = 0x30 +
4381 ((dev_data->dev_descr->bcdDevice>>4) & 0xF);
4382 inqp->inq_revision[3] = 0x30 +
4383 ((dev_data->dev_descr->bcdDevice) & 0xF);
4384 }
4385
4386
4387 /*
4388 * scsa2usb_create_arq_pkt:
4389 * Create and ARQ packet to get request sense data
4390 */
4391 static int
scsa2usb_create_arq_pkt(scsa2usb_state_t * scsa2usbp,struct scsi_address * ap)4392 scsa2usb_create_arq_pkt(scsa2usb_state_t *scsa2usbp, struct scsi_address *ap)
4393 {
4394 struct buf *bp;
4395 scsa2usb_cmd_t *arq_cmd;
4396
4397 USB_DPRINTF_L4(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
4398 "scsa2usb_create_arq_pkt: scsa2usbp: %p, ap: %p",
4399 (void *)scsa2usbp, (void *)ap);
4400
4401 ASSERT(mutex_owned(&scsa2usbp->scsa2usb_mutex));
4402
4403 mutex_exit(&scsa2usbp->scsa2usb_mutex);
4404 if ((bp = scsi_alloc_consistent_buf(ap, (struct buf *)NULL,
4405 SENSE_LENGTH, B_READ, SLEEP_FUNC, NULL)) == NULL) {
4406 mutex_enter(&scsa2usbp->scsa2usb_mutex);
4407
4408 return (USB_FAILURE);
4409 }
4410
4411 arq_cmd = PKT2CMD(scsi_init_pkt(ap, NULL, bp, CDB_GROUP0, 1,
4412 PKT_PRIV_LEN, PKT_CONSISTENT, SLEEP_FUNC, NULL));
4413 mutex_enter(&scsa2usbp->scsa2usb_mutex);
4414
4415 RQ_MAKECOM_G0(arq_cmd->cmd_pkt,
4416 FLAG_SENSING | FLAG_HEAD | FLAG_NODISCON,
4417 (char)SCMD_REQUEST_SENSE, 0, (char)SENSE_LENGTH);
4418
4419 arq_cmd->cmd_pkt->pkt_ha_private = arq_cmd;
4420 scsa2usbp->scsa2usb_arq_cmd = arq_cmd;
4421 scsa2usbp->scsa2usb_arq_bp = bp;
4422 arq_cmd->cmd_pkt->pkt_comp = NULL;
4423 bzero(bp->b_un.b_addr, SENSE_LENGTH);
4424
4425 return (USB_SUCCESS);
4426 }
4427
4428
4429 /*
4430 * scsa2usb_delete_arq_pkt:
4431 * Destroy the ARQ packet
4432 */
4433 static void
scsa2usb_delete_arq_pkt(scsa2usb_state_t * scsa2usbp)4434 scsa2usb_delete_arq_pkt(scsa2usb_state_t *scsa2usbp)
4435 {
4436 USB_DPRINTF_L4(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
4437 "scsa2usb_delete_arq_pkt: cmd: 0x%p",
4438 (void *)scsa2usbp->scsa2usb_arq_cmd);
4439
4440 ASSERT(mutex_owned(&scsa2usbp->scsa2usb_mutex));
4441
4442 if (scsa2usbp->scsa2usb_arq_cmd != NULL) {
4443 scsi_destroy_pkt(scsa2usbp->scsa2usb_arq_cmd->cmd_pkt);
4444 scsi_free_consistent_buf(scsa2usbp->scsa2usb_arq_bp);
4445 }
4446 scsa2usbp->scsa2usb_arq_cmd = NULL;
4447 scsa2usbp->scsa2usb_arq_bp = NULL;
4448 }
4449
4450
4451 /*
4452 * scsa2usb_complete_arq_pkt:
4453 * finish processing the arq packet
4454 */
4455 static void
scsa2usb_complete_arq_pkt(scsa2usb_state_t * scsa2usbp,struct scsi_pkt * pkt,scsa2usb_cmd_t * ssp,struct buf * bp)4456 scsa2usb_complete_arq_pkt(scsa2usb_state_t *scsa2usbp,
4457 struct scsi_pkt *pkt, scsa2usb_cmd_t *ssp, struct buf *bp)
4458 {
4459 scsa2usb_cmd_t *sp = pkt->pkt_ha_private;
4460 struct scsi_arq_status *arqp;
4461
4462 ASSERT(mutex_owned(&scsa2usbp->scsa2usb_mutex));
4463
4464 arqp = (struct scsi_arq_status *)(ssp->cmd_pkt->pkt_scbp);
4465 arqp->sts_rqpkt_status = *((struct scsi_status *)
4466 (sp->cmd_pkt->pkt_scbp));
4467 arqp->sts_rqpkt_reason = CMD_CMPLT;
4468 arqp->sts_rqpkt_state |= STATE_XFERRED_DATA;
4469 arqp->sts_rqpkt_statistics = arqp->sts_rqpkt_resid = 0;
4470
4471 /* is this meaningful sense data */
4472 if (*(bp->b_un.b_addr) != 0) {
4473 bcopy(bp->b_un.b_addr, &arqp->sts_sensedata, SENSE_LENGTH);
4474 ssp->cmd_pkt->pkt_state |= STATE_ARQ_DONE;
4475 }
4476
4477 /* we will not sense start cmd until we receive a NOT READY */
4478 if (arqp->sts_sensedata.es_key == KEY_NOT_READY) {
4479 scsa2usbp->scsa2usb_rcvd_not_ready = B_TRUE;
4480 }
4481 }
4482
4483
4484 /*
4485 * Miscellaneous functions for any command/transport
4486 */
4487 /*
4488 * scsa2usb_open_usb_pipes:
4489 * set up a pipe policy
4490 * open usb bulk pipes (BO and CB/CBI)
4491 * open usb interrupt pipe (CBI)
4492 */
4493 static int
scsa2usb_open_usb_pipes(scsa2usb_state_t * scsa2usbp)4494 scsa2usb_open_usb_pipes(scsa2usb_state_t *scsa2usbp)
4495 {
4496 int rval;
4497 usb_pipe_policy_t policy; /* bulk pipe policy */
4498 size_t sz;
4499
4500 ASSERT(scsa2usbp);
4501 ASSERT(mutex_owned(&scsa2usbp->scsa2usb_mutex));
4502
4503 USB_DPRINTF_L4(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
4504 "scsa2usb_open_usb_pipes: dip = 0x%p flag = 0x%x",
4505 (void *)scsa2usbp->scsa2usb_dip, scsa2usbp->scsa2usb_flags);
4506
4507 if (!(scsa2usbp->scsa2usb_flags & SCSA2USB_FLAGS_PIPES_OPENED)) {
4508
4509 /*
4510 * one pipe policy for all bulk pipes
4511 */
4512 bzero(&policy, sizeof (usb_pipe_policy_t));
4513 /* at least 2, for the normal and exceptional callbacks */
4514 policy.pp_max_async_reqs = 1;
4515
4516 USB_DPRINTF_L4(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
4517 "scsa2usb_open_usb_pipes: opening bulk pipes");
4518
4519 mutex_exit(&scsa2usbp->scsa2usb_mutex);
4520
4521 /* Open the USB bulk-in pipe */
4522 if ((rval = usb_pipe_open(scsa2usbp->scsa2usb_dip,
4523 &scsa2usbp->scsa2usb_bulkin_ept, &policy, USB_FLAGS_SLEEP,
4524 &scsa2usbp->scsa2usb_bulkin_pipe)) != USB_SUCCESS) {
4525 mutex_enter(&scsa2usbp->scsa2usb_mutex);
4526 USB_DPRINTF_L2(DPRINT_MASK_SCSA,
4527 scsa2usbp->scsa2usb_log_handle,
4528 "scsa2usb_open_usb_pipes: bulk/in pipe open "
4529 " failed rval = %d", rval);
4530
4531 return (USB_FAILURE);
4532 }
4533
4534 /* Open the bulk-out pipe using the same policy */
4535 if ((rval = usb_pipe_open(scsa2usbp->scsa2usb_dip,
4536 &scsa2usbp->scsa2usb_bulkout_ept, &policy, USB_FLAGS_SLEEP,
4537 &scsa2usbp->scsa2usb_bulkout_pipe)) != USB_SUCCESS) {
4538 usb_pipe_close(scsa2usbp->scsa2usb_dip,
4539 scsa2usbp->scsa2usb_bulkin_pipe,
4540 USB_FLAGS_SLEEP, NULL, NULL);
4541
4542 mutex_enter(&scsa2usbp->scsa2usb_mutex);
4543 scsa2usbp->scsa2usb_bulkin_pipe = NULL;
4544
4545 USB_DPRINTF_L2(DPRINT_MASK_SCSA,
4546 scsa2usbp->scsa2usb_log_handle,
4547 "scsa2usb_open_usb_pipes: bulk/out pipe open"
4548 " failed rval = %d", rval);
4549
4550 return (USB_FAILURE);
4551 }
4552
4553 mutex_enter(&scsa2usbp->scsa2usb_mutex);
4554
4555 /* open interrupt pipe for CBI protocol */
4556 if (SCSA2USB_IS_CBI(scsa2usbp)) {
4557 mutex_exit(&scsa2usbp->scsa2usb_mutex);
4558
4559 if ((rval = usb_pipe_open(scsa2usbp->scsa2usb_dip,
4560 &scsa2usbp->scsa2usb_intr_ept, &policy,
4561 USB_FLAGS_SLEEP, &scsa2usbp->scsa2usb_intr_pipe)) !=
4562 USB_SUCCESS) {
4563 usb_pipe_close(scsa2usbp->scsa2usb_dip,
4564 scsa2usbp->scsa2usb_bulkin_pipe,
4565 USB_FLAGS_SLEEP, NULL, NULL);
4566
4567 usb_pipe_close(scsa2usbp->scsa2usb_dip,
4568 scsa2usbp->scsa2usb_bulkout_pipe,
4569 USB_FLAGS_SLEEP, NULL, NULL);
4570
4571 mutex_enter(&scsa2usbp->scsa2usb_mutex);
4572 scsa2usbp->scsa2usb_bulkin_pipe = NULL;
4573 scsa2usbp->scsa2usb_bulkout_pipe = NULL;
4574
4575 USB_DPRINTF_L2(DPRINT_MASK_SCSA,
4576 scsa2usbp->scsa2usb_log_handle,
4577 "scsa2usb_open_usb_pipes: intr pipe open"
4578 " failed rval = %d", rval);
4579
4580 return (USB_FAILURE);
4581 }
4582
4583 mutex_enter(&scsa2usbp->scsa2usb_mutex);
4584 }
4585
4586 mutex_exit(&scsa2usbp->scsa2usb_mutex);
4587
4588 /* get the max transfer size of the bulk pipe */
4589 if (usb_pipe_get_max_bulk_transfer_size(scsa2usbp->scsa2usb_dip,
4590 &sz) == USB_SUCCESS) {
4591 mutex_enter(&scsa2usbp->scsa2usb_mutex);
4592 scsa2usbp->scsa2usb_max_bulk_xfer_size = sz;
4593 } else {
4594 mutex_enter(&scsa2usbp->scsa2usb_mutex);
4595 scsa2usbp->scsa2usb_max_bulk_xfer_size = DEV_BSIZE;
4596 }
4597
4598 /* limit the xfer size */
4599 scsa2usbp->scsa2usb_max_bulk_xfer_size = min(
4600 scsa2usbp->scsa2usb_max_bulk_xfer_size,
4601 scsa2usb_max_bulk_xfer_size);
4602
4603 USB_DPRINTF_L4(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
4604 "scsa2usb_open_usb_pipes: max bulk transfer size = %lx",
4605 scsa2usbp->scsa2usb_max_bulk_xfer_size);
4606
4607 /* Set the pipes opened flag */
4608 scsa2usbp->scsa2usb_flags |= SCSA2USB_FLAGS_PIPES_OPENED;
4609
4610 scsa2usbp->scsa2usb_pipe_state = SCSA2USB_PIPE_NORMAL;
4611
4612 /* Set the state to NONE */
4613 scsa2usbp->scsa2usb_pkt_state = SCSA2USB_PKT_NONE;
4614 }
4615
4616 return (USB_SUCCESS);
4617 }
4618
4619
4620 /*
4621 * scsa2usb_close_usb_pipes:
4622 * close all pipes synchronously
4623 */
4624 void
scsa2usb_close_usb_pipes(scsa2usb_state_t * scsa2usbp)4625 scsa2usb_close_usb_pipes(scsa2usb_state_t *scsa2usbp)
4626 {
4627 usb_flags_t flags = USB_FLAGS_SLEEP;
4628
4629 USB_DPRINTF_L4(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
4630 "scsa2usb_close_usb_pipes: scsa2usb_state = 0x%p",
4631 (void *)scsa2usbp);
4632
4633 ASSERT(scsa2usbp);
4634 ASSERT(mutex_owned(&scsa2usbp->scsa2usb_mutex));
4635
4636 if ((scsa2usbp->scsa2usb_flags & SCSA2USB_FLAGS_PIPES_OPENED) == 0) {
4637
4638 return;
4639 }
4640
4641 scsa2usbp->scsa2usb_pipe_state = SCSA2USB_PIPE_CLOSING;
4642 /* to avoid races, reset the flag first */
4643 scsa2usbp->scsa2usb_flags &= ~SCSA2USB_FLAGS_PIPES_OPENED;
4644
4645 mutex_exit(&scsa2usbp->scsa2usb_mutex);
4646
4647 usb_pipe_close(scsa2usbp->scsa2usb_dip,
4648 scsa2usbp->scsa2usb_bulkout_pipe, flags, NULL, NULL);
4649
4650 usb_pipe_close(scsa2usbp->scsa2usb_dip,
4651 scsa2usbp->scsa2usb_bulkin_pipe, flags, NULL, NULL);
4652
4653 mutex_enter(&scsa2usbp->scsa2usb_mutex);
4654 if (SCSA2USB_IS_CBI(scsa2usbp)) {
4655 mutex_exit(&scsa2usbp->scsa2usb_mutex);
4656 usb_pipe_close(scsa2usbp->scsa2usb_dip,
4657 scsa2usbp->scsa2usb_intr_pipe, flags, NULL, NULL);
4658 mutex_enter(&scsa2usbp->scsa2usb_mutex);
4659 }
4660 scsa2usbp->scsa2usb_bulkout_pipe = NULL;
4661 scsa2usbp->scsa2usb_bulkin_pipe = NULL;
4662 scsa2usbp->scsa2usb_intr_pipe = NULL;
4663
4664 scsa2usbp->scsa2usb_pipe_state = SCSA2USB_PIPE_NORMAL;
4665 }
4666
4667
4668 /*
4669 * scsa2usb_fill_up_cdb_lba:
4670 * fill up command CDBs' LBA part
4671 */
4672 static void
scsa2usb_fill_up_cdb_lba(scsa2usb_cmd_t * cmd,int lba)4673 scsa2usb_fill_up_cdb_lba(scsa2usb_cmd_t *cmd, int lba)
4674 {
4675 /* zero cdb1, lba bits so they won't get copied in the new cdb */
4676 cmd->cmd_cdb[SCSA2USB_LUN] &= 0xE0;
4677 cmd->cmd_cdb[SCSA2USB_LBA_0] = lba >> 24;
4678 cmd->cmd_cdb[SCSA2USB_LBA_1] = lba >> 16;
4679 cmd->cmd_cdb[SCSA2USB_LBA_2] = lba >> 8;
4680 cmd->cmd_cdb[SCSA2USB_LBA_3] = (uchar_t)lba;
4681 cmd->cmd_lba = lba;
4682 }
4683
4684
4685 /*
4686 * scsa2usb_fill_up_ReadCD_cdb_len:
4687 * fill up READ_CD command CDBs' len part
4688 */
4689 static void
scsa2usb_fill_up_ReadCD_cdb_len(scsa2usb_cmd_t * cmd,int len,int actual_len)4690 scsa2usb_fill_up_ReadCD_cdb_len(scsa2usb_cmd_t *cmd, int len, int actual_len)
4691 {
4692 cmd->cmd_cdb[SCSA2USB_READ_CD_LEN_0] = len >> 16;
4693 cmd->cmd_cdb[SCSA2USB_READ_CD_LEN_1] = len >> 8;
4694 cmd->cmd_cdb[SCSA2USB_READ_CD_LEN_2] = (uchar_t)len;
4695 cmd->cmd_actual_len = (uchar_t)actual_len;
4696 }
4697
4698
4699 /*
4700 * scsa2usb_fill_up_12byte_cdb_len:
4701 * fill up generic 12-byte command CDBs' len part
4702 */
4703 static void
scsa2usb_fill_up_12byte_cdb_len(scsa2usb_cmd_t * cmd,int len,int actual_len)4704 scsa2usb_fill_up_12byte_cdb_len(scsa2usb_cmd_t *cmd, int len, int actual_len)
4705 {
4706 cmd->cmd_cdb[6] = len >> 24;
4707 cmd->cmd_cdb[7] = len >> 16;
4708 cmd->cmd_cdb[8] = len >> 8;
4709 cmd->cmd_cdb[9] = (uchar_t)len;
4710 cmd->cmd_actual_len = (uchar_t)actual_len;
4711 }
4712
4713
4714 /*
4715 * scsa2usb_fill_up_cdb_len:
4716 * fill up generic 10-byte command CDBs' len part
4717 */
4718 static void
scsa2usb_fill_up_cdb_len(scsa2usb_cmd_t * cmd,int len)4719 scsa2usb_fill_up_cdb_len(scsa2usb_cmd_t *cmd, int len)
4720 {
4721 cmd->cmd_cdb[SCSA2USB_LEN_0] = len >> 8;
4722 cmd->cmd_cdb[SCSA2USB_LEN_1] = (uchar_t)len;
4723 }
4724
4725
4726 /*
4727 * scsa2usb_read_cd_blk_size:
4728 * For SCMD_READ_CD opcode (0xbe). Figure out the
4729 * block size based on expected sector type field
4730 * definition. See MMC SCSI Specs section 6.1.15
4731 *
4732 * Based on the value of the "expected_sector_type"
4733 * field, the block size could be different.
4734 */
4735 static int
scsa2usb_read_cd_blk_size(uchar_t expected_sector_type)4736 scsa2usb_read_cd_blk_size(uchar_t expected_sector_type)
4737 {
4738 int blk_size;
4739
4740 switch (expected_sector_type) {
4741 case READ_CD_EST_CDDA:
4742 blk_size = CDROM_BLK_2352;
4743 break;
4744 case READ_CD_EST_MODE2:
4745 blk_size = CDROM_BLK_2336;
4746 break;
4747 case READ_CD_EST_MODE2FORM2:
4748 blk_size = CDROM_BLK_2324;
4749 break;
4750 case READ_CD_EST_MODE2FORM1:
4751 case READ_CD_EST_ALLTYPE:
4752 case READ_CD_EST_MODE1:
4753 default:
4754 blk_size = CDROM_BLK_2048;
4755 }
4756
4757 USB_DPRINTF_L4(DPRINT_MASK_SCSA, NULL, "scsa2usb_read_cd_blk_size: "
4758 "est = 0x%x blk_size = %d", expected_sector_type, blk_size);
4759
4760 return (blk_size);
4761 }
4762
4763
4764 /*
4765 * scsa2usb_bp_to_mblk:
4766 * Convert a bp to mblk_t. USBA framework understands mblk_t.
4767 */
4768 static mblk_t *
scsa2usb_bp_to_mblk(scsa2usb_state_t * scsa2usbp)4769 scsa2usb_bp_to_mblk(scsa2usb_state_t *scsa2usbp)
4770 {
4771 size_t size;
4772 mblk_t *mp;
4773 struct buf *bp;
4774 scsa2usb_cmd_t *cmd = PKT2CMD(scsa2usbp->scsa2usb_cur_pkt);
4775
4776 USB_DPRINTF_L4(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
4777 "scsa2usb_bp_to_mblk: ");
4778
4779 ASSERT(scsa2usbp->scsa2usb_cur_pkt);
4780 ASSERT(mutex_owned(&scsa2usbp->scsa2usb_mutex));
4781
4782 bp = cmd->cmd_bp;
4783
4784 if (bp && (bp->b_bcount > 0)) {
4785 size = ((bp->b_bcount > cmd->cmd_xfercount) ?
4786 cmd->cmd_xfercount : bp->b_bcount);
4787 } else {
4788
4789 return (NULL);
4790 }
4791
4792 mp = esballoc_wait((uchar_t *)bp->b_un.b_addr + cmd->cmd_offset,
4793 size, BPRI_LO, &frnop);
4794
4795 USB_DPRINTF_L3(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
4796 "scsa2usb_bp_to_mblk: "
4797 "mp=0x%p bp=0x%p pkt=0x%p off=0x%lx sz=%lu add=0x%p",
4798 (void *)mp, (void *)bp, (void *)scsa2usbp->scsa2usb_cur_pkt,
4799 cmd->cmd_offset, bp->b_bcount - cmd->cmd_offset,
4800 (void *)bp->b_un.b_addr);
4801
4802 mp->b_wptr += size;
4803 cmd->cmd_offset += size;
4804
4805 return (mp);
4806 }
4807
4808
4809 /*
4810 * scsa2usb_handle_data_start:
4811 * Initiate the data xfer. It could be IN/OUT direction.
4812 *
4813 * Data IN:
4814 * Send out the bulk-xfer request
4815 * if rval implies STALL
4816 * clear endpoint stall and reset bulk-in pipe
4817 * handle data read in so far; set cmd->cmd_done
4818 * also adjust data xfer length accordingly
4819 * else other error
4820 * report back to transport
4821 * typically transport will call reset recovery
4822 * else (no error)
4823 * return success
4824 *
4825 * Data OUT:
4826 * Send out the bulk-xfer request
4827 * if rval implies STALL
4828 * clear endpoint stall and reset bulk-in pipe
4829 * adjust data xfer length
4830 * else other error
4831 * report back to transport
4832 * typically transport will call reset recovery
4833 * else (no error)
4834 * return success
4835 *
4836 * NOTE: We call this function only if there is xfercount.
4837 */
4838 int
scsa2usb_handle_data_start(scsa2usb_state_t * scsa2usbp,scsa2usb_cmd_t * cmd,usb_bulk_req_t * req)4839 scsa2usb_handle_data_start(scsa2usb_state_t *scsa2usbp,
4840 scsa2usb_cmd_t *cmd, usb_bulk_req_t *req)
4841 {
4842 int rval = USB_SUCCESS;
4843 uint_t ept_addr;
4844 usb_flags_t flags = USB_FLAGS_SLEEP;
4845 #ifdef SCSA2USB_BULK_ONLY_TEST
4846 usb_req_attrs_t attrs = 0;
4847 #else
4848 usb_req_attrs_t attrs = USB_ATTRS_SHORT_XFER_OK;
4849 #endif
4850
4851 USB_DPRINTF_L4(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
4852 "scsa2usb_handle_data_start: BEGIN cmd = %p, req = %p",
4853 (void *)cmd, (void *)req);
4854
4855 ASSERT(mutex_owned(&scsa2usbp->scsa2usb_mutex));
4856
4857 switch (cmd->cmd_dir) {
4858 case USB_EP_DIR_IN:
4859 #ifdef SCSA2USB_BULK_ONLY_TEST
4860 /*
4861 * This case occurs when the host expects to receive
4862 * more data than the device actually transfers. Hi > Di
4863 */
4864 if (scsa2usb_test_case_5) {
4865 usb_bulk_req_t *req2;
4866
4867 req->bulk_len = cmd->cmd_xfercount - 1;
4868 req->bulk_attributes = 0;
4869 mutex_exit(&scsa2usbp->scsa2usb_mutex);
4870 SCSA2USB_FREE_MSG(req->bulk_data);
4871 req->bulk_data = allocb_wait(req->bulk_len, BPRI_LO,
4872 STR_NOSIG, NULL);
4873
4874 ASSERT(req->bulk_timeout);
4875 rval = usb_pipe_bulk_xfer(
4876 scsa2usbp->scsa2usb_bulkin_pipe, req, flags);
4877 mutex_enter(&scsa2usbp->scsa2usb_mutex);
4878 USB_DPRINTF_L1(DPRINT_MASK_SCSA,
4879 scsa2usbp->scsa2usb_log_handle, "rval = %x", rval);
4880
4881 req2 = scsa2usb_init_bulk_req(scsa2usbp,
4882 cmd->cmd_xfercount + 2,
4883 cmd->cmd_timeout, 0, flags);
4884 req2->bulk_len = cmd->cmd_xfercount + 2;
4885 mutex_exit(&scsa2usbp->scsa2usb_mutex);
4886
4887 ASSERT(req2->bulk_timeout);
4888 rval = usb_pipe_bulk_xfer(
4889 scsa2usbp->scsa2usb_bulkin_pipe, req2, flags);
4890 mutex_enter(&scsa2usbp->scsa2usb_mutex);
4891
4892 USB_DPRINTF_L1(DPRINT_MASK_SCSA,
4893 scsa2usbp->scsa2usb_log_handle,
4894 "TEST 5: Hi > Di: rval = 0x%x", rval);
4895 scsa2usb_test_case_5 = 0;
4896 usb_free_bulk_req(req2);
4897
4898 return (rval);
4899 }
4900
4901 /*
4902 * This happens when the host expects to send data to the
4903 * device while the device intends to send data to the host.
4904 */
4905 if (scsa2usb_test_case_8 && (cmd->cmd_cdb[0] == SCMD_READ_G1)) {
4906 USB_DPRINTF_L1(DPRINT_MASK_SCSA,
4907 scsa2usbp->scsa2usb_log_handle,
4908 "TEST 8: Hi <> Do: Step 2");
4909 scsa2usb_test_mblk(scsa2usbp, B_TRUE);
4910 scsa2usb_test_case_8 = 0;
4911
4912 return (rval);
4913 }
4914 #endif /* SCSA2USB_BULK_ONLY_TEST */
4915
4916 ept_addr = scsa2usbp->scsa2usb_bulkin_ept.bEndpointAddress;
4917 req->bulk_len = cmd->cmd_xfercount;
4918 req->bulk_attributes = attrs;
4919 SCSA2USB_FREE_MSG(req->bulk_data);
4920 mutex_exit(&scsa2usbp->scsa2usb_mutex);
4921
4922 req->bulk_data = esballoc_wait(
4923 (uchar_t *)cmd->cmd_bp->b_un.b_addr +
4924 cmd->cmd_offset,
4925 req->bulk_len, BPRI_LO, &frnop);
4926
4927 ASSERT(req->bulk_timeout);
4928 rval = usb_pipe_bulk_xfer(scsa2usbp->scsa2usb_bulkin_pipe,
4929 req, flags);
4930 mutex_enter(&scsa2usbp->scsa2usb_mutex);
4931
4932 break;
4933
4934 case USB_EP_DIR_OUT:
4935 #ifdef SCSA2USB_BULK_ONLY_TEST
4936 /*
4937 * This happens when the host expects to receive data
4938 * from the device while the device intends to receive
4939 * data from the host.
4940 */
4941 if (scsa2usb_test_case_10 &&
4942 (cmd->cmd_cdb[0] == SCMD_WRITE_G1)) {
4943 req->bulk_len = CSW_LEN;
4944 mutex_exit(&scsa2usbp->scsa2usb_mutex);
4945
4946 ASSERT(req->bulk_timeout);
4947 rval = usb_pipe_bulk_xfer(
4948 scsa2usbp->scsa2usb_bulkin_pipe, req, flags);
4949 mutex_enter(&scsa2usbp->scsa2usb_mutex);
4950
4951 USB_DPRINTF_L1(DPRINT_MASK_SCSA,
4952 scsa2usbp->scsa2usb_log_handle,
4953 "TEST 10: Ho <> Di: done rval = 0x%x", rval);
4954 scsa2usb_test_case_10 = 0;
4955
4956 return (rval);
4957 }
4958 #endif /* SCSA2USB_BULK_ONLY_TEST */
4959
4960 req->bulk_data = scsa2usb_bp_to_mblk(scsa2usbp);
4961 if (req->bulk_data == NULL) {
4962
4963 return (USB_FAILURE);
4964 }
4965
4966 #ifdef SCSA2USB_BULK_ONLY_TEST
4967 if (scsa2usb_test_case_11) {
4968 /*
4969 * Host expects to send data to the device and
4970 * device doesn't expect to receive any data
4971 */
4972 USB_DPRINTF_L1(DPRINT_MASK_SCSA,
4973 scsa2usbp->scsa2usb_log_handle, "TEST 11: Ho > Do");
4974
4975 scsa2usb_test_mblk(scsa2usbp, B_FALSE);
4976 scsa2usb_test_case_11 = 0;
4977 }
4978 #endif /* SCSA2USB_BULK_ONLY_TEST */
4979
4980 ept_addr = scsa2usbp->scsa2usb_bulkout_ept.bEndpointAddress;
4981 req->bulk_len = MBLKL(req->bulk_data);
4982 req->bulk_timeout = scsa2usb_bulk_timeout(cmd->cmd_timeout);
4983 mutex_exit(&scsa2usbp->scsa2usb_mutex);
4984
4985 ASSERT(req->bulk_timeout);
4986 rval = usb_pipe_bulk_xfer(scsa2usbp->scsa2usb_bulkout_pipe,
4987 req, flags);
4988 mutex_enter(&scsa2usbp->scsa2usb_mutex);
4989 break;
4990 }
4991
4992 USB_DPRINTF_L3(DPRINT_MASK_SCSA,
4993 scsa2usbp->scsa2usb_log_handle,
4994 "scsa2usb_handle_data_start: rval=%d cr=%d", rval,
4995 req->bulk_completion_reason);
4996
4997 if (rval != USB_SUCCESS) {
4998 /* Handle Errors now */
4999 if (req->bulk_completion_reason == USB_CR_STALL) {
5000 if (cmd->cmd_dir == USB_EP_DIR_IN) {
5001 (void) scsa2usb_clear_ept_stall(
5002 scsa2usbp, ept_addr,
5003 scsa2usbp-> scsa2usb_bulkin_pipe,
5004 "bulk-in");
5005 } else {
5006 (void) scsa2usb_clear_ept_stall(
5007 scsa2usbp, ept_addr,
5008 scsa2usbp-> scsa2usb_bulkout_pipe,
5009 "bulk-out");
5010 }
5011 }
5012
5013 /* no more data to transfer after this */
5014 cmd->cmd_done = 1;
5015 }
5016
5017 USB_DPRINTF_L4(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
5018 "scsa2usb_handle_data_start: END %s data rval = %d",
5019 (cmd->cmd_dir == USB_EP_DIR_IN) ? "bulk-in" : "bulk-out", rval);
5020
5021 return (rval);
5022 }
5023
5024
5025 /*
5026 * scsa2usb_handle_data_done:
5027 * This function handles the completion of the data xfer.
5028 * It also massages the inquiry data. This function may
5029 * also be called after a stall.
5030 */
5031 void
scsa2usb_handle_data_done(scsa2usb_state_t * scsa2usbp,scsa2usb_cmd_t * cmd,usb_bulk_req_t * req)5032 scsa2usb_handle_data_done(scsa2usb_state_t *scsa2usbp,
5033 scsa2usb_cmd_t *cmd, usb_bulk_req_t *req)
5034 {
5035 struct buf *bp = cmd->cmd_bp;
5036 struct scsi_pkt *pkt = scsa2usbp->scsa2usb_cur_pkt;
5037 mblk_t *data = req->bulk_data;
5038 int len = data ? MBLKL(data) : 0;
5039 uint32_t max_lba;
5040
5041 ASSERT(mutex_owned(&scsa2usbp->scsa2usb_mutex));
5042
5043 USB_DPRINTF_L4(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
5044 "scsa2usb_handle_data_done:\n\tcmd = 0x%p data = 0x%p len = 0x%x",
5045 (void *)cmd, (void *)data, len);
5046
5047 cmd->cmd_resid_xfercount = cmd->cmd_xfercount - len;
5048
5049 if (len) {
5050 uchar_t *p;
5051 uchar_t dtype;
5052 scsa2usb_read_cap_t *cap;
5053 struct scsi_inquiry *inq;
5054
5055 switch (cmd->cmd_cdb[SCSA2USB_OPCODE]) {
5056 case SCMD_INQUIRY:
5057 /*
5058 * cache a copy of the inquiry data for our own use
5059 * but ensure that we have at least up to
5060 * inq_revision, inq_serial is not required.
5061 * ignore inquiry data returned for inquiry commands
5062 * with SCSI-3 EVPD, CmdDt bits set.
5063 */
5064 if (((cmd->cmd_cdb[SCSA2USB_LUN] & 0x1f) == 0) &&
5065 (len >= SCSA2USB_MAX_INQ_LEN)) {
5066 inq = (struct scsi_inquiry *)data->b_rptr;
5067 dtype = inq->inq_dtype & DTYPE_MASK;
5068 /*
5069 * scsi framework sends zero byte write(10) cmd
5070 * to (Simplified) direct-access devices with
5071 * inquiry version > 2 for reservation changes.
5072 * But some USB devices don't support zero byte
5073 * write(10) even though they have inquiry
5074 * version > 2. Considering scsa2usb driver
5075 * doesn't support reservation and all the
5076 * reservation cmds are being faked, we fake
5077 * the inquiry version to 0 to make scsi
5078 * framework send test unit ready cmd which is
5079 * supported by all the usb devices.
5080 */
5081 if (((dtype == DTYPE_DIRECT) ||
5082 (dtype == DTYPE_RBC)) &&
5083 (inq->inq_ansi > 2)) {
5084 inq->inq_ansi = 0;
5085 }
5086
5087 bzero(&scsa2usbp->scsa2usb_lun_inquiry
5088 [pkt->pkt_address.a_lun],
5089 sizeof (struct scsi_inquiry));
5090 bcopy(data->b_rptr,
5091 &scsa2usbp->scsa2usb_lun_inquiry
5092 [pkt->pkt_address.a_lun], len);
5093 }
5094
5095 USB_DPRINTF_L3(DPRINT_MASK_SCSA,
5096 scsa2usbp->scsa2usb_log_handle,
5097 "scsi inquiry type = 0x%x",
5098 scsa2usbp->scsa2usb_lun_inquiry
5099 [pkt->pkt_address.a_lun].inq_dtype);
5100
5101 cmd->cmd_done = 1;
5102 goto handle_data;
5103
5104 case SCMD_READ_CAPACITY:
5105 cap = (scsa2usb_read_cap_t *)data->b_rptr;
5106
5107 /* Figure out the logical block size */
5108 if ((len >= sizeof (struct scsa2usb_read_cap)) &&
5109 (req->bulk_completion_reason == USB_CR_OK)) {
5110 scsa2usbp->
5111 scsa2usb_lbasize[pkt->pkt_address.a_lun] =
5112 SCSA2USB_MK_32BIT(
5113 cap->scsa2usb_read_cap_blen3,
5114 cap->scsa2usb_read_cap_blen2,
5115 cap->scsa2usb_read_cap_blen1,
5116 cap->scsa2usb_read_cap_blen0);
5117
5118 max_lba = SCSA2USB_MK_32BIT(
5119 cap->scsa2usb_read_cap_lba3,
5120 cap->scsa2usb_read_cap_lba2,
5121 cap->scsa2usb_read_cap_lba1,
5122 cap->scsa2usb_read_cap_lba0);
5123
5124 /*
5125 * Some devices return total logical block
5126 * number instead of highest logical block
5127 * address. Adjust the value by minus 1.
5128 */
5129 if (max_lba > 0 && (scsa2usbp->scsa2usb_attrs &
5130 SCSA2USB_ATTRS_NO_CAP_ADJUST) == 0) {
5131 max_lba -= 1;
5132 cap->scsa2usb_read_cap_lba0 =
5133 (uchar_t)(max_lba & 0xFF);
5134 cap->scsa2usb_read_cap_lba1 =
5135 (uchar_t)(max_lba >> 8 & 0xFF);
5136 cap->scsa2usb_read_cap_lba2 =
5137 (uchar_t)(max_lba >> 16 & 0xFF);
5138 cap->scsa2usb_read_cap_lba3 =
5139 (uchar_t)(max_lba >> 24 & 0xFF);
5140 }
5141
5142 USB_DPRINTF_L2(DPRINT_MASK_SCSA,
5143 scsa2usbp->scsa2usb_log_handle,
5144 "bytes in each logical block=0x%lx,"
5145 "number of total logical blocks=0x%x",
5146 scsa2usbp->
5147 scsa2usb_lbasize[pkt->pkt_address.a_lun],
5148 max_lba + 1);
5149 }
5150 cmd->cmd_done = 1;
5151 goto handle_data;
5152
5153 case SCMD_REQUEST_SENSE:
5154 p = data->b_rptr;
5155 USB_DPRINTF_L2(DPRINT_MASK_SCSA,
5156 scsa2usbp->scsa2usb_log_handle,
5157 "cdb: %x rqsense: "
5158 "%x %x %x %x %x %x %x %x %x %x\n\t"
5159 "%x %x %x %x %x %x %x %x %x %x",
5160 cmd->cmd_cdb[0],
5161 p[0], p[1], p[2], p[3], p[4],
5162 p[5], p[6], p[7], p[8], p[9],
5163 p[10], p[11], p[12], p[13], p[14],
5164 p[15], p[16], p[17], p[18], p[19]);
5165
5166 scsa2usbp->scsa2usb_last_cmd.status = p[2];
5167 cmd->cmd_done = 1;
5168 /* FALLTHROUGH */
5169
5170 default:
5171 handle_data:
5172 if (bp && len && (cmd->cmd_dir == USB_EP_DIR_IN)) {
5173 /*
5174 * we don't have to copy the data, the
5175 * data pointers for the mblk_t for
5176 * the bulk-in xfer points to the
5177 * struct buf * data.
5178 */
5179 cmd->cmd_offset += len;
5180 }
5181
5182 USB_DPRINTF_L3(DPRINT_MASK_SCSA,
5183 scsa2usbp->scsa2usb_log_handle,
5184 "len = 0x%x total = 0x%lx offset = 0x%lx",
5185 len, cmd->cmd_total_xfercount, cmd->cmd_offset);
5186
5187 /*
5188 * update total_xfercount now but it may be
5189 * adjusted after receiving the residue
5190 */
5191 cmd->cmd_total_xfercount -= len;
5192
5193 if ((req->bulk_completion_reason != USB_CR_OK) ||
5194 (cmd->cmd_resid_xfercount != 0) ||
5195 (cmd->cmd_total_xfercount == 0)) {
5196 /* set pkt_resid to total to be sure */
5197 pkt->pkt_resid = cmd->cmd_total_xfercount;
5198 cmd->cmd_done = 1;
5199 }
5200
5201 break;
5202 }
5203 } else {
5204 if (cmd->cmd_dir == USB_EP_DIR_OUT) {
5205 if (cmd->cmd_total_xfercount == 0) {
5206 cmd->cmd_done = 1;
5207 }
5208 }
5209 }
5210 }
5211
5212
5213 /*
5214 * scsa2usb_init_bulk_req:
5215 * Allocate (synchronously) and fill in a bulk-request
5216 */
5217 usb_bulk_req_t *
scsa2usb_init_bulk_req(scsa2usb_state_t * scsa2usbp,size_t length,uint_t timeout,usb_req_attrs_t attrs,usb_flags_t flags)5218 scsa2usb_init_bulk_req(scsa2usb_state_t *scsa2usbp, size_t length,
5219 uint_t timeout, usb_req_attrs_t attrs, usb_flags_t flags)
5220 {
5221 usb_bulk_req_t *req;
5222
5223 ASSERT(mutex_owned(&scsa2usbp->scsa2usb_mutex));
5224
5225 req = usb_alloc_bulk_req(scsa2usbp->scsa2usb_dip, length,
5226 flags | USB_FLAGS_SLEEP);
5227
5228 req->bulk_len = (uint_t)length; /* xfer length */
5229 req->bulk_timeout = scsa2usb_bulk_timeout(timeout); /* xfer timeout */
5230 req->bulk_attributes = attrs; /* xfer attrs */
5231 req->bulk_client_private = (usb_opaque_t)scsa2usbp; /* statep */
5232
5233 return (req);
5234 }
5235
5236
5237 /*
5238 * scsa2usb_bulk_timeout:
5239 * ensure that bulk requests do not have infinite timeout values
5240 */
5241 int
scsa2usb_bulk_timeout(int timeout)5242 scsa2usb_bulk_timeout(int timeout)
5243 {
5244 return ((timeout == 0) ? scsa2usb_long_timeout : timeout);
5245 }
5246
5247
5248 /*
5249 * scsa2usb_clear_ept_stall:
5250 * clear endpoint stall and reset pipes
5251 */
5252 int
scsa2usb_clear_ept_stall(scsa2usb_state_t * scsa2usbp,uint_t ept_addr,usb_pipe_handle_t ph,char * what)5253 scsa2usb_clear_ept_stall(scsa2usb_state_t *scsa2usbp, uint_t ept_addr,
5254 usb_pipe_handle_t ph, char *what)
5255 {
5256 int rval;
5257 dev_info_t *dip = scsa2usbp->scsa2usb_dip;
5258
5259 ASSERT(mutex_owned(&scsa2usbp->scsa2usb_mutex));
5260 if (!(SCSA2USB_DEVICE_ACCESS_OK(scsa2usbp))) {
5261
5262 return (USB_FAILURE);
5263 }
5264
5265 mutex_exit(&scsa2usbp->scsa2usb_mutex);
5266 rval = usb_clr_feature(dip, USB_DEV_REQ_RCPT_EP, 0, ept_addr,
5267 USB_FLAGS_SLEEP, NULL, NULL);
5268
5269 usb_pipe_reset(dip, ph, USB_FLAGS_SLEEP, NULL, NULL);
5270
5271 mutex_enter(&scsa2usbp->scsa2usb_mutex);
5272 USB_DPRINTF_L4(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
5273 "scsa2usb_clear_ept_stall: on %s: ept = 0x%x rval = %d",
5274 what, ept_addr, rval);
5275
5276 return (rval);
5277 }
5278
5279
5280 /*
5281 * scsa2usb_pkt_completion:
5282 * Handle pkt completion.
5283 */
5284 static void
scsa2usb_pkt_completion(scsa2usb_state_t * scsa2usbp,struct scsi_pkt * pkt)5285 scsa2usb_pkt_completion(scsa2usb_state_t *scsa2usbp, struct scsi_pkt *pkt)
5286 {
5287 scsa2usb_cmd_t *cmd = PKT2CMD(pkt);
5288 size_t len;
5289
5290 ASSERT(pkt);
5291 ASSERT(mutex_owned(&scsa2usbp->scsa2usb_mutex));
5292
5293 USB_DPRINTF_L3(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
5294 "scsa2usb_pkt_completion:\n\tscsa2usbp = 0x%p "
5295 "reason=%d, status=%d state=0x%x stats=0x%x resid=0x%lx",
5296 (void *)scsa2usbp, pkt->pkt_reason, *(pkt->pkt_scbp),
5297 pkt->pkt_state, pkt->pkt_statistics, pkt->pkt_resid);
5298
5299 if (pkt->pkt_reason == CMD_CMPLT) {
5300 pkt->pkt_state |= STATE_GOT_BUS | STATE_GOT_TARGET |
5301 STATE_SENT_CMD | STATE_GOT_STATUS;
5302 if (cmd->cmd_xfercount) {
5303 pkt->pkt_state |= STATE_XFERRED_DATA;
5304 }
5305 } else {
5306 pkt->pkt_state |= STATE_GOT_BUS | STATE_GOT_TARGET |
5307 STATE_SENT_CMD;
5308 }
5309
5310 /*
5311 * don't zap the current state when in panic as this will
5312 * make debugging harder
5313 */
5314 if ((scsa2usbp->scsa2usb_cur_pkt == pkt) && !ddi_in_panic()) {
5315 SCSA2USB_RESET_CUR_PKT(scsa2usbp);
5316
5317 len = sizeof (scsa2usbp->scsa2usb_last_cmd.cdb);
5318 bzero(scsa2usbp->scsa2usb_last_cmd.cdb, len);
5319
5320 len = (len < cmd->cmd_cdblen) ? len : cmd->cmd_cdblen;
5321 USB_DPRINTF_L3(DPRINT_MASK_SCSA,
5322 scsa2usbp->scsa2usb_log_handle,
5323 "scsa2usb_pkt_completion: save last cmd, len=%ld", len);
5324
5325 /* save the last command */
5326 bcopy(pkt->pkt_cdbp, scsa2usbp->scsa2usb_last_cmd.cdb, len);
5327
5328 /* reset the scsa2usb_last_cmd.status value */
5329 if ((pkt->pkt_cdbp[0] != SCMD_REQUEST_SENSE) &&
5330 (pkt->pkt_cdbp[0] != SCMD_INQUIRY)) {
5331 scsa2usbp->scsa2usb_last_cmd.status = 0;
5332 }
5333
5334 /*
5335 * set pkt state to NONE *before* calling back as the target
5336 * driver will immediately submit the next packet
5337 */
5338 scsa2usbp->scsa2usb_pkt_state = SCSA2USB_PKT_NONE;
5339 }
5340
5341 if (pkt->pkt_comp) {
5342 mutex_exit(&scsa2usbp->scsa2usb_mutex);
5343 scsi_hba_pkt_comp(pkt);
5344 mutex_enter(&scsa2usbp->scsa2usb_mutex);
5345
5346 }
5347 }
5348
5349
5350 /*
5351 * Even handling functions:
5352 *
5353 * scsa2usb_reconnect_event_cb:
5354 * event handling
5355 */
5356 static int
scsa2usb_reconnect_event_cb(dev_info_t * dip)5357 scsa2usb_reconnect_event_cb(dev_info_t *dip)
5358 {
5359 scsa2usb_state_t *scsa2usbp =
5360 ddi_get_soft_state(scsa2usb_statep, ddi_get_instance(dip));
5361 dev_info_t *cdip;
5362 int circ;
5363 int rval = USB_SUCCESS;
5364
5365 ASSERT(scsa2usbp != NULL);
5366
5367 USB_DPRINTF_L4(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
5368 "scsa2usb_reconnect_event_cb: dip = 0x%p", (void *)dip);
5369
5370 scsa2usb_restore_device_state(dip, scsa2usbp);
5371
5372 USB_DPRINTF_L0(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
5373 "Reinserted device is accessible again.");
5374
5375 ndi_devi_enter(dip, &circ);
5376 for (cdip = ddi_get_child(dip); cdip; ) {
5377 dev_info_t *next = ddi_get_next_sibling(cdip);
5378
5379 mutex_enter(&DEVI(cdip)->devi_lock);
5380 DEVI_SET_DEVICE_REINSERTED(cdip);
5381 mutex_exit(&DEVI(cdip)->devi_lock);
5382
5383 cdip = next;
5384 }
5385 ndi_devi_exit(dip, circ);
5386
5387 /* stop suppressing warnings */
5388 mutex_enter(&scsa2usbp->scsa2usb_mutex);
5389 scsa2usbp->scsa2usb_warning_given = B_FALSE;
5390 mutex_exit(&scsa2usbp->scsa2usb_mutex);
5391
5392 if (scsa2usbp->scsa2usb_ugen_hdl) {
5393 rval = usb_ugen_reconnect_ev_cb(
5394 scsa2usbp->scsa2usb_ugen_hdl);
5395 }
5396
5397 return (rval);
5398 }
5399
5400
5401 /*
5402 * scsa2usb_all_waitQs_empty:
5403 * check if all waitQs empty
5404 */
5405 static int
scsa2usb_all_waitQs_empty(scsa2usb_state_t * scsa2usbp)5406 scsa2usb_all_waitQs_empty(scsa2usb_state_t *scsa2usbp)
5407 {
5408 uint_t lun;
5409
5410 for (lun = 0; lun < SCSA2USB_MAX_LUNS; lun++) {
5411 if (usba_list_entry_count(
5412 &scsa2usbp->scsa2usb_waitQ[lun])) {
5413
5414 return (USB_FAILURE);
5415 }
5416 }
5417
5418 return (USB_SUCCESS);
5419 }
5420
5421
5422 /*
5423 * scsa2usb_disconnect_event_cb:
5424 * callback for disconnect events
5425 */
5426 static int
scsa2usb_disconnect_event_cb(dev_info_t * dip)5427 scsa2usb_disconnect_event_cb(dev_info_t *dip)
5428 {
5429 scsa2usb_state_t *scsa2usbp =
5430 ddi_get_soft_state(scsa2usb_statep, ddi_get_instance(dip));
5431 dev_info_t *cdip;
5432 int circ, i;
5433 int rval = USB_SUCCESS;
5434
5435 ASSERT(scsa2usbp != NULL);
5436
5437 USB_DPRINTF_L4(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
5438 "scsa2usb_disconnect_event_cb: dip = 0x%p", (void *)dip);
5439
5440 mutex_enter(&scsa2usbp->scsa2usb_mutex);
5441 scsa2usbp->scsa2usb_dev_state = USB_DEV_DISCONNECTED;
5442
5443 /*
5444 * wait till the work thread is done, carry on regardless
5445 * if not.
5446 */
5447 for (i = 0; i < SCSA2USB_DRAIN_TIMEOUT; i++) {
5448 if ((scsa2usbp->scsa2usb_work_thread_id == NULL) &&
5449 (scsa2usbp->scsa2usb_cur_pkt == NULL) &&
5450 (scsa2usb_all_waitQs_empty(scsa2usbp) ==
5451 USB_SUCCESS)) {
5452
5453 break;
5454 }
5455 mutex_exit(&scsa2usbp->scsa2usb_mutex);
5456 delay(drv_usectohz(1000000));
5457 mutex_enter(&scsa2usbp->scsa2usb_mutex);
5458 }
5459 mutex_exit(&scsa2usbp->scsa2usb_mutex);
5460
5461 ndi_devi_enter(dip, &circ);
5462 for (cdip = ddi_get_child(dip); cdip; ) {
5463 dev_info_t *next = ddi_get_next_sibling(cdip);
5464
5465 mutex_enter(&DEVI(cdip)->devi_lock);
5466 DEVI_SET_DEVICE_REMOVED(cdip);
5467 mutex_exit(&DEVI(cdip)->devi_lock);
5468
5469 cdip = next;
5470 }
5471 ndi_devi_exit(dip, circ);
5472
5473 if (scsa2usbp->scsa2usb_ugen_hdl) {
5474 rval = usb_ugen_disconnect_ev_cb(
5475 scsa2usbp->scsa2usb_ugen_hdl);
5476 }
5477
5478 return (rval);
5479 }
5480
5481
5482 /*
5483 * PM support
5484 *
5485 * scsa2usb_create_pm_components:
5486 * create the pm components required for power management
5487 * no mutex is need when calling USBA interfaces
5488 */
5489 static void
scsa2usb_create_pm_components(dev_info_t * dip,scsa2usb_state_t * scsa2usbp)5490 scsa2usb_create_pm_components(dev_info_t *dip, scsa2usb_state_t *scsa2usbp)
5491 {
5492 scsa2usb_power_t *pm;
5493 uint_t pwr_states;
5494
5495 ASSERT(mutex_owned(&scsa2usbp->scsa2usb_mutex));
5496
5497 USB_DPRINTF_L4(DPRINT_MASK_PM, scsa2usbp->scsa2usb_log_handle,
5498 "scsa2usb_create_pm_components: dip = 0x%p, scsa2usbp = 0x%p",
5499 (void *)dip, (void *)scsa2usbp);
5500
5501 /*
5502 * determine if this device is on the blacklist
5503 * or if a conf file entry has disabled PM
5504 */
5505 if ((scsa2usbp->scsa2usb_attrs & SCSA2USB_ATTRS_PM) == 0) {
5506 USB_DPRINTF_L2(DPRINT_MASK_PM, scsa2usbp->scsa2usb_log_handle,
5507 "device cannot be power managed");
5508
5509 return;
5510 }
5511
5512 /* Allocate the PM state structure */
5513 pm = kmem_zalloc(sizeof (scsa2usb_power_t), KM_SLEEP);
5514
5515 scsa2usbp->scsa2usb_pm = pm;
5516 pm->scsa2usb_current_power = USB_DEV_OS_FULL_PWR;
5517 mutex_exit(&scsa2usbp->scsa2usb_mutex);
5518
5519 if (usb_create_pm_components(dip, &pwr_states) ==
5520 USB_SUCCESS) {
5521 if (usb_handle_remote_wakeup(dip,
5522 USB_REMOTE_WAKEUP_ENABLE) == USB_SUCCESS) {
5523 pm->scsa2usb_wakeup_enabled = 1;
5524 }
5525
5526 mutex_enter(&scsa2usbp->scsa2usb_mutex);
5527 pm->scsa2usb_pwr_states = (uint8_t)pwr_states;
5528 scsa2usb_raise_power(scsa2usbp);
5529 mutex_exit(&scsa2usbp->scsa2usb_mutex);
5530 }
5531
5532 mutex_enter(&scsa2usbp->scsa2usb_mutex);
5533 }
5534
5535
5536 /*
5537 * scsa2usb_raise_power:
5538 * check if the device is using full power or not
5539 */
5540 static void
scsa2usb_raise_power(scsa2usb_state_t * scsa2usbp)5541 scsa2usb_raise_power(scsa2usb_state_t *scsa2usbp)
5542 {
5543 USB_DPRINTF_L4(DPRINT_MASK_PM, scsa2usbp->scsa2usb_log_handle,
5544 "scsa2usb_raise_power:");
5545
5546 ASSERT(mutex_owned(&scsa2usbp->scsa2usb_mutex));
5547
5548 if (scsa2usbp->scsa2usb_pm) {
5549 scsa2usb_pm_busy_component(scsa2usbp);
5550 if (scsa2usbp->scsa2usb_pm->scsa2usb_current_power !=
5551 USB_DEV_OS_FULL_PWR) {
5552 mutex_exit(&scsa2usbp->scsa2usb_mutex);
5553 (void) pm_raise_power(scsa2usbp->scsa2usb_dip,
5554 0, USB_DEV_OS_FULL_PWR);
5555 mutex_enter(&scsa2usbp->scsa2usb_mutex);
5556 }
5557 }
5558 }
5559
5560
5561 /*
5562 * functions to handle power transition for OS levels 0 -> 3
5563 */
5564 static int
scsa2usb_pwrlvl0(scsa2usb_state_t * scsa2usbp)5565 scsa2usb_pwrlvl0(scsa2usb_state_t *scsa2usbp)
5566 {
5567 int rval;
5568
5569 switch (scsa2usbp->scsa2usb_dev_state) {
5570 case USB_DEV_ONLINE:
5571 /* Deny the powerdown request if the device is busy */
5572 if (scsa2usbp->scsa2usb_pm->scsa2usb_pm_busy != 0) {
5573
5574 return (USB_FAILURE);
5575 }
5576
5577 /*
5578 * stop polling on interrupt pipe
5579 */
5580 scsa2usb_cbi_stop_intr_polling(scsa2usbp);
5581
5582 /* Issue USB D3 command to the device here */
5583 rval = usb_set_device_pwrlvl3(scsa2usbp->scsa2usb_dip);
5584 ASSERT(rval == USB_SUCCESS);
5585
5586 scsa2usbp->scsa2usb_dev_state = USB_DEV_PWRED_DOWN;
5587
5588 /* FALLTHRU */
5589 case USB_DEV_DISCONNECTED:
5590 case USB_DEV_SUSPENDED:
5591 case USB_DEV_PWRED_DOWN:
5592 default:
5593 scsa2usbp->scsa2usb_pm->scsa2usb_current_power =
5594 USB_DEV_OS_PWR_OFF;
5595
5596 return (USB_SUCCESS);
5597 }
5598 }
5599
5600
5601 static int
scsa2usb_pwrlvl1(scsa2usb_state_t * scsa2usbp)5602 scsa2usb_pwrlvl1(scsa2usb_state_t *scsa2usbp)
5603 {
5604 int rval;
5605
5606 /* Issue USB D2 command to the device here */
5607 rval = usb_set_device_pwrlvl2(scsa2usbp->scsa2usb_dip);
5608 ASSERT(rval == USB_SUCCESS);
5609
5610 return (DDI_FAILURE);
5611 }
5612
5613
5614 static int
scsa2usb_pwrlvl2(scsa2usb_state_t * scsa2usbp)5615 scsa2usb_pwrlvl2(scsa2usb_state_t *scsa2usbp)
5616 {
5617 int rval;
5618
5619 /* Issue USB D1 command to the device here */
5620 rval = usb_set_device_pwrlvl1(scsa2usbp->scsa2usb_dip);
5621 ASSERT(rval == USB_SUCCESS);
5622
5623 return (DDI_FAILURE);
5624 }
5625
5626
5627 static int
scsa2usb_pwrlvl3(scsa2usb_state_t * scsa2usbp)5628 scsa2usb_pwrlvl3(scsa2usb_state_t *scsa2usbp)
5629 {
5630 int rval;
5631
5632 /*
5633 * PM framework tries to put us in full power
5634 * during system shutdown. If we are disconnected
5635 * return success anyways
5636 */
5637 if (scsa2usbp->scsa2usb_dev_state != USB_DEV_DISCONNECTED) {
5638 /* Issue USB D0 command to the device here */
5639 rval = usb_set_device_pwrlvl0(scsa2usbp->scsa2usb_dip);
5640 ASSERT(rval == USB_SUCCESS);
5641
5642 scsa2usbp->scsa2usb_dev_state = USB_DEV_ONLINE;
5643 }
5644 scsa2usbp->scsa2usb_pm->scsa2usb_current_power = USB_DEV_OS_FULL_PWR;
5645
5646 return (DDI_SUCCESS);
5647 }
5648
5649
5650 /*
5651 * scsa2usb_power:
5652 * power entry point
5653 */
5654 /* ARGSUSED */
5655 static int
scsa2usb_power(dev_info_t * dip,int comp,int level)5656 scsa2usb_power(dev_info_t *dip, int comp, int level)
5657 {
5658 scsa2usb_state_t *scsa2usbp;
5659 scsa2usb_power_t *pm;
5660 int rval = DDI_FAILURE;
5661
5662 scsa2usbp = ddi_get_soft_state(scsa2usb_statep, ddi_get_instance(dip));
5663
5664 USB_DPRINTF_L3(DPRINT_MASK_PM, scsa2usbp->scsa2usb_log_handle,
5665 "scsa2usb_power: Begin scsa2usbp (%p): level = %d",
5666 (void *)scsa2usbp, level);
5667
5668 mutex_enter(&scsa2usbp->scsa2usb_mutex);
5669 if (SCSA2USB_BUSY(scsa2usbp)) {
5670 USB_DPRINTF_L2(DPRINT_MASK_PM, scsa2usbp->scsa2usb_log_handle,
5671 "scsa2usb_power: busy");
5672 mutex_exit(&scsa2usbp->scsa2usb_mutex);
5673
5674 return (rval);
5675 }
5676
5677 pm = scsa2usbp->scsa2usb_pm;
5678 if (pm == NULL) {
5679 USB_DPRINTF_L2(DPRINT_MASK_PM, scsa2usbp->scsa2usb_log_handle,
5680 "scsa2usb_power: pm NULL");
5681 mutex_exit(&scsa2usbp->scsa2usb_mutex);
5682
5683 return (rval);
5684 }
5685
5686 /* check if we are transitioning to a legal power level */
5687 if (USB_DEV_PWRSTATE_OK(pm->scsa2usb_pwr_states, level)) {
5688 USB_DPRINTF_L2(DPRINT_MASK_PM, scsa2usbp->scsa2usb_log_handle,
5689 "scsa2usb_power: illegal power level = %d "
5690 "pwr_states: %x", level, pm->scsa2usb_pwr_states);
5691 mutex_exit(&scsa2usbp->scsa2usb_mutex);
5692
5693 return (rval);
5694 }
5695
5696 switch (level) {
5697 case USB_DEV_OS_PWR_OFF :
5698 rval = scsa2usb_pwrlvl0(scsa2usbp);
5699 break;
5700 case USB_DEV_OS_PWR_1 :
5701 rval = scsa2usb_pwrlvl1(scsa2usbp);
5702 break;
5703 case USB_DEV_OS_PWR_2 :
5704 rval = scsa2usb_pwrlvl2(scsa2usbp);
5705 break;
5706 case USB_DEV_OS_FULL_PWR :
5707 rval = scsa2usb_pwrlvl3(scsa2usbp);
5708 break;
5709 }
5710
5711 mutex_exit(&scsa2usbp->scsa2usb_mutex);
5712
5713 return ((rval == USB_SUCCESS) ? DDI_SUCCESS : DDI_FAILURE);
5714 }
5715
5716
5717 static void
scsa2usb_pm_busy_component(scsa2usb_state_t * scsa2usbp)5718 scsa2usb_pm_busy_component(scsa2usb_state_t *scsa2usbp)
5719 {
5720 ASSERT(mutex_owned(&scsa2usbp->scsa2usb_mutex));
5721
5722 if (scsa2usbp->scsa2usb_pm) {
5723 scsa2usbp->scsa2usb_pm->scsa2usb_pm_busy++;
5724
5725 USB_DPRINTF_L4(DPRINT_MASK_PM,
5726 scsa2usbp->scsa2usb_log_handle,
5727 "scsa2usb_pm_busy_component: %d",
5728 scsa2usbp->scsa2usb_pm->scsa2usb_pm_busy);
5729
5730 mutex_exit(&scsa2usbp->scsa2usb_mutex);
5731
5732 if (pm_busy_component(scsa2usbp->scsa2usb_dip, 0) !=
5733 DDI_SUCCESS) {
5734 mutex_enter(&scsa2usbp->scsa2usb_mutex);
5735 ASSERT(scsa2usbp->scsa2usb_pm->scsa2usb_pm_busy > 0);
5736 scsa2usbp->scsa2usb_pm->scsa2usb_pm_busy--;
5737
5738 USB_DPRINTF_L2(DPRINT_MASK_PM,
5739 scsa2usbp->scsa2usb_log_handle,
5740 "scsa2usb_pm_busy_component failed: %d",
5741 scsa2usbp->scsa2usb_pm->scsa2usb_pm_busy);
5742
5743 return;
5744 }
5745 mutex_enter(&scsa2usbp->scsa2usb_mutex);
5746 }
5747 }
5748
5749
5750 /*
5751 * scsa2usb_pm_idle_component:
5752 * idles the device
5753 */
5754 static void
scsa2usb_pm_idle_component(scsa2usb_state_t * scsa2usbp)5755 scsa2usb_pm_idle_component(scsa2usb_state_t *scsa2usbp)
5756 {
5757 ASSERT(!mutex_owned(&scsa2usbp->scsa2usb_mutex));
5758
5759 if (scsa2usbp->scsa2usb_pm) {
5760 if (pm_idle_component(scsa2usbp->scsa2usb_dip, 0) ==
5761 DDI_SUCCESS) {
5762 mutex_enter(&scsa2usbp->scsa2usb_mutex);
5763 ASSERT(scsa2usbp->scsa2usb_pm->scsa2usb_pm_busy > 0);
5764 scsa2usbp->scsa2usb_pm->scsa2usb_pm_busy--;
5765
5766 USB_DPRINTF_L4(DPRINT_MASK_PM,
5767 scsa2usbp->scsa2usb_log_handle,
5768 "scsa2usb_pm_idle_component: %d",
5769 scsa2usbp->scsa2usb_pm->scsa2usb_pm_busy);
5770
5771 mutex_exit(&scsa2usbp->scsa2usb_mutex);
5772 }
5773 }
5774 }
5775
5776
5777 #ifdef DEBUG
5778 /*
5779 * scsa2usb_print_cdb:
5780 * prints CDB
5781 */
5782 void
scsa2usb_print_cdb(scsa2usb_state_t * scsa2usbp,scsa2usb_cmd_t * cmd)5783 scsa2usb_print_cdb(scsa2usb_state_t *scsa2usbp, scsa2usb_cmd_t *cmd)
5784 {
5785 uchar_t *c = (uchar_t *)&cmd->cmd_cdb;
5786
5787 USB_DPRINTF_L3(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
5788 "cmd = 0x%p opcode=%s "
5789 "cdb: %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x",
5790 (void *)cmd,
5791 scsi_cname(cmd->cmd_cdb[SCSA2USB_OPCODE], scsa2usb_cmds),
5792 c[0], c[1], c[2], c[3], c[4], c[5], c[6], c[7], c[8],
5793 c[9], c[10], c[11], c[12], c[13], c[14], c[15]);
5794 }
5795 #endif /* DEBUG */
5796
5797
5798 #ifdef SCSA2USB_BULK_ONLY_TEST
5799 /*
5800 * scsa2usb_test_mblk:
5801 * This function sends a dummy data mblk_t to simulate
5802 * the following test cases: 5 and 11.
5803 */
5804 static void
scsa2usb_test_mblk(scsa2usb_state_t * scsa2usbp,boolean_t large)5805 scsa2usb_test_mblk(scsa2usb_state_t *scsa2usbp, boolean_t large)
5806 {
5807 int i, rval;
5808 size_t len;
5809 usb_flags_t flags = USB_FLAGS_SLEEP;
5810 usb_bulk_req_t *req;
5811
5812 ASSERT(mutex_owned(&scsa2usbp->scsa2usb_mutex));
5813
5814 /* should we create a larger mblk? */
5815 len = (large == B_TRUE) ? DEV_BSIZE : USB_BULK_CBWCMD_LEN;
5816
5817 req = scsa2usb_init_bulk_req(scsa2usbp, len,
5818 SCSA2USB_BULK_PIPE_TIMEOUT, 0, flags);
5819
5820 /* fill up the data mblk */
5821 for (i = 0; i < len; i++) {
5822 *req->bulk_data->b_wptr++ = (uchar_t)i;
5823 }
5824
5825 mutex_exit(&scsa2usbp->scsa2usb_mutex);
5826 ASSERT(req->bulk_timeout);
5827 rval = usb_pipe_bulk_xfer(scsa2usbp->scsa2usb_bulkout_pipe, req, flags);
5828 mutex_enter(&scsa2usbp->scsa2usb_mutex);
5829
5830 USB_DPRINTF_L1(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
5831 "scsa2usb_test_mblk: Sent Data Out rval = 0x%x", rval);
5832
5833 usb_free_bulk_req(req);
5834 }
5835 #endif /* SCSA2USB_BULK_ONLY_TEST */
5836