1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 /* 22 * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 26 /* 27 * 1394 mass storage SBP-2 driver routines 28 */ 29 30 #include <sys/param.h> 31 #include <sys/errno.h> 32 #include <sys/cred.h> 33 #include <sys/conf.h> 34 #include <sys/modctl.h> 35 #include <sys/stat.h> 36 #include <sys/ddi.h> 37 #include <sys/sunddi.h> 38 39 #include <sys/1394/targets/scsa1394/impl.h> 40 #include <sys/1394/targets/scsa1394/cmd.h> 41 #include <sys/sbp2/bus.h> 42 #include <sys/sbp2/driver.h> 43 44 static void scsa1394_sbp2_detect_symbios(scsa1394_state_t *); 45 static void scsa1394_sbp2_worker_thread(void *); 46 static void scsa1394_sbp2_status_cb(void *, sbp2_task_t *); 47 static void scsa1394_sbp2_seg2pt_default(scsa1394_lun_t *, 48 scsa1394_cmd_t *); 49 static void scsa1394_sbp2_seg2pt_symbios(scsa1394_lun_t *, 50 scsa1394_cmd_t *); 51 static void scsa1394_sbp2_req_status(scsa1394_lun_t *); 52 static void scsa1394_sbp2_status_proc(scsa1394_lun_t *, scsa1394_cmd_t *, 53 scsa1394_status_t *); 54 static int scsa1394_sbp2_conv_status(scsa1394_cmd_t *, 55 scsa1394_status_t *); 56 static void scsa1394_sbp2_reset_proc(scsa1394_lun_t *, int, 57 scsa1394_cmd_t *); 58 static boolean_t scsa1394_sbp2_logged_in(scsa1394_lun_t *); 59 60 extern sbp2_bus_t scsa1394_sbp2_bus; 61 62 /* tunables */ 63 uint_t scsa1394_sbp2_max_payload_sub = 2; 64 extern int scsa1394_symbios_size_max; 65 extern int scsa1394_symbios_page_size; 66 extern int scsa1394_wrka_symbios; 67 68 /* symbios workaround will be applied unless device is on this list */ 69 scsa1394_bw_list_t scsa1394_sbp2_symbios_whitelist[] = { 70 { SCSA1394_BW_ONE, 0x0a27 }, /* Apple */ 71 { SCSA1394_BW_ONE, 0xd04b } /* LaCie */ 72 }; 73 74 /* 75 * 76 * --- SBP-2 routines 77 * 78 */ 79 int 80 scsa1394_sbp2_attach(scsa1394_state_t *sp) 81 { 82 sbp2_tgt_t *tp; 83 scsa1394_lun_t *lp; 84 int i; 85 86 /* 87 * target 88 */ 89 if (sbp2_tgt_init(sp, &scsa1394_sbp2_bus, NLUNS_PER_TARGET, 90 &sp->s_tgt) != SBP2_SUCCESS) { 91 return (DDI_FAILURE); 92 } 93 tp = sp->s_tgt; 94 95 /* 96 * luns 97 */ 98 sp->s_nluns = tp->t_nluns; 99 sp->s_lun = kmem_zalloc(sp->s_nluns * sizeof (scsa1394_lun_t), 100 KM_SLEEP); 101 102 for (i = 0; i < sp->s_nluns; i++) { 103 lp = &sp->s_lun[i]; 104 105 mutex_init(&lp->l_mutex, NULL, MUTEX_DRIVER, 106 sp->s_attachinfo.iblock_cookie); 107 108 lp->l_rmb_orig = -1; 109 lp->l_lun = &tp->t_lun[i]; 110 lp->l_sp = sp; 111 lp->l_lba_size = DEV_BSIZE; 112 } 113 114 scsa1394_sbp2_detect_symbios(sp); 115 116 return (DDI_SUCCESS); 117 } 118 119 void 120 scsa1394_sbp2_detach(scsa1394_state_t *sp) 121 { 122 int i; 123 scsa1394_lun_t *lp; 124 125 for (i = 0; i < sp->s_nluns; i++) { 126 lp = &sp->s_lun[i]; 127 if (lp->l_sp != NULL) { 128 mutex_destroy(&lp->l_mutex); 129 } 130 } 131 132 kmem_free(sp->s_lun, sp->s_nluns * sizeof (scsa1394_lun_t)); 133 sbp2_tgt_fini(sp->s_tgt); 134 } 135 136 static void 137 scsa1394_sbp2_detect_symbios(scsa1394_state_t *sp) 138 { 139 sbp2_cfgrom_ent_t *root = &sp->s_tgt->t_cfgrom.cr_root; 140 sbp2_cfgrom_ent_t *ent; 141 scsa1394_bw_list_t *wl; 142 int vid; 143 int i; 144 145 146 if (!scsa1394_wrka_symbios) { 147 sp->s_symbios = B_FALSE; 148 return; 149 } else { 150 sp->s_symbios = B_TRUE; 151 } 152 153 /* get device's vendor ID */ 154 if ((ent = sbp2_cfgrom_ent_by_key(root, IEEE1212_IMMEDIATE_TYPE, 155 IEEE1212_MODULE_VENDOR_ID, 0)) == NULL) { 156 return; 157 } 158 vid = ent->ce_data.imm; 159 160 /* find a match in the whitelist */ 161 for (i = 0; i < NELEM(scsa1394_sbp2_symbios_whitelist); i++) { 162 wl = &scsa1394_sbp2_symbios_whitelist[i]; 163 if ((wl->vid_match == SCSA1394_BW_ONE) && (wl->vid == vid)) { 164 sp->s_symbios = B_FALSE; 165 break; 166 } 167 } 168 } 169 170 171 /* 172 * functional equivalent of ddi_rep_get32() with big endian access handle 173 */ 174 static void 175 bcopy_swap32(uint32_t *from, uint32_t *to, int count) 176 { 177 int i; 178 uint32_t data; 179 180 ASSERT((uintptr_t)to % 4 == 0); 181 182 for (i = 0; i < count; i++) { 183 data = *from++; 184 *to++ = SBP2_SWAP32(data); 185 } 186 } 187 188 /* 189 * Build an inquiry for a given device that doesn't like inquiry commands. 190 */ 191 void 192 scsa1394_sbp2_fake_inquiry(scsa1394_state_t *sp, struct scsi_inquiry *inq) 193 { 194 sbp2_cfgrom_ent_t *r = &sp->s_tgt->t_cfgrom.cr_root; 195 sbp2_cfgrom_ent_t *e, *eref, *evid; 196 int i, len; 197 198 bzero(inq, sizeof (struct scsi_inquiry)); 199 200 inq->inq_dtype = DTYPE_DIRECT; 201 inq->inq_rmb = 1; 202 inq->inq_ansi = 2; 203 inq->inq_rdf = RDF_SCSI2; 204 inq->inq_len = sizeof (struct scsi_inquiry) - 4; 205 206 (void) memset(inq->inq_vid, ' ', sizeof (inq->inq_vid)); 207 (void) memset(inq->inq_pid, ' ', sizeof (inq->inq_pid)); 208 (void) memset(inq->inq_revision, ' ', sizeof (inq->inq_revision)); 209 210 /* 211 * vid/pid/rev can be derived from Config ROM textual descriptors 212 */ 213 for (i = 0; i < 256; i++) { 214 if ((e = sbp2_cfgrom_ent_by_key(r, IEEE1212_LEAF_TYPE, 215 IEEE1212_TEXTUAL_DESCRIPTOR, i)) == NULL) { 216 break; 217 } 218 eref = e->ce_ref; 219 if ((eref == NULL) || (eref->ce_len < 3) && 220 (eref->ce_kt != IEEE1212_IMMEDIATE_TYPE)) { 221 continue; 222 } 223 224 len = e->ce_len - 2; 225 if (eref->ce_kv == IEEE1212_MODULE_VENDOR_ID) { 226 evid = e; 227 bcopy_swap32(&e->ce_data.leaf[2], 228 (uint32_t *)inq->inq_vid, 229 min(sizeof (inq->inq_vid) / 4, len)); 230 } else if (eref->ce_kv == 0x17) { 231 bcopy_swap32(&e->ce_data.leaf[2], 232 (uint32_t *)inq->inq_pid, 233 min(sizeof (inq->inq_pid) / 4, len)); 234 } else if ((eref->ce_kv == IEEE1212_MODULE_HW_VERSION) || 235 (eref == evid)) { 236 bcopy_swap32(&e->ce_data.leaf[2], 237 (uint32_t *)inq->inq_revision, 238 min(sizeof (inq->inq_revision) / 4, len)); 239 } 240 } 241 } 242 243 int 244 scsa1394_sbp2_threads_init(scsa1394_state_t *sp) 245 { 246 scsa1394_lun_t *lp; 247 scsa1394_thread_t *thr; 248 int i; 249 250 for (i = 0; i < sp->s_nluns; i++) { 251 lp = &sp->s_lun[i]; 252 thr = &lp->l_worker_thread; 253 254 thr->thr_func = scsa1394_sbp2_worker_thread; 255 thr->thr_arg = thr; 256 thr->thr_state = SCSA1394_THR_INIT; 257 cv_init(&thr->thr_cv, NULL, CV_DRIVER, NULL); 258 thr->thr_lun = lp; 259 thr->thr_req = 0; 260 261 mutex_enter(&lp->l_mutex); 262 if (scsa1394_thr_dispatch(thr) != DDI_SUCCESS) { 263 mutex_exit(&lp->l_mutex); 264 scsa1394_sbp2_threads_fini(sp); 265 return (DDI_FAILURE); 266 } 267 mutex_exit(&lp->l_mutex); 268 } 269 270 return (DDI_SUCCESS); 271 } 272 273 void 274 scsa1394_sbp2_threads_fini(scsa1394_state_t *sp) 275 { 276 scsa1394_lun_t *lp; 277 scsa1394_thread_t *thr; 278 int i; 279 280 for (i = 0; i < sp->s_nluns; i++) { 281 lp = &sp->s_lun[i]; 282 thr = &lp->l_worker_thread; 283 284 /* if thread wasn't initialized, thr_lun will be NULL */ 285 if (thr->thr_lun == lp) { 286 mutex_enter(&lp->l_mutex); 287 scsa1394_thr_cancel(thr); 288 mutex_exit(&lp->l_mutex); 289 ASSERT(thr->thr_state != SCSA1394_THR_RUN); 290 cv_destroy(&thr->thr_cv); 291 } 292 } 293 } 294 295 int 296 scsa1394_sbp2_get_lun_type(scsa1394_lun_t *lp) 297 { 298 return (lp->l_lun->l_type); 299 } 300 301 int 302 scsa1394_sbp2_login(scsa1394_state_t *sp, int lun) 303 { 304 scsa1394_lun_t *lp = &sp->s_lun[lun]; 305 int berr; 306 307 if (sbp2_lun_login(lp->l_lun, &lp->l_ses, 308 scsa1394_sbp2_status_cb, lp, &berr) != SBP2_SUCCESS) { 309 return (DDI_FAILURE); 310 } 311 ASSERT(lp->l_ses != NULL); 312 return (DDI_SUCCESS); 313 } 314 315 void 316 scsa1394_sbp2_logout(scsa1394_state_t *sp, int lun, boolean_t phys) 317 { 318 scsa1394_lun_t *lp = &sp->s_lun[lun]; 319 int berr; 320 321 if (scsa1394_sbp2_logged_in(lp)) { 322 (void) sbp2_lun_logout(lp->l_lun, &lp->l_ses, &berr, phys); 323 } 324 } 325 326 void 327 scsa1394_sbp2_req(scsa1394_state_t *sp, int lun, int req) 328 { 329 scsa1394_lun_t *lp = &sp->s_lun[lun]; 330 331 if (lp != NULL) { 332 mutex_enter(&lp->l_mutex); 333 scsa1394_thr_wake(&lp->l_worker_thread, req); 334 mutex_exit(&lp->l_mutex); 335 } 336 } 337 338 void 339 scsa1394_sbp2_req_bus_reset(scsa1394_lun_t *lp) 340 { 341 scsa1394_state_t *sp = lp->l_sp; 342 int berr = 0; 343 344 if (t1394_get_targetinfo(sp->s_t1394_hdl, SCSA1394_BUSGEN(sp), 0, 345 &sp->s_targetinfo) != DDI_SUCCESS) { 346 goto disconnect; 347 } 348 349 if (sp->s_targetinfo.target_nodeID == T1394_INVALID_NODEID) { 350 goto disconnect; 351 } 352 353 if (!scsa1394_sbp2_logged_in(lp)) { 354 /* reconnect procedure is only for logged in hosts */ 355 return; 356 } 357 358 /* 359 * Try SBP-2 RECONNECT procedure first. Note that we're passing 360 * local Node ID, which might have changed during bus reset. 361 * sbp2_ses_reconnect() will use it to update the ORBs. 362 */ 363 if (sbp2_ses_reconnect(lp->l_ses, &berr, 364 SCSA1394_NODEID(sp)) == SBP2_SUCCESS) { 365 mutex_enter(&sp->s_mutex); 366 sp->s_dev_state = SCSA1394_DEV_ONLINE; 367 mutex_exit(&sp->s_mutex); 368 369 /* resume task processing */ 370 scsa1394_sbp2_nudge(lp); 371 372 return; 373 } 374 375 if (berr == CMD1394_EDEVICE_REMOVED) { 376 goto disconnect; 377 } 378 379 /* reconnect failed, try to logout and login again */ 380 scsa1394_sbp2_flush_cmds(lp, CMD_TRAN_ERR, 0, STAT_BUS_RESET); 381 (void) sbp2_lun_logout(lp->l_lun, &lp->l_ses, &berr, B_FALSE); 382 383 if (scsa1394_sbp2_login(sp, 0) != SBP2_SUCCESS) { 384 goto disconnect; 385 } 386 387 mutex_enter(&sp->s_mutex); 388 sp->s_dev_state = SCSA1394_DEV_ONLINE; 389 mutex_exit(&sp->s_mutex); 390 391 return; 392 393 disconnect: 394 mutex_enter(&sp->s_mutex); 395 sp->s_dev_state = SCSA1394_DEV_DISCONNECTED; 396 mutex_exit(&sp->s_mutex); 397 if (scsa1394_sbp2_logged_in(lp)) { 398 scsa1394_sbp2_flush_cmds(lp, CMD_DEV_GONE, 0, STAT_BUS_RESET); 399 (void) sbp2_lun_logout(lp->l_lun, &lp->l_ses, &berr, B_FALSE); 400 } 401 } 402 403 /*ARGSUSED*/ 404 void 405 scsa1394_sbp2_req_reconnect(scsa1394_lun_t *lp) 406 { 407 scsa1394_state_t *sp = lp->l_sp; 408 409 if (t1394_get_targetinfo(sp->s_t1394_hdl, SCSA1394_BUSGEN(sp), 0, 410 &sp->s_targetinfo) != DDI_SUCCESS) { 411 return; 412 } 413 414 mutex_enter(&sp->s_mutex); 415 sp->s_dev_state = SCSA1394_DEV_ONLINE; 416 mutex_exit(&sp->s_mutex); 417 418 if (sbp2_tgt_reconnect(sp->s_tgt) != SBP2_SUCCESS) { 419 goto disconnect; 420 } 421 422 if (scsa1394_sbp2_login(sp, 0) != SBP2_SUCCESS) { 423 goto disconnect; 424 } 425 426 cmn_err(CE_WARN, "scsa1394(%d): " 427 "Reinserted device is accessible again.\n", sp->s_instance); 428 429 return; 430 431 disconnect: 432 mutex_enter(&sp->s_mutex); 433 sp->s_dev_state = SCSA1394_DEV_DISCONNECTED; 434 mutex_exit(&sp->s_mutex); 435 } 436 437 void 438 scsa1394_sbp2_disconnect(scsa1394_state_t *sp) 439 { 440 scsa1394_lun_t *lp = &sp->s_lun[0]; 441 int berr; 442 443 scsa1394_sbp2_flush_cmds(lp, CMD_DEV_GONE, 0, STAT_BUS_RESET); 444 if (scsa1394_sbp2_logged_in(lp)) { 445 (void) sbp2_lun_logout(lp->l_lun, &lp->l_ses, &berr, B_FALSE); 446 } 447 sbp2_tgt_disconnect(sp->s_tgt); 448 } 449 450 /* 451 * convert segment array into DMA-mapped SBP-2 page table 452 */ 453 void 454 scsa1394_sbp2_seg2pt(scsa1394_lun_t *lp, scsa1394_cmd_t *cmd) 455 { 456 scsa1394_state_t *sp = lp->l_sp; 457 458 ASSERT(cmd->sc_flags & SCSA1394_CMD_DMA_BUF_PT_VALID); 459 460 if (sp->s_symbios) { 461 scsa1394_sbp2_seg2pt_symbios(lp, cmd); 462 } else { 463 scsa1394_sbp2_seg2pt_default(lp, cmd); 464 } 465 } 466 467 /*ARGSUSED*/ 468 static void 469 scsa1394_sbp2_seg2pt_default(scsa1394_lun_t *lp, scsa1394_cmd_t *cmd) 470 { 471 sbp2_pt_unrestricted_t *pt; 472 scsa1394_cmd_seg_t *seg; 473 int i; 474 475 pt = (sbp2_pt_unrestricted_t *)cmd->sc_pt_kaddr; 476 seg = &cmd->sc_buf_seg[0]; 477 for (i = 0; i < cmd->sc_buf_nsegs; i++) { 478 pt->pt_seg_len = SBP2_SWAP16(seg->ss_len); 479 pt->pt_seg_base_hi = SBP2_SWAP16(seg->ss_baddr >> 32); 480 pt->pt_seg_base_lo = SBP2_SWAP32(seg->ss_baddr & 0xFFFFFFFF); 481 482 pt++; 483 seg++; 484 } 485 (void) ddi_dma_sync(cmd->sc_pt_dma_hdl, 0, 0, DDI_DMA_SYNC_FORDEV); 486 487 cmd->sc_pt_cmd_size = cmd->sc_buf_nsegs; 488 } 489 490 /* 491 * fill page table for Symbios workaround 492 */ 493 /*ARGSUSED*/ 494 static void 495 scsa1394_sbp2_seg2pt_symbios(scsa1394_lun_t *lp, scsa1394_cmd_t *cmd) 496 { 497 sbp2_pt_unrestricted_t *pt; 498 scsa1394_cmd_seg_t *seg; 499 int nsegs; 500 size_t resid, skiplen, dataoff, segoff, seglen; 501 uint64_t baddr; 502 503 /* data offset within command */ 504 if (cmd->sc_flags & SCSA1394_CMD_SYMBIOS_BREAKUP) { 505 dataoff = (cmd->sc_total_blks - cmd->sc_resid_blks) * 506 cmd->sc_blk_size; 507 } else { 508 dataoff = 0; 509 } 510 511 /* skip dataoff bytes */ 512 seg = &cmd->sc_buf_seg[0]; 513 skiplen = 0; 514 while (skiplen + seg->ss_len <= dataoff) { 515 skiplen += seg->ss_len; 516 seg++; 517 } 518 segoff = dataoff - skiplen; /* offset within segment */ 519 520 pt = (sbp2_pt_unrestricted_t *)cmd->sc_pt_kaddr; 521 resid = cmd->sc_xfer_bytes; 522 nsegs = 0; 523 while (resid > 0) { 524 ASSERT(seg->ss_len <= scsa1394_symbios_page_size); 525 526 seglen = min(seg->ss_len, resid) - segoff; 527 baddr = seg->ss_baddr + segoff; 528 529 pt->pt_seg_len = SBP2_SWAP16(seglen); 530 pt->pt_seg_base_hi = SBP2_SWAP16(baddr >> 32); 531 pt->pt_seg_base_lo = SBP2_SWAP32(baddr & 0xFFFFFFFF); 532 533 segoff = 0; 534 resid -= seglen; 535 nsegs++; 536 pt++; 537 seg++; 538 } 539 (void) ddi_dma_sync(cmd->sc_pt_dma_hdl, 0, 0, DDI_DMA_SYNC_FORDEV); 540 541 cmd->sc_pt_cmd_size = nsegs; 542 } 543 544 /* 545 * convert command into DMA-mapped SBP-2 ORB 546 */ 547 void 548 scsa1394_sbp2_cmd2orb(scsa1394_lun_t *lp, scsa1394_cmd_t *cmd) 549 { 550 scsa1394_state_t *sp = lp->l_sp; 551 scsa1394_cmd_orb_t *orb = sbp2_task_orb_kaddr(&cmd->sc_task); 552 553 mutex_enter(&lp->l_mutex); 554 555 lp->l_stat.stat_cmd_cnt++; 556 557 bzero(orb->co_cdb, sizeof (orb->co_cdb)); 558 559 /* CDB */ 560 bcopy(cmd->sc_cdb, orb->co_cdb, cmd->sc_cdb_actual_len); 561 562 /* 563 * ORB parameters 564 * 565 * use max speed and max payload for this speed. 566 * max async data transfer for a given speed is 512<<speed 567 * SBP-2 defines (see 5.1.2) max data transfer as 2^(max_payload+2), 568 * hence max_payload = 7 + speed 569 */ 570 orb->co_params = SBP2_ORB_NOTIFY | SBP2_ORB_RQ_FMT_SBP2 | 571 (sp->s_targetinfo.current_max_speed << SBP2_ORB_CMD_SPD_SHIFT) | 572 ((7 + sp->s_targetinfo.current_max_speed - 573 scsa1394_sbp2_max_payload_sub) << SBP2_ORB_CMD_MAX_PAYLOAD_SHIFT); 574 575 /* direction: initiator's read is target's write (and vice versa) */ 576 if (cmd->sc_flags & SCSA1394_CMD_READ) { 577 orb->co_params |= SBP2_ORB_CMD_DIR; 578 } 579 580 /* 581 * data_size and data_descriptor 582 */ 583 if (cmd->sc_buf_nsegs == 0) { 584 /* no data */ 585 orb->co_data_size = 0; 586 SCSA1394_ADDR_SET(sp, orb->co_data_descr, 0); 587 } else if (cmd->sc_buf_nsegs == 1) { 588 /* contiguous buffer - use direct addressing */ 589 ASSERT(cmd->sc_buf_seg[0].ss_len != 0); 590 orb->co_data_size = SBP2_SWAP16(cmd->sc_buf_seg[0].ss_len); 591 SCSA1394_ADDR_SET(sp, orb->co_data_descr, 592 cmd->sc_buf_seg[0].ss_baddr); 593 } else { 594 /* non-contiguous s/g list - page table */ 595 ASSERT(cmd->sc_pt_cmd_size > 0); 596 orb->co_params |= SBP2_ORB_CMD_PT; 597 orb->co_data_size = SBP2_SWAP16(cmd->sc_pt_cmd_size); 598 SCSA1394_ADDR_SET(sp, orb->co_data_descr, cmd->sc_pt_baddr); 599 } 600 601 SBP2_SWAP16_1(orb->co_params); 602 603 SBP2_ORBP_SET(orb->co_next_orb, SBP2_ORBP_NULL); 604 605 mutex_exit(&lp->l_mutex); 606 607 sbp2_task_orb_sync(lp->l_lun, &cmd->sc_task, DDI_DMA_SYNC_FORDEV); 608 } 609 610 611 /*ARGSUSED*/ 612 int 613 scsa1394_sbp2_start(scsa1394_lun_t *lp, scsa1394_cmd_t *cmd) 614 { 615 sbp2_task_t *task = CMD2TASK(cmd); 616 int ret; 617 618 ASSERT(lp->l_ses != NULL); 619 620 task->ts_timeout = cmd->sc_timeout; 621 task->ts_error = SBP2_TASK_ERR_NONE; 622 task->ts_bus_error = 0; 623 task->ts_state = SBP2_TASK_INIT; 624 625 ret = sbp2_ses_submit_task(lp->l_ses, task); 626 627 if ((ret == SBP2_SUCCESS) || (ret == SBP2_ECONTEXT)) { 628 return (TRAN_ACCEPT); 629 } if (task->ts_error == SBP2_TASK_ERR_BUS) { 630 if (task->ts_bus_error == CMD1394_EDEVICE_BUSY) { 631 return (TRAN_BUSY); 632 } else { 633 return (TRAN_FATAL_ERROR); 634 } 635 } else { 636 return (TRAN_FATAL_ERROR); 637 } 638 } 639 640 /* 641 * This function is called by SBP-2 layer when task status is received, 642 * typically from interrupt handler. Just wake the thread to do the actual work. 643 */ 644 /*ARGSUSED*/ 645 static void 646 scsa1394_sbp2_status_cb(void *arg, sbp2_task_t *task) 647 { 648 scsa1394_lun_t *lp = (scsa1394_lun_t *)arg; 649 650 mutex_enter(&lp->l_mutex); 651 scsa1394_thr_wake(&lp->l_worker_thread, SCSA1394_THREQ_TASK_STATUS); 652 mutex_exit(&lp->l_mutex); 653 } 654 655 void 656 scsa1394_sbp2_nudge(scsa1394_lun_t *lp) 657 { 658 mutex_enter(&lp->l_mutex); 659 scsa1394_thr_wake(&lp->l_worker_thread, SCSA1394_THREQ_NUDGE); 660 mutex_exit(&lp->l_mutex); 661 } 662 663 /* 664 * worker thread 665 */ 666 static void 667 scsa1394_sbp2_worker_thread(void *arg) 668 { 669 scsa1394_thread_t *thr = (scsa1394_thread_t *)arg; 670 scsa1394_lun_t *lp = thr->thr_lun; 671 672 mutex_enter(&lp->l_mutex); 673 for (;;) { 674 while (thr->thr_req == 0) { 675 cv_wait(&thr->thr_cv, &lp->l_mutex); 676 } 677 if (thr->thr_req & SCSA1394_THREQ_EXIT) { 678 break; 679 } 680 if (thr->thr_req & SCSA1394_THREQ_BUS_RESET) { 681 thr->thr_req &= ~SCSA1394_THREQ_BUS_RESET; 682 mutex_exit(&lp->l_mutex); 683 scsa1394_sbp2_req_bus_reset(lp); 684 mutex_enter(&lp->l_mutex); 685 continue; 686 } 687 if (thr->thr_req & SCSA1394_THREQ_RECONNECT) { 688 thr->thr_req &= ~SCSA1394_THREQ_RECONNECT; 689 mutex_exit(&lp->l_mutex); 690 scsa1394_sbp2_req_reconnect(lp); 691 mutex_enter(&lp->l_mutex); 692 continue; 693 } 694 if (thr->thr_req & SCSA1394_THREQ_TASK_STATUS) { 695 thr->thr_req &= ~SCSA1394_THREQ_TASK_STATUS; 696 mutex_exit(&lp->l_mutex); 697 scsa1394_sbp2_req_status(lp); 698 mutex_enter(&lp->l_mutex); 699 continue; 700 } 701 if (thr->thr_req & SCSA1394_THREQ_NUDGE) { 702 thr->thr_req &= ~SCSA1394_THREQ_NUDGE; 703 mutex_exit(&lp->l_mutex); 704 if (scsa1394_sbp2_logged_in(lp)) { 705 sbp2_ses_nudge(lp->l_ses); 706 } 707 mutex_enter(&lp->l_mutex); 708 continue; 709 } 710 } 711 thr->thr_state = SCSA1394_THR_EXIT; 712 cv_signal(&thr->thr_cv); 713 mutex_exit(&lp->l_mutex); 714 } 715 716 /* 717 * task status handler 718 */ 719 static void 720 scsa1394_sbp2_req_status(scsa1394_lun_t *lp) 721 { 722 sbp2_ses_t *sp = lp->l_ses; 723 sbp2_task_t *task; 724 725 if (sp == NULL) { 726 return; 727 } 728 729 /* 730 * Process all tasks that received status. 731 * This algorithm preserves callback order. 732 */ 733 while ((task = sbp2_ses_remove_first_task_state(sp, SBP2_TASK_COMP)) != 734 NULL) { 735 sbp2_ses_nudge(sp); 736 737 ASSERT(task->ts_state == SBP2_TASK_COMP); 738 task->ts_state = SBP2_TASK_PROC; 739 scsa1394_sbp2_status_proc(lp, TASK2CMD(task), 740 (scsa1394_status_t *)&task->ts_status); 741 } 742 sbp2_ses_nudge(sp); /* submit next task */ 743 } 744 745 static void 746 scsa1394_sbp2_status_proc(scsa1394_lun_t *lp, scsa1394_cmd_t *cmd, 747 scsa1394_status_t *st) 748 { 749 sbp2_task_t *task = CMD2TASK(cmd); 750 struct scsi_pkt *pkt = CMD2PKT(cmd); 751 uint64_t *p; 752 753 if (cmd->sc_flags & SCSA1394_CMD_READ) { 754 (void) ddi_dma_sync(cmd->sc_buf_dma_hdl, 0, 0, 755 DDI_DMA_SYNC_FORKERNEL); 756 } 757 758 if (task->ts_error != SBP2_TASK_ERR_NONE) { 759 pkt->pkt_state |= STATE_GOT_BUS; 760 switch (task->ts_error) { 761 case SBP2_TASK_ERR_ABORT: 762 pkt->pkt_state |= STATE_GOT_TARGET; 763 pkt->pkt_reason = CMD_ABORTED; 764 break; 765 case SBP2_TASK_ERR_LUN_RESET: 766 pkt->pkt_state |= STATE_GOT_TARGET; 767 pkt->pkt_reason = CMD_RESET; 768 pkt->pkt_statistics |= STAT_DEV_RESET; 769 break; 770 case SBP2_TASK_ERR_TGT_RESET: 771 pkt->pkt_state |= STATE_GOT_TARGET; 772 pkt->pkt_reason = CMD_RESET; 773 pkt->pkt_statistics |= STAT_DEV_RESET; 774 break; 775 case SBP2_TASK_ERR_TIMEOUT: 776 (void) scsa1394_sbp2_reset(lp, RESET_TARGET, cmd); 777 return; 778 case SBP2_TASK_ERR_DEAD: 779 case SBP2_TASK_ERR_BUS: 780 default: 781 pkt->pkt_reason = CMD_TRAN_ERR; 782 break; 783 } 784 } else if ((st->st_param & SBP2_ST_RESP) == SBP2_ST_RESP_COMPLETE) { 785 /* 786 * SBP-2 status block has been received, now look at sbp_status. 787 * 788 * Note: ANSI NCITS 325-1998 B.2 requires that when status is 789 * GOOD, length must be one, but some devices do not comply 790 */ 791 if (st->st_sbp_status == SBP2_ST_SBP_DUMMY_ORB) { 792 pkt->pkt_state |= (STATE_GOT_BUS | STATE_GOT_TARGET); 793 pkt->pkt_reason = CMD_ABORTED; 794 pkt->pkt_statistics |= STAT_DEV_RESET; 795 } else if ((st->st_status & SCSA1394_ST_STATUS) == 796 STATUS_GOOD) { 797 /* request complete */ 798 *(pkt->pkt_scbp) = STATUS_GOOD; 799 pkt->pkt_state |= (STATE_GOT_BUS | STATE_GOT_TARGET | 800 STATE_SENT_CMD | STATE_XFERRED_DATA | 801 STATE_GOT_STATUS); 802 pkt->pkt_reason = CMD_CMPLT; 803 } else if (scsa1394_sbp2_conv_status(cmd, st) == DDI_SUCCESS) { 804 pkt->pkt_state |= (STATE_GOT_BUS | STATE_GOT_TARGET | 805 STATE_SENT_CMD | STATE_XFERRED_DATA | 806 STATE_GOT_STATUS | STATE_ARQ_DONE); 807 pkt->pkt_reason = CMD_TRAN_ERR; 808 } else { 809 pkt->pkt_state |= (STATE_GOT_BUS | STATE_GOT_TARGET | 810 STATE_SENT_CMD | STATE_XFERRED_DATA | 811 STATE_GOT_STATUS); 812 pkt->pkt_reason = CMD_TRAN_ERR; 813 lp->l_stat.stat_err_status_conv++; 814 } 815 } else { 816 /* transport or serial bus failure */ 817 pkt->pkt_state |= (STATE_GOT_BUS | STATE_GOT_TARGET); 818 pkt->pkt_reason = CMD_TRAN_ERR; 819 lp->l_stat.stat_err_status_resp++; 820 } 821 822 if (pkt->pkt_reason == CMD_TRAN_ERR) { 823 lp->l_stat.stat_err_status_tran_err++; 824 825 /* save the command */ 826 p = &lp->l_stat.stat_cmd_last_fail[ 827 lp->l_stat.stat_cmd_last_fail_idx][0]; 828 bcopy(&pkt->pkt_cdbp[0], p, min(cmd->sc_cdb_len, 16)); 829 *(clock_t *)&p[2] = ddi_get_lbolt(); 830 lp->l_stat.stat_cmd_last_fail_idx = 831 (lp->l_stat.stat_cmd_last_fail_idx + 1) % 832 SCSA1394_STAT_NCMD_LAST; 833 } 834 835 /* generic HBA status processing */ 836 scsa1394_cmd_status_proc(lp, cmd); 837 } 838 839 840 /* 841 * Convert SBP-2 status block into SCSA status. 842 * 843 * Note: (ref: B.2) "SBP-2 permits the return of a status block between two 844 * and quadlets in length. When a truncated status block is stored, the 845 * omitted quadlets shall be interpreted as if zero values were stored." 846 * We expect the sbp2 layer to do the zeroing for us. 847 */ 848 static int 849 scsa1394_sbp2_conv_status(scsa1394_cmd_t *cmd, scsa1394_status_t *st) 850 { 851 struct scsi_pkt *pkt = CMD2PKT(cmd); 852 uint8_t status = st->st_status; 853 uint8_t bits = st->st_sense_bits; 854 struct scsi_arq_status *arqp = (struct scsi_arq_status *)pkt->pkt_scbp; 855 struct scsi_extended_sense *esp = &arqp->sts_sensedata; 856 857 *(pkt->pkt_scbp) = (status & SCSA1394_ST_STATUS); 858 *(uint8_t *)&arqp->sts_rqpkt_status = STATUS_GOOD; 859 arqp->sts_rqpkt_reason = CMD_CMPLT; 860 arqp->sts_rqpkt_resid = 0; 861 arqp->sts_rqpkt_state |= STATE_XFERRED_DATA; 862 arqp->sts_rqpkt_statistics = 0; 863 864 esp->es_valid = (bits & SCSA1394_ST_VALID) >> SCSA1394_ST_VALID_SHIFT; 865 esp->es_class = CLASS_EXTENDED_SENSE; 866 esp->es_code = (status & SCSA1394_ST_SFMT) >> SCSA1394_ST_SFMT_SHIFT; 867 868 esp->es_segnum = 0; 869 870 esp->es_filmk = (bits & SCSA1394_ST_MARK) >> SCSA1394_ST_MARK_SHIFT; 871 esp->es_eom = (bits & SCSA1394_ST_EOM) >> SCSA1394_ST_EOM_SHIFT; 872 esp->es_ili = (bits & SCSA1394_ST_ILI) >> SCSA1394_ST_ILI_SHIFT; 873 esp->es_key = (bits & SCSA1394_ST_SENSE_KEY); 874 875 esp->es_info_1 = st->st_info[0]; 876 esp->es_info_2 = st->st_info[1]; 877 esp->es_info_3 = st->st_info[2]; 878 esp->es_info_4 = st->st_info[3]; 879 esp->es_add_len = 4; 880 881 esp->es_cmd_info[0] = st->st_cdb[0]; 882 esp->es_cmd_info[1] = st->st_cdb[1]; 883 esp->es_cmd_info[2] = st->st_cdb[2]; 884 esp->es_cmd_info[3] = st->st_cdb[3]; 885 esp->es_add_code = st->st_sense_code; 886 esp->es_qual_code = st->st_sense_qual; 887 esp->es_fru_code = st->st_fru; 888 esp->es_skey_specific[0] = st->st_sks[0]; 889 esp->es_skey_specific[1] = st->st_sks[1]; 890 esp->es_skey_specific[2] = st->st_sks[2]; 891 892 esp->es_add_info[0] = esp->es_add_info[1] = 0; 893 894 return (DDI_SUCCESS); 895 } 896 897 /* 898 * Sends appropriate reset command to the target. LUN reset is optional, so it 899 * can fail, in which case the SCSA target driver will use RESET_TARGET/ALL. 900 * Target reset support is mandatory in SBP-2, if it fails, it means something's 901 * terribly wrong with the device - blow away outstanding tasks in that case. 902 */ 903 int 904 scsa1394_sbp2_reset(scsa1394_lun_t *lp, int level, scsa1394_cmd_t *cmd) 905 { 906 scsa1394_state_t *sp = lp->l_sp; 907 sbp2_task_t *task; 908 int berr; 909 int ret = DDI_FAILURE; 910 911 if (scsa1394_dev_is_online(sp)) { 912 switch (level) { 913 case RESET_LUN: 914 ret = sbp2_lun_reset(lp->l_lun, &berr); 915 if (ret != SBP2_SUCCESS) { 916 return (ret); 917 } 918 break; 919 case RESET_TARGET: 920 case RESET_ALL: 921 ret = sbp2_tgt_reset(sp->s_tgt, &berr); 922 break; 923 } 924 } 925 926 if (cmd != NULL) { 927 scsa1394_sbp2_reset_proc(lp, level, cmd); 928 } 929 if (scsa1394_sbp2_logged_in(lp)) { 930 while ((task = sbp2_ses_cancel_first_task(lp->l_ses)) != NULL) { 931 ASSERT(task->ts_state < SBP2_TASK_PROC); 932 scsa1394_sbp2_reset_proc(lp, level, TASK2CMD(task)); 933 } 934 } 935 936 return (ret); 937 } 938 939 static void 940 scsa1394_sbp2_reset_proc(scsa1394_lun_t *lp, int level, scsa1394_cmd_t *cmd) 941 { 942 sbp2_task_t *task = CMD2TASK(cmd); 943 struct scsi_pkt *pkt = CMD2PKT(cmd); 944 int ts_error; 945 946 pkt->pkt_reason = CMD_RESET; 947 if (level == RESET_LUN) { 948 if (task->ts_state == SBP2_TASK_PEND) { 949 pkt->pkt_statistics |= STAT_DEV_RESET; 950 } else { 951 pkt->pkt_statistics |= STAT_ABORTED; 952 } 953 ts_error = SBP2_TASK_ERR_LUN_RESET; 954 } else { 955 pkt->pkt_statistics |= STAT_BUS_RESET; 956 ts_error = SBP2_TASK_ERR_TGT_RESET; 957 } 958 task->ts_error = ts_error; 959 task->ts_state = SBP2_TASK_PROC; 960 scsa1394_cmd_status_proc(lp, cmd); 961 } 962 963 /* 964 * Cancel commands immediately. 965 * 966 * Caller's responsibility to set device state such that no new tasks are added. 967 */ 968 void 969 scsa1394_sbp2_flush_cmds(scsa1394_lun_t *lp, int reason, int state, 970 int statistics) 971 { 972 scsa1394_cmd_t *cmd; 973 struct scsi_pkt *pkt; 974 sbp2_ses_t *sp = lp->l_ses; 975 sbp2_task_t *task; 976 977 if (sp == NULL) { 978 return; 979 } 980 981 while ((task = sbp2_ses_cancel_first_task(sp)) != NULL) { 982 ASSERT(task->ts_state < SBP2_TASK_PROC); 983 cmd = TASK2CMD(task); 984 pkt = CMD2PKT(cmd); 985 986 pkt->pkt_reason = reason; 987 pkt->pkt_state |= state; 988 pkt->pkt_statistics |= statistics; 989 task->ts_state = SBP2_TASK_PROC; 990 scsa1394_cmd_status_proc(lp, cmd); 991 } 992 993 scsa1394_thr_clear_req(&lp->l_worker_thread, 994 SCSA1394_THREQ_TASK_STATUS | SCSA1394_THREQ_NUDGE); 995 } 996 997 static boolean_t 998 scsa1394_sbp2_logged_in(scsa1394_lun_t *lp) 999 { 1000 return (lp->l_ses != NULL); 1001 } 1002