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