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