sbp.c revision 111199
1/* 2 * Copyright (c) 1998,1999,2000,2001 Katsushi Kobayashi and Hidetosh Shimokawa 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 3. All advertising materials mentioning features or use of this software 14 * must display the acknowledgement as bellow: 15 * 16 * This product includes software developed by K. Kobayashi and H. Shimokawa 17 * 18 * 4. The name of the author may not be used to endorse or promote products 19 * derived from this software without specific prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 22 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 23 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 24 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, 25 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 26 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 27 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 29 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 30 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 31 * POSSIBILITY OF SUCH DAMAGE. 32 * 33 * $FreeBSD: head/sys/dev/firewire/sbp.c 111199 2003-02-21 02:09:04Z simokawa $ 34 * 35 */ 36 37#include <sys/param.h> 38#include <sys/systm.h> 39#include <sys/module.h> 40#include <sys/bus.h> 41#include <sys/mbuf.h> 42#include <sys/sysctl.h> 43#include <machine/bus.h> 44#include <sys/malloc.h> 45#include <sys/devicestat.h> /* for struct devstat */ 46 47 48#include <cam/cam.h> 49#include <cam/cam_ccb.h> 50#include <cam/cam_sim.h> 51#include <cam/cam_xpt_sim.h> 52#include <cam/cam_debug.h> 53#include <cam/cam_periph.h> 54 55#include <cam/scsi/scsi_all.h> 56#include <cam/scsi/scsi_message.h> 57#include <cam/scsi/scsi_da.h> 58 59#include <sys/kernel.h> 60 61#include <vm/vm.h> 62#include <vm/pmap.h> 63 64#include <dev/firewire/firewire.h> 65#include <dev/firewire/firewirereg.h> 66#include <dev/firewire/iec13213.h> 67 68#define ccb_sdev_ptr spriv_ptr0 69#define ccb_sbp_ptr spriv_ptr1 70 71#define SBP_NUM_TARGETS 8 72#define SBP_NUM_LUNS 8 /* limited by CAM_SCSI2_MAXLUN in cam_xpt.c */ 73#define SBP_QUEUE_LEN 4 74#define SBP_NUM_OCB (SBP_QUEUE_LEN * SBP_NUM_TARGETS) 75#define SBP_INITIATOR 7 76#define SBP_ESELECT_TIMEOUT 1 77#define SBP_BIND_HI 0x1 78#define SBP_DEV2ADDR(u, t, l) \ 79 ((((u) & 0xff) << 16) | (((l) & 0xff) << 8) | (((t) & 0x3f) << 2)) 80#define SBP_ADDR2TRG(a) (((a) >> 2) & 0x3f) 81#define SBP_ADDR2LUN(a) (((a) >> 8) & 0xff) 82 83#define MAX_FREEZE 10 84 85#define ORB_NOTIFY (1 << 31) 86#define ORB_FMT_STD (0 << 29) 87#define ORB_FMT_VED (2 << 29) 88#define ORB_FMT_NOP (3 << 29) 89#define ORB_FMT_MSK (3 << 29) 90#define ORB_EXV (1 << 28) 91/* */ 92#define ORB_CMD_IN (1 << 27) 93/* */ 94#define ORB_CMD_SPD(x) ((x) << 24) 95#define ORB_CMD_MAXP(x) ((x) << 20) 96#define ORB_RCN_TMO(x) ((x) << 20) 97#define ORB_CMD_PTBL (1 << 19) 98#define ORB_CMD_PSZ(x) ((x) << 16) 99 100#define ORB_FUN_LGI (0 << 16) 101#define ORB_FUN_QLG (1 << 16) 102#define ORB_FUN_RCN (3 << 16) 103#define ORB_FUN_LGO (7 << 16) 104#define ORB_FUN_ATA (0xb << 16) 105#define ORB_FUN_ATS (0xc << 16) 106#define ORB_FUN_LUR (0xe << 16) 107#define ORB_FUN_RST (0xf << 16) 108#define ORB_FUN_MSK (0xf << 16) 109 110static char *orb_fun_name[] = { 111 /* 0 */ "LOGIN", 112 /* 1 */ "QUERY LOGINS", 113 /* 2 */ "Reserved", 114 /* 3 */ "RECONNECT", 115 /* 4 */ "SET PASSWORD", 116 /* 5 */ "Reserved", 117 /* 6 */ "Reserved", 118 /* 7 */ "LOGOUT", 119 /* 8 */ "Reserved", 120 /* 9 */ "Reserved", 121 /* A */ "Reserved", 122 /* B */ "ABORT TASK", 123 /* C */ "ABORT TASK SET", 124 /* D */ "Reserved", 125 /* E */ "LOGICAL UNIT RESET", 126 /* F */ "TARGET RESET" 127}; 128 129#define ORB_RES_CMPL 0 130#define ORB_RES_FAIL 1 131#define ORB_RES_ILLE 2 132#define ORB_RES_VEND 3 133 134static int debug = 1; 135static int auto_login = 1; 136static int max_speed = 2; 137static int sbp_cold = 1; 138 139SYSCTL_DECL(_hw_firewire); 140SYSCTL_NODE(_hw_firewire, OID_AUTO, sbp, CTLFLAG_RD, 0, "SBP-II Subsystem"); 141SYSCTL_INT(_debug, OID_AUTO, sbp_debug, CTLFLAG_RW, &debug, 0, 142 "SBP debug flag"); 143SYSCTL_INT(_hw_firewire_sbp, OID_AUTO, auto_login, CTLFLAG_RW, &auto_login, 0, 144 "SBP perform login automatically"); 145SYSCTL_INT(_hw_firewire_sbp, OID_AUTO, max_speed, CTLFLAG_RW, &max_speed, 0, 146 "SBP transfer max speed"); 147 148#define SBP_DEBUG(x) if (debug > x) { 149#define END_DEBUG } 150 151#define NEED_RESPONSE 0 152 153struct ind_ptr { 154 u_int32_t hi,lo; 155}; 156#define SBP_IND_MAX 0x20 157struct sbp_ocb { 158 STAILQ_ENTRY(sbp_ocb) ocb; 159 union ccb *ccb; 160 volatile u_int32_t orb[8]; 161 volatile struct ind_ptr ind_ptr[SBP_IND_MAX]; 162 struct sbp_dev *sdev; 163 int flags; 164 bus_dmamap_t dmamap; 165}; 166#define OCB_ACT_MGM 0 167#define OCB_ACT_CMD 1 168#define OCB_ACT_MASK 3 169#define OCB_RESERVED 0x10 170#define OCB_DONE 0x20 171 172#define SBP_RESOURCE_SHORTAGE 0x10 173 174struct sbp_login_res{ 175 u_int16_t len; 176 u_int16_t id; 177 u_int16_t res0; 178 u_int16_t cmd_hi; 179 u_int32_t cmd_lo; 180 u_int16_t res1; 181 u_int16_t recon_hold; 182}; 183struct sbp_status{ 184 u_int8_t len:3, 185 dead:1, 186 resp:2, 187 src:2; 188 u_int8_t status:8; 189 u_int16_t orb_hi; 190 u_int32_t orb_lo; 191 u_int32_t data[6]; 192}; 193struct sbp_cmd_status{ 194#define SBP_SFMT_CURR 0 195#define SBP_SFMT_DEFER 1 196 u_int8_t status:6, 197 sfmt:2; 198 u_int8_t s_key:4, 199 ill_len:1, 200 eom:1, 201 mark:1, 202 valid:1; 203 u_int8_t s_code; 204 u_int8_t s_qlfr; 205 u_int32_t info; 206 u_int32_t cdb; 207 u_int32_t fru:8, 208 s_keydep:24; 209 u_int32_t vend[2]; 210}; 211 212struct sbp_dev{ 213#define SBP_DEV_RESET 0 /* accept login */ 214#if 0 215#define SBP_DEV_LOGIN 1 /* to login */ 216#define SBP_DEV_RECONN 2 /* to reconnect */ 217#endif 218#define SBP_DEV_TOATTACH 3 /* to attach */ 219#define SBP_DEV_PROBE 4 /* scan lun */ 220#define SBP_DEV_ATTACHED 5 /* in operation */ 221#define SBP_DEV_DEAD 6 /* unavailable unit */ 222#define SBP_DEV_RETRY 7 /* unavailable unit */ 223 u_int8_t status:4, 224#define SBP_DEV_TIMEOUT 1 225 flags:4; 226 u_int8_t type; 227 u_int16_t lun_id; 228 struct cam_path *path; 229 struct sbp_target *target; 230 struct sbp_login_res login; 231 STAILQ_HEAD(, sbp_ocb) ocbs; 232 char vendor[32]; 233 char product[32]; 234 char revision[10]; 235}; 236 237struct sbp_target { 238 int target_id; 239 int num_lun; 240 struct sbp_dev *luns; 241 struct sbp_softc *sbp; 242 struct fw_device *fwdev; 243 u_int32_t mgm_hi, mgm_lo; 244}; 245 246struct sbp_softc { 247 struct firewire_dev_comm fd; 248 unsigned char flags; 249 struct cam_sim *sim; 250 struct sbp_target targets[SBP_NUM_TARGETS]; 251 struct fw_bind fwb; 252 STAILQ_HEAD(, sbp_ocb) free_ocbs; 253 struct sbp_ocb *ocb; 254 bus_dma_tag_t dmat; 255}; 256static void sbp_post_explore __P((void *)); 257static void sbp_recv __P((struct fw_xfer *)); 258static void sbp_login_callback __P((struct fw_xfer *)); 259static void sbp_cmd_callback __P((struct fw_xfer *)); 260static void sbp_orb_pointer __P((struct sbp_dev *, struct sbp_ocb *)); 261static void sbp_execute_ocb __P((void *, bus_dma_segment_t *, int, int)); 262static void sbp_free_ocb __P((struct sbp_softc *, struct sbp_ocb *)); 263static void sbp_abort_ocb __P((struct sbp_ocb *, int)); 264static void sbp_abort_all_ocbs __P((struct sbp_dev *, int)); 265static struct fw_xfer * sbp_write_cmd __P((struct sbp_dev *, int, int)); 266static struct sbp_ocb * sbp_get_ocb __P((struct sbp_softc *)); 267static struct sbp_ocb * sbp_enqueue_ocb __P((struct sbp_dev *, struct sbp_ocb *)); 268static struct sbp_ocb * sbp_dequeue_ocb __P((struct sbp_dev *, u_int32_t)); 269static void sbp_cam_detach_target __P((struct sbp_target *)); 270static void sbp_timeout __P((void *arg)); 271static void sbp_mgm_orb __P((struct sbp_dev *, int, u_int16_t, u_int32_t)); 272 273MALLOC_DEFINE(M_SBP, "sbp", "SBP-II/FireWire"); 274 275/* cam related functions */ 276static void sbp_action(struct cam_sim *sim, union ccb *ccb); 277static void sbp_poll(struct cam_sim *sim); 278static void sbp_cam_callback(struct cam_periph *periph, 279 union ccb *ccb); 280static void sbp_cam_scan_lun(struct sbp_dev *sdev); 281 282static char *orb_status0[] = { 283 /* 0 */ "No additional information to report", 284 /* 1 */ "Request type not supported", 285 /* 2 */ "Speed not supported", 286 /* 3 */ "Page size not supported", 287 /* 4 */ "Access denied", 288 /* 5 */ "Logical unit not supported", 289 /* 6 */ "Maximum payload too small", 290 /* 7 */ "Reserved for future standardization", 291 /* 8 */ "Resources unavailable", 292 /* 9 */ "Function rejected", 293 /* A */ "Login ID not recognized", 294 /* B */ "Dummy ORB completed", 295 /* C */ "Request aborted", 296 /* FF */ "Unspecified error" 297#define MAX_ORB_STATUS0 0xd 298}; 299 300static char *orb_status1_object[] = { 301 /* 0 */ "Operation request block (ORB)", 302 /* 1 */ "Data buffer", 303 /* 2 */ "Page table", 304 /* 3 */ "Unable to specify" 305}; 306 307static char *orb_status1_serial_bus_error[] = { 308 /* 0 */ "Missing acknowledge", 309 /* 1 */ "Reserved; not to be used", 310 /* 2 */ "Time-out error", 311 /* 3 */ "Reserved; not to be used", 312 /* 4 */ "Busy retry limit exceeded(X)", 313 /* 5 */ "Busy retry limit exceeded(A)", 314 /* 6 */ "Busy retry limit exceeded(B)", 315 /* 7 */ "Reserved for future standardization", 316 /* 8 */ "Reserved for future standardization", 317 /* 9 */ "Reserved for future standardization", 318 /* A */ "Reserved for future standardization", 319 /* B */ "Tardy retry limit exceeded", 320 /* C */ "Conflict error", 321 /* D */ "Data error", 322 /* E */ "Type error", 323 /* F */ "Address error" 324}; 325 326static void 327sbp_identify(driver_t *driver, device_t parent) 328{ 329 device_t child; 330SBP_DEBUG(0) 331 printf("sbp_identify\n"); 332END_DEBUG 333 334 child = BUS_ADD_CHILD(parent, 0, "sbp", device_get_unit(parent)); 335} 336 337/* 338 * sbp_probe() 339 */ 340static int 341sbp_probe(device_t dev) 342{ 343 device_t pa; 344 345SBP_DEBUG(0) 346 printf("sbp_probe\n"); 347END_DEBUG 348 349 pa = device_get_parent(dev); 350 if(device_get_unit(dev) != device_get_unit(pa)){ 351 return(ENXIO); 352 } 353 354 device_set_desc(dev, "SBP2/SCSI over firewire"); 355 return (0); 356} 357 358static void 359sbp_show_sdev_info(struct sbp_dev *sdev, int new) 360{ 361 struct fw_device *fwdev; 362 363 printf("%s:%d:%d ", 364 device_get_nameunit(sdev->target->sbp->fd.dev), 365 sdev->target->target_id, 366 sdev->lun_id 367 ); 368 if (new == 2) { 369 return; 370 } 371 fwdev = sdev->target->fwdev; 372 printf("ordered:%d type:%d EUI:%08x%08x node:%d " 373 "speed:%d maxrec:%d", 374 (sdev->type & 0x40) >> 6, 375 (sdev->type & 0x1f), 376 fwdev->eui.hi, 377 fwdev->eui.lo, 378 fwdev->dst, 379 fwdev->speed, 380 fwdev->maxrec 381 ); 382 if (new) 383 printf(" new!\n"); 384 else 385 printf("\n"); 386 sbp_show_sdev_info(sdev, 2); 387 printf("'%s' '%s' '%s'\n", sdev->vendor, sdev->product, sdev->revision); 388} 389 390static struct { 391 int bus; 392 int target; 393 struct fw_eui64 eui; 394} wired[] = { 395 /* Bus Target EUI64 */ 396#if 0 397 {0, 2, {0x00018ea0, 0x01fd0154}}, /* Logitec HDD */ 398 {0, 0, {0x00018ea6, 0x00100682}}, /* Logitec DVD */ 399 {0, 1, {0x00d03200, 0xa412006a}}, /* Yano HDD */ 400#endif 401 {-1, -1, {0,0}} 402}; 403 404static int 405sbp_new_target(struct sbp_softc *sbp, struct fw_device *fwdev) 406{ 407 int bus, i, target=-1; 408 char w[SBP_NUM_TARGETS]; 409 410 bzero(w, sizeof(w)); 411 bus = device_get_unit(sbp->fd.dev); 412 413 /* XXX wired-down configuration should be gotten from 414 tunable or device hint */ 415 for (i = 0; wired[i].bus >= 0; i ++) { 416 if (wired[i].bus == bus) { 417 w[wired[i].target] = 1; 418 if (wired[i].eui.hi == fwdev->eui.hi && 419 wired[i].eui.lo == fwdev->eui.lo) 420 target = wired[i].target; 421 } 422 } 423 if (target >= 0) { 424 if(target < SBP_NUM_TARGETS && 425 sbp->targets[target].fwdev == NULL) 426 return(target); 427 device_printf(sbp->fd.dev, 428 "target %d is not free for %08x:%08x\n", 429 target, fwdev->eui.hi, fwdev->eui.lo); 430 target = -1; 431 } 432 /* non-wired target */ 433 for (i = 0; i < SBP_NUM_TARGETS; i ++) 434 if (sbp->targets[i].fwdev == NULL && w[i] == 0) { 435 target = i; 436 break; 437 } 438 439 return target; 440} 441 442static struct sbp_target * 443sbp_alloc_target(struct sbp_softc *sbp, struct fw_device *fwdev) 444{ 445 int i, maxlun, lun; 446 struct sbp_target *target; 447 struct sbp_dev *sdev; 448 struct crom_context cc; 449 struct csrreg *reg; 450 451SBP_DEBUG(1) 452 printf("sbp_alloc_target\n"); 453END_DEBUG 454 i = sbp_new_target(sbp, fwdev); 455 if (i < 0) { 456 device_printf(sbp->fd.dev, "increase SBP_NUM_TARGETS!\n"); 457 return NULL; 458 } 459 /* new target */ 460 target = &sbp->targets[i]; 461 target->sbp = sbp; 462 target->fwdev = fwdev; 463 target->target_id = i; 464 if((target->mgm_lo = getcsrdata(fwdev, 0x54)) == 0 ){ 465 /* bad target */ 466 printf("NULL management address\n"); 467 target->fwdev = NULL; 468 return NULL; 469 } 470 target->mgm_hi = 0xffff; 471 target->mgm_lo = 0xf0000000 | target->mgm_lo << 2; 472 /* XXX num_lun may be changed. realloc luns? */ 473 crom_init_context(&cc, target->fwdev->csrrom); 474 /* XXX shoud parse appropriate unit directories only */ 475 maxlun = -1; 476 while (cc.depth >= 0) { 477 reg = crom_search_key(&cc, CROM_LUN); 478 if (reg == NULL) 479 break; 480 lun = reg->val & 0xffff; 481SBP_DEBUG(0) 482 printf("target %d lun %d found\n", target->target_id, lun); 483END_DEBUG 484 if (maxlun < lun) 485 maxlun = lun; 486 crom_next(&cc); 487 } 488 if (maxlun < 0) 489 printf("no lun found!\n"); 490 if (maxlun >= SBP_NUM_LUNS) 491 maxlun = SBP_NUM_LUNS; 492 target->num_lun = maxlun + 1; 493 target->luns = (struct sbp_dev *) malloc( 494 sizeof(struct sbp_dev) * target->num_lun, 495 M_SBP, M_NOWAIT | M_ZERO); 496 for (i = 0; i < target->num_lun; i++) { 497 sdev = &target->luns[i]; 498 sdev->lun_id = i; 499 sdev->target = target; 500 STAILQ_INIT(&sdev->ocbs); 501 sdev->status = SBP_DEV_DEAD; 502 } 503 crom_init_context(&cc, target->fwdev->csrrom); 504 while (cc.depth >= 0) { 505 reg = crom_search_key(&cc, CROM_LUN); 506 if (reg == NULL) 507 break; 508 lun = reg->val & 0xffff; 509 if (lun >= SBP_NUM_LUNS) { 510 printf("too large lun %d\n", lun); 511 continue; 512 } 513 target->luns[lun].status = SBP_DEV_RESET; 514 target->luns[lun].type = (reg->val & 0xf0000) >> 16; 515 crom_next(&cc); 516 } 517 return target; 518 } 519 520static void 521sbp_get_text_leaf(struct fw_device *fwdev, int key, char *buf, int len) 522{ 523 static char *nullstr = "(null)"; 524 int i, clen, found=0; 525 struct csrhdr *chdr; 526 struct csrreg *creg; 527 u_int32_t *src, *dst; 528 529 chdr = (struct csrhdr *)&fwdev->csrrom[0]; 530 /* skip crom header, bus info and root directory */ 531 creg = (struct csrreg *)chdr + chdr->info_len + 2; 532 /* search unitl the one before the last. */ 533 for (i = chdr->info_len + 2; i < fwdev->rommax / 4; i++) { 534 if((creg++)->key == key){ 535 found = 1; 536 break; 537 } 538 } 539 if (!found || creg->key != CROM_TEXTLEAF) { 540 strncpy(buf, nullstr, len); 541 return; 542 } 543 src = (u_int32_t *) creg + creg->val; 544 clen = ((*src >> 16) - 2) * 4; 545 src += 3; 546 dst = (u_int32_t *) buf; 547 if (len < clen) 548 clen = len; 549 for (i = 0; i < clen/4; i++) 550 *dst++ = htonl(*src++); 551 buf[clen] = 0; 552} 553 554static void 555sbp_probe_lun(struct sbp_dev *sdev) 556{ 557 struct fw_device *fwdev; 558 int rev; 559 560 fwdev = sdev->target->fwdev; 561 bzero(sdev->vendor, sizeof(sdev->vendor)); 562 bzero(sdev->product, sizeof(sdev->product)); 563 sbp_get_text_leaf(fwdev, 0x03, sdev->vendor, sizeof(sdev->vendor)); 564 sbp_get_text_leaf(fwdev, 0x17, sdev->product, sizeof(sdev->product)); 565 rev = getcsrdata(sdev->target->fwdev, 0x3c); 566 snprintf(sdev->revision, sizeof(sdev->revision), "%06x", rev); 567} 568static void 569sbp_probe_target(struct sbp_target *target, int alive) 570{ 571 struct sbp_softc *sbp; 572 struct sbp_dev *sdev; 573 struct firewire_comm *fc; 574 int i; 575 576SBP_DEBUG(1) 577 printf("sbp_probe_target %d\n", target->target_id); 578 if (!alive) 579 printf("not alive\n"); 580END_DEBUG 581 582 sbp = target->sbp; 583 fc = target->sbp->fd.fc; 584 for (i=0; i < target->num_lun; i++) { 585 sdev = &target->luns[i]; 586 if (alive && (sdev->status != SBP_DEV_DEAD)) { 587 if (sdev->path != NULL) { 588 xpt_freeze_devq(sdev->path, 1); 589 } 590 sbp_abort_all_ocbs(sdev, CAM_REQUEUE_REQ); 591 switch (sdev->status) { 592 case SBP_DEV_RESET: 593 /* new or revived target */ 594 sbp_probe_lun(sdev); 595 if (auto_login) { 596 sdev->status = SBP_DEV_TOATTACH; 597 sbp_mgm_orb(sdev, ORB_FUN_LGI, 0, 0); 598 } 599 break; 600 case SBP_DEV_RETRY: 601 sbp_probe_lun(sdev); 602 default: 603 sbp_mgm_orb(sdev, ORB_FUN_RCN, 0, 0); 604 break; 605 } 606SBP_DEBUG(0) 607 sbp_show_sdev_info(sdev, 608 (sdev->status == SBP_DEV_TOATTACH)); 609END_DEBUG 610 } else { 611 switch (sdev->status) { 612 case SBP_DEV_ATTACHED: 613SBP_DEBUG(0) 614 /* the device has gone */ 615 sbp_show_sdev_info(sdev, 2); 616 printf("lost target\n"); 617END_DEBUG 618 if (sdev->path) 619 xpt_freeze_devq(sdev->path, 1); 620 sdev->status = SBP_DEV_RETRY; 621 sbp_abort_all_ocbs(sdev, CAM_REQUEUE_REQ); 622 break; 623 case SBP_DEV_PROBE: 624 case SBP_DEV_TOATTACH: 625 sdev->status = SBP_DEV_RESET; 626 break; 627 case SBP_DEV_RETRY: 628 case SBP_DEV_RESET: 629 case SBP_DEV_DEAD: 630 break; 631 } 632 } 633 } 634} 635 636static void 637sbp_post_explore(void *arg) 638{ 639 struct sbp_softc *sbp = (struct sbp_softc *)arg; 640 struct sbp_target *target; 641 struct fw_device *fwdev; 642 int i, alive; 643 644SBP_DEBUG(0) 645 printf("sbp_post_explore (sbp_cold=%d)\n", sbp_cold); 646END_DEBUG 647#if 0 648 xpt_freeze_simq(sbp->sim, /*count*/ 1); 649#endif 650 if (sbp_cold > 0) 651 sbp_cold --; 652 /* Gabage Collection */ 653 for(i = 0 ; i < SBP_NUM_TARGETS ; i ++){ 654 target = &sbp->targets[i]; 655 STAILQ_FOREACH(fwdev, &sbp->fd.fc->devices, link) 656 if (target->fwdev == NULL || target->fwdev == fwdev) 657 break; 658 if(fwdev == NULL){ 659 /* device has removed in lower driver */ 660 sbp_cam_detach_target(target); 661 if (target->luns != NULL) 662 free(target->luns, M_SBP); 663 target->num_lun = 0;; 664 target->luns = NULL; 665 target->fwdev = NULL; 666 } 667 } 668 /* traverse device list */ 669 STAILQ_FOREACH(fwdev, &sbp->fd.fc->devices, link) { 670SBP_DEBUG(0) 671 printf("sbp_post_explore: EUI:%08x%08x ", 672 fwdev->eui.hi, fwdev->eui.lo); 673 if (fwdev->status == FWDEVATTACHED) { 674 printf("spec=%d key=%d.\n", 675 getcsrdata(fwdev, CSRKEY_SPEC) == CSRVAL_ANSIT10, 676 getcsrdata(fwdev, CSRKEY_VER) == CSRVAL_T10SBP2); 677 } else { 678 printf("not attached, state=%d.\n", fwdev->status); 679 } 680END_DEBUG 681 alive = (fwdev->status == FWDEVATTACHED) 682 && (getcsrdata(fwdev, CSRKEY_SPEC) == CSRVAL_ANSIT10) 683 && (getcsrdata(fwdev, CSRKEY_VER) == CSRVAL_T10SBP2); 684 for(i = 0 ; i < SBP_NUM_TARGETS ; i ++){ 685 target = &sbp->targets[i]; 686 if(target->fwdev == fwdev ) { 687 /* known target */ 688 break; 689 } 690 } 691 if(i == SBP_NUM_TARGETS){ 692 if (alive) { 693 /* new target */ 694 target = sbp_alloc_target(sbp, fwdev); 695 if (target == NULL) 696 continue; 697 } else { 698 continue; 699 } 700 } 701 sbp_probe_target(target, alive); 702 } 703#if 0 704 timeout(sbp_release_queue, (caddr_t)sbp, bus_reset_rest * hz / 1000); 705#endif 706} 707 708#if NEED_RESPONSE 709static void 710sbp_loginres_callback(struct fw_xfer *xfer){ 711SBP_DEBUG(1) 712 struct sbp_dev *sdev; 713 sdev = (struct sbp_dev *)xfer->sc; 714 sbp_show_sdev_info(sdev, 2); 715 printf("sbp_loginres_callback\n"); 716END_DEBUG 717 fw_xfer_free(xfer); 718 return; 719} 720#endif 721 722static void 723sbp_login_callback(struct fw_xfer *xfer) 724{ 725SBP_DEBUG(1) 726 struct sbp_dev *sdev; 727 sdev = (struct sbp_dev *)xfer->sc; 728 sbp_show_sdev_info(sdev, 2); 729 printf("sbp_login_callback\n"); 730END_DEBUG 731 fw_xfer_free(xfer); 732 return; 733} 734 735static void 736sbp_cmd_callback(struct fw_xfer *xfer) 737{ 738SBP_DEBUG(2) 739 struct sbp_dev *sdev; 740 sdev = (struct sbp_dev *)xfer->sc; 741 sbp_show_sdev_info(sdev, 2); 742 printf("sbp_cmd_callback\n"); 743END_DEBUG 744 fw_xfer_free(xfer); 745 return; 746} 747 748static void 749sbp_cam_callback(struct cam_periph *periph, union ccb *ccb) 750{ 751 struct sbp_dev *sdev; 752 sdev = (struct sbp_dev *) ccb->ccb_h.ccb_sdev_ptr; 753SBP_DEBUG(0) 754 sbp_show_sdev_info(sdev, 2); 755 printf("sbp_cam_callback\n"); 756END_DEBUG 757 sdev->status = SBP_DEV_ATTACHED; 758 free(ccb, M_SBP); 759} 760 761static void 762sbp_cam_scan_lun(struct sbp_dev *sdev) 763{ 764 union ccb *ccb; 765 766 ccb = malloc(sizeof(union ccb), M_SBP, M_NOWAIT | M_ZERO); 767 if (ccb == NULL) { 768 printf("sbp_cam_scan_lun: malloc failed\n"); 769 return; 770 } 771 772SBP_DEBUG(0) 773 sbp_show_sdev_info(sdev, 2); 774 printf("sbp_cam_scan_lun\n"); 775END_DEBUG 776 xpt_setup_ccb(&ccb->ccb_h, sdev->path, 5/*priority (low)*/); 777 ccb->ccb_h.func_code = XPT_SCAN_LUN; 778 ccb->ccb_h.cbfcnp = sbp_cam_callback; 779 ccb->crcn.flags = CAM_FLAG_NONE; 780 ccb->ccb_h.ccb_sdev_ptr = sdev; 781 782 /* The scan is in progress now. */ 783 sdev->status = SBP_DEV_PROBE; 784 xpt_action(ccb); 785} 786 787 788static void 789sbp_ping_unit_callback(struct cam_periph *periph, union ccb *ccb) 790{ 791 struct sbp_dev *sdev; 792 sdev = (struct sbp_dev *) ccb->ccb_h.ccb_sdev_ptr; 793SBP_DEBUG(0) 794 sbp_show_sdev_info(sdev, 2); 795 printf("sbp_ping_unit_callback\n"); 796END_DEBUG 797 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) { 798 if (--ccb->ccb_h.retry_count == 0) { 799 sbp_show_sdev_info(sdev, 2); 800 printf("sbp_ping_unit_callback: " 801 "retry count exceeded\n"); 802 sdev->status = SBP_DEV_RETRY; 803 free(ccb, M_SBP); 804 } else { 805 /* requeue */ 806 xpt_action(ccb); 807 xpt_release_devq(sdev->path, MAX_FREEZE, TRUE); 808 } 809 } else { 810 free(ccb->csio.data_ptr, M_SBP); 811 free(ccb, M_SBP); 812 sdev->status = SBP_DEV_ATTACHED; 813 xpt_release_devq(sdev->path, MAX_FREEZE, TRUE); 814 } 815} 816 817/* 818 * XXX Some devices need to execute inquiry or read_capacity 819 * after bus_rest during busy transfer. 820 * Otherwise they return incorrect result for READ(and WRITE?) 821 * command without any SBP-II/SCSI error. 822 * 823 * e.g. Maxtor 3000XT, Yano A-dish. 824 */ 825static void 826sbp_ping_unit(struct sbp_dev *sdev) 827{ 828 union ccb *ccb; 829 struct scsi_inquiry_data *inq_buf; 830 831 832 ccb = malloc(sizeof(union ccb), M_SBP, M_NOWAIT | M_ZERO); 833 if (ccb == NULL) { 834 printf("sbp_ping_unit: malloc failed\n"); 835 return; 836 } 837 838 inq_buf = (struct scsi_inquiry_data *) 839 malloc(sizeof(*inq_buf), M_SBP, M_NOWAIT); 840 if (inq_buf == NULL) { 841 free(ccb, M_SBP); 842 printf("sbp_ping_unit: malloc failed\n"); 843 return; 844 } 845 846SBP_DEBUG(0) 847 sbp_show_sdev_info(sdev, 2); 848 printf("sbp_ping_unit\n"); 849END_DEBUG 850 851 /* 852 * We need to execute this command before any other queued command. 853 * Make priority 0 and freeze queue after execution for retry. 854 * cam's scan_lun command doesn't provide this feature. 855 */ 856 xpt_setup_ccb(&ccb->ccb_h, sdev->path, 0/*priority (high)*/); 857 scsi_inquiry( 858 &ccb->csio, 859 /*retries*/ 5, 860 sbp_ping_unit_callback, 861 MSG_SIMPLE_Q_TAG, 862 (u_int8_t *)inq_buf, 863 SHORT_INQUIRY_LENGTH, 864 /*evpd*/FALSE, 865 /*page_code*/0, 866 SSD_MIN_SIZE, 867 /*timeout*/60000 868 ); 869 ccb->ccb_h.flags |= CAM_DEV_QFREEZE; 870 xpt_action(ccb); 871 sdev->status = SBP_DEV_PROBE; 872} 873 874static void 875sbp_do_attach(struct fw_xfer *xfer) 876{ 877 struct sbp_dev *sdev; 878 879 sdev = (struct sbp_dev *)xfer->sc; 880SBP_DEBUG(0) 881 sbp_show_sdev_info(sdev, 2); 882 printf("sbp_do_attach\n"); 883END_DEBUG 884 fw_xfer_free(xfer); 885 886 if (sdev->path == NULL) 887 xpt_create_path(&sdev->path, xpt_periph, 888 cam_sim_path(sdev->target->sbp->sim), 889 sdev->target->target_id, sdev->lun_id); 890 891 /* 892 * Let CAM scan the bus if we are in the boot process. 893 * XXX xpt_scan_bus cannot detect LUN larger than 0 894 * if LUN 0 doesn't exists. 895 */ 896 if (sbp_cold > 0) { 897 sdev->status = SBP_DEV_PROBE; 898 return; 899 } 900 901 if (sdev->status == SBP_DEV_RETRY) 902 sbp_ping_unit(sdev); 903 else 904 sbp_cam_scan_lun(sdev); 905 xpt_release_devq(sdev->path, MAX_FREEZE, TRUE); 906 return; 907} 908 909static void 910sbp_agent_reset_callback(struct fw_xfer *xfer) 911{ 912 struct sbp_dev *sdev; 913 914 sdev = (struct sbp_dev *)xfer->sc; 915SBP_DEBUG(1) 916 sbp_show_sdev_info(sdev, 2); 917 printf("sbp_cmd_callback\n"); 918END_DEBUG 919 fw_xfer_free(xfer); 920 sbp_abort_all_ocbs(sdev, CAM_REQUEUE_REQ); 921 if (sdev->path) 922 xpt_release_devq(sdev->path, MAX_FREEZE, TRUE); 923} 924 925static void 926sbp_agent_reset(struct sbp_dev *sdev) 927{ 928 struct fw_xfer *xfer; 929 struct fw_pkt *fp; 930 931SBP_DEBUG(0) 932 sbp_show_sdev_info(sdev, 2); 933 printf("sbp_agent_reset\n"); 934END_DEBUG 935 xfer = sbp_write_cmd(sdev, FWTCODE_WREQQ, 0x04); 936 if (xfer == NULL) 937 return; 938 if (sdev->status == SBP_DEV_ATTACHED) 939 xfer->act.hand = sbp_agent_reset_callback; 940 else 941 xfer->act.hand = sbp_do_attach; 942 fp = (struct fw_pkt *)xfer->send.buf; 943 fp->mode.wreqq.data = htonl(0xf); 944 fw_asyreq(xfer->fc, -1, xfer); 945} 946 947static void 948sbp_busy_timeout_callback(struct fw_xfer *xfer) 949{ 950 struct sbp_dev *sdev; 951 952 sdev = (struct sbp_dev *)xfer->sc; 953SBP_DEBUG(1) 954 sbp_show_sdev_info(sdev, 2); 955 printf("sbp_busy_timeout_callback\n"); 956END_DEBUG 957 fw_xfer_free(xfer); 958 sbp_agent_reset(sdev); 959} 960 961static void 962sbp_busy_timeout(struct sbp_dev *sdev) 963{ 964 struct fw_pkt *fp; 965 struct fw_xfer *xfer; 966SBP_DEBUG(0) 967 sbp_show_sdev_info(sdev, 2); 968 printf("sbp_busy_timeout\n"); 969END_DEBUG 970 xfer = sbp_write_cmd(sdev, FWTCODE_WREQQ, 0); 971 972 xfer->act.hand = sbp_busy_timeout_callback; 973 fp = (struct fw_pkt *)xfer->send.buf; 974 fp->mode.wreqq.dest_hi = htons(0xffff); 975 fp->mode.wreqq.dest_lo = htonl(0xf0000000 | BUSY_TIMEOUT); 976 fp->mode.wreqq.data = htonl((1 << (13+12)) | 0xf); 977 fw_asyreq(xfer->fc, -1, xfer); 978} 979 980#if 0 981static void 982sbp_reset_start(struct sbp_dev *sdev) 983{ 984 struct fw_xfer *xfer; 985 struct fw_pkt *fp; 986 987SBP_DEBUG(0) 988 sbp_show_sdev_info(sdev, 2); 989 printf("sbp_reset_start\n"); 990END_DEBUG 991 xfer = sbp_write_cmd(sdev, FWTCODE_WREQQ, 0); 992 993 xfer->act.hand = sbp_busy_timeout; 994 fp = (struct fw_pkt *)xfer->send.buf; 995 fp->mode.wreqq.dest_hi = htons(0xffff); 996 fp->mode.wreqq.dest_lo = htonl(0xf0000000 | RESET_START); 997 fp->mode.wreqq.data = htonl(0xf); 998 fw_asyreq(xfer->fc, -1, xfer); 999} 1000#endif 1001 1002static void 1003sbp_orb_pointer(struct sbp_dev *sdev, struct sbp_ocb *ocb) 1004{ 1005 struct fw_xfer *xfer; 1006 struct fw_pkt *fp; 1007SBP_DEBUG(2) 1008 sbp_show_sdev_info(sdev, 2); 1009 printf("sbp_orb_pointer\n"); 1010END_DEBUG 1011 1012 xfer = sbp_write_cmd(sdev, FWTCODE_WREQB, 0x08); 1013 if (xfer == NULL) 1014 return; 1015 xfer->act.hand = sbp_cmd_callback; 1016 1017 fp = (struct fw_pkt *)xfer->send.buf; 1018 fp->mode.wreqb.len = htons(8); 1019 fp->mode.wreqb.extcode = 0; 1020 fp->mode.wreqb.payload[0] = 1021 htonl(((sdev->target->sbp->fd.fc->nodeid | FWLOCALBUS )<< 16)); 1022 fp->mode.wreqb.payload[1] = htonl(vtophys(&ocb->orb[0])); 1023 1024 if(fw_asyreq(xfer->fc, -1, xfer) != 0){ 1025 fw_xfer_free(xfer); 1026 ocb->ccb->ccb_h.status = CAM_REQ_INVALID; 1027 xpt_done(ocb->ccb); 1028 } 1029} 1030 1031static void 1032sbp_doorbell(struct sbp_dev *sdev) 1033{ 1034 struct fw_xfer *xfer; 1035 struct fw_pkt *fp; 1036SBP_DEBUG(1) 1037 sbp_show_sdev_info(sdev, 2); 1038 printf("sbp_doorbell\n"); 1039END_DEBUG 1040 1041 xfer = sbp_write_cmd(sdev, FWTCODE_WREQQ, 0x10); 1042 if (xfer == NULL) 1043 return; 1044 xfer->act.hand = sbp_cmd_callback; 1045 fp = (struct fw_pkt *)xfer->send.buf; 1046 fp->mode.wreqq.data = htonl(0xf); 1047 fw_asyreq(xfer->fc, -1, xfer); 1048} 1049 1050static struct fw_xfer * 1051sbp_write_cmd(struct sbp_dev *sdev, int tcode, int offset) 1052{ 1053 struct fw_xfer *xfer; 1054 struct fw_pkt *fp; 1055 1056 xfer = fw_xfer_alloc(M_SBP); 1057 if(xfer == NULL){ 1058 return NULL; 1059 } 1060 if (tcode == FWTCODE_WREQQ) 1061 xfer->send.len = 16; 1062 else 1063 xfer->send.len = 24; 1064 1065 xfer->send.buf = malloc(xfer->send.len, M_FW, M_NOWAIT); 1066 if(xfer->send.buf == NULL){ 1067 fw_xfer_free(xfer); 1068 return NULL; 1069 } 1070 1071 xfer->send.off = 0; 1072 xfer->spd = min(sdev->target->fwdev->speed, max_speed); 1073 xfer->sc = (caddr_t)sdev; 1074 xfer->fc = sdev->target->sbp->fd.fc; 1075 xfer->retry_req = fw_asybusy; 1076 1077 fp = (struct fw_pkt *)xfer->send.buf; 1078 fp->mode.wreqq.dest_hi = htons(sdev->login.cmd_hi); 1079 fp->mode.wreqq.dest_lo = htonl(sdev->login.cmd_lo + offset); 1080 fp->mode.wreqq.tlrt = 0; 1081 fp->mode.wreqq.tcode = tcode; 1082 fp->mode.wreqq.pri = 0; 1083 xfer->dst = FWLOCALBUS | sdev->target->fwdev->dst; 1084 fp->mode.wreqq.dst = htons(xfer->dst); 1085 1086 return xfer; 1087 1088} 1089 1090static void 1091sbp_mgm_orb(struct sbp_dev *sdev, int func, u_int16_t orb_hi, u_int32_t orb_lo) 1092{ 1093 struct fw_xfer *xfer; 1094 struct fw_pkt *fp; 1095 struct sbp_ocb *ocb; 1096 int s, nid; 1097 1098 if ((ocb = sbp_get_ocb(sdev->target->sbp)) == NULL) { 1099 s = splfw(); 1100 sdev->target->sbp->flags |= SBP_RESOURCE_SHORTAGE; 1101 splx(s); 1102 return; 1103 } 1104 ocb->flags = OCB_ACT_MGM; 1105 ocb->sdev = sdev; 1106 ocb->ccb = NULL; 1107 1108 nid = sdev->target->sbp->fd.fc->nodeid | FWLOCALBUS; 1109 bzero((void *)(uintptr_t)(volatile void *)ocb->orb, sizeof(ocb->orb)); 1110 ocb->orb[6] = htonl((nid << 16) | SBP_BIND_HI); 1111 ocb->orb[7] = htonl(SBP_DEV2ADDR( 1112 device_get_unit(sdev->target->sbp->fd.dev), 1113 sdev->target->target_id, 1114 sdev->lun_id)); 1115 1116SBP_DEBUG(0) 1117 sbp_show_sdev_info(sdev, 2); 1118 printf("%s\n", orb_fun_name[(func>>16)&0xf]); 1119END_DEBUG 1120 switch (func) { 1121 case ORB_FUN_LGI: 1122 ocb->orb[2] = htonl(nid << 16); 1123 ocb->orb[3] = htonl(vtophys(&sdev->login)); 1124 ocb->orb[4] = htonl(ORB_NOTIFY | ORB_EXV | sdev->lun_id); 1125 ocb->orb[5] = htonl(sizeof(struct sbp_login_res)); 1126 break; 1127 case ORB_FUN_ATA: 1128 ocb->orb[0] = htonl((0 << 16) | orb_hi); 1129 ocb->orb[1] = htonl(orb_lo); 1130 /* fall through */ 1131 case ORB_FUN_RCN: 1132 case ORB_FUN_LGO: 1133 case ORB_FUN_LUR: 1134 case ORB_FUN_RST: 1135 case ORB_FUN_ATS: 1136 ocb->orb[4] = htonl(ORB_NOTIFY | func | sdev->login.id); 1137 break; 1138 } 1139 1140 xfer = sbp_write_cmd(sdev, FWTCODE_WREQB, 0); 1141 if(xfer == NULL){ 1142 return; 1143 } 1144 xfer->act.hand = sbp_login_callback; 1145 1146 fp = (struct fw_pkt *)xfer->send.buf; 1147 fp->mode.wreqb.dest_hi = htons(sdev->target->mgm_hi); 1148 fp->mode.wreqb.dest_lo = htonl(sdev->target->mgm_lo); 1149 fp->mode.wreqb.len = htons(8); 1150 fp->mode.wreqb.extcode = 0; 1151 fp->mode.wreqb.payload[0] = htonl(nid << 16); 1152 fp->mode.wreqb.payload[1] = htonl(vtophys(&ocb->orb[0])); 1153 sbp_enqueue_ocb(sdev, ocb); 1154 1155 fw_asyreq(xfer->fc, -1, xfer); 1156} 1157 1158static void 1159sbp_print_scsi_cmd(struct sbp_ocb *ocb) 1160{ 1161 struct ccb_scsiio *csio; 1162 1163 csio = &ocb->ccb->csio; 1164 printf("%s:%d:%d XPT_SCSI_IO: " 1165 "cmd: %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x" 1166 ", flags: 0x%02x, " 1167 "%db cmd/%db data/%db sense\n", 1168 device_get_nameunit(ocb->sdev->target->sbp->fd.dev), 1169 ocb->ccb->ccb_h.target_id, ocb->ccb->ccb_h.target_lun, 1170 csio->cdb_io.cdb_bytes[0], 1171 csio->cdb_io.cdb_bytes[1], 1172 csio->cdb_io.cdb_bytes[2], 1173 csio->cdb_io.cdb_bytes[3], 1174 csio->cdb_io.cdb_bytes[4], 1175 csio->cdb_io.cdb_bytes[5], 1176 csio->cdb_io.cdb_bytes[6], 1177 csio->cdb_io.cdb_bytes[7], 1178 csio->cdb_io.cdb_bytes[8], 1179 csio->cdb_io.cdb_bytes[9], 1180 ocb->ccb->ccb_h.flags & CAM_DIR_MASK, 1181 csio->cdb_len, csio->dxfer_len, 1182 csio->sense_len); 1183} 1184 1185static void 1186sbp_scsi_status(struct sbp_status *sbp_status, struct sbp_ocb *ocb) 1187{ 1188 struct sbp_cmd_status *sbp_cmd_status; 1189 struct scsi_sense_data *sense; 1190 1191 sbp_cmd_status = (struct sbp_cmd_status *)sbp_status->data; 1192 sense = &ocb->ccb->csio.sense_data; 1193 1194SBP_DEBUG(0) 1195 sbp_print_scsi_cmd(ocb); 1196 /* XXX need decode status */ 1197 sbp_show_sdev_info(ocb->sdev, 2); 1198 printf("SCSI status %x sfmt %x valid %x key %x code %x qlfr %x len %d", 1199 sbp_cmd_status->status, 1200 sbp_cmd_status->sfmt, 1201 sbp_cmd_status->valid, 1202 sbp_cmd_status->s_key, 1203 sbp_cmd_status->s_code, 1204 sbp_cmd_status->s_qlfr, 1205 sbp_status->len 1206 ); 1207#if 0 /* XXX */ 1208 if (sbp_cmd_status->status == SCSI_STATUS_CHECK_COND) { 1209 printf(" %s\n", scsi_sense_key_text[sbp_cmd_status->s_key]); 1210 scsi_sense_desc( 1211 sbp_cmd_status->s_code, 1212 sbp_cmd_status->s_qlfr, 1213 ocb->ccb->ccb_h.path->device->inq_data 1214 ) 1215 } else { 1216 printf("\n"); 1217 } 1218#else 1219 printf("\n"); 1220#endif 1221END_DEBUG 1222 1223 switch (sbp_cmd_status->status) { 1224 case SCSI_STATUS_CHECK_COND: 1225 case SCSI_STATUS_BUSY: 1226 case SCSI_STATUS_CMD_TERMINATED: 1227 if(sbp_cmd_status->sfmt == SBP_SFMT_CURR){ 1228 sense->error_code = SSD_CURRENT_ERROR; 1229 }else{ 1230 sense->error_code = SSD_DEFERRED_ERROR; 1231 } 1232 if(sbp_cmd_status->valid) 1233 sense->error_code |= SSD_ERRCODE_VALID; 1234 sense->flags = sbp_cmd_status->s_key; 1235 if(sbp_cmd_status->mark) 1236 sense->flags |= SSD_FILEMARK; 1237 if(sbp_cmd_status->eom) 1238 sense->flags |= SSD_EOM; 1239 if(sbp_cmd_status->ill_len) 1240 sense->flags |= SSD_ILI; 1241 sense->info[0] = ntohl(sbp_cmd_status->info) & 0xff; 1242 sense->info[1] =(ntohl(sbp_cmd_status->info) >> 8) & 0xff; 1243 sense->info[2] =(ntohl(sbp_cmd_status->info) >> 16) & 0xff; 1244 sense->info[3] =(ntohl(sbp_cmd_status->info) >> 24) & 0xff; 1245 if (sbp_status->len <= 1) 1246 /* XXX not scsi status. shouldn't be happened */ 1247 sense->extra_len = 0; 1248 else if (sbp_status->len <= 4) 1249 /* add_sense_code(_qual), info, cmd_spec_info */ 1250 sense->extra_len = 6; 1251 else 1252 /* fru, sense_key_spec */ 1253 sense->extra_len = 10; 1254 sense->cmd_spec_info[0] = ntohl(sbp_cmd_status->cdb) & 0xff; 1255 sense->cmd_spec_info[1] = (ntohl(sbp_cmd_status->cdb) >> 8) & 0xff; 1256 sense->cmd_spec_info[2] = (ntohl(sbp_cmd_status->cdb) >> 16) & 0xff; 1257 sense->cmd_spec_info[3] = (ntohl(sbp_cmd_status->cdb) >> 24) & 0xff; 1258 sense->add_sense_code = sbp_cmd_status->s_code; 1259 sense->add_sense_code_qual = sbp_cmd_status->s_qlfr; 1260 sense->fru = sbp_cmd_status->fru; 1261 sense->sense_key_spec[0] = ntohl(sbp_cmd_status->s_keydep) & 0xff; 1262 sense->sense_key_spec[1] = (ntohl(sbp_cmd_status->s_keydep) >>8) & 0xff; 1263 sense->sense_key_spec[2] = (ntohl(sbp_cmd_status->s_keydep) >>16) & 0xff; 1264 1265 ocb->ccb->csio.scsi_status = sbp_cmd_status->status;; 1266 ocb->ccb->ccb_h.status = CAM_SCSI_STATUS_ERROR 1267 | CAM_AUTOSNS_VALID; 1268/* 1269{ 1270 u_int8_t j, *tmp; 1271 tmp = sense; 1272 for( j = 0 ; j < 32 ; j+=8){ 1273 printf("sense %02x%02x %02x%02x %02x%02x %02x%02x\n", 1274 tmp[j], tmp[j+1], tmp[j+2], tmp[j+3], 1275 tmp[j+4], tmp[j+5], tmp[j+6], tmp[j+7]); 1276 } 1277 1278} 1279*/ 1280 break; 1281 default: 1282 sbp_show_sdev_info(ocb->sdev, 2); 1283 printf("sbp_scsi_status: unknown scsi status 0x%x\n", 1284 sbp_cmd_status->status); 1285 } 1286} 1287 1288static void 1289sbp_fix_inq_data(struct sbp_ocb *ocb) 1290{ 1291 union ccb *ccb; 1292 struct sbp_dev *sdev; 1293 struct scsi_inquiry_data *inq; 1294 1295 ccb = ocb->ccb; 1296 sdev = ocb->sdev; 1297 1298 if (ccb->csio.cdb_io.cdb_bytes[1] & SI_EVPD) 1299 return; 1300SBP_DEBUG(1) 1301 sbp_show_sdev_info(sdev, 2); 1302 printf("sbp_fix_inq_data\n"); 1303END_DEBUG 1304 inq = (struct scsi_inquiry_data *) ccb->csio.data_ptr; 1305 switch (SID_TYPE(inq)) { 1306 case T_DIRECT: 1307 /* 1308 * XXX Convert Direct Access device to RBC. 1309 * I've never seen FireWire DA devices which support READ_6. 1310 */ 1311#if 1 1312 if (SID_TYPE(inq) == T_DIRECT) 1313 inq->device |= T_RBC; /* T_DIRECT == 0 */ 1314#endif 1315 /* fall through */ 1316 case T_RBC: 1317 /* disable tag queuing */ 1318 inq->flags &= ~SID_CmdQue; 1319 /* 1320 * Override vendor/product/revision information. 1321 * Some devices sometimes return strange strings. 1322 */ 1323 bcopy(sdev->vendor, inq->vendor, sizeof(inq->vendor)); 1324 bcopy(sdev->product, inq->product, sizeof(inq->product)); 1325 bcopy(sdev->revision+2, inq->revision, sizeof(inq->revision)); 1326 break; 1327 } 1328} 1329 1330static void 1331sbp_recv1(struct fw_xfer *xfer){ 1332 struct fw_pkt *rfp; 1333#if NEED_RESPONSE 1334 struct fw_pkt *sfp; 1335#endif 1336 struct sbp_softc *sbp; 1337 struct sbp_dev *sdev; 1338 struct sbp_ocb *ocb; 1339 struct sbp_login_res *login_res = NULL; 1340 struct sbp_status *sbp_status; 1341 struct sbp_target *target; 1342 int orb_fun, status_valid, t, l; 1343 u_int32_t addr; 1344/* 1345 u_int32_t *ld; 1346 ld = xfer->recv.buf; 1347printf("sbp %x %d %d %08x %08x %08x %08x\n", 1348 xfer->resp, xfer->recv.len, xfer->recv.off, ntohl(ld[0]), ntohl(ld[1]), ntohl(ld[2]), ntohl(ld[3])); 1349printf("sbp %08x %08x %08x %08x\n", ntohl(ld[4]), ntohl(ld[5]), ntohl(ld[6]), ntohl(ld[7])); 1350printf("sbp %08x %08x %08x %08x\n", ntohl(ld[8]), ntohl(ld[9]), ntohl(ld[10]), ntohl(ld[11])); 1351*/ 1352 if(xfer->resp != 0){ 1353 printf("sbp_recv: xfer->resp != 0\n"); 1354 fw_xfer_free( xfer); 1355 return; 1356 } 1357 if(xfer->recv.buf == NULL){ 1358 printf("sbp_recv: xfer->recv.buf == NULL\n"); 1359 fw_xfer_free( xfer); 1360 return; 1361 } 1362 sbp = (struct sbp_softc *)xfer->sc; 1363 rfp = (struct fw_pkt *)xfer->recv.buf; 1364 if(rfp->mode.wreqb.tcode != FWTCODE_WREQB){ 1365 printf("sbp_recv: tcode = %d\n", rfp->mode.wreqb.tcode); 1366 fw_xfer_free( xfer); 1367 return; 1368 } 1369 sbp_status = (struct sbp_status *)rfp->mode.wreqb.payload; 1370 addr = ntohl(rfp->mode.wreqb.dest_lo); 1371SBP_DEBUG(2) 1372 printf("received address 0x%x\n", addr); 1373END_DEBUG 1374 t = SBP_ADDR2TRG(addr); 1375 if (t >= SBP_NUM_TARGETS) { 1376 device_printf(sbp->fd.dev, 1377 "sbp_recv1: invalid target %d\n", t); 1378 fw_xfer_free(xfer); 1379 return; 1380 } 1381 target = &sbp->targets[t]; 1382 l = SBP_ADDR2LUN(addr); 1383 if (l >= target->num_lun) { 1384 device_printf(sbp->fd.dev, 1385 "sbp_recv1: invalid lun %d (target=%d)\n", l, t); 1386 fw_xfer_free(xfer); 1387 return; 1388 } 1389 sdev = &target->luns[l]; 1390 1391 ocb = NULL; 1392 switch (sbp_status->src) { 1393 case 0: 1394 case 1: 1395 ocb = sbp_dequeue_ocb(sdev, ntohl(sbp_status->orb_lo)); 1396 if (ocb == NULL) { 1397 sbp_show_sdev_info(sdev, 2); 1398 printf("No ocb on the queue\n"); 1399 } 1400 break; 1401 case 2: 1402 /* unsolicit */ 1403 sbp_show_sdev_info(sdev, 2); 1404 printf("unsolicit status received\n"); 1405 break; 1406 default: 1407 sbp_show_sdev_info(sdev, 2); 1408 printf("unknown sbp_status->src\n"); 1409 } 1410 1411 status_valid = (sbp_status->src < 2 1412 && sbp_status->resp == ORB_RES_CMPL 1413 && sbp_status->dead == 0 1414 && sbp_status->status == 0); 1415 1416 if (!status_valid || debug > 1){ 1417 int status; 1418SBP_DEBUG(0) 1419 sbp_show_sdev_info(sdev, 2); 1420 printf("ORB status src:%x resp:%x dead:%x" 1421#if __FreeBSD_version >= 500000 1422 " len:%x stat:%x orb:%x%08x\n", 1423#else 1424 " len:%x stat:%x orb:%x%08lx\n", 1425#endif 1426 sbp_status->src, sbp_status->resp, sbp_status->dead, 1427 sbp_status->len, sbp_status->status, 1428 ntohs(sbp_status->orb_hi), ntohl(sbp_status->orb_lo)); 1429END_DEBUG 1430 sbp_show_sdev_info(sdev, 2); 1431 status = sbp_status->status; 1432 switch(sbp_status->resp) { 1433 case 0: 1434 if (status > MAX_ORB_STATUS0) 1435 printf("%s\n", orb_status0[MAX_ORB_STATUS0]); 1436 else 1437 printf("%s\n", orb_status0[status]); 1438 break; 1439 case 1: 1440 printf("Obj: %s, Error: %s\n", 1441 orb_status1_object[(status>>6) & 3], 1442 orb_status1_serial_bus_error[status & 0xf]); 1443 break; 1444 case 2: 1445 printf("Illegal request\n"); 1446 break; 1447 case 3: 1448 printf("Vendor dependent\n"); 1449 break; 1450 default: 1451 printf("unknown respose code %d\n", sbp_status->resp); 1452 } 1453 } 1454 1455 /* we have to reset the fetch agent if it's dead */ 1456 if (sbp_status->dead) { 1457 if (sdev->path) 1458 xpt_freeze_devq(sdev->path, 1); 1459 sbp_agent_reset(sdev); 1460 } 1461 1462 if (ocb == NULL) { 1463 fw_xfer_free(xfer); 1464 return; 1465 } 1466 1467 sdev->flags &= ~SBP_DEV_TIMEOUT; 1468 1469 switch(ntohl(ocb->orb[4]) & ORB_FMT_MSK){ 1470 case ORB_FMT_NOP: 1471 break; 1472 case ORB_FMT_VED: 1473 break; 1474 case ORB_FMT_STD: 1475 switch(ocb->flags & OCB_ACT_MASK){ 1476 case OCB_ACT_MGM: 1477 orb_fun = ntohl(ocb->orb[4]) & ORB_FUN_MSK; 1478 switch(orb_fun) { 1479 case ORB_FUN_LGI: 1480 login_res = &sdev->login; 1481 login_res->len = ntohs(login_res->len); 1482 login_res->id = ntohs(login_res->id); 1483 login_res->cmd_hi = ntohs(login_res->cmd_hi); 1484 login_res->cmd_lo = ntohl(login_res->cmd_lo); 1485 if (status_valid) { 1486SBP_DEBUG(0) 1487sbp_show_sdev_info(sdev, 2); 1488printf("login: len %d, ID %d, cmd %08x%08x, recon_hold %d\n", login_res->len, login_res->id, login_res->cmd_hi, login_res->cmd_lo, ntohs(login_res->recon_hold)); 1489END_DEBUG 1490#if 1 1491 sbp_busy_timeout(sdev); 1492#else 1493 sbp_mgm_orb(sdev, ORB_FUN_ATS, 0, 0); 1494#endif 1495 } else { 1496 /* forgot logout? */ 1497 sbp_show_sdev_info(sdev, 2); 1498 printf("login failed\n"); 1499 sdev->status = SBP_DEV_RESET; 1500 } 1501 break; 1502 case ORB_FUN_RCN: 1503 login_res = &sdev->login; 1504 if (status_valid) { 1505SBP_DEBUG(0) 1506sbp_show_sdev_info(sdev, 2); 1507printf("reconnect: len %d, ID %d, cmd %08x%08x\n", login_res->len, login_res->id, login_res->cmd_hi, login_res->cmd_lo); 1508END_DEBUG 1509#if 1 1510 sbp_ping_unit(sdev); 1511 xpt_release_devq(sdev->path, 1512 MAX_FREEZE, TRUE); 1513#else 1514 sdev->status = SBP_DEV_ATTACHED; 1515 sbp_mgm_orb(sdev, ORB_FUN_ATS, 0, 0); 1516#endif 1517 } else { 1518 /* reconnection hold time exceed? */ 1519SBP_DEBUG(0) 1520 sbp_show_sdev_info(sdev, 2); 1521 printf("reconnect failed\n"); 1522END_DEBUG 1523 sbp_mgm_orb(sdev, ORB_FUN_LGI, 0, 0); 1524 } 1525 break; 1526 case ORB_FUN_LGO: 1527 sdev->status = SBP_DEV_RESET; 1528 break; 1529 case ORB_FUN_RST: 1530 sbp_busy_timeout(sdev); 1531 break; 1532 case ORB_FUN_LUR: 1533 case ORB_FUN_ATA: 1534 case ORB_FUN_ATS: 1535 sbp_agent_reset(sdev); 1536 break; 1537 default: 1538 sbp_show_sdev_info(sdev, 2); 1539 printf("unknown function %d\n", orb_fun); 1540 break; 1541 } 1542 break; 1543 case OCB_ACT_CMD: 1544 if(ocb->ccb != NULL){ 1545 union ccb *ccb; 1546/* 1547 u_int32_t *ld; 1548 ld = ocb->ccb->csio.data_ptr; 1549 if(ld != NULL && ocb->ccb->csio.dxfer_len != 0) 1550 printf("ptr %08x %08x %08x %08x\n", ld[0], ld[1], ld[2], ld[3]); 1551 else 1552 printf("ptr NULL\n"); 1553printf("len %d\n", sbp_status->len); 1554*/ 1555 ccb = ocb->ccb; 1556 if(sbp_status->len > 1){ 1557 sbp_scsi_status(sbp_status, ocb); 1558 }else{ 1559 if(sbp_status->resp != ORB_RES_CMPL){ 1560 ccb->ccb_h.status = CAM_REQ_CMP_ERR; 1561 }else{ 1562 ccb->ccb_h.status = CAM_REQ_CMP; 1563 } 1564 } 1565 /* fix up inq data */ 1566 if (ccb->csio.cdb_io.cdb_bytes[0] == INQUIRY) 1567 sbp_fix_inq_data(ocb); 1568 xpt_done(ccb); 1569 } 1570 break; 1571 default: 1572 break; 1573 } 1574 } 1575 1576 if (!(ocb->flags & OCB_RESERVED)) 1577 sbp_free_ocb(sbp, ocb); 1578 1579/* The received packet is usually small enough to be stored within 1580 * the buffer. In that case, the controller return ack_complete and 1581 * no respose is necessary. 1582 * 1583 * XXX fwohci.c and firewire.c should inform event_code such as 1584 * ack_complete or ack_pending to upper driver. 1585 */ 1586#if NEED_RESPONSE 1587 xfer->send.buf = malloc(12, M_SBP, M_NOWAIT | M_ZERO); 1588 xfer->send.len = 12; 1589 xfer->send.off = 0; 1590 sfp = (struct fw_pkt *)xfer->send.buf; 1591 sfp->mode.wres.dst = rfp->mode.wreqb.src; 1592 xfer->dst = ntohs(sfp->mode.wres.dst); 1593 xfer->spd = min(sdev->target->fwdev->speed, max_speed); 1594 xfer->act.hand = sbp_loginres_callback; 1595 xfer->retry_req = fw_asybusy; 1596 1597 sfp->mode.wres.tlrt = rfp->mode.wreqb.tlrt; 1598 sfp->mode.wres.tcode = FWTCODE_WRES; 1599 sfp->mode.wres.rtcode = 0; 1600 sfp->mode.wres.pri = 0; 1601 1602 fw_asyreq(xfer->fc, -1, xfer); 1603#else 1604 fw_xfer_free(xfer); 1605#endif 1606 1607 return; 1608 1609} 1610 1611static void 1612sbp_recv(struct fw_xfer *xfer) 1613{ 1614 int s; 1615 1616 s = splcam(); 1617 sbp_recv1(xfer); 1618 splx(s); 1619} 1620/* 1621 * sbp_attach() 1622 */ 1623static int 1624sbp_attach(device_t dev) 1625{ 1626 struct sbp_softc *sbp; 1627 struct cam_devq *devq; 1628 struct fw_xfer *xfer; 1629 int i, s, error; 1630 1631SBP_DEBUG(0) 1632 printf("sbp_attach (cold=%d)\n", cold); 1633END_DEBUG 1634 1635 if (cold) 1636 sbp_cold ++; 1637 sbp = ((struct sbp_softc *)device_get_softc(dev)); 1638 bzero(sbp, sizeof(struct sbp_softc)); 1639 sbp->fd.dev = dev; 1640 sbp->fd.fc = device_get_ivars(dev); 1641 error = bus_dma_tag_create(/*parent*/NULL, /*alignment*/1, 1642 /*boundary*/0, 1643 /*lowaddr*/BUS_SPACE_MAXADDR_32BIT, 1644 /*highaddr*/BUS_SPACE_MAXADDR, 1645 /*filter*/NULL, /*filterarg*/NULL, 1646 /*maxsize*/0x100000, /*nsegments*/SBP_IND_MAX, 1647 /*maxsegsz*/0x8000, 1648 /*flags*/BUS_DMA_ALLOCNOW, 1649 &sbp->dmat); 1650 if (error != 0) { 1651 printf("sbp_attach: Could not allocate DMA tag " 1652 "- error %d\n", error); 1653 return (ENOMEM); 1654 } 1655 1656 devq = cam_simq_alloc(/*maxopenings*/SBP_NUM_OCB); 1657 if (devq == NULL) 1658 return (ENXIO); 1659 1660 for( i = 0 ; i < SBP_NUM_TARGETS ; i++){ 1661 sbp->targets[i].fwdev = NULL; 1662 sbp->targets[i].luns = NULL; 1663 } 1664 1665 sbp->sim = cam_sim_alloc(sbp_action, sbp_poll, "sbp", sbp, 1666 device_get_unit(dev), 1667 /*untagged*/ SBP_QUEUE_LEN, 1668 /*tagged*/0, devq); 1669 1670 if (sbp->sim == NULL) { 1671 cam_simq_free(devq); 1672 return (ENXIO); 1673 } 1674 1675 sbp->ocb = (struct sbp_ocb *) contigmalloc( 1676 sizeof (struct sbp_ocb) * SBP_NUM_OCB, 1677 M_SBP, M_NOWAIT, 0x10000, 0xffffffff, PAGE_SIZE, 0ul); 1678 bzero(sbp->ocb, sizeof (struct sbp_ocb) * SBP_NUM_OCB); 1679 1680 if (sbp->ocb == NULL) { 1681 printf("sbp0: ocb alloction failure\n"); 1682 return (ENOMEM); 1683 } 1684 1685 STAILQ_INIT(&sbp->free_ocbs); 1686 for (i = 0; i < SBP_NUM_OCB; i++) { 1687 sbp_free_ocb(sbp, &sbp->ocb[i]); 1688 } 1689 1690 if (xpt_bus_register(sbp->sim, /*bus*/0) != CAM_SUCCESS) { 1691 cam_sim_free(sbp->sim, /*free_devq*/TRUE); 1692 contigfree(sbp->ocb, sizeof (struct sbp_ocb) * SBP_NUM_OCB, 1693 M_SBP); 1694 return (ENXIO); 1695 } 1696 1697 xfer = fw_xfer_alloc(M_SBP); 1698 xfer->act.hand = sbp_recv; 1699 xfer->act_type = FWACT_XFER; 1700#if NEED_RESPONSE 1701 xfer->fc = sbp->fd.fc; 1702#endif 1703 xfer->sc = (caddr_t)sbp; 1704 1705 sbp->fwb.start_hi = SBP_BIND_HI; 1706 sbp->fwb.start_lo = SBP_DEV2ADDR(device_get_unit(sbp->fd.dev), 0, 0); 1707 /* We reserve 16 bit space (4 bytes X 64 targets X 256 luns) */ 1708 sbp->fwb.addrlen = 0xffff; 1709 sbp->fwb.xfer = xfer; 1710 fw_bindadd(sbp->fd.fc, &sbp->fwb); 1711 1712 sbp->fd.post_explore = sbp_post_explore; 1713 1714 if (sbp->fd.fc->status != -1) { 1715 s = splfw(); 1716 sbp_post_explore((void *)sbp); 1717 splx(s); 1718 } 1719 1720 return (0); 1721} 1722 1723static int 1724sbp_logout_all(struct sbp_softc *sbp) 1725{ 1726 struct sbp_target *target; 1727 struct sbp_dev *sdev; 1728 int i, j; 1729 1730SBP_DEBUG(0) 1731 printf("sbp_logout_all\n"); 1732END_DEBUG 1733 for (i = 0 ; i < SBP_NUM_TARGETS ; i ++) { 1734 target = &sbp->targets[i]; 1735 if (target->luns == NULL) 1736 continue; 1737 for (j = 0; j < target->num_lun; j++) { 1738 sdev = &target->luns[j]; 1739 if (sdev->status >= SBP_DEV_TOATTACH && 1740 sdev->status <= SBP_DEV_ATTACHED) 1741 sbp_mgm_orb(sdev, ORB_FUN_LGO, 0, 0); 1742 } 1743 } 1744 return 0; 1745} 1746 1747static int 1748sbp_shutdown(device_t dev) 1749{ 1750 struct sbp_softc *sbp = ((struct sbp_softc *)device_get_softc(dev)); 1751 1752 sbp_logout_all(sbp); 1753 return (0); 1754} 1755 1756static int 1757sbp_detach(device_t dev) 1758{ 1759 struct sbp_softc *sbp = ((struct sbp_softc *)device_get_softc(dev)); 1760 struct firewire_comm *fc = sbp->fd.fc; 1761 int i; 1762 1763SBP_DEBUG(0) 1764 printf("sbp_detach\n"); 1765END_DEBUG 1766#if 0 1767 /* bus reset for logout */ 1768 sbp->fd.post_explore = NULL; 1769 fc->ibr(fc); 1770#endif 1771 1772 for (i = 0; i < SBP_NUM_TARGETS; i ++) 1773 sbp_cam_detach_target(&sbp->targets[i]); 1774 xpt_bus_deregister(cam_sim_path(sbp->sim)); 1775 1776 sbp_logout_all(sbp); 1777 /* XXX wait for logout completion */ 1778 tsleep(&i, FWPRI, "sbpdtc", hz/2); 1779 1780 fw_bindremove(fc, &sbp->fwb); 1781 contigfree(sbp->ocb, sizeof (struct sbp_ocb) * SBP_NUM_OCB, M_SBP); 1782 bus_dma_tag_destroy(sbp->dmat); 1783 1784 for (i = 0; i < SBP_NUM_TARGETS; i ++) 1785 if (sbp->targets[i].luns != NULL) 1786 free(sbp->targets[i].luns, M_SBP); 1787 1788 return (0); 1789} 1790 1791static void 1792sbp_cam_detach_target(struct sbp_target *target) 1793{ 1794 int i; 1795 struct sbp_dev *sdev; 1796 1797 if (target->luns != NULL) { 1798SBP_DEBUG(0) 1799 printf("sbp_detach_target %d\n", target->target_id); 1800END_DEBUG 1801 for (i = 0; i < target->num_lun; i++) { 1802 sdev = &target->luns[i]; 1803 if (sdev->status == SBP_DEV_RESET || 1804 sdev->status == SBP_DEV_DEAD) 1805 continue; 1806 if (sdev->path) { 1807 xpt_async(AC_LOST_DEVICE, sdev->path, NULL); 1808 xpt_free_path(sdev->path); 1809 sdev->path = NULL; 1810 } 1811 sbp_abort_all_ocbs(sdev, CAM_DEV_NOT_THERE); 1812 } 1813 } 1814} 1815 1816static void 1817sbp_timeout(void *arg) 1818{ 1819 struct sbp_ocb *ocb = (struct sbp_ocb *)arg; 1820 struct sbp_dev *sdev = ocb->sdev; 1821 1822 sbp_show_sdev_info(sdev, 2); 1823 printf("request timeout ... "); 1824 1825 xpt_freeze_devq(sdev->path, 1); 1826 sbp_abort_all_ocbs(sdev, CAM_CMD_TIMEOUT); 1827 if (sdev->flags & SBP_DEV_TIMEOUT) { 1828#if 0 1829 struct firewire_comm *fc; 1830 1831 printf("bus reset\n"); 1832 fc = sdev->target->sbp->fd.fc; 1833 fc->ibr(fc); 1834 sdev->status == SBP_DEV_RETRY; 1835#else 1836 printf("target reset\n"); 1837 sbp_mgm_orb(sdev, ORB_FUN_RST, 0, 0); 1838#endif 1839 sdev->flags &= ~SBP_DEV_TIMEOUT; 1840 } else { 1841 printf("agent reset\n"); 1842 sdev->flags |= SBP_DEV_TIMEOUT; 1843 sbp_agent_reset(sdev); 1844 } 1845 return; 1846} 1847 1848static void 1849sbp_action1(struct cam_sim *sim, union ccb *ccb) 1850{ 1851 1852 struct sbp_softc *sbp = (struct sbp_softc *)sim->softc; 1853 struct sbp_target *target = NULL; 1854 struct sbp_dev *sdev = NULL; 1855 1856 /* target:lun -> sdev mapping */ 1857 if (sbp != NULL 1858 && ccb->ccb_h.target_id != CAM_TARGET_WILDCARD 1859 && ccb->ccb_h.target_id < SBP_NUM_TARGETS) { 1860 target = &sbp->targets[ccb->ccb_h.target_id]; 1861 if (target->fwdev != NULL 1862 && ccb->ccb_h.target_lun != CAM_LUN_WILDCARD 1863 && ccb->ccb_h.target_lun < target->num_lun) { 1864 sdev = &target->luns[ccb->ccb_h.target_lun]; 1865 if (sdev->status != SBP_DEV_ATTACHED && 1866 sdev->status != SBP_DEV_PROBE) 1867 sdev = NULL; 1868 } 1869 } 1870 1871SBP_DEBUG(1) 1872 if (sdev == NULL) 1873 printf("invalid target %d lun %d\n", 1874 ccb->ccb_h.target_id, ccb->ccb_h.target_lun); 1875END_DEBUG 1876 1877 switch (ccb->ccb_h.func_code) { 1878 case XPT_SCSI_IO: 1879 case XPT_RESET_DEV: 1880 case XPT_GET_TRAN_SETTINGS: 1881 case XPT_SET_TRAN_SETTINGS: 1882 case XPT_CALC_GEOMETRY: 1883 if (sdev == NULL) { 1884SBP_DEBUG(1) 1885 printf("%s:%d:%d:func_code 0x%04x: " 1886 "Invalid target (target needed)\n", 1887 device_get_nameunit(sbp->fd.dev), 1888 ccb->ccb_h.target_id, ccb->ccb_h.target_lun, 1889 ccb->ccb_h.func_code); 1890END_DEBUG 1891 1892 ccb->ccb_h.status = CAM_DEV_NOT_THERE; 1893 xpt_done(ccb); 1894 return; 1895 } 1896 break; 1897 case XPT_PATH_INQ: 1898 case XPT_NOOP: 1899 /* The opcodes sometimes aimed at a target (sc is valid), 1900 * sometimes aimed at the SIM (sc is invalid and target is 1901 * CAM_TARGET_WILDCARD) 1902 */ 1903 if (sbp == NULL && 1904 ccb->ccb_h.target_id != CAM_TARGET_WILDCARD) { 1905SBP_DEBUG(0) 1906 printf("%s:%d:%d func_code 0x%04x: " 1907 "Invalid target (no wildcard)\n", 1908 device_get_nameunit(sbp->fd.dev), 1909 ccb->ccb_h.target_id, ccb->ccb_h.target_lun, 1910 ccb->ccb_h.func_code); 1911END_DEBUG 1912 ccb->ccb_h.status = CAM_DEV_NOT_THERE; 1913 xpt_done(ccb); 1914 return; 1915 } 1916 break; 1917 default: 1918 /* XXX Hm, we should check the input parameters */ 1919 break; 1920 } 1921 1922 switch (ccb->ccb_h.func_code) { 1923 case XPT_SCSI_IO: 1924 { 1925 struct ccb_scsiio *csio; 1926 struct sbp_ocb *ocb; 1927 int s, speed; 1928 void *cdb; 1929 1930 csio = &ccb->csio; 1931 1932SBP_DEBUG(1) 1933 printf("%s:%d:%d XPT_SCSI_IO: " 1934 "cmd: %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x" 1935 ", flags: 0x%02x, " 1936 "%db cmd/%db data/%db sense\n", 1937 device_get_nameunit(sbp->fd.dev), 1938 ccb->ccb_h.target_id, ccb->ccb_h.target_lun, 1939 csio->cdb_io.cdb_bytes[0], 1940 csio->cdb_io.cdb_bytes[1], 1941 csio->cdb_io.cdb_bytes[2], 1942 csio->cdb_io.cdb_bytes[3], 1943 csio->cdb_io.cdb_bytes[4], 1944 csio->cdb_io.cdb_bytes[5], 1945 csio->cdb_io.cdb_bytes[6], 1946 csio->cdb_io.cdb_bytes[7], 1947 csio->cdb_io.cdb_bytes[8], 1948 csio->cdb_io.cdb_bytes[9], 1949 ccb->ccb_h.flags & CAM_DIR_MASK, 1950 csio->cdb_len, csio->dxfer_len, 1951 csio->sense_len); 1952END_DEBUG 1953 if(sdev == NULL){ 1954 ccb->ccb_h.status = CAM_DEV_NOT_THERE; 1955 xpt_done(ccb); 1956 return; 1957 } 1958#if 0 1959 /* if we are in probe stage, pass only probe commands */ 1960 if (sdev->status == SBP_DEV_PROBE) { 1961 char *name; 1962 name = xpt_path_periph(ccb->ccb_h.path)->periph_name; 1963 printf("probe stage, periph name: %s\n", name); 1964 if (strcmp(name, "probe") != 0) { 1965 ccb->ccb_h.status = CAM_REQUEUE_REQ; 1966 xpt_done(ccb); 1967 return; 1968 } 1969 } 1970#endif 1971 if ((ocb = sbp_get_ocb(sbp)) == NULL) { 1972 s = splfw(); 1973 sbp->flags |= SBP_RESOURCE_SHORTAGE; 1974 splx(s); 1975 return; 1976 } 1977 ocb->flags = OCB_ACT_CMD; 1978 ocb->sdev = sdev; 1979 ocb->ccb = ccb; 1980 ccb->ccb_h.ccb_sdev_ptr = sdev; 1981 ocb->orb[0] = htonl(1 << 31); 1982 ocb->orb[1] = 0; 1983 ocb->orb[2] = htonl(((sbp->fd.fc->nodeid | FWLOCALBUS )<< 16) ); 1984 ocb->orb[3] = htonl(vtophys(ocb->ind_ptr)); 1985 speed = min(target->fwdev->speed, max_speed); 1986 ocb->orb[4] = htonl(ORB_NOTIFY | ORB_CMD_SPD(speed) 1987 | ORB_CMD_MAXP(speed + 7)); 1988 if((ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_IN){ 1989 ocb->orb[4] |= htonl(ORB_CMD_IN); 1990 } 1991 1992 if (csio->ccb_h.flags & CAM_SCATTER_VALID) 1993 printf("sbp: CAM_SCATTER_VALID\n"); 1994 if (csio->ccb_h.flags & CAM_DATA_PHYS) 1995 printf("sbp: CAM_DATA_PHYS\n"); 1996 1997 if (csio->ccb_h.flags & CAM_CDB_POINTER) 1998 cdb = (void *)csio->cdb_io.cdb_ptr; 1999 else 2000 cdb = (void *)&csio->cdb_io.cdb_bytes; 2001 bcopy(cdb, 2002 (void *)(uintptr_t)(volatile void *)&ocb->orb[5], 2003 csio->cdb_len); 2004/* 2005printf("ORB %08x %08x %08x %08x\n", ntohl(ocb->orb[0]), ntohl(ocb->orb[1]), ntohl(ocb->orb[2]), ntohl(ocb->orb[3])); 2006printf("ORB %08x %08x %08x %08x\n", ntohl(ocb->orb[4]), ntohl(ocb->orb[5]), ntohl(ocb->orb[6]), ntohl(ocb->orb[7])); 2007*/ 2008 if (ccb->csio.dxfer_len > 0) { 2009 int s; 2010 2011 if (bus_dmamap_create(sbp->dmat, 0, &ocb->dmamap)) { 2012 printf("sbp_action1: cannot create dmamap\n"); 2013 break; 2014 } 2015 2016 s = splsoftvm(); 2017 bus_dmamap_load(/*dma tag*/sbp->dmat, 2018 /*dma map*/ocb->dmamap, 2019 ccb->csio.data_ptr, 2020 ccb->csio.dxfer_len, 2021 sbp_execute_ocb, 2022 ocb, 2023 /*flags*/0); 2024 splx(s); 2025 } else 2026 sbp_execute_ocb(ocb, NULL, 0, 0); 2027 break; 2028 } 2029 case XPT_CALC_GEOMETRY: 2030 { 2031 struct ccb_calc_geometry *ccg; 2032 u_int32_t size_mb; 2033 u_int32_t secs_per_cylinder; 2034 int extended = 1; 2035 ccg = &ccb->ccg; 2036 2037 if (ccg->block_size == 0) { 2038 printf("sbp_action1: block_size is 0.\n"); 2039 ccb->ccb_h.status = CAM_REQ_INVALID; 2040 xpt_done(ccb); 2041 break; 2042 } 2043SBP_DEBUG(1) 2044 printf("%s:%d:%d:%d:XPT_CALC_GEOMETRY: " 2045 "Volume size = %d\n", 2046 device_get_nameunit(sbp->fd.dev), cam_sim_path(sbp->sim), 2047 ccb->ccb_h.target_id, ccb->ccb_h.target_lun, 2048 ccg->volume_size); 2049END_DEBUG 2050 2051 size_mb = ccg->volume_size 2052 / ((1024L * 1024L) / ccg->block_size); 2053 2054 if (size_mb >= 1024 && extended) { 2055 ccg->heads = 255; 2056 ccg->secs_per_track = 63; 2057 } else { 2058 ccg->heads = 64; 2059 ccg->secs_per_track = 32; 2060 } 2061 secs_per_cylinder = ccg->heads * ccg->secs_per_track; 2062 ccg->cylinders = ccg->volume_size / secs_per_cylinder; 2063 ccb->ccb_h.status = CAM_REQ_CMP; 2064 xpt_done(ccb); 2065 break; 2066 } 2067 case XPT_RESET_BUS: /* Reset the specified SCSI bus */ 2068 { 2069 2070SBP_DEBUG(1) 2071 printf("%s:%d:XPT_RESET_BUS: \n", 2072 device_get_nameunit(sbp->fd.dev), cam_sim_path(sbp->sim)); 2073END_DEBUG 2074 2075 ccb->ccb_h.status = CAM_REQ_INVALID; 2076 xpt_done(ccb); 2077 break; 2078 } 2079 case XPT_PATH_INQ: /* Path routing inquiry */ 2080 { 2081 struct ccb_pathinq *cpi = &ccb->cpi; 2082 2083SBP_DEBUG(1) 2084 printf("%s:%d:%d XPT_PATH_INQ:.\n", 2085 device_get_nameunit(sbp->fd.dev), 2086 ccb->ccb_h.target_id, ccb->ccb_h.target_lun); 2087END_DEBUG 2088 cpi->version_num = 1; /* XXX??? */ 2089 cpi->hba_inquiry = 0; 2090 cpi->target_sprt = 0; 2091 cpi->hba_misc = PIM_NOBUSRESET; 2092 cpi->hba_eng_cnt = 0; 2093 cpi->max_target = SBP_NUM_TARGETS - 1; 2094 cpi->max_lun = SBP_NUM_LUNS - 1; 2095 cpi->initiator_id = SBP_INITIATOR; 2096 cpi->bus_id = sim->bus_id; 2097 cpi->base_transfer_speed = 400 * 1000 / 8; 2098 strncpy(cpi->sim_vid, "FreeBSD", SIM_IDLEN); 2099 strncpy(cpi->hba_vid, "SBP", HBA_IDLEN); 2100 strncpy(cpi->dev_name, sim->sim_name, DEV_IDLEN); 2101 cpi->unit_number = sim->unit_number; 2102 2103 cpi->ccb_h.status = CAM_REQ_CMP; 2104 xpt_done(ccb); 2105 break; 2106 } 2107 case XPT_GET_TRAN_SETTINGS: 2108 { 2109 struct ccb_trans_settings *cts = &ccb->cts; 2110SBP_DEBUG(1) 2111 printf("%s:%d:%d XPT_GET_TRAN_SETTINGS:.\n", 2112 device_get_nameunit(sbp->fd.dev), 2113 ccb->ccb_h.target_id, ccb->ccb_h.target_lun); 2114END_DEBUG 2115 /* Disable disconnect and tagged queuing */ 2116 cts->valid = CCB_TRANS_DISC_VALID | CCB_TRANS_TQ_VALID; 2117 cts->flags = 0; 2118 2119 cts->ccb_h.status = CAM_REQ_CMP; 2120 xpt_done(ccb); 2121 break; 2122 } 2123 case XPT_ABORT: 2124 ccb->ccb_h.status = CAM_UA_ABORT; 2125 xpt_done(ccb); 2126 break; 2127 default: 2128 ccb->ccb_h.status = CAM_REQ_INVALID; 2129 xpt_done(ccb); 2130 break; 2131 } 2132 return; 2133} 2134 2135static void 2136sbp_action(struct cam_sim *sim, union ccb *ccb) 2137{ 2138 int s; 2139 2140 s = splfw(); 2141 sbp_action1(sim, ccb); 2142 splx(s); 2143} 2144 2145static void 2146sbp_execute_ocb(void *arg, bus_dma_segment_t *segments, int seg, int error) 2147{ 2148 int i; 2149 struct sbp_ocb *ocb; 2150 struct sbp_ocb *prev; 2151 union ccb *ccb; 2152 bus_dma_segment_t *s; 2153 2154 if (error) 2155 printf("sbp_execute_ocb: error=%d\n", error); 2156 2157 ocb = (struct sbp_ocb *)arg; 2158 if (seg == 1) { 2159 /* direct pointer */ 2160 ocb->orb[3] = htonl(segments[0].ds_addr); 2161 ocb->orb[4] |= htonl(segments[0].ds_len); 2162 } else if(seg > 1) { 2163 /* page table */ 2164SBP_DEBUG(1) 2165 printf("sbp_execute_ocb: seg %d", seg); 2166 for (i = 0; i < seg; i++) 2167#if __FreeBSD_version >= 500000 2168 printf(", %tx:%zd", segments[i].ds_addr, 2169#else 2170 printf(", %x:%d", segments[i].ds_addr, 2171#endif 2172 segments[i].ds_len); 2173 printf("\n"); 2174END_DEBUG 2175 for (i = 0; i < seg; i++) { 2176 s = &segments[i]; 2177SBP_DEBUG(0) 2178 /* XXX LSI Logic "< 16 byte" bug might be hit */ 2179 if (s->ds_len < 16) 2180 printf("sbp_execute_ocb: warning, " 2181#if __FreeBSD_version >= 500000 2182 "segment length(%zd) is less than 16." 2183#else 2184 "segment length(%d) is less than 16." 2185#endif 2186 "(seg=%d/%d)\n", s->ds_len, i+1, seg); 2187END_DEBUG 2188 ocb->ind_ptr[i].hi = htonl(s->ds_len << 16); 2189 ocb->ind_ptr[i].lo = htonl(s->ds_addr); 2190 } 2191 ocb->orb[4] |= htonl(ORB_CMD_PTBL | seg); 2192 } 2193 2194 ccb = ocb->ccb; 2195 prev = sbp_enqueue_ocb(ocb->sdev, ocb); 2196 if (prev) 2197 sbp_doorbell(ocb->sdev); 2198 else 2199 sbp_orb_pointer(ocb->sdev, ocb); 2200} 2201 2202static void 2203sbp_poll(struct cam_sim *sim) 2204{ 2205 /* should call fwohci_intr? */ 2206 return; 2207} 2208static struct sbp_ocb * 2209sbp_dequeue_ocb(struct sbp_dev *sdev, u_int32_t orb_lo) 2210{ 2211 struct sbp_ocb *ocb; 2212 struct sbp_ocb *next; 2213 int s = splfw(), order = 0; 2214 int flags; 2215 2216 for (ocb = STAILQ_FIRST(&sdev->ocbs); ocb != NULL; ocb = next) { 2217 next = STAILQ_NEXT(ocb, ocb); 2218 flags = ocb->flags; 2219SBP_DEBUG(1) 2220 sbp_show_sdev_info(sdev, 2); 2221#if __FreeBSD_version >= 500000 2222 printf("orb: 0x%tx next: 0x%x, flags %x\n", 2223#else 2224 printf("orb: 0x%x next: 0x%lx, flags %x\n", 2225#endif 2226 vtophys(&ocb->orb[0]), ntohl(ocb->orb[1]), flags); 2227END_DEBUG 2228 if (vtophys(&ocb->orb[0]) == orb_lo) { 2229 /* found */ 2230 if (ocb->flags & OCB_RESERVED) 2231 ocb->flags |= OCB_DONE; 2232 else 2233 STAILQ_REMOVE(&sdev->ocbs, ocb, sbp_ocb, ocb); 2234 if (ocb->ccb != NULL) 2235 untimeout(sbp_timeout, (caddr_t)ocb, 2236 ocb->ccb->ccb_h.timeout_ch); 2237 if (ocb->dmamap != NULL) { 2238 bus_dmamap_destroy(sdev->target->sbp->dmat, 2239 ocb->dmamap); 2240 ocb->dmamap = NULL; 2241 } 2242 break; 2243 } else { 2244 if ((ocb->flags & OCB_RESERVED) && 2245 (ocb->flags & OCB_DONE)) { 2246 /* next orb must be fetched already */ 2247 STAILQ_REMOVE(&sdev->ocbs, ocb, sbp_ocb, ocb); 2248 sbp_free_ocb(sdev->target->sbp, ocb); 2249 } else 2250 order ++; 2251 } 2252 } 2253 splx(s); 2254SBP_DEBUG(0) 2255 if (ocb && order > 0) { 2256 sbp_show_sdev_info(sdev, 2); 2257 printf("unordered execution order:%d\n", order); 2258 } 2259END_DEBUG 2260 return (ocb); 2261} 2262 2263static struct sbp_ocb * 2264sbp_enqueue_ocb(struct sbp_dev *sdev, struct sbp_ocb *ocb) 2265{ 2266 int s = splfw(); 2267 struct sbp_ocb *prev; 2268 2269SBP_DEBUG(2) 2270 sbp_show_sdev_info(sdev, 2); 2271#if __FreeBSD_version >= 500000 2272 printf("sbp_enqueue_ocb orb=0x%tx in physical memory\n", vtophys(&ocb->orb[0])); 2273#else 2274 printf("sbp_enqueue_ocb orb=0x%x in physical memory\n", vtophys(&ocb->orb[0])); 2275#endif 2276END_DEBUG 2277 prev = STAILQ_LAST(&sdev->ocbs, sbp_ocb, ocb); 2278 STAILQ_INSERT_TAIL(&sdev->ocbs, ocb, ocb); 2279 2280 if (ocb->ccb != NULL) 2281 ocb->ccb->ccb_h.timeout_ch = timeout(sbp_timeout, (caddr_t)ocb, 2282 (ocb->ccb->ccb_h.timeout * hz) / 1000); 2283 2284 if (prev != NULL ) { 2285SBP_DEBUG(1) 2286#if __FreeBSD_version >= 500000 2287 printf("linking chain 0x%tx -> 0x%tx\n", vtophys(&prev->orb[0]), 2288#else 2289 printf("linking chain 0x%x -> 0x%x\n", vtophys(&prev->orb[0]), 2290#endif 2291 vtophys(&ocb->orb[0])); 2292END_DEBUG 2293 prev->flags |= OCB_RESERVED; 2294 prev->orb[1] = htonl(vtophys(&ocb->orb[0])); 2295 prev->orb[0] = 0; 2296 } 2297 splx(s); 2298 2299 return prev; 2300} 2301 2302static struct sbp_ocb * 2303sbp_get_ocb(struct sbp_softc *sbp) 2304{ 2305 struct sbp_ocb *ocb; 2306 int s = splfw(); 2307 ocb = STAILQ_FIRST(&sbp->free_ocbs); 2308 if (ocb == NULL) { 2309 printf("ocb shortage!!!\n"); 2310 return NULL; 2311 } 2312 STAILQ_REMOVE(&sbp->free_ocbs, ocb, sbp_ocb, ocb); 2313 splx(s); 2314 ocb->ccb = NULL; 2315 return (ocb); 2316} 2317 2318static void 2319sbp_free_ocb(struct sbp_softc *sbp, struct sbp_ocb *ocb) 2320{ 2321#if 0 /* XXX make sure that ocb has ccb */ 2322 if ((sbp->flags & SBP_RESOURCE_SHORTAGE) != 0 && 2323 (ocb->ccb->ccb_h.status & CAM_RELEASE_SIMQ) == 0) { 2324 ocb->ccb->ccb_h.status |= CAM_RELEASE_SIMQ; 2325 sbp->flags &= ~SBP_RESOURCE_SHORTAGE; 2326 } 2327#else 2328 if ((sbp->flags & SBP_RESOURCE_SHORTAGE) != 0) 2329 sbp->flags &= ~SBP_RESOURCE_SHORTAGE; 2330#endif 2331 ocb->flags = 0; 2332 ocb->ccb = NULL; 2333 STAILQ_INSERT_TAIL(&sbp->free_ocbs, ocb, ocb); 2334} 2335 2336static void 2337sbp_abort_ocb(struct sbp_ocb *ocb, int status) 2338{ 2339 struct sbp_dev *sdev; 2340 2341 sdev = ocb->sdev; 2342SBP_DEBUG(1) 2343 sbp_show_sdev_info(sdev, 2); 2344 printf("sbp_abort_ocb 0x%x\n", status); 2345 if (ocb->ccb != NULL) 2346 sbp_print_scsi_cmd(ocb); 2347END_DEBUG 2348 if (ocb->ccb != NULL && !(ocb->flags & OCB_DONE)) { 2349 untimeout(sbp_timeout, (caddr_t)ocb, 2350 ocb->ccb->ccb_h.timeout_ch); 2351 ocb->ccb->ccb_h.status = status; 2352 xpt_done(ocb->ccb); 2353 } 2354 if (ocb->dmamap != NULL) { 2355 bus_dmamap_destroy(sdev->target->sbp->dmat, ocb->dmamap); 2356 ocb->dmamap = NULL; 2357 } 2358 sbp_free_ocb(sdev->target->sbp, ocb); 2359} 2360 2361static void 2362sbp_abort_all_ocbs(struct sbp_dev *sdev, int status) 2363{ 2364 int s; 2365 struct sbp_ocb *ocb, *next; 2366 STAILQ_HEAD(, sbp_ocb) temp; 2367 2368 s = splfw(); 2369 2370 bcopy(&sdev->ocbs, &temp, sizeof(temp)); 2371 STAILQ_INIT(&sdev->ocbs); 2372 for (ocb = STAILQ_FIRST(&temp); ocb != NULL; ocb = next) { 2373 next = STAILQ_NEXT(ocb, ocb); 2374 sbp_abort_ocb(ocb, status); 2375 } 2376 2377 splx(s); 2378} 2379 2380static devclass_t sbp_devclass; 2381 2382static device_method_t sbp_methods[] = { 2383 /* device interface */ 2384 DEVMETHOD(device_identify, sbp_identify), 2385 DEVMETHOD(device_probe, sbp_probe), 2386 DEVMETHOD(device_attach, sbp_attach), 2387 DEVMETHOD(device_detach, sbp_detach), 2388 DEVMETHOD(device_shutdown, sbp_shutdown), 2389 2390 { 0, 0 } 2391}; 2392 2393static driver_t sbp_driver = { 2394 "sbp", 2395 sbp_methods, 2396 sizeof(struct sbp_softc), 2397}; 2398DRIVER_MODULE(sbp, firewire, sbp_driver, sbp_devclass, 0, 0); 2399MODULE_VERSION(sbp, 1); 2400MODULE_DEPEND(sbp, firewire, 1, 1, 1); 2401MODULE_DEPEND(sbp, cam, 1, 1, 1); 2402