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