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