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