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 2009 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
24 */
25
26
27 /*
28 * 1394 mass storage HBA driver
29 */
30
31 #include <sys/param.h>
32 #include <sys/errno.h>
33 #include <sys/cred.h>
34 #include <sys/conf.h>
35 #include <sys/modctl.h>
36 #include <sys/stat.h>
37 #include <sys/byteorder.h>
38 #include <sys/ddi.h>
39 #include <sys/sunddi.h>
40
41 #include <sys/1394/targets/scsa1394/impl.h>
42 #include <sys/1394/targets/scsa1394/cmd.h>
43
44 /* DDI/DKI entry points */
45 static int scsa1394_attach(dev_info_t *, ddi_attach_cmd_t);
46 static int scsa1394_detach(dev_info_t *, ddi_detach_cmd_t);
47 static int scsa1394_power(dev_info_t *, int, int);
48 static int scsa1394_cpr_suspend(dev_info_t *);
49 static void scsa1394_cpr_resume(dev_info_t *);
50
51 /* configuration routines */
52 static void scsa1394_cleanup(scsa1394_state_t *, int);
53 static int scsa1394_attach_1394(scsa1394_state_t *);
54 static void scsa1394_detach_1394(scsa1394_state_t *);
55 static int scsa1394_attach_threads(scsa1394_state_t *);
56 static void scsa1394_detach_threads(scsa1394_state_t *);
57 static int scsa1394_attach_scsa(scsa1394_state_t *);
58 static void scsa1394_detach_scsa(scsa1394_state_t *);
59 static int scsa1394_create_cmd_cache(scsa1394_state_t *);
60 static void scsa1394_destroy_cmd_cache(scsa1394_state_t *);
61 static int scsa1394_add_events(scsa1394_state_t *);
62 static void scsa1394_remove_events(scsa1394_state_t *);
63
64 /* device configuration */
65 static int scsa1394_scsi_bus_config(dev_info_t *, uint_t,
66 ddi_bus_config_op_t, void *, dev_info_t **);
67 static int scsa1394_scsi_bus_unconfig(dev_info_t *, uint_t,
68 ddi_bus_config_op_t, void *);
69 static void scsa1394_create_children(scsa1394_state_t *);
70 static void scsa1394_bus_reset(dev_info_t *, ddi_eventcookie_t, void *,
71 void *);
72 static void scsa1394_disconnect(dev_info_t *, ddi_eventcookie_t, void *,
73 void *);
74 static void scsa1394_reconnect(dev_info_t *, ddi_eventcookie_t, void *,
75 void *);
76
77 /* SCSA HBA entry points */
78 static int scsa1394_scsi_tgt_init(dev_info_t *, dev_info_t *,
79 scsi_hba_tran_t *, struct scsi_device *);
80 static void scsa1394_scsi_tgt_free(dev_info_t *, dev_info_t *,
81 scsi_hba_tran_t *, struct scsi_device *);
82 static int scsa1394_scsi_tgt_probe(struct scsi_device *, int (*)());
83 static int scsa1394_probe_g0_nodata(struct scsi_device *, int (*)(),
84 uchar_t, uint_t, uint_t);
85 static int scsa1394_probe_tran(struct scsi_pkt *);
86 static struct scsi_pkt *scsa1394_scsi_init_pkt(struct scsi_address *,
87 struct scsi_pkt *, struct buf *, int, int, int, int,
88 int (*)(), caddr_t arg);
89 static void scsa1394_scsi_destroy_pkt(struct scsi_address *,
90 struct scsi_pkt *);
91 static int scsa1394_scsi_start(struct scsi_address *, struct scsi_pkt *);
92 static int scsa1394_scsi_abort(struct scsi_address *, struct scsi_pkt *);
93 static int scsa1394_scsi_reset(struct scsi_address *, int);
94 static int scsa1394_scsi_getcap(struct scsi_address *, char *, int);
95 static int scsa1394_scsi_setcap(struct scsi_address *, char *, int, int);
96 static void scsa1394_scsi_dmafree(struct scsi_address *, struct scsi_pkt *);
97 static void scsa1394_scsi_sync_pkt(struct scsi_address *,
98 struct scsi_pkt *);
99
100 /* pkt resource allocation routines */
101 static int scsa1394_cmd_cache_constructor(void *, void *, int);
102 static void scsa1394_cmd_cache_destructor(void *, void *);
103 static int scsa1394_cmd_ext_alloc(scsa1394_state_t *, scsa1394_cmd_t *,
104 int);
105 static void scsa1394_cmd_ext_free(scsa1394_state_t *, scsa1394_cmd_t *);
106 static int scsa1394_cmd_cdb_dma_alloc(scsa1394_state_t *, scsa1394_cmd_t *,
107 int, int (*)(), caddr_t);
108 static void scsa1394_cmd_cdb_dma_free(scsa1394_state_t *, scsa1394_cmd_t *);
109 static int scsa1394_cmd_buf_dma_alloc(scsa1394_state_t *, scsa1394_cmd_t *,
110 int, int (*)(), caddr_t, struct buf *);
111 static void scsa1394_cmd_buf_dma_free(scsa1394_state_t *, scsa1394_cmd_t *);
112 static int scsa1394_cmd_dmac2seg(scsa1394_state_t *, scsa1394_cmd_t *,
113 ddi_dma_cookie_t *, uint_t, int);
114 static void scsa1394_cmd_seg_free(scsa1394_state_t *, scsa1394_cmd_t *);
115 static int scsa1394_cmd_pt_dma_alloc(scsa1394_state_t *, scsa1394_cmd_t *,
116 int (*)(), caddr_t, int);
117 static void scsa1394_cmd_pt_dma_free(scsa1394_state_t *, scsa1394_cmd_t *);
118 static int scsa1394_cmd_buf_addr_alloc(scsa1394_state_t *,
119 scsa1394_cmd_t *);
120 static void scsa1394_cmd_buf_addr_free(scsa1394_state_t *,
121 scsa1394_cmd_t *);
122 static int scsa1394_cmd_buf_dma_move(scsa1394_state_t *, scsa1394_cmd_t *);
123
124
125 /* pkt and data transfer routines */
126 static void scsa1394_prepare_pkt(scsa1394_state_t *, struct scsi_pkt *);
127 static void scsa1394_cmd_fill_cdb(scsa1394_lun_t *, scsa1394_cmd_t *);
128 static void scsa1394_cmd_fill_cdb_rbc(scsa1394_lun_t *, scsa1394_cmd_t *);
129 static void scsa1394_cmd_fill_cdb_other(scsa1394_lun_t *, scsa1394_cmd_t *);
130 static void scsa1394_cmd_fill_cdb_len(scsa1394_cmd_t *, int);
131 static void scsa1394_cmd_fill_cdb_lba(scsa1394_cmd_t *, int);
132 static void scsa1394_cmd_fill_12byte_cdb_len(scsa1394_cmd_t *, int);
133 static void scsa1394_cmd_fill_read_cd_cdb_len(scsa1394_cmd_t *, int);
134 static int scsa1394_cmd_read_cd_blk_size(uchar_t);
135 static int scsa1394_cmd_fake_mode_sense(scsa1394_state_t *,
136 scsa1394_cmd_t *);
137 static int scsa1394_cmd_fake_inquiry(scsa1394_state_t *, scsa1394_cmd_t *);
138 static int scsa1394_cmd_fake_comp(scsa1394_state_t *, scsa1394_cmd_t *);
139 static int scsa1394_cmd_setup_next_xfer(scsa1394_lun_t *,
140 scsa1394_cmd_t *);
141 static void scsa1394_cmd_adjust_cdb(scsa1394_lun_t *, scsa1394_cmd_t *);
142 static void scsa1394_cmd_status_wrka(scsa1394_lun_t *, scsa1394_cmd_t *);
143
144 /* other routines */
145 static boolean_t scsa1394_is_my_child(dev_info_t *);
146 static void * scsa1394_kmem_realloc(void *, int, int, size_t, int);
147
148 static void *scsa1394_statep;
149 #define SCSA1394_INST2STATE(inst) (ddi_get_soft_state(scsa1394_statep, inst))
150
151 static struct cb_ops scsa1394_cb_ops = {
152 nodev, /* open */
153 nodev, /* close */
154 nodev, /* strategy */
155 nodev, /* print */
156 nodev, /* dump */
157 nodev, /* read */
158 nodev, /* write */
159 NULL, /* ioctl */
160 nodev, /* devmap */
161 nodev, /* mmap */
162 nodev, /* segmap */
163 nochpoll, /* poll */
164 ddi_prop_op, /* prop_op */
165 NULL, /* stream */
166 D_MP, /* cb_flag */
167 CB_REV, /* rev */
168 nodev, /* aread */
169 nodev /* awrite */
170 };
171
172 static struct dev_ops scsa1394_ops = {
173 DEVO_REV, /* devo_rev, */
174 0, /* refcnt */
175 ddi_no_info, /* info */
176 nulldev, /* identify */
177 nulldev, /* probe */
178 scsa1394_attach, /* attach */
179 scsa1394_detach, /* detach */
180 nodev, /* reset */
181 &scsa1394_cb_ops, /* driver operations */
182 NULL, /* bus operations */
183 scsa1394_power, /* power */
184 ddi_quiesce_not_supported, /* devo_quiesce */
185 };
186
187 static struct modldrv scsa1394_modldrv = {
188 &mod_driverops, /* module type */
189 "1394 Mass Storage HBA Driver", /* name of the module */
190 &scsa1394_ops, /* driver ops */
191 };
192
193 static struct modlinkage scsa1394_modlinkage = {
194 MODREV_1, (void *)&scsa1394_modldrv, NULL
195 };
196
197 /* tunables */
198 int scsa1394_bus_config_debug = 0;
199 int scsa1394_start_stop_fail_max = SCSA1394_START_STOP_FAIL_MAX;
200 int scsa1394_mode_sense_fail_max = SCSA1394_MODE_SENSE_FAIL_MAX;
201 int scsa1394_start_stop_timeout_max = SCSA1394_START_STOP_TIMEOUT_MAX;
202
203 /* workarounds */
204 int scsa1394_wrka_rbc2direct = 1;
205 int scsa1394_wrka_fake_rmb = 0;
206 int scsa1394_wrka_fake_prin = 1;
207
208 int scsa1394_wrka_symbios = 1;
209 int scsa1394_symbios_page_size = 4 * 1024; /* must be <= _pagesize */
210 int scsa1394_symbios_size_max = 512 * 248; /* multiple of page size */
211
212 /*
213 *
214 * --- DDI/DKI entry points
215 *
216 */
217 int
218 _init(void)
219 {
220 int ret;
221
222 if (((ret = ddi_soft_state_init(&scsa1394_statep,
223 sizeof (scsa1394_state_t), 1)) != 0)) {
224 return (ret);
225 }
226
227 if ((ret = scsi_hba_init(&scsa1394_modlinkage)) != 0) {
228 ddi_soft_state_fini(&scsa1394_statep);
229 return (ret);
230 }
231
232 if ((ret = mod_install(&scsa1394_modlinkage)) != 0) {
233 scsi_hba_fini(&scsa1394_modlinkage);
234 ddi_soft_state_fini(&scsa1394_statep);
235 return (ret);
236 }
237
238 return (ret);
239 }
240
241 int
242 _fini(void)
243 {
244 int ret;
245
246 if ((ret = mod_remove(&scsa1394_modlinkage)) == 0) {
247 scsi_hba_fini(&scsa1394_modlinkage);
248 ddi_soft_state_fini(&scsa1394_statep);
249 }
250
251 return (ret);
252 }
253
254 int
255 _info(struct modinfo *modinfop)
256 {
257 return (mod_info(&scsa1394_modlinkage, modinfop));
258 }
259
260 static int
261 scsa1394_attach(dev_info_t *dip, ddi_attach_cmd_t cmd)
262 {
263 int instance = ddi_get_instance(dip);
264 scsa1394_state_t *sp;
265
266 switch (cmd) {
267 case DDI_ATTACH:
268 break;
269 case DDI_RESUME:
270 scsa1394_cpr_resume(dip);
271 return (DDI_SUCCESS);
272 default:
273 return (DDI_FAILURE);
274 }
275
276 if (ddi_soft_state_zalloc(scsa1394_statep, instance) != 0) {
277 return (DDI_FAILURE);
278 }
279 sp = SCSA1394_INST2STATE(instance);
280
281 sp->s_dip = dip;
282 sp->s_instance = instance;
283 mutex_init(&sp->s_mutex, NULL, MUTEX_DRIVER,
284 sp->s_attachinfo.iblock_cookie);
285 cv_init(&sp->s_event_cv, NULL, CV_DRIVER, NULL);
286
287 if (scsa1394_attach_1394(sp) != DDI_SUCCESS) {
288 scsa1394_cleanup(sp, 1);
289 return (DDI_FAILURE);
290 }
291
292 if (scsa1394_sbp2_attach(sp) != DDI_SUCCESS) {
293 scsa1394_cleanup(sp, 2);
294 return (DDI_FAILURE);
295 }
296
297 if (scsa1394_attach_threads(sp) != DDI_SUCCESS) {
298 scsa1394_cleanup(sp, 3);
299 return (DDI_FAILURE);
300 }
301
302 if (scsa1394_attach_scsa(sp) != DDI_SUCCESS) {
303 scsa1394_cleanup(sp, 4);
304 return (DDI_FAILURE);
305 }
306
307 if (scsa1394_create_cmd_cache(sp) != DDI_SUCCESS) {
308 scsa1394_cleanup(sp, 5);
309 return (DDI_FAILURE);
310 }
311
312 if (scsa1394_add_events(sp) != DDI_SUCCESS) {
313 scsa1394_cleanup(sp, 6);
314 return (DDI_FAILURE);
315 }
316
317 /* prevent async PM changes until we are done */
318 (void) pm_busy_component(dip, 0);
319
320 /* Set power to full on */
321 (void) pm_raise_power(dip, 0, PM_LEVEL_D0);
322
323 /* we are done */
324 (void) pm_idle_component(dip, 0);
325
326 sp->s_dev_state = SCSA1394_DEV_ONLINE;
327
328 ddi_report_dev(dip);
329
330 return (DDI_SUCCESS);
331 }
332
333 static int
334 scsa1394_detach(dev_info_t *dip, ddi_detach_cmd_t cmd)
335 {
336 int instance = ddi_get_instance(dip);
337 scsa1394_state_t *sp;
338
339 if ((sp = SCSA1394_INST2STATE(instance)) == NULL) {
340 return (DDI_FAILURE);
341 }
342
343 switch (cmd) {
344 case DDI_DETACH:
345 /* Cycle power state to off and idle where done/gone */
346 (void) pm_lower_power(dip, 0, PM_LEVEL_D3);
347
348 scsa1394_cleanup(sp, SCSA1394_CLEANUP_LEVEL_MAX);
349 return (DDI_SUCCESS);
350 case DDI_SUSPEND:
351 return (scsa1394_cpr_suspend(dip));
352 default:
353 return (DDI_FAILURE);
354 }
355 }
356
357 /*ARGSUSED*/
358 static int
359 scsa1394_power(dev_info_t *dip, int comp, int level)
360 {
361 return (DDI_SUCCESS);
362 }
363
364 /*
365 * scsa1394_cpr_suspend
366 * determine if the device's state can be changed to SUSPENDED
367 */
368 /* ARGSUSED */
369 static int
370 scsa1394_cpr_suspend(dev_info_t *dip)
371 {
372 int instance = ddi_get_instance(dip);
373 scsa1394_state_t *sp;
374 int rval = DDI_FAILURE;
375
376 sp = SCSA1394_INST2STATE(instance);
377
378 ASSERT(sp != NULL);
379
380
381 mutex_enter(&sp->s_mutex);
382 switch (sp->s_dev_state) {
383 case SCSA1394_DEV_ONLINE:
384 case SCSA1394_DEV_PWRED_DOWN:
385 case SCSA1394_DEV_DISCONNECTED:
386 sp->s_dev_state = SCSA1394_DEV_SUSPENDED;
387
388 /* Power down and make device idle */
389 (void) pm_lower_power(dip, 0, PM_LEVEL_D3);
390
391 rval = DDI_SUCCESS;
392 break;
393 case SCSA1394_DEV_SUSPENDED:
394 default:
395 if (scsa1394_bus_config_debug)
396 cmn_err(CE_WARN,
397 "scsa1304_cpr_suspend: Illegal dev state: %d",
398 sp->s_dev_state);
399
400 rval = DDI_SUCCESS;
401 break;
402 }
403 mutex_exit(&sp->s_mutex);
404
405 return (rval);
406 }
407
408 /*
409 * scsa2usb_cpr_resume:
410 * restore device's state
411 */
412 static void
413 scsa1394_cpr_resume(dev_info_t *dip)
414 {
415 int instance = ddi_get_instance(dip);
416 scsa1394_state_t *sp;
417 int i;
418 scsa1394_lun_t *lp;
419
420 sp = SCSA1394_INST2STATE(instance);
421
422 ASSERT(sp != NULL);
423
424 if (sp->s_dev_state != SCSA1394_DEV_SUSPENDED)
425 return;
426
427 /*
428 * Go through each lun and reset it to force a reconnect.
429 */
430 for (i = 0; i < sp->s_nluns; i++) {
431 lp = &sp->s_lun[i];
432 if (lp->l_ses != NULL) { /* Are we loged in? */
433 scsa1394_sbp2_req_bus_reset(lp);
434 scsa1394_sbp2_req_reconnect(lp);
435 }
436 }
437
438 /* we are down so let the power get managed */
439 (void) pm_idle_component(dip, 0);
440 }
441
442
443
444 /*
445 *
446 * --- configuration routines
447 *
448 */
449 static void
450 scsa1394_cleanup(scsa1394_state_t *sp, int level)
451 {
452 ASSERT((level > 0) && (level <= SCSA1394_CLEANUP_LEVEL_MAX));
453
454 switch (level) {
455 default:
456 scsa1394_remove_events(sp);
457 /* FALLTHRU */
458 case 6:
459 scsa1394_detach_scsa(sp);
460 /* FALLTHRU */
461 case 5:
462 scsa1394_destroy_cmd_cache(sp);
463 /* FALLTHRU */
464 case 4:
465 scsa1394_detach_threads(sp);
466 /* FALLTHRU */
467 case 3:
468 scsa1394_sbp2_detach(sp);
469 /* FALLTHRU */
470 case 2:
471 scsa1394_detach_1394(sp);
472 /* FALLTHRU */
473 case 1:
474 cv_destroy(&sp->s_event_cv);
475 mutex_destroy(&sp->s_mutex);
476 ddi_soft_state_free(scsa1394_statep, sp->s_instance);
477 }
478 }
479
480 static int
481 scsa1394_attach_1394(scsa1394_state_t *sp)
482 {
483 int ret;
484
485 if ((ret = t1394_attach(sp->s_dip, T1394_VERSION_V1, 0,
486 &sp->s_attachinfo, &sp->s_t1394_hdl)) != DDI_SUCCESS) {
487 return (ret);
488 }
489
490 /* DMA attributes for data buffers */
491 sp->s_buf_dma_attr = sp->s_attachinfo.dma_attr;
492
493 /* DMA attributes for page tables */
494 sp->s_pt_dma_attr = sp->s_attachinfo.dma_attr;
495 sp->s_pt_dma_attr.dma_attr_sgllen = 1; /* pt must be contiguous */
496
497 if ((ret = t1394_get_targetinfo(sp->s_t1394_hdl, SCSA1394_BUSGEN(sp), 0,
498 &sp->s_targetinfo)) != DDI_SUCCESS) {
499 (void) t1394_detach(&sp->s_t1394_hdl, 0);
500 return (ret);
501 }
502
503 return (DDI_SUCCESS);
504 }
505
506 static void
507 scsa1394_detach_1394(scsa1394_state_t *sp)
508 {
509 (void) t1394_detach(&sp->s_t1394_hdl, 0);
510 }
511
512 static int
513 scsa1394_attach_threads(scsa1394_state_t *sp)
514 {
515 char name[16];
516 int nthr;
517
518 nthr = sp->s_nluns;
519 (void) snprintf(name, sizeof (name), "scsa1394%d", sp->s_instance);
520 if ((sp->s_taskq = ddi_taskq_create(sp->s_dip, name, nthr,
521 TASKQ_DEFAULTPRI, 0)) == NULL) {
522 return (DDI_FAILURE);
523 }
524
525 if (scsa1394_sbp2_threads_init(sp) != DDI_SUCCESS) {
526 ddi_taskq_destroy(sp->s_taskq);
527 return (DDI_FAILURE);
528 }
529
530 return (DDI_SUCCESS);
531 }
532
533 static void
534 scsa1394_detach_threads(scsa1394_state_t *sp)
535 {
536 scsa1394_sbp2_threads_fini(sp);
537 ddi_taskq_destroy(sp->s_taskq);
538 }
539
540 static int
541 scsa1394_attach_scsa(scsa1394_state_t *sp)
542 {
543 scsi_hba_tran_t *tran;
544 int ret;
545
546 sp->s_tran = tran = scsi_hba_tran_alloc(sp->s_dip, SCSI_HBA_CANSLEEP);
547
548 tran->tran_hba_private = sp;
549 tran->tran_tgt_private = NULL;
550 tran->tran_tgt_init = scsa1394_scsi_tgt_init;
551 tran->tran_tgt_probe = scsa1394_scsi_tgt_probe;
552 tran->tran_tgt_free = scsa1394_scsi_tgt_free;
553 tran->tran_start = scsa1394_scsi_start;
554 tran->tran_abort = scsa1394_scsi_abort;
555 tran->tran_reset = scsa1394_scsi_reset;
556 tran->tran_getcap = scsa1394_scsi_getcap;
557 tran->tran_setcap = scsa1394_scsi_setcap;
558 tran->tran_init_pkt = scsa1394_scsi_init_pkt;
559 tran->tran_destroy_pkt = scsa1394_scsi_destroy_pkt;
560 tran->tran_dmafree = scsa1394_scsi_dmafree;
561 tran->tran_sync_pkt = scsa1394_scsi_sync_pkt;
562 tran->tran_reset_notify = NULL;
563 tran->tran_get_bus_addr = NULL;
564 tran->tran_get_name = NULL;
565 tran->tran_bus_reset = NULL;
566 tran->tran_quiesce = NULL;
567 tran->tran_unquiesce = NULL;
568 tran->tran_get_eventcookie = NULL;
569 tran->tran_add_eventcall = NULL;
570 tran->tran_remove_eventcall = NULL;
571 tran->tran_post_event = NULL;
572 tran->tran_bus_config = scsa1394_scsi_bus_config;
573 tran->tran_bus_unconfig = scsa1394_scsi_bus_unconfig;
574
575 if ((ret = scsi_hba_attach_setup(sp->s_dip, &sp->s_attachinfo.dma_attr,
576 tran, 0)) != DDI_SUCCESS) {
577 scsi_hba_tran_free(tran);
578 return (ret);
579 }
580
581 return (DDI_SUCCESS);
582 }
583
584 static void
585 scsa1394_detach_scsa(scsa1394_state_t *sp)
586 {
587 int ret;
588
589 ret = scsi_hba_detach(sp->s_dip);
590 ASSERT(ret == DDI_SUCCESS);
591
592 scsi_hba_tran_free(sp->s_tran);
593 }
594
595 static int
596 scsa1394_create_cmd_cache(scsa1394_state_t *sp)
597 {
598 char name[64];
599
600 (void) sprintf(name, "scsa1394%d_cache", sp->s_instance);
601 sp->s_cmd_cache = kmem_cache_create(name,
602 SCSA1394_CMD_SIZE, sizeof (void *),
603 scsa1394_cmd_cache_constructor, scsa1394_cmd_cache_destructor,
604 NULL, (void *)sp, NULL, 0);
605
606 return ((sp->s_cmd_cache == NULL) ? DDI_FAILURE : DDI_SUCCESS);
607 }
608
609 static void
610 scsa1394_destroy_cmd_cache(scsa1394_state_t *sp)
611 {
612 kmem_cache_destroy(sp->s_cmd_cache);
613 }
614
615 static int
616 scsa1394_add_events(scsa1394_state_t *sp)
617 {
618 ddi_eventcookie_t br_evc, rem_evc, ins_evc;
619
620 if (ddi_get_eventcookie(sp->s_dip, DDI_DEVI_BUS_RESET_EVENT,
621 &br_evc) != DDI_SUCCESS) {
622 return (DDI_FAILURE);
623 }
624 if (ddi_add_event_handler(sp->s_dip, br_evc, scsa1394_bus_reset,
625 sp, &sp->s_reset_cb_id) != DDI_SUCCESS) {
626 return (DDI_FAILURE);
627 }
628
629 if (ddi_get_eventcookie(sp->s_dip, DDI_DEVI_REMOVE_EVENT,
630 &rem_evc) != DDI_SUCCESS) {
631 (void) ddi_remove_event_handler(sp->s_reset_cb_id);
632 return (DDI_FAILURE);
633 }
634 if (ddi_add_event_handler(sp->s_dip, rem_evc, scsa1394_disconnect,
635 sp, &sp->s_remove_cb_id) != DDI_SUCCESS) {
636 (void) ddi_remove_event_handler(sp->s_reset_cb_id);
637 return (DDI_FAILURE);
638 }
639
640 if (ddi_get_eventcookie(sp->s_dip, DDI_DEVI_INSERT_EVENT,
641 &ins_evc) != DDI_SUCCESS) {
642 (void) ddi_remove_event_handler(sp->s_remove_cb_id);
643 (void) ddi_remove_event_handler(sp->s_reset_cb_id);
644 return (DDI_FAILURE);
645 }
646 if (ddi_add_event_handler(sp->s_dip, ins_evc, scsa1394_reconnect,
647 sp, &sp->s_insert_cb_id) != DDI_SUCCESS) {
648 (void) ddi_remove_event_handler(sp->s_remove_cb_id);
649 (void) ddi_remove_event_handler(sp->s_reset_cb_id);
650 return (DDI_FAILURE);
651 }
652
653 return (DDI_SUCCESS);
654 }
655
656 static void
657 scsa1394_remove_events(scsa1394_state_t *sp)
658 {
659 ddi_eventcookie_t evc;
660
661 if (ddi_get_eventcookie(sp->s_dip, DDI_DEVI_INSERT_EVENT,
662 &evc) == DDI_SUCCESS) {
663 (void) ddi_remove_event_handler(sp->s_insert_cb_id);
664 }
665
666 if (ddi_get_eventcookie(sp->s_dip, DDI_DEVI_REMOVE_EVENT,
667 &evc) == DDI_SUCCESS) {
668 (void) ddi_remove_event_handler(sp->s_remove_cb_id);
669 }
670
671 if (ddi_get_eventcookie(sp->s_dip, DDI_DEVI_BUS_RESET_EVENT,
672 &evc) == DDI_SUCCESS) {
673 (void) ddi_remove_event_handler(sp->s_reset_cb_id);
674 }
675 }
676
677 /*
678 *
679 * --- device configuration
680 *
681 */
682 static int
683 scsa1394_scsi_bus_config(dev_info_t *dip, uint_t flag, ddi_bus_config_op_t op,
684 void *arg, dev_info_t **child)
685 {
686 scsa1394_state_t *sp = SCSA1394_INST2STATE(ddi_get_instance(dip));
687 int circ;
688 int ret;
689
690 if (scsa1394_bus_config_debug) {
691 flag |= NDI_DEVI_DEBUG;
692 }
693
694 ndi_devi_enter(dip, &circ);
695 if (DEVI(dip)->devi_child == NULL) {
696 scsa1394_create_children(sp);
697 }
698 ret = ndi_busop_bus_config(dip, flag, op, arg, child, 0);
699 ndi_devi_exit(dip, circ);
700
701 return (ret);
702 }
703
704 static int
705 scsa1394_scsi_bus_unconfig(dev_info_t *dip, uint_t flag, ddi_bus_config_op_t op,
706 void *arg)
707 {
708 scsa1394_state_t *sp = SCSA1394_INST2STATE(ddi_get_instance(dip));
709 int circ;
710 int ret;
711 uint_t saved_flag = flag;
712
713 if (scsa1394_bus_config_debug) {
714 flag |= NDI_DEVI_DEBUG;
715 }
716
717 /*
718 * First offline and if offlining successful, then remove children.
719 */
720 if (op == BUS_UNCONFIG_ALL) {
721 flag &= ~(NDI_DEVI_REMOVE | NDI_UNCONFIG);
722 }
723
724 ndi_devi_enter(dip, &circ);
725
726 ret = ndi_busop_bus_unconfig(dip, flag, op, arg);
727
728 /*
729 * If previous step was successful and not part of modunload daemon,
730 * attempt to remove children.
731 */
732 if ((op == BUS_UNCONFIG_ALL) && (ret == NDI_SUCCESS) &&
733 ((flag & NDI_AUTODETACH) == 0)) {
734 flag |= NDI_DEVI_REMOVE;
735 ret = ndi_busop_bus_unconfig(dip, flag, op, arg);
736 }
737 ndi_devi_exit(dip, circ);
738
739 if ((ret != NDI_SUCCESS) && (op == BUS_UNCONFIG_ALL) &&
740 ((saved_flag & NDI_DEVI_REMOVE) != 0)) {
741 mutex_enter(&sp->s_mutex);
742 if (!sp->s_disconnect_warned) {
743 cmn_err(CE_WARN, "scsa1394(%d): "
744 "Disconnected device was busy, please reconnect.\n",
745 sp->s_instance);
746 sp->s_disconnect_warned = B_TRUE;
747 }
748 mutex_exit(&sp->s_mutex);
749 }
750
751 return (ret);
752 }
753
754 void
755 scsa1394_dtype2name(int dtype, char **node_name, char **driver_name)
756 {
757 static struct {
758 char *node_name;
759 char *driver_name;
760 } dtype2name[] = {
761 { "disk", "sd" }, /* DTYPE_DIRECT 0x00 */
762 { "tape", "st" }, /* DTYPE_SEQUENTIAL 0x01 */
763 { "printer", NULL }, /* DTYPE_PRINTER 0x02 */
764 { "processor", NULL }, /* DTYPE_PROCESSOR 0x03 */
765 { "worm", NULL }, /* DTYPE_WORM 0x04 */
766 { "disk", "sd" }, /* DTYPE_RODIRECT 0x05 */
767 { "scanner", NULL }, /* DTYPE_SCANNER 0x06 */
768 { "disk", "sd" }, /* DTYPE_OPTICAL 0x07 */
769 { "changer", NULL }, /* DTYPE_CHANGER 0x08 */
770 { "comm", NULL }, /* DTYPE_COMM 0x09 */
771 { "generic", NULL }, /* DTYPE_??? 0x0A */
772 { "generic", NULL }, /* DTYPE_??? 0x0B */
773 { "array_ctrl", NULL }, /* DTYPE_ARRAY_CTRL 0x0C */
774 { "esi", "ses" }, /* DTYPE_ESI 0x0D */
775 { "disk", "sd" } /* DTYPE_RBC 0x0E */
776 };
777
778 if (dtype < NELEM(dtype2name)) {
779 *node_name = dtype2name[dtype].node_name;
780 *driver_name = dtype2name[dtype].driver_name;
781 } else {
782 *node_name = "generic";
783 *driver_name = NULL;
784 }
785 }
786
787 static void
788 scsa1394_create_children(scsa1394_state_t *sp)
789 {
790 char name[SCSA1394_COMPAT_MAX][16];
791 char *compatible[SCSA1394_COMPAT_MAX];
792 dev_info_t *cdip;
793 int i;
794 int dtype;
795 char *node_name;
796 char *driver_name;
797 int ret;
798
799 bzero(name, sizeof (name));
800 (void) strcpy(name[0], "sd");
801 for (i = 0; i < SCSA1394_COMPAT_MAX; i++) {
802 compatible[i] = name[i];
803 }
804
805 for (i = 0; i < sp->s_nluns; i++) {
806 dtype = scsa1394_sbp2_get_lun_type(&sp->s_lun[i]);
807 scsa1394_dtype2name(dtype, &node_name, &driver_name);
808
809 ndi_devi_alloc_sleep(sp->s_dip, node_name,
810 (pnode_t)DEVI_SID_NODEID, &cdip);
811
812 ret = ndi_prop_update_int(DDI_DEV_T_NONE, cdip,
813 SCSI_ADDR_PROP_TARGET, 0);
814 if (ret != DDI_PROP_SUCCESS) {
815 (void) ndi_devi_free(cdip);
816 continue;
817 }
818
819 ret = ndi_prop_update_int(DDI_DEV_T_NONE, cdip,
820 SCSI_ADDR_PROP_LUN, i);
821 if (ret != DDI_PROP_SUCCESS) {
822 ddi_prop_remove_all(cdip);
823 (void) ndi_devi_free(cdip);
824 continue;
825 }
826
827 /*
828 * Some devices don't support LOG SENSE, so tell
829 * sd driver not to send this command.
830 */
831 ret = ndi_prop_update_int(DDI_DEV_T_NONE, cdip,
832 "pm-capable", 1);
833 if (ret != DDI_PROP_SUCCESS) {
834 ddi_prop_remove_all(cdip);
835 (void) ndi_devi_free(cdip);
836 continue;
837 }
838
839 ret = ndi_prop_create_boolean(DDI_DEV_T_NONE, cdip,
840 "hotpluggable");
841 if (ret != DDI_PROP_SUCCESS) {
842 ddi_prop_remove_all(cdip);
843 (void) ndi_devi_free(cdip);
844 continue;
845 }
846
847 if (driver_name) {
848 compatible[0] = driver_name;
849 ret = ndi_prop_update_string_array(DDI_DEV_T_NONE, cdip,
850 "compatible", (char **)compatible,
851 SCSA1394_COMPAT_MAX);
852 if (ret != DDI_PROP_SUCCESS) {
853 ddi_prop_remove_all(cdip);
854 (void) ndi_devi_free(cdip);
855 continue;
856 }
857 }
858
859 /*
860 * add property "scsa1394" to distinguish from others' children
861 */
862 ret = ndi_prop_create_boolean(DDI_DEV_T_NONE, cdip, "scsa1394");
863 if (ret != DDI_PROP_SUCCESS) {
864 ddi_prop_remove_all(cdip);
865 (void) ndi_devi_free(cdip);
866 continue;
867 }
868
869 (void) ddi_initchild(sp->s_dip, cdip);
870 }
871 }
872
873 /*ARGSUSED*/
874 static void
875 scsa1394_bus_reset(dev_info_t *dip, ddi_eventcookie_t evc, void *arg,
876 void *data)
877 {
878 scsa1394_state_t *sp = arg;
879
880 if (sp != NULL) {
881 mutex_enter(&sp->s_mutex);
882 if (sp->s_dev_state == SCSA1394_DEV_DISCONNECTED) {
883 mutex_exit(&sp->s_mutex);
884 return;
885 }
886 sp->s_stat.stat_bus_reset_cnt++;
887 sp->s_dev_state = SCSA1394_DEV_BUS_RESET;
888 sp->s_attachinfo.localinfo = *(t1394_localinfo_t *)data;
889 mutex_exit(&sp->s_mutex);
890
891 scsa1394_sbp2_req(sp, 0, SCSA1394_THREQ_BUS_RESET);
892 }
893 }
894
895 /*ARGSUSED*/
896 static void
897 scsa1394_disconnect(dev_info_t *dip, ddi_eventcookie_t evc, void *arg,
898 void *data)
899 {
900 scsa1394_state_t *sp = arg;
901 int circ;
902 dev_info_t *cdip, *cdip_next;
903
904 if (sp == NULL) {
905 return;
906 }
907
908 mutex_enter(&sp->s_mutex);
909 sp->s_stat.stat_disconnect_cnt++;
910 sp->s_dev_state = SCSA1394_DEV_DISCONNECTED;
911 mutex_exit(&sp->s_mutex);
912
913 scsa1394_sbp2_disconnect(sp);
914
915 ndi_devi_enter(dip, &circ);
916 for (cdip = ddi_get_child(dip); cdip != NULL; cdip = cdip_next) {
917 cdip_next = ddi_get_next_sibling(cdip);
918
919 mutex_enter(&DEVI(cdip)->devi_lock);
920 DEVI_SET_DEVICE_REMOVED(cdip);
921 mutex_exit(&DEVI(cdip)->devi_lock);
922 }
923 ndi_devi_exit(dip, circ);
924 }
925
926 /*ARGSUSED*/
927 static void
928 scsa1394_reconnect(dev_info_t *dip, ddi_eventcookie_t evc, void *arg,
929 void *data)
930 {
931 scsa1394_state_t *sp = arg;
932 int circ;
933 dev_info_t *cdip, *cdip_next;
934
935 if (sp == NULL) {
936 return;
937 }
938
939 mutex_enter(&sp->s_mutex);
940 sp->s_stat.stat_reconnect_cnt++;
941 sp->s_attachinfo.localinfo = *(t1394_localinfo_t *)data;
942 sp->s_disconnect_warned = B_FALSE;
943 mutex_exit(&sp->s_mutex);
944
945 ndi_devi_enter(dip, &circ);
946 for (cdip = ddi_get_child(dip); cdip != NULL; cdip = cdip_next) {
947 cdip_next = ddi_get_next_sibling(cdip);
948
949 mutex_enter(&DEVI(cdip)->devi_lock);
950 DEVI_SET_DEVICE_REINSERTED(cdip);
951 mutex_exit(&DEVI(cdip)->devi_lock);
952 }
953 ndi_devi_exit(dip, circ);
954
955 scsa1394_sbp2_req(sp, 0, SCSA1394_THREQ_RECONNECT);
956 }
957
958 /*
959 *
960 * --- SCSA entry points
961 *
962 */
963 /*ARGSUSED*/
964 static int
965 scsa1394_scsi_tgt_init(dev_info_t *dip, dev_info_t *cdip, scsi_hba_tran_t *tran,
966 struct scsi_device *sd)
967 {
968 scsa1394_state_t *sp = (scsa1394_state_t *)tran->tran_hba_private;
969 int lun;
970 int plen = sizeof (int);
971 int ret = DDI_FAILURE;
972
973 if (ddi_prop_op(DDI_DEV_T_ANY, cdip, PROP_LEN_AND_VAL_BUF,
974 DDI_PROP_DONTPASS | DDI_PROP_CANSLEEP, SCSI_ADDR_PROP_LUN,
975 (caddr_t)&lun, &plen) != DDI_PROP_SUCCESS) {
976 return (DDI_FAILURE);
977 }
978
979 if (!scsa1394_is_my_child(cdip)) {
980 /*
981 * add property "scsa1394" to distinguish from others' children
982 */
983 ret = ndi_prop_create_boolean(DDI_DEV_T_NONE, cdip, "scsa1394");
984 if (ret != DDI_PROP_SUCCESS) {
985 return (DDI_FAILURE);
986 }
987
988 if (scsa1394_dev_is_online(sp)) {
989 return (scsa1394_sbp2_login(sp, lun));
990 } else {
991 return (DDI_FAILURE);
992 }
993 }
994
995 if ((lun >= sp->s_nluns) || (sp->s_lun[lun].l_cdip != NULL) ||
996 !scsa1394_dev_is_online(sp)) {
997 return (DDI_FAILURE);
998 }
999
1000 if ((ret = scsa1394_sbp2_login(sp, lun)) == DDI_SUCCESS) {
1001 sp->s_lun[lun].l_cdip = cdip;
1002 }
1003 return (ret);
1004 }
1005
1006 /*ARGSUSED*/
1007 static void
1008 scsa1394_scsi_tgt_free(dev_info_t *dip, dev_info_t *cdip, scsi_hba_tran_t *tran,
1009 struct scsi_device *sd)
1010 {
1011 scsa1394_state_t *sp = (scsa1394_state_t *)tran->tran_hba_private;
1012 int lun;
1013 int plen = sizeof (int);
1014
1015 if (!scsa1394_is_my_child(cdip)) {
1016 return;
1017 }
1018
1019 if (ddi_prop_op(DDI_DEV_T_ANY, cdip, PROP_LEN_AND_VAL_BUF,
1020 DDI_PROP_DONTPASS | DDI_PROP_CANSLEEP, SCSI_ADDR_PROP_LUN,
1021 (caddr_t)&lun, &plen) != DDI_PROP_SUCCESS) {
1022 return;
1023 }
1024
1025 if ((lun < sp->s_nluns) && (sp->s_lun[lun].l_cdip == cdip)) {
1026 if (scsa1394_dev_is_online(sp)) {
1027 scsa1394_sbp2_logout(sp, lun, B_TRUE);
1028 }
1029 sp->s_lun[lun].l_cdip = NULL;
1030 }
1031 }
1032
1033 static int
1034 scsa1394_scsi_tgt_probe(struct scsi_device *sd, int (*waitfunc)())
1035 {
1036 dev_info_t *dip = ddi_get_parent(sd->sd_dev);
1037 scsi_hba_tran_t *tran = (scsi_hba_tran_t *)ddi_get_driver_private(dip);
1038 scsa1394_state_t *sp = (scsa1394_state_t *)tran->tran_hba_private;
1039 scsa1394_lun_t *lp;
1040
1041 if (!scsa1394_dev_is_online(sp)) {
1042 return (SCSIPROBE_FAILURE);
1043 }
1044 lp = &sp->s_lun[sd->sd_address.a_lun];
1045
1046 if (scsa1394_probe_g0_nodata(sd, waitfunc,
1047 SCMD_TEST_UNIT_READY, 0, 0) != SCSIPROBE_EXISTS) {
1048 lp->l_nosup_tur = B_TRUE;
1049 (void) scsa1394_sbp2_reset(lp, RESET_LUN, NULL);
1050 }
1051 if (scsa1394_probe_g0_nodata(sd, waitfunc,
1052 SCMD_START_STOP, 0, 1) != SCSIPROBE_EXISTS) {
1053 lp->l_nosup_start_stop = B_TRUE;
1054 }
1055
1056 /* standard probe issues INQUIRY, which some devices may not support */
1057 if (scsi_hba_probe(sd, waitfunc) != SCSIPROBE_EXISTS) {
1058 lp->l_nosup_inquiry = B_TRUE;
1059 scsa1394_sbp2_fake_inquiry(sp, &lp->l_fake_inq);
1060 bcopy(&lp->l_fake_inq, sd->sd_inq, SUN_INQSIZE);
1061 lp->l_rmb_orig = 1;
1062 }
1063
1064 if (scsa1394_wrka_fake_rmb) {
1065 sd->sd_inq->inq_rmb = 1;
1066 }
1067
1068 return (SCSIPROBE_EXISTS);
1069 }
1070
1071 static int
1072 scsa1394_probe_g0_nodata(struct scsi_device *sd, int (*waitfunc)(),
1073 uchar_t cmd, uint_t addr, uint_t cnt)
1074 {
1075 struct scsi_pkt *pkt;
1076 int ret = SCSIPROBE_EXISTS;
1077
1078 pkt = scsi_init_pkt(&sd->sd_address, NULL, NULL, CDB_GROUP0,
1079 sizeof (struct scsi_arq_status), 0, PKT_CONSISTENT, waitfunc, NULL);
1080
1081 if (pkt == NULL) {
1082 return (SCSIPROBE_NOMEM);
1083 }
1084
1085 (void) scsi_setup_cdb((union scsi_cdb *)pkt->pkt_cdbp, cmd, addr, cnt,
1086 0);
1087 ((union scsi_cdb *)(pkt)->pkt_cdbp)->scc_lun = sd->sd_address.a_lun;
1088 pkt->pkt_flags = FLAG_NOINTR;
1089
1090 if (scsa1394_probe_tran(pkt) < 0) {
1091 if (pkt->pkt_reason == CMD_INCOMPLETE) {
1092 ret = SCSIPROBE_NORESP;
1093 } else if ((pkt->pkt_reason == CMD_TRAN_ERR) &&
1094 ((*(pkt->pkt_scbp) & STATUS_MASK) == STATUS_CHECK) &&
1095 (pkt->pkt_state & STATE_ARQ_DONE)) {
1096 ret = SCSIPROBE_EXISTS;
1097 } else {
1098 ret = SCSIPROBE_FAILURE;
1099 }
1100 }
1101
1102 scsi_destroy_pkt(pkt);
1103
1104 return (ret);
1105 }
1106
1107 static int
1108 scsa1394_probe_tran(struct scsi_pkt *pkt)
1109 {
1110 pkt->pkt_time = SCSA1394_PROBE_TIMEOUT;
1111
1112 if (scsi_transport(pkt) != TRAN_ACCEPT) {
1113 return (-1);
1114 } else if ((pkt->pkt_reason == CMD_INCOMPLETE) &&
1115 (pkt->pkt_state == 0)) {
1116 return (-1);
1117 } else if (pkt->pkt_reason != CMD_CMPLT) {
1118 return (-1);
1119 } else if (((*pkt->pkt_scbp) & STATUS_MASK) == STATUS_BUSY) {
1120 return (0);
1121 }
1122 return (0);
1123 }
1124
1125 /*ARGSUSED*/
1126 static int
1127 scsa1394_scsi_abort(struct scsi_address *ap, struct scsi_pkt *pkt)
1128 {
1129 return (0);
1130 }
1131
1132 static int
1133 scsa1394_scsi_reset(struct scsi_address *ap, int level)
1134 {
1135 scsa1394_state_t *sp = ADDR2STATE(ap);
1136 scsa1394_lun_t *lp;
1137 int ret;
1138
1139 switch (level) {
1140 case RESET_ALL:
1141 case RESET_TARGET:
1142 lp = &sp->s_lun[0];
1143 break;
1144 case RESET_LUN:
1145 lp = &sp->s_lun[ap->a_lun];
1146 break;
1147 default:
1148 return (DDI_FAILURE);
1149 }
1150
1151 ret = scsa1394_sbp2_reset(lp, level, NULL);
1152
1153 return ((ret == SBP2_SUCCESS) ? 1 : 0);
1154 }
1155
1156 /*ARGSUSED*/
1157 static int
1158 scsa1394_scsi_getcap(struct scsi_address *ap, char *cap, int whom)
1159 {
1160 scsa1394_state_t *sp = ADDR2STATE(ap);
1161 size_t dev_bsize_cap;
1162 int ret = -1;
1163
1164 if (!scsa1394_dev_is_online(sp)) {
1165 return (-1);
1166 }
1167
1168 if (cap == NULL) {
1169 return (-1);
1170 }
1171
1172 switch (scsi_hba_lookup_capstr(cap)) {
1173 case SCSI_CAP_DMA_MAX:
1174 ret = sp->s_attachinfo.dma_attr.dma_attr_maxxfer;
1175 break;
1176 case SCSI_CAP_SCSI_VERSION:
1177 ret = SCSI_VERSION_2;
1178 break;
1179 case SCSI_CAP_ARQ:
1180 ret = 1;
1181 break;
1182 case SCSI_CAP_UNTAGGED_QING:
1183 ret = 1;
1184 break;
1185 case SCSI_CAP_GEOMETRY:
1186 dev_bsize_cap = sp->s_totalsec;
1187
1188 if (sp->s_secsz > DEV_BSIZE) {
1189 dev_bsize_cap *= sp->s_secsz / DEV_BSIZE;
1190 } else if (sp->s_secsz < DEV_BSIZE) {
1191 dev_bsize_cap /= DEV_BSIZE / sp->s_secsz;
1192 }
1193
1194 if (dev_bsize_cap < 65536 * 2 * 18) { /* < ~1GB */
1195 /* unlabeled floppy, 18k per cylinder */
1196 ret = ((2 << 16) | 18);
1197 } else if (dev_bsize_cap < 65536 * 64 * 32) { /* < 64GB */
1198 /* 1024k per cylinder */
1199 ret = ((64 << 16) | 32);
1200 } else if (dev_bsize_cap < 65536 * 255 * 63) { /* < ~500GB */
1201 /* ~8m per cylinder */
1202 ret = ((255 << 16) | 63);
1203 } else { /* .. 8TB */
1204 /* 64m per cylinder */
1205 ret = ((512 << 16) | 256);
1206 }
1207 break;
1208 default:
1209 break;
1210 }
1211
1212 return (ret);
1213 }
1214
1215 /*ARGSUSED*/
1216 static int
1217 scsa1394_scsi_setcap(struct scsi_address *ap, char *cap, int value, int whom)
1218 {
1219 scsa1394_state_t *sp = ADDR2STATE(ap);
1220 int ret = -1;
1221
1222 if (!scsa1394_dev_is_online(sp)) {
1223 return (-1);
1224 }
1225
1226 switch (scsi_hba_lookup_capstr(cap)) {
1227 case SCSI_CAP_ARQ:
1228 ret = 1;
1229 break;
1230 case SCSI_CAP_DMA_MAX:
1231 case SCSI_CAP_SCSI_VERSION:
1232 case SCSI_CAP_UNTAGGED_QING:
1233 /* supported but not settable */
1234 ret = 0;
1235 break;
1236 case SCSI_CAP_SECTOR_SIZE:
1237 if (value) {
1238 sp->s_secsz = value;
1239 }
1240 break;
1241 case SCSI_CAP_TOTAL_SECTORS:
1242 if (value) {
1243 sp->s_totalsec = value;
1244 }
1245 break;
1246 default:
1247 break;
1248 }
1249
1250 return (ret);
1251 }
1252
1253 /*ARGSUSED*/
1254 static void
1255 scsa1394_scsi_sync_pkt(struct scsi_address *ap, struct scsi_pkt *pkt)
1256 {
1257 scsa1394_cmd_t *cmd = PKT2CMD(pkt);
1258
1259 if (cmd->sc_flags & SCSA1394_CMD_DMA_BUF_VALID) {
1260 (void) ddi_dma_sync(cmd->sc_buf_dma_hdl, 0, 0,
1261 (cmd->sc_flags & SCSA1394_CMD_READ) ?
1262 DDI_DMA_SYNC_FORCPU : DDI_DMA_SYNC_FORDEV);
1263 }
1264 }
1265
1266 /*
1267 *
1268 * --- pkt resource allocation routines
1269 *
1270 */
1271 static struct scsi_pkt *
1272 scsa1394_scsi_init_pkt(struct scsi_address *ap, struct scsi_pkt *pkt,
1273 struct buf *bp, int cmdlen, int statuslen, int tgtlen, int flags,
1274 int (*callback)(), caddr_t arg)
1275 {
1276 scsa1394_state_t *sp = ADDR2STATE(ap);
1277 scsa1394_lun_t *lp;
1278 scsa1394_cmd_t *cmd;
1279 boolean_t is_new; /* new cmd is being allocated */
1280 int kf = (callback == SLEEP_FUNC) ? KM_SLEEP : KM_NOSLEEP;
1281
1282 if (ap->a_lun >= sp->s_nluns) {
1283 return (NULL);
1284 }
1285 lp = &sp->s_lun[ap->a_lun];
1286
1287 /*
1288 * allocate cmd space
1289 */
1290 if (pkt == NULL) {
1291 is_new = B_TRUE;
1292 if ((cmd = kmem_cache_alloc(sp->s_cmd_cache, kf)) == NULL) {
1293 return (NULL);
1294 }
1295
1296 /* initialize cmd */
1297 pkt = &cmd->sc_scsi_pkt;
1298 pkt->pkt_ha_private = cmd;
1299 pkt->pkt_address = *ap;
1300 pkt->pkt_private = cmd->sc_priv;
1301 pkt->pkt_scbp = (uchar_t *)&cmd->sc_scb;
1302 pkt->pkt_cdbp = (uchar_t *)&cmd->sc_pkt_cdb;
1303 pkt->pkt_resid = 0;
1304
1305 cmd->sc_lun = lp;
1306 cmd->sc_pkt = pkt;
1307 cmd->sc_cdb_len = cmdlen;
1308 cmd->sc_scb_len = statuslen;
1309 cmd->sc_priv_len = tgtlen;
1310
1311 /* need external space? */
1312 if ((cmdlen > sizeof (cmd->sc_pkt_cdb)) ||
1313 (statuslen > sizeof (cmd->sc_scb)) ||
1314 (tgtlen > sizeof (cmd->sc_priv))) {
1315 if (scsa1394_cmd_ext_alloc(sp, cmd, kf) !=
1316 DDI_SUCCESS) {
1317 kmem_cache_free(sp->s_cmd_cache, cmd);
1318 lp->l_stat.stat_err_pkt_kmem_alloc++;
1319 return (NULL);
1320 }
1321 }
1322
1323 /* allocate DMA resources for CDB */
1324 if (scsa1394_cmd_cdb_dma_alloc(sp, cmd, flags, callback, arg) !=
1325 DDI_SUCCESS) {
1326 scsa1394_scsi_destroy_pkt(ap, pkt);
1327 return (NULL);
1328 }
1329 } else {
1330 is_new = B_FALSE;
1331 cmd = PKT2CMD(pkt);
1332 }
1333
1334 cmd->sc_flags &= ~SCSA1394_CMD_RDWR;
1335
1336 /* allocate/move DMA resources for data buffer */
1337 if ((bp != NULL) && (bp->b_bcount > 0)) {
1338 if ((cmd->sc_flags & SCSA1394_CMD_DMA_BUF_VALID) == 0) {
1339 if (scsa1394_cmd_buf_dma_alloc(sp, cmd, flags, callback,
1340 arg, bp) != DDI_SUCCESS) {
1341 if (is_new) {
1342 scsa1394_scsi_destroy_pkt(ap, pkt);
1343 }
1344 return (NULL);
1345 }
1346 } else {
1347 if (scsa1394_cmd_buf_dma_move(sp, cmd) != DDI_SUCCESS) {
1348 return (NULL);
1349 }
1350 }
1351
1352 ASSERT(cmd->sc_win_len > 0);
1353 pkt->pkt_resid = bp->b_bcount - cmd->sc_win_len;
1354 }
1355
1356 /*
1357 * kernel virtual address may be required for certain workarounds
1358 * and in case of B_PHYS or B_PAGEIO, bp_mapin() will get it for us
1359 */
1360 if ((bp != NULL) && ((bp->b_flags & (B_PAGEIO | B_PHYS)) != 0) &&
1361 (bp->b_bcount < SCSA1394_MAPIN_SIZE_MAX) &&
1362 ((cmd->sc_flags & SCSA1394_CMD_DMA_BUF_MAPIN) == 0)) {
1363 bp_mapin(bp);
1364 cmd->sc_flags |= SCSA1394_CMD_DMA_BUF_MAPIN;
1365 }
1366
1367 return (pkt);
1368 }
1369
1370 static void
1371 scsa1394_scsi_destroy_pkt(struct scsi_address *ap, struct scsi_pkt *pkt)
1372 {
1373 scsa1394_state_t *sp = ADDR2STATE(ap);
1374 scsa1394_cmd_t *cmd = PKT2CMD(pkt);
1375
1376 if (cmd->sc_flags & SCSA1394_CMD_DMA_BUF_VALID) {
1377 scsa1394_cmd_buf_dma_free(sp, cmd);
1378 }
1379 if (cmd->sc_flags & SCSA1394_CMD_DMA_CDB_VALID) {
1380 scsa1394_cmd_cdb_dma_free(sp, cmd);
1381 }
1382 if (cmd->sc_flags & SCSA1394_CMD_DMA_BUF_MAPIN) {
1383 bp_mapout(cmd->sc_bp);
1384 cmd->sc_flags &= ~SCSA1394_CMD_DMA_BUF_MAPIN;
1385 }
1386 if (cmd->sc_flags & SCSA1394_CMD_EXT) {
1387 scsa1394_cmd_ext_free(sp, cmd);
1388 }
1389
1390 kmem_cache_free(sp->s_cmd_cache, cmd);
1391 }
1392
1393 static void
1394 scsa1394_scsi_dmafree(struct scsi_address *ap, struct scsi_pkt *pkt)
1395 {
1396 scsa1394_state_t *sp = ADDR2STATE(ap);
1397 scsa1394_cmd_t *cmd = PKT2CMD(pkt);
1398
1399 if (cmd->sc_flags & SCSA1394_CMD_DMA_BUF_VALID) {
1400 scsa1394_cmd_buf_dma_free(sp, cmd);
1401 }
1402 if (cmd->sc_flags & SCSA1394_CMD_DMA_BUF_MAPIN) {
1403 bp_mapout(cmd->sc_bp);
1404 cmd->sc_flags &= ~SCSA1394_CMD_DMA_BUF_MAPIN;
1405 }
1406 }
1407
1408 /*ARGSUSED*/
1409 static int
1410 scsa1394_cmd_cache_constructor(void *buf, void *cdrarg, int kf)
1411 {
1412 scsa1394_cmd_t *cmd = buf;
1413
1414 bzero(buf, SCSA1394_CMD_SIZE);
1415 cmd->sc_task.ts_drv_priv = cmd;
1416
1417 return (0);
1418 }
1419
1420 /*ARGSUSED*/
1421 static void
1422 scsa1394_cmd_cache_destructor(void *buf, void *cdrarg)
1423 {
1424 }
1425
1426 /*
1427 * allocate and deallocate external cmd space (ie. not part of scsa1394_cmd_t)
1428 * for non-standard length cdb, pkt_private, status areas
1429 */
1430 static int
1431 scsa1394_cmd_ext_alloc(scsa1394_state_t *sp, scsa1394_cmd_t *cmd, int kf)
1432 {
1433 struct scsi_pkt *pkt = cmd->sc_pkt;
1434 void *buf;
1435
1436 if (cmd->sc_cdb_len > sizeof (cmd->sc_pkt_cdb)) {
1437 if ((buf = kmem_zalloc(cmd->sc_cdb_len, kf)) == NULL) {
1438 return (DDI_FAILURE);
1439 }
1440 pkt->pkt_cdbp = buf;
1441 cmd->sc_flags |= SCSA1394_CMD_CDB_EXT;
1442 }
1443
1444 if (cmd->sc_scb_len > sizeof (cmd->sc_scb)) {
1445 if ((buf = kmem_zalloc(cmd->sc_scb_len, kf)) == NULL) {
1446 scsa1394_cmd_ext_free(sp, cmd);
1447 return (DDI_FAILURE);
1448 }
1449 pkt->pkt_scbp = buf;
1450 cmd->sc_flags |= SCSA1394_CMD_SCB_EXT;
1451 }
1452
1453 if (cmd->sc_priv_len > sizeof (cmd->sc_priv)) {
1454 if ((buf = kmem_zalloc(cmd->sc_priv_len, kf)) == NULL) {
1455 scsa1394_cmd_ext_free(sp, cmd);
1456 return (DDI_FAILURE);
1457 }
1458 pkt->pkt_private = buf;
1459 cmd->sc_flags |= SCSA1394_CMD_PRIV_EXT;
1460 }
1461
1462 return (DDI_SUCCESS);
1463 }
1464
1465 /*ARGSUSED*/
1466 static void
1467 scsa1394_cmd_ext_free(scsa1394_state_t *sp, scsa1394_cmd_t *cmd)
1468 {
1469 struct scsi_pkt *pkt = cmd->sc_pkt;
1470
1471 if (cmd->sc_flags & SCSA1394_CMD_CDB_EXT) {
1472 kmem_free(pkt->pkt_cdbp, cmd->sc_cdb_len);
1473 }
1474 if (cmd->sc_flags & SCSA1394_CMD_SCB_EXT) {
1475 kmem_free(pkt->pkt_scbp, cmd->sc_scb_len);
1476 }
1477 if (cmd->sc_flags & SCSA1394_CMD_PRIV_EXT) {
1478 kmem_free(pkt->pkt_private, cmd->sc_priv_len);
1479 }
1480 cmd->sc_flags &= ~SCSA1394_CMD_EXT;
1481 }
1482
1483 /*ARGSUSED*/
1484 static int
1485 scsa1394_cmd_cdb_dma_alloc(scsa1394_state_t *sp, scsa1394_cmd_t *cmd,
1486 int flags, int (*callback)(), caddr_t arg)
1487 {
1488 if (sbp2_task_orb_alloc(cmd->sc_lun->l_lun, &cmd->sc_task,
1489 sizeof (scsa1394_cmd_orb_t)) != SBP2_SUCCESS) {
1490 return (DDI_FAILURE);
1491 }
1492
1493 cmd->sc_flags |= SCSA1394_CMD_DMA_CDB_VALID;
1494 return (DDI_SUCCESS);
1495 }
1496
1497 /*ARGSUSED*/
1498 static void
1499 scsa1394_cmd_cdb_dma_free(scsa1394_state_t *sp, scsa1394_cmd_t *cmd)
1500 {
1501 sbp2_task_orb_free(cmd->sc_lun->l_lun, &cmd->sc_task);
1502 cmd->sc_flags &= ~SCSA1394_CMD_DMA_CDB_VALID;
1503 }
1504
1505 /*
1506 * buffer resources
1507 */
1508 static int
1509 scsa1394_cmd_buf_dma_alloc(scsa1394_state_t *sp, scsa1394_cmd_t *cmd,
1510 int flags, int (*callback)(), caddr_t arg, struct buf *bp)
1511 {
1512 scsa1394_lun_t *lp = cmd->sc_lun;
1513 int kf = (callback == SLEEP_FUNC) ? KM_SLEEP : KM_NOSLEEP;
1514 int dma_flags;
1515 ddi_dma_cookie_t dmac;
1516 uint_t ccount;
1517 int error;
1518 int ret;
1519
1520 cmd->sc_bp = bp;
1521
1522 if ((ddi_dma_alloc_handle(sp->s_dip, &sp->s_buf_dma_attr, callback,
1523 NULL, &cmd->sc_buf_dma_hdl)) != DDI_SUCCESS) {
1524 bioerror(bp, 0);
1525 return (DDI_FAILURE);
1526 }
1527
1528 cmd->sc_flags &= ~SCSA1394_CMD_RDWR;
1529 if (bp->b_flags & B_READ) {
1530 dma_flags = DDI_DMA_READ;
1531 cmd->sc_flags |= SCSA1394_CMD_READ;
1532 } else {
1533 dma_flags = DDI_DMA_WRITE;
1534 cmd->sc_flags |= SCSA1394_CMD_WRITE;
1535 }
1536 if (flags & PKT_CONSISTENT) {
1537 dma_flags |= DDI_DMA_CONSISTENT;
1538 }
1539 if (flags & PKT_DMA_PARTIAL) {
1540 dma_flags |= DDI_DMA_PARTIAL;
1541 }
1542
1543 ret = ddi_dma_buf_bind_handle(cmd->sc_buf_dma_hdl, bp, dma_flags,
1544 callback, arg, &dmac, &ccount);
1545
1546 switch (ret) {
1547 case DDI_DMA_MAPPED:
1548 cmd->sc_nwin = 1;
1549 cmd->sc_curwin = 0;
1550 cmd->sc_win_offset = 0;
1551 cmd->sc_win_len = bp->b_bcount;
1552 break;
1553
1554 case DDI_DMA_PARTIAL_MAP:
1555 /* retrieve number of windows and first window cookie */
1556 cmd->sc_curwin = 0;
1557 if ((ddi_dma_numwin(cmd->sc_buf_dma_hdl, &cmd->sc_nwin) !=
1558 DDI_SUCCESS) ||
1559 (ddi_dma_getwin(cmd->sc_buf_dma_hdl, cmd->sc_curwin,
1560 &cmd->sc_win_offset, &cmd->sc_win_len, &dmac, &ccount) !=
1561 DDI_SUCCESS)) {
1562 (void) ddi_dma_unbind_handle(cmd->sc_buf_dma_hdl);
1563 ddi_dma_free_handle(&cmd->sc_buf_dma_hdl);
1564 return (DDI_FAILURE);
1565 }
1566 lp->l_stat.stat_cmd_buf_dma_partial++;
1567 break;
1568
1569 case DDI_DMA_NORESOURCES:
1570 error = 0;
1571 goto map_error;
1572
1573 case DDI_DMA_BADATTR:
1574 case DDI_DMA_NOMAPPING:
1575 error = EFAULT;
1576 goto map_error;
1577
1578 default:
1579 error = EINVAL;
1580
1581 map_error:
1582 bioerror(bp, error);
1583 lp->l_stat.stat_err_cmd_buf_dbind++;
1584 ddi_dma_free_handle(&cmd->sc_buf_dma_hdl);
1585 return (DDI_FAILURE);
1586 }
1587 cmd->sc_flags |= SCSA1394_CMD_DMA_BUF_BIND_VALID;
1588
1589 /*
1590 * setup page table if needed
1591 */
1592 if ((ccount == 1) && (dmac.dmac_size <= SBP2_PT_SEGSIZE_MAX) &&
1593 (!sp->s_symbios ||
1594 (dmac.dmac_size <= scsa1394_symbios_page_size))) {
1595 cmd->sc_buf_nsegs = 1;
1596 cmd->sc_buf_seg_mem.ss_len = dmac.dmac_size;
1597 cmd->sc_buf_seg_mem.ss_daddr = dmac.dmac_address;
1598 cmd->sc_buf_seg = &cmd->sc_buf_seg_mem;
1599 } else {
1600 /* break window into segments */
1601 if (scsa1394_cmd_dmac2seg(sp, cmd, &dmac, ccount, kf) !=
1602 DDI_SUCCESS) {
1603 scsa1394_cmd_buf_dma_free(sp, cmd);
1604 bioerror(bp, 0);
1605 return (DDI_FAILURE);
1606 }
1607
1608 /* allocate DMA resources for page table */
1609 if (scsa1394_cmd_pt_dma_alloc(sp, cmd, callback, arg,
1610 cmd->sc_buf_nsegs) != DDI_SUCCESS) {
1611 scsa1394_cmd_buf_dma_free(sp, cmd);
1612 bioerror(bp, 0);
1613 return (DDI_FAILURE);
1614 }
1615 }
1616
1617 /* allocate 1394 addresses for segments */
1618 if (scsa1394_cmd_buf_addr_alloc(sp, cmd) != DDI_SUCCESS) {
1619 scsa1394_cmd_buf_dma_free(sp, cmd);
1620 bioerror(bp, 0);
1621 return (DDI_FAILURE);
1622 }
1623
1624 return (DDI_SUCCESS);
1625 }
1626
1627 static void
1628 scsa1394_cmd_buf_dma_free(scsa1394_state_t *sp, scsa1394_cmd_t *cmd)
1629 {
1630 scsa1394_cmd_buf_addr_free(sp, cmd);
1631 if (cmd->sc_flags & SCSA1394_CMD_DMA_BUF_PT_VALID) {
1632 scsa1394_cmd_pt_dma_free(sp, cmd);
1633 }
1634 scsa1394_cmd_seg_free(sp, cmd);
1635 if (cmd->sc_flags & SCSA1394_CMD_DMA_BUF_BIND_VALID) {
1636 (void) ddi_dma_unbind_handle(cmd->sc_buf_dma_hdl);
1637 ddi_dma_free_handle(&cmd->sc_buf_dma_hdl);
1638 }
1639 cmd->sc_flags &= ~(SCSA1394_CMD_DMA_BUF_VALID | SCSA1394_CMD_RDWR);
1640 }
1641
1642 /*
1643 * Break a set DMA cookies into segments suitable for SBP-2 page table.
1644 * This routine can reuse/reallocate segment array from previous calls.
1645 */
1646 static int
1647 scsa1394_cmd_dmac2seg(scsa1394_state_t *sp, scsa1394_cmd_t *cmd,
1648 ddi_dma_cookie_t *dmac, uint_t ccount, int kf)
1649 {
1650 scsa1394_lun_t *lp = cmd->sc_lun;
1651 int i;
1652 int nsegs;
1653 size_t segsize_max;
1654 size_t dmac_resid;
1655 uint32_t dmac_addr;
1656 scsa1394_cmd_seg_t *seg;
1657
1658 if (!sp->s_symbios) {
1659 /*
1660 * Number of segments is unknown at this point. Start with
1661 * a reasonable estimate and grow it later if needed.
1662 */
1663 nsegs = max(ccount, cmd->sc_win_len / SBP2_PT_SEGSIZE_MAX) * 2;
1664 segsize_max = SBP2_PT_SEGSIZE_MAX;
1665 } else {
1666 /*
1667 * For Symbios workaround we know exactly the number of segments
1668 * Additional segment may be needed if buffer is not aligned.
1669 */
1670 nsegs =
1671 howmany(cmd->sc_win_len, scsa1394_symbios_page_size) + 1;
1672 segsize_max = scsa1394_symbios_page_size;
1673 }
1674
1675 if (nsegs > cmd->sc_buf_nsegs_alloc) {
1676 if ((cmd->sc_buf_seg = scsa1394_kmem_realloc(cmd->sc_buf_seg,
1677 cmd->sc_buf_nsegs_alloc, nsegs,
1678 sizeof (scsa1394_cmd_seg_t), kf)) == NULL) {
1679 cmd->sc_buf_nsegs_alloc = 0;
1680 return (DDI_FAILURE);
1681 }
1682 cmd->sc_buf_nsegs_alloc = nsegs;
1683 }
1684
1685 /* each cookie maps into one or more segments */
1686 cmd->sc_buf_nsegs = 0;
1687 i = ccount;
1688 for (;;) {
1689 dmac_resid = dmac->dmac_size;
1690 dmac_addr = dmac->dmac_address;
1691 while (dmac_resid > 0) {
1692 /* grow array if needed */
1693 if (cmd->sc_buf_nsegs >= cmd->sc_buf_nsegs_alloc) {
1694 if ((cmd->sc_buf_seg = scsa1394_kmem_realloc(
1695 cmd->sc_buf_seg,
1696 cmd->sc_buf_nsegs_alloc,
1697 cmd->sc_buf_nsegs_alloc + ccount,
1698 sizeof (scsa1394_cmd_seg_t), kf)) == NULL) {
1699 return (DDI_FAILURE);
1700 }
1701 cmd->sc_buf_nsegs_alloc += ccount;
1702 }
1703
1704 seg = &cmd->sc_buf_seg[cmd->sc_buf_nsegs];
1705 seg->ss_len = min(dmac_resid, segsize_max);
1706 seg->ss_daddr = (uint64_t)dmac_addr;
1707 dmac_addr += seg->ss_len;
1708 dmac_resid -= seg->ss_len;
1709 cmd->sc_buf_nsegs++;
1710 }
1711 ASSERT(dmac_resid == 0);
1712
1713 /* grab next cookie */
1714 if (--i <= 0) {
1715 break;
1716 }
1717 ddi_dma_nextcookie(cmd->sc_buf_dma_hdl, dmac);
1718 }
1719
1720 if (cmd->sc_buf_nsegs > lp->l_stat.stat_cmd_buf_max_nsegs) {
1721 lp->l_stat.stat_cmd_buf_max_nsegs = cmd->sc_buf_nsegs;
1722 }
1723
1724 return (DDI_SUCCESS);
1725 }
1726
1727 /*ARGSUSED*/
1728 static void
1729 scsa1394_cmd_seg_free(scsa1394_state_t *sp, scsa1394_cmd_t *cmd)
1730 {
1731 if (cmd->sc_buf_nsegs_alloc > 0) {
1732 kmem_free(cmd->sc_buf_seg, cmd->sc_buf_nsegs_alloc *
1733 sizeof (scsa1394_cmd_seg_t));
1734 }
1735 cmd->sc_buf_seg = NULL;
1736 cmd->sc_buf_nsegs = 0;
1737 cmd->sc_buf_nsegs_alloc = 0;
1738 }
1739
1740 static int
1741 scsa1394_cmd_pt_dma_alloc(scsa1394_state_t *sp, scsa1394_cmd_t *cmd,
1742 int (*callback)(), caddr_t arg, int cnt)
1743 {
1744 scsa1394_lun_t *lp = cmd->sc_lun;
1745 size_t len, rlen;
1746 uint_t ccount;
1747 t1394_alloc_addr_t aa;
1748 int result;
1749
1750 /* allocate DMA memory for page table */
1751 if ((ddi_dma_alloc_handle(sp->s_dip, &sp->s_pt_dma_attr,
1752 callback, NULL, &cmd->sc_pt_dma_hdl)) != DDI_SUCCESS) {
1753 lp->l_stat.stat_err_cmd_pt_dmem_alloc++;
1754 return (DDI_FAILURE);
1755 }
1756
1757 cmd->sc_pt_ent_alloc = cnt;
1758 len = cmd->sc_pt_ent_alloc * SBP2_PT_ENT_SIZE;
1759 if (ddi_dma_mem_alloc(cmd->sc_pt_dma_hdl, len,
1760 &sp->s_attachinfo.acc_attr, DDI_DMA_CONSISTENT, callback, arg,
1761 &cmd->sc_pt_kaddr, &rlen, &cmd->sc_pt_acc_hdl) != DDI_SUCCESS) {
1762 ddi_dma_free_handle(&cmd->sc_pt_dma_hdl);
1763 lp->l_stat.stat_err_cmd_pt_dmem_alloc++;
1764 return (DDI_FAILURE);
1765 }
1766
1767 if (ddi_dma_addr_bind_handle(cmd->sc_pt_dma_hdl, NULL,
1768 cmd->sc_pt_kaddr, len, DDI_DMA_READ | DDI_DMA_CONSISTENT,
1769 callback, arg, &cmd->sc_pt_dmac, &ccount) != DDI_DMA_MAPPED) {
1770 ddi_dma_mem_free(&cmd->sc_pt_acc_hdl);
1771 ddi_dma_free_handle(&cmd->sc_pt_dma_hdl);
1772 lp->l_stat.stat_err_cmd_pt_dmem_alloc++;
1773 return (DDI_FAILURE);
1774 }
1775 ASSERT(ccount == 1); /* because dma_attr_sgllen is 1 */
1776
1777 /* allocate 1394 address for page table */
1778 aa.aa_type = T1394_ADDR_FIXED;
1779 aa.aa_length = len;
1780 aa.aa_address = cmd->sc_pt_dmac.dmac_address;
1781 aa.aa_evts.recv_read_request = NULL;
1782 aa.aa_evts.recv_write_request = NULL;
1783 aa.aa_evts.recv_lock_request = NULL;
1784 aa.aa_arg = NULL;
1785 aa.aa_kmem_bufp = NULL;
1786 aa.aa_enable = T1394_ADDR_RDENBL;
1787 if (t1394_alloc_addr(sp->s_t1394_hdl, &aa, 0, &result) != DDI_SUCCESS) {
1788 (void) ddi_dma_unbind_handle(cmd->sc_pt_dma_hdl);
1789 ddi_dma_mem_free(&cmd->sc_pt_acc_hdl);
1790 ddi_dma_free_handle(&cmd->sc_pt_dma_hdl);
1791 lp->l_stat.stat_err_cmd_pt_addr_alloc++;
1792 return (DDI_FAILURE);
1793 }
1794 ASSERT(aa.aa_address != 0);
1795 cmd->sc_pt_baddr = aa.aa_address;
1796 cmd->sc_pt_addr_hdl = aa.aa_hdl;
1797
1798 cmd->sc_flags |= SCSA1394_CMD_DMA_BUF_PT_VALID;
1799
1800 return (DDI_SUCCESS);
1801 }
1802
1803 static void
1804 scsa1394_cmd_pt_dma_free(scsa1394_state_t *sp, scsa1394_cmd_t *cmd)
1805 {
1806 (void) ddi_dma_unbind_handle(cmd->sc_pt_dma_hdl);
1807 ddi_dma_mem_free(&cmd->sc_pt_acc_hdl);
1808 ddi_dma_free_handle(&cmd->sc_pt_dma_hdl);
1809 (void) t1394_free_addr(sp->s_t1394_hdl, &cmd->sc_pt_addr_hdl, 0);
1810 cmd->sc_flags &= ~SCSA1394_CMD_DMA_BUF_PT_VALID;
1811 }
1812
1813 /*
1814 * allocate 1394 addresses for all buffer segments
1815 */
1816 static int
1817 scsa1394_cmd_buf_addr_alloc(scsa1394_state_t *sp, scsa1394_cmd_t *cmd)
1818 {
1819 scsa1394_lun_t *lp = cmd->sc_lun;
1820 t1394_alloc_addr_t aa;
1821 scsa1394_cmd_seg_t *seg;
1822 int result;
1823 int i;
1824
1825 aa.aa_type = T1394_ADDR_FIXED;
1826 aa.aa_evts.recv_read_request = NULL;
1827 aa.aa_evts.recv_write_request = NULL;
1828 aa.aa_evts.recv_lock_request = NULL;
1829 aa.aa_arg = NULL;
1830 aa.aa_kmem_bufp = NULL;
1831 if (cmd->sc_flags & SCSA1394_CMD_READ) {
1832 aa.aa_enable = T1394_ADDR_RDENBL;
1833 } else {
1834 aa.aa_enable = T1394_ADDR_WRENBL;
1835 }
1836
1837 for (i = 0; i < cmd->sc_buf_nsegs; i++) {
1838 seg = &cmd->sc_buf_seg[i];
1839
1840 /* segment bus address */
1841 aa.aa_length = seg->ss_len;
1842 aa.aa_address = seg->ss_daddr;
1843
1844 if (t1394_alloc_addr(sp->s_t1394_hdl, &aa, 0, &result) !=
1845 DDI_SUCCESS) {
1846 lp->l_stat.stat_err_cmd_buf_addr_alloc++;
1847 return (DDI_FAILURE);
1848 }
1849 ASSERT(aa.aa_address != 0);
1850 seg->ss_baddr = aa.aa_address;
1851 seg->ss_addr_hdl = aa.aa_hdl;
1852 }
1853
1854 cmd->sc_flags |= SCSA1394_CMD_DMA_BUF_ADDR_VALID;
1855
1856 return (DDI_SUCCESS);
1857 }
1858
1859 static void
1860 scsa1394_cmd_buf_addr_free(scsa1394_state_t *sp, scsa1394_cmd_t *cmd)
1861 {
1862 int i;
1863
1864 for (i = 0; i < cmd->sc_buf_nsegs; i++) {
1865 if (cmd->sc_buf_seg[i].ss_addr_hdl) {
1866 (void) t1394_free_addr(sp->s_t1394_hdl,
1867 &cmd->sc_buf_seg[i].ss_addr_hdl, 0);
1868 }
1869 }
1870 cmd->sc_flags &= ~SCSA1394_CMD_DMA_BUF_ADDR_VALID;
1871 }
1872
1873 /*
1874 * move to next DMA window
1875 */
1876 static int
1877 scsa1394_cmd_buf_dma_move(scsa1394_state_t *sp, scsa1394_cmd_t *cmd)
1878 {
1879 /* scsa1394_lun_t *lp = cmd->sc_lun; */
1880 ddi_dma_cookie_t dmac;
1881 uint_t ccount;
1882
1883 /* for small pkts, leave things where they are (says WDD) */
1884 if ((cmd->sc_curwin == cmd->sc_nwin) && (cmd->sc_nwin == 1)) {
1885 return (DDI_SUCCESS);
1886 }
1887 if (++cmd->sc_curwin >= cmd->sc_nwin) {
1888 return (DDI_FAILURE);
1889 }
1890 if (ddi_dma_getwin(cmd->sc_buf_dma_hdl, cmd->sc_curwin,
1891 &cmd->sc_win_offset, &cmd->sc_win_len, &dmac, &ccount) !=
1892 DDI_SUCCESS) {
1893 return (DDI_FAILURE);
1894 }
1895
1896 scsa1394_cmd_buf_addr_free(sp, cmd);
1897
1898 /*
1899 * setup page table if needed
1900 */
1901 if ((ccount == 1) && (dmac.dmac_size <= SBP2_PT_SEGSIZE_MAX) &&
1902 (!sp->s_symbios ||
1903 (dmac.dmac_size <= scsa1394_symbios_page_size))) {
1904 /* but first, free old resources */
1905 if (cmd->sc_flags & SCSA1394_CMD_DMA_BUF_PT_VALID) {
1906 scsa1394_cmd_pt_dma_free(sp, cmd);
1907 }
1908 scsa1394_cmd_seg_free(sp, cmd);
1909
1910 cmd->sc_buf_nsegs = 1;
1911 cmd->sc_buf_seg_mem.ss_len = dmac.dmac_size;
1912 cmd->sc_buf_seg_mem.ss_daddr = dmac.dmac_address;
1913 cmd->sc_buf_seg = &cmd->sc_buf_seg_mem;
1914 } else {
1915 /* break window into segments */
1916 if (scsa1394_cmd_dmac2seg(sp, cmd, &dmac, ccount, KM_NOSLEEP) !=
1917 DDI_SUCCESS) {
1918 return (DDI_FAILURE);
1919 }
1920
1921 /* allocate DMA resources */
1922 if (scsa1394_cmd_pt_dma_alloc(sp, cmd, NULL_FUNC, NULL,
1923 cmd->sc_buf_nsegs) != DDI_SUCCESS) {
1924 return (DDI_FAILURE);
1925 }
1926 }
1927
1928 /* allocate 1394 addresses for segments */
1929 if (scsa1394_cmd_buf_addr_alloc(sp, cmd) != DDI_SUCCESS) {
1930 return (DDI_FAILURE);
1931 }
1932
1933 return (DDI_SUCCESS);
1934 }
1935
1936 /*
1937 *
1938 * --- pkt and data transfer routines
1939 *
1940 */
1941 static int
1942 scsa1394_scsi_start(struct scsi_address *ap, struct scsi_pkt *pkt)
1943 {
1944 scsa1394_state_t *sp = ADDR2STATE(ap);
1945 scsa1394_cmd_t *cmd = PKT2CMD(pkt);
1946 scsa1394_lun_t *lp = cmd->sc_lun;
1947 int ret;
1948
1949 /*
1950 * since we don't support polled I/O, just accept the packet
1951 * so the rest of the file systems get synced properly
1952 */
1953 if (ddi_in_panic()) {
1954 scsa1394_prepare_pkt(sp, pkt);
1955 return (TRAN_ACCEPT);
1956 }
1957
1958 /* polling not supported yet */
1959 if (pkt->pkt_flags & FLAG_NOINTR) {
1960 return (TRAN_BADPKT);
1961 }
1962
1963 mutex_enter(&sp->s_mutex);
1964 if (sp->s_dev_state != SCSA1394_DEV_ONLINE) {
1965 /*
1966 * If device is temporarily gone due to bus reset,
1967 * return busy to prevent prevent scary console messages.
1968 * If permanently gone, leave it to scsa1394_cmd_fake_comp().
1969 */
1970 if (sp->s_dev_state == SCSA1394_DEV_BUS_RESET) {
1971 mutex_exit(&sp->s_mutex);
1972 return (TRAN_BUSY);
1973 }
1974 }
1975 mutex_exit(&sp->s_mutex);
1976
1977 if ((ap->a_lun >= sp->s_nluns) ||
1978 (ap->a_lun != pkt->pkt_address.a_lun)) {
1979 return (TRAN_BADPKT);
1980 }
1981
1982 scsa1394_prepare_pkt(sp, pkt);
1983
1984 /* some commands may require fake completion */
1985 if ((ret = scsa1394_cmd_fake_comp(sp, cmd)) == DDI_SUCCESS) {
1986 return (TRAN_ACCEPT);
1987 }
1988
1989 scsa1394_cmd_fill_cdb(lp, cmd);
1990
1991 if (cmd->sc_flags & SCSA1394_CMD_DMA_BUF_PT_VALID) {
1992 scsa1394_sbp2_seg2pt(lp, cmd);
1993 }
1994
1995 scsa1394_sbp2_cmd2orb(lp, cmd); /* convert into ORB */
1996
1997 if ((ret = scsa1394_sbp2_start(lp, cmd)) != TRAN_BUSY) {
1998 scsa1394_sbp2_nudge(lp);
1999 }
2000
2001 return (ret);
2002 }
2003
2004 /*ARGSUSED*/
2005 static void
2006 scsa1394_prepare_pkt(scsa1394_state_t *sp, struct scsi_pkt *pkt)
2007 {
2008 scsa1394_cmd_t *cmd = PKT2CMD(pkt);
2009
2010 pkt->pkt_reason = CMD_CMPLT;
2011 pkt->pkt_state = 0;
2012 pkt->pkt_statistics = 0;
2013 *(pkt->pkt_scbp) = STATUS_GOOD;
2014
2015 if (cmd) {
2016 cmd->sc_timeout = pkt->pkt_time;
2017
2018 /* workarounds */
2019 switch (pkt->pkt_cdbp[0]) {
2020 /*
2021 * sd does START_STOP_UNIT during attach with a 200 sec timeout.
2022 * at this time devi_lock is held, prtconf will be stuck.
2023 * reduce timeout for the time being.
2024 */
2025 case SCMD_START_STOP:
2026 cmd->sc_timeout = min(cmd->sc_timeout,
2027 scsa1394_start_stop_timeout_max);
2028 break;
2029 default:
2030 break;
2031 }
2032 }
2033 }
2034
2035 static void
2036 scsa1394_cmd_fill_cdb(scsa1394_lun_t *lp, scsa1394_cmd_t *cmd)
2037 {
2038 cmd->sc_cdb_actual_len = cmd->sc_cdb_len;
2039
2040 mutex_enter(&lp->l_mutex);
2041
2042 switch (lp->l_dtype_orig) {
2043 case DTYPE_DIRECT:
2044 case DTYPE_RODIRECT:
2045 case DTYPE_OPTICAL:
2046 case SCSA1394_DTYPE_RBC:
2047 scsa1394_cmd_fill_cdb_rbc(lp, cmd);
2048 break;
2049 default:
2050 scsa1394_cmd_fill_cdb_other(lp, cmd);
2051 break;
2052 }
2053
2054 mutex_exit(&lp->l_mutex);
2055 }
2056
2057 static void
2058 scsa1394_cmd_fill_cdb_rbc(scsa1394_lun_t *lp, scsa1394_cmd_t *cmd)
2059 {
2060 scsa1394_state_t *sp = lp->l_sp;
2061 struct scsi_pkt *pkt = CMD2PKT(cmd);
2062 int lba, opcode;
2063 struct buf *bp = cmd->sc_bp;
2064 size_t len;
2065 size_t blk_size;
2066 int sz;
2067
2068 opcode = pkt->pkt_cdbp[0];
2069 blk_size = lp->l_lba_size;
2070
2071 switch (opcode) {
2072 case SCMD_READ:
2073 /* RBC only supports 10-byte read/write */
2074 lba = SCSA1394_LBA_6BYTE(pkt);
2075 len = SCSA1394_LEN_6BYTE(pkt);
2076 opcode = SCMD_READ_G1;
2077 cmd->sc_cdb_actual_len = CDB_GROUP1;
2078 break;
2079 case SCMD_WRITE:
2080 lba = SCSA1394_LBA_6BYTE(pkt);
2081 len = SCSA1394_LEN_6BYTE(pkt);
2082 opcode = SCMD_WRITE_G1;
2083 cmd->sc_cdb_actual_len = CDB_GROUP1;
2084 break;
2085 case SCMD_READ_G1:
2086 case SCMD_READ_LONG:
2087 lba = SCSA1394_LBA_10BYTE(pkt);
2088 len = SCSA1394_LEN_10BYTE(pkt);
2089 break;
2090 case SCMD_WRITE_G1:
2091 case SCMD_WRITE_LONG:
2092 lba = SCSA1394_LBA_10BYTE(pkt);
2093 len = SCSA1394_LEN_10BYTE(pkt);
2094 if ((lp->l_dtype_orig == DTYPE_RODIRECT) &&
2095 (bp != NULL) && (len != 0)) {
2096 sz = SCSA1394_CDRW_BLKSZ(bp->b_bcount, len);
2097 if (SCSA1394_VALID_CDRW_BLKSZ(sz)) {
2098 blk_size = sz;
2099 }
2100 }
2101 break;
2102 case SCMD_READ_CD:
2103 lba = SCSA1394_LBA_10BYTE(pkt);
2104 len = SCSA1394_LEN_READ_CD(pkt);
2105 blk_size = scsa1394_cmd_read_cd_blk_size(pkt->pkt_cdbp[1] >> 2);
2106 break;
2107 case SCMD_READ_G5:
2108 lba = SCSA1394_LBA_12BYTE(pkt);
2109 len = SCSA1394_LEN_12BYTE(pkt);
2110 break;
2111 case SCMD_WRITE_G5:
2112 lba = SCSA1394_LBA_12BYTE(pkt);
2113 len = SCSA1394_LEN_12BYTE(pkt);
2114 break;
2115 default:
2116 /* no special mapping for other commands */
2117 scsa1394_cmd_fill_cdb_other(lp, cmd);
2118 return;
2119 }
2120 cmd->sc_blk_size = blk_size;
2121
2122 /* limit xfer length for Symbios workaround */
2123 if (sp->s_symbios && (len * blk_size > scsa1394_symbios_size_max)) {
2124 cmd->sc_flags |= SCSA1394_CMD_SYMBIOS_BREAKUP;
2125
2126 cmd->sc_total_blks = cmd->sc_resid_blks = len;
2127
2128 len = scsa1394_symbios_size_max / blk_size;
2129 }
2130 cmd->sc_xfer_blks = len;
2131 cmd->sc_xfer_bytes = len * blk_size;
2132
2133 /* finalize new CDB */
2134 switch (pkt->pkt_cdbp[0]) {
2135 case SCMD_READ:
2136 case SCMD_WRITE:
2137 /*
2138 * We rewrite READ/WRITE G0 commands as READ/WRITE G1.
2139 * Build new cdb from scatch.
2140 * The lba and length fields is updated below.
2141 */
2142 bzero(cmd->sc_cdb, cmd->sc_cdb_actual_len);
2143 break;
2144 default:
2145 /*
2146 * Copy the non lba/len fields.
2147 * The lba and length fields is updated below.
2148 */
2149 bcopy(pkt->pkt_cdbp, cmd->sc_cdb, cmd->sc_cdb_actual_len);
2150 break;
2151 }
2152
2153 cmd->sc_cdb[0] = (uchar_t)opcode;
2154 scsa1394_cmd_fill_cdb_lba(cmd, lba);
2155 switch (opcode) {
2156 case SCMD_READ_CD:
2157 scsa1394_cmd_fill_read_cd_cdb_len(cmd, len);
2158 break;
2159 case SCMD_WRITE_G5:
2160 case SCMD_READ_G5:
2161 scsa1394_cmd_fill_12byte_cdb_len(cmd, len);
2162 break;
2163 default:
2164 scsa1394_cmd_fill_cdb_len(cmd, len);
2165 break;
2166 }
2167 }
2168
2169 /*ARGSUSED*/
2170 static void
2171 scsa1394_cmd_fill_cdb_other(scsa1394_lun_t *lp, scsa1394_cmd_t *cmd)
2172 {
2173 struct scsi_pkt *pkt = CMD2PKT(cmd);
2174
2175 cmd->sc_xfer_bytes = cmd->sc_win_len;
2176 cmd->sc_xfer_blks = cmd->sc_xfer_bytes / lp->l_lba_size;
2177 cmd->sc_total_blks = cmd->sc_xfer_blks;
2178 cmd->sc_lba = 0;
2179
2180 bcopy(pkt->pkt_cdbp, cmd->sc_cdb, cmd->sc_cdb_len);
2181 }
2182
2183 /*
2184 * fill up parts of CDB
2185 */
2186 static void
2187 scsa1394_cmd_fill_cdb_len(scsa1394_cmd_t *cmd, int len)
2188 {
2189 cmd->sc_cdb[7] = len >> 8;
2190 cmd->sc_cdb[8] = (uchar_t)len;
2191 }
2192
2193 static void
2194 scsa1394_cmd_fill_cdb_lba(scsa1394_cmd_t *cmd, int lba)
2195 {
2196 cmd->sc_cdb[2] = lba >> 24;
2197 cmd->sc_cdb[3] = lba >> 16;
2198 cmd->sc_cdb[4] = lba >> 8;
2199 cmd->sc_cdb[5] = (uchar_t)lba;
2200 cmd->sc_lba = lba;
2201 }
2202
2203 static void
2204 scsa1394_cmd_fill_12byte_cdb_len(scsa1394_cmd_t *cmd, int len)
2205 {
2206 cmd->sc_cdb[6] = len >> 24;
2207 cmd->sc_cdb[7] = len >> 16;
2208 cmd->sc_cdb[8] = len >> 8;
2209 cmd->sc_cdb[9] = (uchar_t)len;
2210 }
2211
2212 static void
2213 scsa1394_cmd_fill_read_cd_cdb_len(scsa1394_cmd_t *cmd, int len)
2214 {
2215 cmd->sc_cdb[6] = len >> 16;
2216 cmd->sc_cdb[7] = len >> 8;
2217 cmd->sc_cdb[8] = (uchar_t)len;
2218 }
2219
2220 /*
2221 * For SCMD_READ_CD, figure out the block size based on expected sector type.
2222 * See MMC SCSI Specs section 6.1.15
2223 */
2224 static int
2225 scsa1394_cmd_read_cd_blk_size(uchar_t expected_sector_type)
2226 {
2227 int blk_size;
2228
2229 switch (expected_sector_type) {
2230 case READ_CD_EST_CDDA:
2231 blk_size = CDROM_BLK_2352;
2232 break;
2233 case READ_CD_EST_MODE2:
2234 blk_size = CDROM_BLK_2336;
2235 break;
2236 case READ_CD_EST_MODE2FORM2:
2237 blk_size = CDROM_BLK_2324;
2238 break;
2239 case READ_CD_EST_MODE2FORM1:
2240 case READ_CD_EST_ALLTYPE:
2241 case READ_CD_EST_MODE1:
2242 default:
2243 blk_size = CDROM_BLK_2048;
2244 }
2245
2246 return (blk_size);
2247 }
2248
2249 /*ARGSUSED*/
2250 static int
2251 scsa1394_cmd_fake_mode_sense(scsa1394_state_t *sp, scsa1394_cmd_t *cmd)
2252 {
2253 struct scsi_pkt *pkt = CMD2PKT(cmd);
2254 struct scsi_arq_status *arqp = (struct scsi_arq_status *)pkt->pkt_scbp;
2255 struct scsi_extended_sense *esp = &arqp->sts_sensedata;
2256
2257 *(pkt->pkt_scbp) = STATUS_CHECK;
2258 *(uint8_t *)&arqp->sts_rqpkt_status = STATUS_GOOD;
2259 arqp->sts_rqpkt_reason = CMD_CMPLT;
2260 arqp->sts_rqpkt_resid = 0;
2261 arqp->sts_rqpkt_state |= STATE_XFERRED_DATA;
2262 arqp->sts_rqpkt_statistics = 0;
2263
2264 bzero(esp, sizeof (struct scsi_extended_sense));
2265
2266 esp->es_class = CLASS_EXTENDED_SENSE;
2267
2268 esp->es_key = KEY_ILLEGAL_REQUEST;
2269
2270 pkt->pkt_reason = CMD_CMPLT;
2271 pkt->pkt_state |= (STATE_GOT_BUS | STATE_GOT_TARGET | STATE_SENT_CMD |
2272 STATE_XFERRED_DATA | STATE_GOT_STATUS);
2273
2274 if (pkt->pkt_comp) {
2275 (*pkt->pkt_comp)(pkt);
2276 }
2277 return (DDI_SUCCESS);
2278 }
2279
2280 /*ARGSUSED*/
2281 static int
2282 scsa1394_cmd_fake_inquiry(scsa1394_state_t *sp, scsa1394_cmd_t *cmd)
2283 {
2284 scsa1394_lun_t *lp = cmd->sc_lun;
2285 struct scsi_pkt *pkt = CMD2PKT(cmd);
2286 struct scsi_inquiry *inq;
2287
2288 /* copy fabricated inquiry data */
2289 inq = (struct scsi_inquiry *)cmd->sc_bp->b_un.b_addr;
2290 bcopy(&lp->l_fake_inq, inq, sizeof (struct scsi_inquiry));
2291
2292 pkt->pkt_resid -= sizeof (struct scsi_inquiry);
2293 pkt->pkt_reason = CMD_CMPLT;
2294 pkt->pkt_state |= (STATE_GOT_BUS | STATE_GOT_TARGET | STATE_SENT_CMD |
2295 STATE_XFERRED_DATA | STATE_GOT_STATUS);
2296
2297 if (pkt->pkt_comp) {
2298 (*pkt->pkt_comp)(pkt);
2299 }
2300 return (DDI_SUCCESS);
2301 }
2302
2303 /*
2304 * If command allows fake completion (without actually being transported),
2305 * call completion callback and return DDI_SUCCESS.
2306 * Otherwise return DDI_FAILURE.
2307 */
2308 static int
2309 scsa1394_cmd_fake_comp(scsa1394_state_t *sp, scsa1394_cmd_t *cmd)
2310 {
2311 struct scsi_pkt *pkt = CMD2PKT(cmd);
2312 scsa1394_lun_t *lp = cmd->sc_lun;
2313 int ret = DDI_SUCCESS;
2314
2315 /*
2316 * agreement with sd in case of device hot removal
2317 * is to fake completion with CMD_DEV_GONE
2318 */
2319 mutex_enter(&sp->s_mutex);
2320 if (sp->s_dev_state != SCSA1394_DEV_ONLINE) {
2321 mutex_exit(&sp->s_mutex);
2322 pkt->pkt_reason = CMD_DEV_GONE;
2323 if (pkt->pkt_comp) {
2324 (*pkt->pkt_comp)(pkt);
2325 }
2326 return (DDI_SUCCESS);
2327 }
2328 mutex_exit(&sp->s_mutex);
2329
2330 mutex_enter(&lp->l_mutex);
2331
2332 switch (pkt->pkt_cdbp[0]) {
2333 /*
2334 * RBC support for PRIN/PROUT is optional
2335 */
2336 case SCMD_PRIN:
2337 case SCMD_PROUT:
2338 if (!scsa1394_wrka_fake_prin) {
2339 ret = DDI_FAILURE;
2340 }
2341 break;
2342 /*
2343 * Some fixed disks don't like doorlock cmd. And they don't need it.
2344 */
2345 case SCMD_DOORLOCK:
2346 if (lp->l_rmb_orig != 0) {
2347 ret = DDI_FAILURE;
2348 }
2349 break;
2350 case SCMD_TEST_UNIT_READY:
2351 if (!lp->l_nosup_tur) {
2352 ret = DDI_FAILURE;
2353 }
2354 break;
2355 case SCMD_START_STOP:
2356 if (!lp->l_nosup_start_stop) {
2357 ret = DDI_FAILURE;
2358 }
2359 break;
2360 case SCMD_INQUIRY:
2361 if (!lp->l_nosup_inquiry) {
2362 ret = DDI_FAILURE;
2363 } else {
2364 mutex_exit(&lp->l_mutex);
2365 return (scsa1394_cmd_fake_inquiry(sp, cmd));
2366 }
2367 break;
2368 case SCMD_MODE_SENSE:
2369 if (!lp->l_mode_sense_fake) {
2370 ret = DDI_FAILURE;
2371 } else {
2372 mutex_exit(&lp->l_mutex);
2373 return (scsa1394_cmd_fake_mode_sense(sp, cmd));
2374 }
2375 default:
2376 ret = DDI_FAILURE;
2377 }
2378
2379 mutex_exit(&lp->l_mutex);
2380
2381 if (ret != DDI_SUCCESS) {
2382 return (ret);
2383 }
2384
2385 ASSERT(*(pkt->pkt_scbp) == STATUS_GOOD);
2386 ASSERT(pkt->pkt_reason == CMD_CMPLT);
2387 pkt->pkt_state |= (STATE_GOT_BUS | STATE_GOT_TARGET | STATE_SENT_CMD |
2388 STATE_XFERRED_DATA | STATE_GOT_STATUS);
2389
2390 if (pkt->pkt_comp) {
2391 (*pkt->pkt_comp)(pkt);
2392 }
2393 return (DDI_SUCCESS);
2394 }
2395
2396 /*
2397 * Returns DDI_SUCCESS if next xfer setup successfully, DDI_FAILURE otherwise.
2398 */
2399 static int
2400 scsa1394_cmd_setup_next_xfer(scsa1394_lun_t *lp, scsa1394_cmd_t *cmd)
2401 {
2402 struct scsi_pkt *pkt = CMD2PKT(cmd);
2403
2404 ASSERT(cmd->sc_flags & SCSA1394_CMD_SYMBIOS_BREAKUP);
2405
2406 cmd->sc_resid_blks -= cmd->sc_xfer_blks;
2407 if (cmd->sc_resid_blks <= 0) {
2408 pkt->pkt_resid = 0;
2409 return (DDI_FAILURE);
2410 }
2411
2412 scsa1394_cmd_adjust_cdb(lp, cmd);
2413
2414 scsa1394_sbp2_seg2pt(lp, cmd);
2415
2416 scsa1394_sbp2_cmd2orb(lp, cmd);
2417
2418 if (scsa1394_sbp2_start(lp, cmd) != TRAN_ACCEPT) {
2419 pkt->pkt_resid = cmd->sc_resid_blks * cmd->sc_blk_size;
2420 return (DDI_FAILURE);
2421 }
2422
2423 return (DDI_SUCCESS);
2424 }
2425
2426 /*
2427 * new lba = current lba + previous xfer len
2428 */
2429 /*ARGSUSED*/
2430 static void
2431 scsa1394_cmd_adjust_cdb(scsa1394_lun_t *lp, scsa1394_cmd_t *cmd)
2432 {
2433 int len;
2434
2435 ASSERT(cmd->sc_flags & SCSA1394_CMD_SYMBIOS_BREAKUP);
2436
2437 cmd->sc_lba += cmd->sc_xfer_blks;
2438 len = cmd->sc_resid_blks;
2439
2440 /* limit xfer length for Symbios workaround */
2441 if (len * cmd->sc_blk_size > scsa1394_symbios_size_max) {
2442 len = scsa1394_symbios_size_max / cmd->sc_blk_size;
2443 }
2444
2445 switch (cmd->sc_cdb[0]) {
2446 case SCMD_READ_CD:
2447 scsa1394_cmd_fill_read_cd_cdb_len(cmd, len);
2448 break;
2449 case SCMD_WRITE_G5:
2450 case SCMD_READ_G5:
2451 scsa1394_cmd_fill_12byte_cdb_len(cmd, len);
2452 break;
2453 case SCMD_WRITE_G1:
2454 case SCMD_WRITE_LONG:
2455 default:
2456 scsa1394_cmd_fill_cdb_len(cmd, len);
2457 }
2458
2459 scsa1394_cmd_fill_cdb_lba(cmd, cmd->sc_lba);
2460
2461 cmd->sc_xfer_blks = len;
2462 cmd->sc_xfer_bytes = len * cmd->sc_blk_size;
2463 }
2464
2465 void
2466 scsa1394_cmd_status_proc(scsa1394_lun_t *lp, scsa1394_cmd_t *cmd)
2467 {
2468 struct scsi_pkt *pkt = CMD2PKT(cmd);
2469
2470 /* next iteration of partial xfer? */
2471 if ((pkt->pkt_reason == CMD_CMPLT) &&
2472 (cmd->sc_flags & SCSA1394_CMD_SYMBIOS_BREAKUP)) {
2473 if (scsa1394_cmd_setup_next_xfer(lp, cmd) == DDI_SUCCESS) {
2474 return;
2475 }
2476 }
2477 cmd->sc_flags &= ~SCSA1394_CMD_SYMBIOS_BREAKUP;
2478
2479 /* apply workarounds */
2480 if (pkt->pkt_reason == CMD_CMPLT) {
2481 scsa1394_cmd_status_wrka(lp, cmd);
2482 }
2483
2484 mutex_enter(&lp->l_mutex);
2485
2486 /* mode sense workaround */
2487 if (pkt->pkt_cdbp[0] == SCMD_MODE_SENSE) {
2488 if (pkt->pkt_reason == CMD_CMPLT) {
2489 lp->l_mode_sense_fail_cnt = 0;
2490 } else if (++lp->l_mode_sense_fail_cnt >=
2491 scsa1394_mode_sense_fail_max) {
2492 lp->l_mode_sense_fake = B_TRUE;
2493 }
2494 } else {
2495 lp->l_mode_sense_fail_cnt = 0;
2496 }
2497
2498 mutex_exit(&lp->l_mutex);
2499
2500 if (pkt->pkt_comp) {
2501 (*pkt->pkt_comp)(pkt);
2502 }
2503 }
2504
2505 static void
2506 scsa1394_cmd_status_wrka(scsa1394_lun_t *lp, scsa1394_cmd_t *cmd)
2507 {
2508 struct scsi_pkt *pkt = CMD2PKT(cmd);
2509
2510 mutex_enter(&lp->l_mutex);
2511
2512 switch (pkt->pkt_cdbp[0]) {
2513 case SCMD_INQUIRY: {
2514 struct scsi_inquiry *inq;
2515
2516 inq = (struct scsi_inquiry *)cmd->sc_bp->b_un.b_addr;
2517
2518 /* change dtype RBC to DIRECT, sd doesn't support RBC */
2519 lp->l_dtype_orig = inq->inq_dtype;
2520 if ((inq->inq_dtype == SCSA1394_DTYPE_RBC) &&
2521 scsa1394_wrka_rbc2direct) {
2522 inq->inq_dtype = DTYPE_DIRECT;
2523 }
2524
2525 /* force RMB to 1 */
2526 lp->l_rmb_orig = inq->inq_rmb;
2527 if (scsa1394_wrka_fake_rmb) {
2528 inq->inq_rmb = 1;
2529 }
2530 break;
2531 }
2532 case SCMD_READ_CAPACITY: {
2533 uint32_t *capacity_buf;
2534
2535 capacity_buf = (uint32_t *)cmd->sc_bp->b_un.b_addr;
2536
2537 if (lp->l_dtype_orig != DTYPE_RODIRECT) {
2538 lp->l_lba_size = min(BE_32(capacity_buf[1]), DEV_BSIZE);
2539 if (lp->l_lba_size == 0) {
2540 cmn_err(CE_WARN, "zero LBA size reported, "
2541 "possibly broken device");
2542 lp->l_lba_size = DEV_BSIZE;
2543 }
2544 } else {
2545 lp->l_lba_size = 2048;
2546 }
2547 }
2548 default:
2549 break;
2550 }
2551
2552 mutex_exit(&lp->l_mutex);
2553 }
2554
2555 /*
2556 * --- thread management
2557 *
2558 * dispatch a thread
2559 */
2560 int
2561 scsa1394_thr_dispatch(scsa1394_thread_t *thr)
2562 {
2563 scsa1394_lun_t *lp = thr->thr_lun;
2564 scsa1394_state_t *sp = lp->l_sp;
2565 int ret;
2566
2567 ASSERT(mutex_owned(&lp->l_mutex));
2568 ASSERT(thr->thr_state == SCSA1394_THR_INIT);
2569
2570 thr->thr_state = SCSA1394_THR_RUN;
2571
2572 ret = ddi_taskq_dispatch(sp->s_taskq, thr->thr_func, thr->thr_arg,
2573 KM_SLEEP);
2574 return (ret);
2575 }
2576
2577 /*
2578 * cancel thread
2579 */
2580 void
2581 scsa1394_thr_cancel(scsa1394_thread_t *thr)
2582 {
2583 scsa1394_lun_t *lp = thr->thr_lun;
2584
2585 ASSERT(mutex_owned(&lp->l_mutex));
2586
2587 thr->thr_req |= SCSA1394_THREQ_EXIT;
2588 cv_signal(&thr->thr_cv);
2589
2590 /* wait until the thread actually exits */
2591 do {
2592 if (cv_wait_sig(&thr->thr_cv, &lp->l_mutex) == 0) {
2593 break;
2594 }
2595 } while (thr->thr_state != SCSA1394_THR_EXIT);
2596 }
2597
2598 /*
2599 * wake thread
2600 */
2601 void
2602 scsa1394_thr_wake(scsa1394_thread_t *thr, int req)
2603 {
2604 scsa1394_lun_t *lp = thr->thr_lun;
2605
2606 ASSERT(mutex_owned(&lp->l_mutex));
2607
2608 thr->thr_req |= req;
2609 cv_signal(&thr->thr_cv);
2610 }
2611
2612 void
2613 scsa1394_thr_clear_req(scsa1394_thread_t *thr, int mask)
2614 {
2615 scsa1394_lun_t *lp = thr->thr_lun;
2616
2617 mutex_enter(&lp->l_mutex);
2618 thr->thr_req &= ~mask;
2619 mutex_exit(&lp->l_mutex);
2620 }
2621
2622 /*
2623 *
2624 * --- other routines
2625 *
2626 */
2627 static boolean_t
2628 scsa1394_is_my_child(dev_info_t *dip)
2629 {
2630 return ((dip != NULL) && (ddi_prop_exists(DDI_DEV_T_ANY, dip,
2631 DDI_PROP_DONTPASS, "scsa1394") == 1));
2632 }
2633
2634 boolean_t
2635 scsa1394_dev_is_online(scsa1394_state_t *sp)
2636 {
2637 boolean_t ret;
2638
2639 mutex_enter(&sp->s_mutex);
2640 ret = (sp->s_dev_state == SCSA1394_DEV_ONLINE);
2641 mutex_exit(&sp->s_mutex);
2642
2643 return (ret);
2644 }
2645
2646 static void *
2647 scsa1394_kmem_realloc(void *old_buf, int old_size, int new_size, size_t elsize,
2648 int kf)
2649 {
2650 void *new_buf;
2651
2652 new_buf = kmem_zalloc(new_size * elsize, kf);
2653
2654 if (old_size > 0) {
2655 if (new_buf != NULL) {
2656 bcopy(old_buf, new_buf, old_size * elsize);
2657 }
2658 kmem_free(old_buf, old_size * elsize);
2659 }
2660
2661 return (new_buf);
2662 }