1 /*- 2 * SPDX-License-Identifier: BSD-2-Clause-FreeBSD 3 * 4 * Copyright (c) 2002-2010 Adaptec, Inc. 5 * Copyright (c) 2010-2012 PMC-Sierra, Inc. 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27 * SUCH DAMAGE. 28 */ 29 30 #include <sys/cdefs.h> 31 __FBSDID("$FreeBSD$"); 32 33 /* 34 * CAM front-end for communicating with non-DASD devices 35 */ 36 37 #include "opt_aacraid.h" 38 39 #include <sys/param.h> 40 #include <sys/systm.h> 41 #include <sys/kernel.h> 42 #include <sys/sysctl.h> 43 #include <sys/lock.h> 44 #include <sys/malloc.h> 45 #include <sys/module.h> 46 #include <sys/mutex.h> 47 48 #include <cam/cam.h> 49 #include <cam/cam_ccb.h> 50 #include <cam/cam_debug.h> 51 #include <cam/cam_periph.h> 52 #if __FreeBSD_version < 801000 53 #include <cam/cam_xpt_periph.h> 54 #endif 55 #include <cam/cam_sim.h> 56 #include <cam/cam_xpt_sim.h> 57 #include <cam/scsi/scsi_all.h> 58 #include <cam/scsi/scsi_message.h> 59 60 #include <sys/bus.h> 61 #include <sys/conf.h> 62 #include <sys/disk.h> 63 64 #include <machine/md_var.h> 65 #include <machine/bus.h> 66 #include <sys/rman.h> 67 68 #include <vm/vm.h> 69 #include <vm/pmap.h> 70 71 #include <dev/aacraid/aacraid_reg.h> 72 #include <sys/aac_ioctl.h> 73 #include <dev/aacraid/aacraid_debug.h> 74 #include <dev/aacraid/aacraid_var.h> 75 76 #if __FreeBSD_version >= 700025 77 #ifndef CAM_NEW_TRAN_CODE 78 #define CAM_NEW_TRAN_CODE 1 79 #endif 80 #endif 81 82 #ifndef SVPD_SUPPORTED_PAGE_LIST 83 struct scsi_vpd_supported_page_list 84 { 85 u_int8_t device; 86 u_int8_t page_code; 87 #define SVPD_SUPPORTED_PAGE_LIST 0x00 88 u_int8_t reserved; 89 u_int8_t length; /* number of VPD entries */ 90 #define SVPD_SUPPORTED_PAGES_SIZE 251 91 u_int8_t list[SVPD_SUPPORTED_PAGES_SIZE]; 92 }; 93 #endif 94 95 /************************** Version Compatibility *************************/ 96 #if __FreeBSD_version < 700031 97 #define aac_sim_alloc(a,b,c,d,e,f,g,h,i) cam_sim_alloc(a,b,c,d,e,g,h,i) 98 #else 99 #define aac_sim_alloc cam_sim_alloc 100 #endif 101 102 struct aac_cam { 103 device_t dev; 104 struct aac_sim *inf; 105 struct cam_sim *sim; 106 struct cam_path *path; 107 }; 108 109 static int aac_cam_probe(device_t dev); 110 static int aac_cam_attach(device_t dev); 111 static int aac_cam_detach(device_t dev); 112 static void aac_cam_action(struct cam_sim *, union ccb *); 113 static void aac_cam_poll(struct cam_sim *); 114 static void aac_cam_complete(struct aac_command *); 115 static void aac_container_complete(struct aac_command *); 116 #if __FreeBSD_version >= 700000 117 static void aac_cam_rescan(struct aac_softc *sc, uint32_t channel, 118 uint32_t target_id); 119 #endif 120 static void aac_set_scsi_error(struct aac_softc *sc, union ccb *ccb, 121 u_int8_t status, u_int8_t key, u_int8_t asc, u_int8_t ascq); 122 static int aac_load_map_command_sg(struct aac_softc *, struct aac_command *); 123 static u_int64_t aac_eval_blockno(u_int8_t *); 124 static void aac_container_rw_command(struct cam_sim *, union ccb *, u_int8_t *); 125 static void aac_container_special_command(struct cam_sim *, union ccb *, 126 u_int8_t *); 127 static void aac_passthrough_command(struct cam_sim *, union ccb *); 128 129 static u_int32_t aac_cam_reset_bus(struct cam_sim *, union ccb *); 130 static u_int32_t aac_cam_abort_ccb(struct cam_sim *, union ccb *); 131 static u_int32_t aac_cam_term_io(struct cam_sim *, union ccb *); 132 133 static devclass_t aacraid_pass_devclass; 134 135 static device_method_t aacraid_pass_methods[] = { 136 DEVMETHOD(device_probe, aac_cam_probe), 137 DEVMETHOD(device_attach, aac_cam_attach), 138 DEVMETHOD(device_detach, aac_cam_detach), 139 { 0, 0 } 140 }; 141 142 static driver_t aacraid_pass_driver = { 143 "aacraidp", 144 aacraid_pass_methods, 145 sizeof(struct aac_cam) 146 }; 147 148 DRIVER_MODULE(aacraidp, aacraid, aacraid_pass_driver, aacraid_pass_devclass, 0, 0); 149 MODULE_DEPEND(aacraidp, cam, 1, 1, 1); 150 151 MALLOC_DEFINE(M_AACRAIDCAM, "aacraidcam", "AACRAID CAM info"); 152 153 static void 154 aac_set_scsi_error(struct aac_softc *sc, union ccb *ccb, u_int8_t status, 155 u_int8_t key, u_int8_t asc, u_int8_t ascq) 156 { 157 #if __FreeBSD_version >= 900000 158 struct scsi_sense_data_fixed *sense = 159 (struct scsi_sense_data_fixed *)&ccb->csio.sense_data; 160 #else 161 struct scsi_sense_data *sense = &ccb->csio.sense_data; 162 #endif 163 164 fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "Error %d!", status); 165 166 ccb->ccb_h.status = CAM_SCSI_STATUS_ERROR; 167 ccb->csio.scsi_status = status; 168 if (status == SCSI_STATUS_CHECK_COND) { 169 ccb->ccb_h.status |= CAM_AUTOSNS_VALID; 170 bzero(&ccb->csio.sense_data, ccb->csio.sense_len); 171 ccb->csio.sense_data.error_code = 172 SSD_CURRENT_ERROR | SSD_ERRCODE_VALID; 173 sense->flags = key; 174 if (ccb->csio.sense_len >= 14) { 175 sense->extra_len = 6; 176 sense->add_sense_code = asc; 177 sense->add_sense_code_qual = ascq; 178 } 179 } 180 } 181 182 #if __FreeBSD_version >= 700000 183 static void 184 aac_cam_rescan(struct aac_softc *sc, uint32_t channel, uint32_t target_id) 185 { 186 union ccb *ccb; 187 struct aac_sim *sim; 188 struct aac_cam *camsc; 189 190 if (target_id == AAC_CAM_TARGET_WILDCARD) 191 target_id = CAM_TARGET_WILDCARD; 192 193 TAILQ_FOREACH(sim, &sc->aac_sim_tqh, sim_link) { 194 camsc = sim->aac_cam; 195 if (camsc == NULL || camsc->inf == NULL || 196 camsc->inf->BusNumber != channel) 197 continue; 198 199 ccb = xpt_alloc_ccb_nowait(); 200 if (ccb == NULL) { 201 device_printf(sc->aac_dev, 202 "Cannot allocate ccb for bus rescan.\n"); 203 return; 204 } 205 206 if (xpt_create_path(&ccb->ccb_h.path, xpt_periph, 207 cam_sim_path(camsc->sim), 208 target_id, CAM_LUN_WILDCARD) != CAM_REQ_CMP) { 209 xpt_free_ccb(ccb); 210 device_printf(sc->aac_dev, 211 "Cannot create path for bus rescan.\n"); 212 return; 213 } 214 xpt_rescan(ccb); 215 break; 216 } 217 } 218 #endif 219 220 static void 221 aac_cam_event(struct aac_softc *sc, struct aac_event *event, void *arg) 222 { 223 union ccb *ccb; 224 struct aac_cam *camsc; 225 226 switch (event->ev_type) { 227 case AAC_EVENT_CMFREE: 228 ccb = arg; 229 camsc = ccb->ccb_h.sim_priv.entries[0].ptr; 230 free(event, M_AACRAIDCAM); 231 xpt_release_simq(camsc->sim, 1); 232 ccb->ccb_h.status = CAM_REQUEUE_REQ; 233 xpt_done(ccb); 234 break; 235 default: 236 device_printf(sc->aac_dev, "unknown event %d in aac_cam\n", 237 event->ev_type); 238 break; 239 } 240 241 return; 242 } 243 244 static int 245 aac_cam_probe(device_t dev) 246 { 247 struct aac_cam *camsc; 248 249 camsc = (struct aac_cam *)device_get_softc(dev); 250 if (!camsc->inf) 251 return (0); 252 fwprintf(camsc->inf->aac_sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, ""); 253 return (0); 254 } 255 256 static int 257 aac_cam_detach(device_t dev) 258 { 259 struct aac_softc *sc; 260 struct aac_cam *camsc; 261 262 camsc = (struct aac_cam *)device_get_softc(dev); 263 if (!camsc->inf) 264 return (0); 265 sc = camsc->inf->aac_sc; 266 fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, ""); 267 camsc->inf->aac_cam = NULL; 268 269 mtx_lock(&sc->aac_io_lock); 270 271 xpt_async(AC_LOST_DEVICE, camsc->path, NULL); 272 xpt_free_path(camsc->path); 273 xpt_bus_deregister(cam_sim_path(camsc->sim)); 274 cam_sim_free(camsc->sim, /*free_devq*/TRUE); 275 276 sc->cam_rescan_cb = NULL; 277 278 mtx_unlock(&sc->aac_io_lock); 279 280 return (0); 281 } 282 283 /* 284 * Register the driver as a CAM SIM 285 */ 286 static int 287 aac_cam_attach(device_t dev) 288 { 289 struct cam_devq *devq; 290 struct cam_sim *sim; 291 struct cam_path *path; 292 struct aac_cam *camsc; 293 struct aac_sim *inf; 294 295 camsc = (struct aac_cam *)device_get_softc(dev); 296 inf = (struct aac_sim *)device_get_ivars(dev); 297 if (!inf) 298 return (EIO); 299 fwprintf(inf->aac_sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, ""); 300 camsc->inf = inf; 301 camsc->inf->aac_cam = camsc; 302 303 devq = cam_simq_alloc(inf->TargetsPerBus); 304 if (devq == NULL) 305 return (EIO); 306 307 sim = aac_sim_alloc(aac_cam_action, aac_cam_poll, "aacraidp", camsc, 308 device_get_unit(dev), &inf->aac_sc->aac_io_lock, 1, 1, devq); 309 if (sim == NULL) { 310 cam_simq_free(devq); 311 return (EIO); 312 } 313 314 /* Since every bus has it's own sim, every bus 'appears' as bus 0 */ 315 mtx_lock(&inf->aac_sc->aac_io_lock); 316 if (aac_xpt_bus_register(sim, dev, 0) != CAM_SUCCESS) { 317 cam_sim_free(sim, TRUE); 318 mtx_unlock(&inf->aac_sc->aac_io_lock); 319 return (EIO); 320 } 321 322 if (xpt_create_path(&path, NULL, cam_sim_path(sim), 323 CAM_TARGET_WILDCARD, CAM_LUN_WILDCARD) != CAM_REQ_CMP) { 324 xpt_bus_deregister(cam_sim_path(sim)); 325 cam_sim_free(sim, TRUE); 326 mtx_unlock(&inf->aac_sc->aac_io_lock); 327 return (EIO); 328 } 329 330 #if __FreeBSD_version >= 700000 331 inf->aac_sc->cam_rescan_cb = aac_cam_rescan; 332 #endif 333 mtx_unlock(&inf->aac_sc->aac_io_lock); 334 335 camsc->sim = sim; 336 camsc->path = path; 337 338 return (0); 339 } 340 341 static u_int64_t 342 aac_eval_blockno(u_int8_t *cmdp) 343 { 344 u_int64_t blockno; 345 346 switch (cmdp[0]) { 347 case READ_6: 348 case WRITE_6: 349 blockno = scsi_3btoul(((struct scsi_rw_6 *)cmdp)->addr); 350 break; 351 case READ_10: 352 case WRITE_10: 353 blockno = scsi_4btoul(((struct scsi_rw_10 *)cmdp)->addr); 354 break; 355 case READ_12: 356 case WRITE_12: 357 blockno = scsi_4btoul(((struct scsi_rw_12 *)cmdp)->addr); 358 break; 359 case READ_16: 360 case WRITE_16: 361 blockno = scsi_8btou64(((struct scsi_rw_16 *)cmdp)->addr); 362 break; 363 default: 364 blockno = 0; 365 break; 366 } 367 return(blockno); 368 } 369 370 static void 371 aac_container_rw_command(struct cam_sim *sim, union ccb *ccb, u_int8_t *cmdp) 372 { 373 struct aac_cam *camsc; 374 struct aac_softc *sc; 375 struct aac_command *cm; 376 struct aac_fib *fib; 377 u_int64_t blockno; 378 379 camsc = (struct aac_cam *)cam_sim_softc(sim); 380 sc = camsc->inf->aac_sc; 381 mtx_assert(&sc->aac_io_lock, MA_OWNED); 382 383 if (aacraid_alloc_command(sc, &cm)) { 384 struct aac_event *event; 385 386 xpt_freeze_simq(sim, 1); 387 ccb->ccb_h.status = CAM_RESRC_UNAVAIL; 388 ccb->ccb_h.sim_priv.entries[0].ptr = camsc; 389 event = malloc(sizeof(struct aac_event), M_AACRAIDCAM, 390 M_NOWAIT | M_ZERO); 391 if (event == NULL) { 392 device_printf(sc->aac_dev, 393 "Warning, out of memory for event\n"); 394 return; 395 } 396 event->ev_callback = aac_cam_event; 397 event->ev_arg = ccb; 398 event->ev_type = AAC_EVENT_CMFREE; 399 aacraid_add_event(sc, event); 400 return; 401 } 402 403 fib = cm->cm_fib; 404 switch (ccb->ccb_h.flags & CAM_DIR_MASK) { 405 case CAM_DIR_IN: 406 cm->cm_flags |= AAC_CMD_DATAIN; 407 break; 408 case CAM_DIR_OUT: 409 cm->cm_flags |= AAC_CMD_DATAOUT; 410 break; 411 case CAM_DIR_NONE: 412 break; 413 default: 414 cm->cm_flags |= AAC_CMD_DATAIN | AAC_CMD_DATAOUT; 415 break; 416 } 417 418 blockno = aac_eval_blockno(cmdp); 419 420 cm->cm_complete = aac_container_complete; 421 cm->cm_ccb = ccb; 422 cm->cm_timestamp = time_uptime; 423 cm->cm_data = (void *)ccb->csio.data_ptr; 424 cm->cm_datalen = ccb->csio.dxfer_len; 425 426 fib->Header.Size = sizeof(struct aac_fib_header); 427 fib->Header.XferState = 428 AAC_FIBSTATE_HOSTOWNED | 429 AAC_FIBSTATE_INITIALISED | 430 AAC_FIBSTATE_EMPTY | 431 AAC_FIBSTATE_FROMHOST | 432 AAC_FIBSTATE_REXPECTED | 433 AAC_FIBSTATE_NORM | 434 AAC_FIBSTATE_ASYNC | 435 AAC_FIBSTATE_FAST_RESPONSE; 436 437 if (sc->flags & AAC_FLAGS_NEW_COMM_TYPE2) { 438 struct aac_raw_io2 *raw; 439 raw = (struct aac_raw_io2 *)&fib->data[0]; 440 bzero(raw, sizeof(struct aac_raw_io2)); 441 fib->Header.Command = RawIo2; 442 raw->strtBlkLow = (u_int32_t)blockno; 443 raw->strtBlkHigh = (u_int32_t)(blockno >> 32); 444 raw->byteCnt = cm->cm_datalen; 445 raw->ldNum = ccb->ccb_h.target_id; 446 fib->Header.Size += sizeof(struct aac_raw_io2); 447 cm->cm_sgtable = (struct aac_sg_table *)raw->sge; 448 if (cm->cm_flags & AAC_CMD_DATAIN) 449 raw->flags = RIO2_IO_TYPE_READ | RIO2_SG_FORMAT_IEEE1212; 450 else 451 raw->flags = RIO2_IO_TYPE_WRITE | RIO2_SG_FORMAT_IEEE1212; 452 } else if (sc->flags & AAC_FLAGS_RAW_IO) { 453 struct aac_raw_io *raw; 454 raw = (struct aac_raw_io *)&fib->data[0]; 455 bzero(raw, sizeof(struct aac_raw_io)); 456 fib->Header.Command = RawIo; 457 raw->BlockNumber = blockno; 458 raw->ByteCount = cm->cm_datalen; 459 raw->ContainerId = ccb->ccb_h.target_id; 460 fib->Header.Size += sizeof(struct aac_raw_io); 461 cm->cm_sgtable = (struct aac_sg_table *) 462 &raw->SgMapRaw; 463 if (cm->cm_flags & AAC_CMD_DATAIN) 464 raw->Flags = 1; 465 } else if ((sc->flags & AAC_FLAGS_SG_64BIT) == 0) { 466 fib->Header.Command = ContainerCommand; 467 if (cm->cm_flags & AAC_CMD_DATAIN) { 468 struct aac_blockread *br; 469 br = (struct aac_blockread *)&fib->data[0]; 470 br->Command = VM_CtBlockRead; 471 br->ContainerId = ccb->ccb_h.target_id; 472 br->BlockNumber = blockno; 473 br->ByteCount = cm->cm_datalen; 474 fib->Header.Size += sizeof(struct aac_blockread); 475 cm->cm_sgtable = &br->SgMap; 476 } else { 477 struct aac_blockwrite *bw; 478 bw = (struct aac_blockwrite *)&fib->data[0]; 479 bw->Command = VM_CtBlockWrite; 480 bw->ContainerId = ccb->ccb_h.target_id; 481 bw->BlockNumber = blockno; 482 bw->ByteCount = cm->cm_datalen; 483 bw->Stable = CUNSTABLE; 484 fib->Header.Size += sizeof(struct aac_blockwrite); 485 cm->cm_sgtable = &bw->SgMap; 486 } 487 } else { 488 fib->Header.Command = ContainerCommand64; 489 if (cm->cm_flags & AAC_CMD_DATAIN) { 490 struct aac_blockread64 *br; 491 br = (struct aac_blockread64 *)&fib->data[0]; 492 br->Command = VM_CtHostRead64; 493 br->ContainerId = ccb->ccb_h.target_id; 494 br->SectorCount = cm->cm_datalen/AAC_BLOCK_SIZE; 495 br->BlockNumber = blockno; 496 br->Pad = 0; 497 br->Flags = 0; 498 fib->Header.Size += sizeof(struct aac_blockread64); 499 cm->cm_sgtable = (struct aac_sg_table *)&br->SgMap64; 500 } else { 501 struct aac_blockwrite64 *bw; 502 bw = (struct aac_blockwrite64 *)&fib->data[0]; 503 bw->Command = VM_CtHostWrite64; 504 bw->ContainerId = ccb->ccb_h.target_id; 505 bw->SectorCount = cm->cm_datalen/AAC_BLOCK_SIZE; 506 bw->BlockNumber = blockno; 507 bw->Pad = 0; 508 bw->Flags = 0; 509 fib->Header.Size += sizeof(struct aac_blockwrite64); 510 cm->cm_sgtable = (struct aac_sg_table *)&bw->SgMap64; 511 } 512 } 513 aac_enqueue_ready(cm); 514 aacraid_startio(cm->cm_sc); 515 } 516 517 static void 518 aac_container_special_command(struct cam_sim *sim, union ccb *ccb, 519 u_int8_t *cmdp) 520 { 521 struct aac_cam *camsc; 522 struct aac_softc *sc; 523 struct aac_container *co; 524 525 camsc = (struct aac_cam *)cam_sim_softc(sim); 526 sc = camsc->inf->aac_sc; 527 mtx_assert(&sc->aac_io_lock, MA_OWNED); 528 529 TAILQ_FOREACH(co, &sc->aac_container_tqh, co_link) { 530 fwprintf(sc, HBA_FLAGS_DBG_ERROR_B, "found container %d search for %d", co->co_mntobj.ObjectId, ccb->ccb_h.target_id); 531 if (co->co_mntobj.ObjectId == ccb->ccb_h.target_id) 532 break; 533 } 534 if (co == NULL || ccb->ccb_h.target_lun != 0) { 535 fwprintf(sc, HBA_FLAGS_DBG_ERROR_B, 536 "Container not present: cmd 0x%x id %d lun %d len %d", 537 *cmdp, ccb->ccb_h.target_id, ccb->ccb_h.target_lun, 538 ccb->csio.dxfer_len); 539 ccb->ccb_h.status = CAM_DEV_NOT_THERE; 540 xpt_done(ccb); 541 return; 542 } 543 544 if (ccb->csio.dxfer_len) 545 bzero(ccb->csio.data_ptr, ccb->csio.dxfer_len); 546 547 switch (*cmdp) { 548 case INQUIRY: 549 { 550 struct scsi_inquiry *inq = (struct scsi_inquiry *)cmdp; 551 552 fwprintf(sc, HBA_FLAGS_DBG_COMM_B, 553 "Container INQUIRY id %d lun %d len %d VPD 0x%x Page 0x%x", 554 ccb->ccb_h.target_id, ccb->ccb_h.target_lun, 555 ccb->csio.dxfer_len, inq->byte2, inq->page_code); 556 if (!(inq->byte2 & SI_EVPD)) { 557 struct scsi_inquiry_data *p = 558 (struct scsi_inquiry_data *)ccb->csio.data_ptr; 559 if (inq->page_code != 0) { 560 aac_set_scsi_error(sc, ccb, 561 SCSI_STATUS_CHECK_COND, 562 SSD_KEY_ILLEGAL_REQUEST, 0x24, 0x00); 563 xpt_done(ccb); 564 return; 565 } 566 p->device = T_DIRECT; 567 p->version = SCSI_REV_SPC2; 568 p->response_format = 2; 569 if (ccb->csio.dxfer_len >= 36) { 570 p->additional_length = 31; 571 p->flags = SID_WBus16|SID_Sync|SID_CmdQue; 572 /* OEM Vendor defines */ 573 strncpy(p->vendor, "Adaptec ", sizeof(p->vendor)); 574 strncpy(p->product, "Array ", 575 sizeof(p->product)); 576 strncpy(p->revision, "V1.0", 577 sizeof(p->revision)); 578 } 579 } else { 580 if (inq->page_code == SVPD_SUPPORTED_PAGE_LIST) { 581 struct scsi_vpd_supported_page_list *p = 582 (struct scsi_vpd_supported_page_list *) 583 ccb->csio.data_ptr; 584 p->device = T_DIRECT; 585 p->page_code = SVPD_SUPPORTED_PAGE_LIST; 586 p->length = 2; 587 p->list[0] = SVPD_SUPPORTED_PAGE_LIST; 588 p->list[1] = SVPD_UNIT_SERIAL_NUMBER; 589 } else if (inq->page_code == SVPD_UNIT_SERIAL_NUMBER) { 590 struct scsi_vpd_unit_serial_number *p = 591 (struct scsi_vpd_unit_serial_number *) 592 ccb->csio.data_ptr; 593 p->device = T_DIRECT; 594 p->page_code = SVPD_UNIT_SERIAL_NUMBER; 595 p->length = sprintf((char *)p->serial_num, 596 "%08X%02X", co->co_uid, 597 ccb->ccb_h.target_id); 598 } else { 599 aac_set_scsi_error(sc, ccb, 600 SCSI_STATUS_CHECK_COND, 601 SSD_KEY_ILLEGAL_REQUEST, 0x24, 0x00); 602 xpt_done(ccb); 603 return; 604 } 605 } 606 ccb->ccb_h.status = CAM_REQ_CMP; 607 break; 608 } 609 610 case REPORT_LUNS: 611 fwprintf(sc, HBA_FLAGS_DBG_COMM_B, 612 "Container REPORT_LUNS id %d lun %d len %d", 613 ccb->ccb_h.target_id, ccb->ccb_h.target_lun, 614 ccb->csio.dxfer_len); 615 ccb->ccb_h.status = CAM_REQ_CMP; 616 break; 617 618 case START_STOP: 619 { 620 struct scsi_start_stop_unit *ss = 621 (struct scsi_start_stop_unit *)cmdp; 622 fwprintf(sc, HBA_FLAGS_DBG_COMM_B, 623 "Container START_STOP id %d lun %d len %d", 624 ccb->ccb_h.target_id, ccb->ccb_h.target_lun, 625 ccb->csio.dxfer_len); 626 if (sc->aac_support_opt2 & AAC_SUPPORTED_POWER_MANAGEMENT) { 627 struct aac_command *cm; 628 struct aac_fib *fib; 629 struct aac_cnt_config *ccfg; 630 631 if (aacraid_alloc_command(sc, &cm)) { 632 struct aac_event *event; 633 634 xpt_freeze_simq(sim, 1); 635 ccb->ccb_h.status = CAM_RESRC_UNAVAIL; 636 ccb->ccb_h.sim_priv.entries[0].ptr = camsc; 637 event = malloc(sizeof(struct aac_event), M_AACRAIDCAM, 638 M_NOWAIT | M_ZERO); 639 if (event == NULL) { 640 device_printf(sc->aac_dev, 641 "Warning, out of memory for event\n"); 642 return; 643 } 644 event->ev_callback = aac_cam_event; 645 event->ev_arg = ccb; 646 event->ev_type = AAC_EVENT_CMFREE; 647 aacraid_add_event(sc, event); 648 return; 649 } 650 651 fib = cm->cm_fib; 652 cm->cm_timestamp = time_uptime; 653 cm->cm_datalen = 0; 654 655 fib->Header.Size = 656 sizeof(struct aac_fib_header) + sizeof(struct aac_cnt_config); 657 fib->Header.XferState = 658 AAC_FIBSTATE_HOSTOWNED | 659 AAC_FIBSTATE_INITIALISED | 660 AAC_FIBSTATE_EMPTY | 661 AAC_FIBSTATE_FROMHOST | 662 AAC_FIBSTATE_REXPECTED | 663 AAC_FIBSTATE_NORM | 664 AAC_FIBSTATE_ASYNC | 665 AAC_FIBSTATE_FAST_RESPONSE; 666 fib->Header.Command = ContainerCommand; 667 668 /* Start unit */ 669 ccfg = (struct aac_cnt_config *)&fib->data[0]; 670 bzero(ccfg, sizeof (*ccfg) - CT_PACKET_SIZE); 671 ccfg->Command = VM_ContainerConfig; 672 ccfg->CTCommand.command = CT_PM_DRIVER_SUPPORT; 673 ccfg->CTCommand.param[0] = (ss->how & SSS_START ? 674 AAC_PM_DRIVERSUP_START_UNIT : 675 AAC_PM_DRIVERSUP_STOP_UNIT); 676 ccfg->CTCommand.param[1] = co->co_mntobj.ObjectId; 677 ccfg->CTCommand.param[2] = 0; /* 1 - immediate */ 678 679 if (aacraid_wait_command(cm) != 0 || 680 *(u_int32_t *)&fib->data[0] != 0) { 681 printf("Power Management: Error start/stop container %d\n", 682 co->co_mntobj.ObjectId); 683 } 684 aacraid_release_command(cm); 685 } 686 ccb->ccb_h.status = CAM_REQ_CMP; 687 break; 688 } 689 690 case TEST_UNIT_READY: 691 fwprintf(sc, HBA_FLAGS_DBG_COMM_B, 692 "Container TEST_UNIT_READY id %d lun %d len %d", 693 ccb->ccb_h.target_id, ccb->ccb_h.target_lun, 694 ccb->csio.dxfer_len); 695 ccb->ccb_h.status = CAM_REQ_CMP; 696 break; 697 698 case REQUEST_SENSE: 699 fwprintf(sc, HBA_FLAGS_DBG_COMM_B, 700 "Container REQUEST_SENSE id %d lun %d len %d", 701 ccb->ccb_h.target_id, ccb->ccb_h.target_lun, 702 ccb->csio.dxfer_len); 703 ccb->ccb_h.status = CAM_REQ_CMP; 704 break; 705 706 case READ_CAPACITY: 707 { 708 struct scsi_read_capacity_data *p = 709 (struct scsi_read_capacity_data *)ccb->csio.data_ptr; 710 fwprintf(sc, HBA_FLAGS_DBG_COMM_B, 711 "Container READ_CAPACITY id %d lun %d len %d", 712 ccb->ccb_h.target_id, ccb->ccb_h.target_lun, 713 ccb->csio.dxfer_len); 714 scsi_ulto4b(co->co_mntobj.ObjExtension.BlockDevice.BlockSize, p->length); 715 /* check if greater than 2TB */ 716 if (co->co_mntobj.CapacityHigh) { 717 if (sc->flags & AAC_FLAGS_LBA_64BIT) 718 scsi_ulto4b(0xffffffff, p->addr); 719 } else { 720 scsi_ulto4b(co->co_mntobj.Capacity-1, p->addr); 721 } 722 ccb->ccb_h.status = CAM_REQ_CMP; 723 break; 724 } 725 726 case SERVICE_ACTION_IN: 727 { 728 struct scsi_read_capacity_data_long *p = 729 (struct scsi_read_capacity_data_long *) 730 ccb->csio.data_ptr; 731 fwprintf(sc, HBA_FLAGS_DBG_COMM_B, 732 "Container SERVICE_ACTION_IN id %d lun %d len %d", 733 ccb->ccb_h.target_id, ccb->ccb_h.target_lun, 734 ccb->csio.dxfer_len); 735 if (((struct scsi_read_capacity_16 *)cmdp)->service_action != 736 SRC16_SERVICE_ACTION) { 737 aac_set_scsi_error(sc, ccb, SCSI_STATUS_CHECK_COND, 738 SSD_KEY_ILLEGAL_REQUEST, 0x24, 0x00); 739 xpt_done(ccb); 740 return; 741 } 742 scsi_ulto4b(co->co_mntobj.ObjExtension.BlockDevice.BlockSize, p->length); 743 scsi_ulto4b(co->co_mntobj.CapacityHigh, p->addr); 744 scsi_ulto4b(co->co_mntobj.Capacity-1, &p->addr[4]); 745 746 if (ccb->csio.dxfer_len >= 14) { 747 u_int32_t mapping = co->co_mntobj.ObjExtension.BlockDevice.bdLgclPhysMap; 748 p->prot_lbppbe = 0; 749 while (mapping > 1) { 750 mapping >>= 1; 751 p->prot_lbppbe++; 752 } 753 p->prot_lbppbe &= 0x0f; 754 } 755 756 ccb->ccb_h.status = CAM_REQ_CMP; 757 break; 758 } 759 760 case MODE_SENSE_6: 761 { 762 struct scsi_mode_sense_6 *msp =(struct scsi_mode_sense_6 *)cmdp; 763 struct ms6_data { 764 struct scsi_mode_hdr_6 hd; 765 struct scsi_mode_block_descr bd; 766 char pages; 767 } *p = (struct ms6_data *)ccb->csio.data_ptr; 768 char *pagep; 769 int return_all_pages = FALSE; 770 771 fwprintf(sc, HBA_FLAGS_DBG_COMM_B, 772 "Container MODE_SENSE id %d lun %d len %d page %d", 773 ccb->ccb_h.target_id, ccb->ccb_h.target_lun, 774 ccb->csio.dxfer_len, msp->page); 775 p->hd.datalen = sizeof(struct scsi_mode_hdr_6) - 1; 776 if (co->co_mntobj.ContentState & AAC_FSCS_READONLY) 777 p->hd.dev_specific = 0x80; /* WP */ 778 p->hd.dev_specific |= 0x10; /* DPOFUA */ 779 if (msp->byte2 & SMS_DBD) { 780 p->hd.block_descr_len = 0; 781 } else { 782 p->hd.block_descr_len = 783 sizeof(struct scsi_mode_block_descr); 784 p->hd.datalen += p->hd.block_descr_len; 785 scsi_ulto3b(co->co_mntobj.ObjExtension.BlockDevice.BlockSize, p->bd.block_len); 786 if (co->co_mntobj.Capacity > 0xffffff || 787 co->co_mntobj.CapacityHigh) { 788 p->bd.num_blocks[0] = 0xff; 789 p->bd.num_blocks[1] = 0xff; 790 p->bd.num_blocks[2] = 0xff; 791 } else { 792 p->bd.num_blocks[0] = (u_int8_t) 793 (co->co_mntobj.Capacity >> 16); 794 p->bd.num_blocks[1] = (u_int8_t) 795 (co->co_mntobj.Capacity >> 8); 796 p->bd.num_blocks[2] = (u_int8_t) 797 (co->co_mntobj.Capacity); 798 } 799 } 800 pagep = &p->pages; 801 switch (msp->page & SMS_PAGE_CODE) { 802 case SMS_ALL_PAGES_PAGE: 803 return_all_pages = TRUE; 804 case SMS_CONTROL_MODE_PAGE: 805 { 806 struct scsi_control_page *cp = 807 (struct scsi_control_page *)pagep; 808 809 if (ccb->csio.dxfer_len <= p->hd.datalen + 8) { 810 aac_set_scsi_error(sc, ccb, 811 SCSI_STATUS_CHECK_COND, 812 SSD_KEY_ILLEGAL_REQUEST, 0x24, 0x00); 813 xpt_done(ccb); 814 return; 815 } 816 cp->page_code = SMS_CONTROL_MODE_PAGE; 817 cp->page_length = 6; 818 p->hd.datalen += 8; 819 pagep += 8; 820 if (!return_all_pages) 821 break; 822 } 823 case SMS_VENDOR_SPECIFIC_PAGE: 824 break; 825 default: 826 aac_set_scsi_error(sc, ccb, SCSI_STATUS_CHECK_COND, 827 SSD_KEY_ILLEGAL_REQUEST, 0x24, 0x00); 828 xpt_done(ccb); 829 return; 830 } 831 ccb->ccb_h.status = CAM_REQ_CMP; 832 break; 833 } 834 835 case SYNCHRONIZE_CACHE: 836 fwprintf(sc, HBA_FLAGS_DBG_COMM_B, 837 "Container SYNCHRONIZE_CACHE id %d lun %d len %d", 838 ccb->ccb_h.target_id, ccb->ccb_h.target_lun, 839 ccb->csio.dxfer_len); 840 ccb->ccb_h.status = CAM_REQ_CMP; 841 break; 842 843 default: 844 fwprintf(sc, HBA_FLAGS_DBG_ERROR_B, 845 "Container unsupp. cmd 0x%x id %d lun %d len %d", 846 *cmdp, ccb->ccb_h.target_id, ccb->ccb_h.target_lun, 847 ccb->csio.dxfer_len); 848 ccb->ccb_h.status = CAM_REQ_CMP; /*CAM_REQ_INVALID*/ 849 break; 850 } 851 xpt_done(ccb); 852 } 853 854 static void 855 aac_passthrough_command(struct cam_sim *sim, union ccb *ccb) 856 { 857 struct aac_cam *camsc; 858 struct aac_softc *sc; 859 struct aac_command *cm; 860 struct aac_fib *fib; 861 struct aac_srb *srb; 862 863 camsc = (struct aac_cam *)cam_sim_softc(sim); 864 sc = camsc->inf->aac_sc; 865 mtx_assert(&sc->aac_io_lock, MA_OWNED); 866 867 if (aacraid_alloc_command(sc, &cm)) { 868 struct aac_event *event; 869 870 xpt_freeze_simq(sim, 1); 871 ccb->ccb_h.status = CAM_RESRC_UNAVAIL; 872 ccb->ccb_h.sim_priv.entries[0].ptr = camsc; 873 event = malloc(sizeof(struct aac_event), M_AACRAIDCAM, 874 M_NOWAIT | M_ZERO); 875 if (event == NULL) { 876 device_printf(sc->aac_dev, 877 "Warning, out of memory for event\n"); 878 return; 879 } 880 event->ev_callback = aac_cam_event; 881 event->ev_arg = ccb; 882 event->ev_type = AAC_EVENT_CMFREE; 883 aacraid_add_event(sc, event); 884 return; 885 } 886 887 fib = cm->cm_fib; 888 switch (ccb->ccb_h.flags & CAM_DIR_MASK) { 889 case CAM_DIR_IN: 890 cm->cm_flags |= AAC_CMD_DATAIN; 891 break; 892 case CAM_DIR_OUT: 893 cm->cm_flags |= AAC_CMD_DATAOUT; 894 break; 895 case CAM_DIR_NONE: 896 break; 897 default: 898 cm->cm_flags |= AAC_CMD_DATAIN | AAC_CMD_DATAOUT; 899 break; 900 } 901 902 srb = (struct aac_srb *)&fib->data[0]; 903 srb->function = AAC_SRB_FUNC_EXECUTE_SCSI; 904 if (cm->cm_flags & (AAC_CMD_DATAIN|AAC_CMD_DATAOUT)) 905 srb->flags = AAC_SRB_FLAGS_UNSPECIFIED_DIRECTION; 906 if (cm->cm_flags & AAC_CMD_DATAIN) 907 srb->flags = AAC_SRB_FLAGS_DATA_IN; 908 else if (cm->cm_flags & AAC_CMD_DATAOUT) 909 srb->flags = AAC_SRB_FLAGS_DATA_OUT; 910 else 911 srb->flags = AAC_SRB_FLAGS_NO_DATA_XFER; 912 913 /* 914 * Copy the CDB into the SRB. It's only 6-16 bytes, 915 * so a copy is not too expensive. 916 */ 917 srb->cdb_len = ccb->csio.cdb_len; 918 if (ccb->ccb_h.flags & CAM_CDB_POINTER) 919 bcopy(ccb->csio.cdb_io.cdb_ptr, (u_int8_t *)&srb->cdb[0], 920 srb->cdb_len); 921 else 922 bcopy(ccb->csio.cdb_io.cdb_bytes, (u_int8_t *)&srb->cdb[0], 923 srb->cdb_len); 924 925 /* Set command */ 926 fib->Header.Command = (sc->flags & AAC_FLAGS_SG_64BIT) ? 927 ScsiPortCommandU64 : ScsiPortCommand; 928 fib->Header.Size = sizeof(struct aac_fib_header) + 929 sizeof(struct aac_srb); 930 931 /* Map the s/g list */ 932 cm->cm_sgtable = &srb->sg_map; 933 if ((ccb->ccb_h.flags & CAM_DIR_MASK) != CAM_DIR_NONE) { 934 /* 935 * Arrange things so that the S/G 936 * map will get set up automagically 937 */ 938 cm->cm_data = (void *)ccb->csio.data_ptr; 939 cm->cm_datalen = ccb->csio.dxfer_len; 940 srb->data_len = ccb->csio.dxfer_len; 941 } else { 942 cm->cm_data = NULL; 943 cm->cm_datalen = 0; 944 srb->data_len = 0; 945 } 946 947 srb->bus = camsc->inf->BusNumber - 1; /* Bus no. rel. to the card */ 948 srb->target = ccb->ccb_h.target_id; 949 srb->lun = ccb->ccb_h.target_lun; 950 srb->timeout = ccb->ccb_h.timeout; /* XXX */ 951 srb->retry_limit = 0; 952 953 cm->cm_complete = aac_cam_complete; 954 cm->cm_ccb = ccb; 955 cm->cm_timestamp = time_uptime; 956 957 fib->Header.XferState = 958 AAC_FIBSTATE_HOSTOWNED | 959 AAC_FIBSTATE_INITIALISED | 960 AAC_FIBSTATE_FROMHOST | 961 AAC_FIBSTATE_REXPECTED | 962 AAC_FIBSTATE_NORM | 963 AAC_FIBSTATE_ASYNC | 964 AAC_FIBSTATE_FAST_RESPONSE; 965 966 aac_enqueue_ready(cm); 967 aacraid_startio(cm->cm_sc); 968 } 969 970 static void 971 aac_cam_action(struct cam_sim *sim, union ccb *ccb) 972 { 973 struct aac_cam *camsc; 974 struct aac_softc *sc; 975 976 camsc = (struct aac_cam *)cam_sim_softc(sim); 977 sc = camsc->inf->aac_sc; 978 fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, ""); 979 mtx_assert(&sc->aac_io_lock, MA_OWNED); 980 981 /* Synchronous ops, and ops that don't require communication with the 982 * controller */ 983 switch(ccb->ccb_h.func_code) { 984 case XPT_SCSI_IO: 985 /* This is handled down below */ 986 break; 987 case XPT_CALC_GEOMETRY: 988 { 989 struct ccb_calc_geometry *ccg; 990 u_int32_t size_mb; 991 u_int32_t secs_per_cylinder; 992 993 ccg = &ccb->ccg; 994 size_mb = ccg->volume_size / 995 ((1024L * 1024L) / ccg->block_size); 996 if (size_mb >= (2 * 1024)) { /* 2GB */ 997 ccg->heads = 255; 998 ccg->secs_per_track = 63; 999 } else if (size_mb >= (1 * 1024)) { /* 1GB */ 1000 ccg->heads = 128; 1001 ccg->secs_per_track = 32; 1002 } else { 1003 ccg->heads = 64; 1004 ccg->secs_per_track = 32; 1005 } 1006 secs_per_cylinder = ccg->heads * ccg->secs_per_track; 1007 ccg->cylinders = ccg->volume_size / secs_per_cylinder; 1008 1009 ccb->ccb_h.status = CAM_REQ_CMP; 1010 xpt_done(ccb); 1011 return; 1012 } 1013 case XPT_PATH_INQ: 1014 { 1015 struct ccb_pathinq *cpi = &ccb->cpi; 1016 1017 cpi->version_num = 1; 1018 cpi->target_sprt = 0; 1019 cpi->hba_eng_cnt = 0; 1020 cpi->max_target = camsc->inf->TargetsPerBus; 1021 cpi->max_lun = 8; /* Per the controller spec */ 1022 cpi->initiator_id = camsc->inf->InitiatorBusId; 1023 cpi->bus_id = camsc->inf->BusNumber; 1024 #if __FreeBSD_version >= 800000 1025 cpi->maxio = sc->aac_max_sectors << 9; 1026 #endif 1027 1028 /* 1029 * Resetting via the passthrough or parallel bus scan 1030 * causes problems. 1031 */ 1032 cpi->hba_misc = PIM_NOBUSRESET; 1033 cpi->hba_inquiry = PI_TAG_ABLE; 1034 cpi->base_transfer_speed = 300000; 1035 #ifdef CAM_NEW_TRAN_CODE 1036 cpi->hba_misc |= PIM_SEQSCAN; 1037 cpi->protocol = PROTO_SCSI; 1038 cpi->transport = XPORT_SAS; 1039 cpi->transport_version = 0; 1040 cpi->protocol_version = SCSI_REV_SPC2; 1041 #endif 1042 strlcpy(cpi->sim_vid, "FreeBSD", SIM_IDLEN); 1043 strlcpy(cpi->hba_vid, "PMC-Sierra", HBA_IDLEN); 1044 strlcpy(cpi->dev_name, cam_sim_name(sim), DEV_IDLEN); 1045 cpi->unit_number = cam_sim_unit(sim); 1046 ccb->ccb_h.status = CAM_REQ_CMP; 1047 xpt_done(ccb); 1048 return; 1049 } 1050 case XPT_GET_TRAN_SETTINGS: 1051 { 1052 #ifdef CAM_NEW_TRAN_CODE 1053 struct ccb_trans_settings_scsi *scsi = 1054 &ccb->cts.proto_specific.scsi; 1055 struct ccb_trans_settings_spi *spi = 1056 &ccb->cts.xport_specific.spi; 1057 ccb->cts.protocol = PROTO_SCSI; 1058 ccb->cts.protocol_version = SCSI_REV_SPC2; 1059 ccb->cts.transport = XPORT_SAS; 1060 ccb->cts.transport_version = 0; 1061 scsi->valid = CTS_SCSI_VALID_TQ; 1062 scsi->flags = CTS_SCSI_FLAGS_TAG_ENB; 1063 spi->valid |= CTS_SPI_VALID_DISC; 1064 spi->flags |= CTS_SPI_FLAGS_DISC_ENB; 1065 #else 1066 ccb->cts.flags = ~(CCB_TRANS_DISC_ENB | CCB_TRANS_TAG_ENB); 1067 ccb->cts.valid = CCB_TRANS_DISC_VALID | CCB_TRANS_TQ_VALID; 1068 #endif 1069 ccb->ccb_h.status = CAM_REQ_CMP; 1070 xpt_done(ccb); 1071 return; 1072 } 1073 case XPT_SET_TRAN_SETTINGS: 1074 ccb->ccb_h.status = CAM_FUNC_NOTAVAIL; 1075 xpt_done(ccb); 1076 return; 1077 case XPT_RESET_BUS: 1078 if (!(sc->flags & AAC_FLAGS_CAM_NORESET) && 1079 camsc->inf->BusType != CONTAINER_BUS) { 1080 ccb->ccb_h.status = aac_cam_reset_bus(sim, ccb); 1081 } else { 1082 ccb->ccb_h.status = CAM_REQ_CMP; 1083 } 1084 xpt_done(ccb); 1085 return; 1086 case XPT_RESET_DEV: 1087 ccb->ccb_h.status = CAM_REQ_CMP; 1088 xpt_done(ccb); 1089 return; 1090 case XPT_ABORT: 1091 ccb->ccb_h.status = aac_cam_abort_ccb(sim, ccb); 1092 xpt_done(ccb); 1093 return; 1094 case XPT_TERM_IO: 1095 ccb->ccb_h.status = aac_cam_term_io(sim, ccb); 1096 xpt_done(ccb); 1097 return; 1098 default: 1099 device_printf(sc->aac_dev, "Unsupported command 0x%x\n", 1100 ccb->ccb_h.func_code); 1101 ccb->ccb_h.status = CAM_PROVIDE_FAIL; 1102 xpt_done(ccb); 1103 return; 1104 } 1105 1106 /* Async ops that require communcation with the controller */ 1107 if (camsc->inf->BusType == CONTAINER_BUS) { 1108 u_int8_t *cmdp; 1109 1110 if (ccb->ccb_h.flags & CAM_CDB_POINTER) 1111 cmdp = ccb->csio.cdb_io.cdb_ptr; 1112 else 1113 cmdp = &ccb->csio.cdb_io.cdb_bytes[0]; 1114 1115 if (*cmdp==READ_6 || *cmdp==WRITE_6 || *cmdp==READ_10 || 1116 *cmdp==WRITE_10 || *cmdp==READ_12 || *cmdp==WRITE_12 || 1117 *cmdp==READ_16 || *cmdp==WRITE_16) 1118 aac_container_rw_command(sim, ccb, cmdp); 1119 else 1120 aac_container_special_command(sim, ccb, cmdp); 1121 } else { 1122 aac_passthrough_command(sim, ccb); 1123 } 1124 } 1125 1126 static void 1127 aac_cam_poll(struct cam_sim *sim) 1128 { 1129 /* 1130 * Pinging the interrupt routine isn't very safe, nor is it 1131 * really necessary. Do nothing. 1132 */ 1133 } 1134 1135 static void 1136 aac_container_complete(struct aac_command *cm) 1137 { 1138 union ccb *ccb; 1139 u_int32_t status; 1140 1141 fwprintf(cm->cm_sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, ""); 1142 ccb = cm->cm_ccb; 1143 status = ((u_int32_t *)cm->cm_fib->data)[0]; 1144 1145 if (cm->cm_flags & AAC_CMD_RESET) { 1146 ccb->ccb_h.status = CAM_SCSI_BUS_RESET; 1147 } else if (status == ST_OK) { 1148 ccb->ccb_h.status = CAM_REQ_CMP; 1149 } else if (status == ST_NOT_READY) { 1150 ccb->ccb_h.status = CAM_BUSY; 1151 } else { 1152 ccb->ccb_h.status = CAM_REQ_CMP_ERR; 1153 } 1154 1155 aacraid_release_command(cm); 1156 xpt_done(ccb); 1157 } 1158 1159 static void 1160 aac_cam_complete(struct aac_command *cm) 1161 { 1162 union ccb *ccb; 1163 struct aac_srb_response *srbr; 1164 struct aac_softc *sc; 1165 1166 sc = cm->cm_sc; 1167 fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, ""); 1168 ccb = cm->cm_ccb; 1169 srbr = (struct aac_srb_response *)&cm->cm_fib->data[0]; 1170 1171 if (cm->cm_flags & AAC_CMD_FASTRESP) { 1172 /* fast response */ 1173 srbr->srb_status = CAM_REQ_CMP; 1174 srbr->scsi_status = SCSI_STATUS_OK; 1175 srbr->sense_len = 0; 1176 } 1177 1178 if (cm->cm_flags & AAC_CMD_RESET) { 1179 ccb->ccb_h.status = CAM_SCSI_BUS_RESET; 1180 } else if (srbr->fib_status != 0) { 1181 device_printf(sc->aac_dev, "Passthru FIB failed!\n"); 1182 ccb->ccb_h.status = CAM_REQ_ABORTED; 1183 } else { 1184 /* 1185 * The SRB error codes just happen to match the CAM error 1186 * codes. How convenient! 1187 */ 1188 ccb->ccb_h.status = srbr->srb_status; 1189 1190 /* Take care of SCSI_IO ops. */ 1191 if (ccb->ccb_h.func_code == XPT_SCSI_IO) { 1192 u_int8_t command, device; 1193 1194 ccb->csio.scsi_status = srbr->scsi_status; 1195 1196 /* Take care of autosense */ 1197 if (srbr->sense_len) { 1198 int sense_len, scsi_sense_len; 1199 1200 scsi_sense_len = sizeof(struct scsi_sense_data); 1201 bzero(&ccb->csio.sense_data, scsi_sense_len); 1202 sense_len = (srbr->sense_len > 1203 scsi_sense_len) ? scsi_sense_len : 1204 srbr->sense_len; 1205 bcopy(&srbr->sense[0], &ccb->csio.sense_data, 1206 srbr->sense_len); 1207 ccb->csio.sense_len = sense_len; 1208 ccb->ccb_h.status |= CAM_AUTOSNS_VALID; 1209 // scsi_sense_print(&ccb->csio); 1210 } 1211 1212 /* If this is an inquiry command, fake things out */ 1213 if (ccb->ccb_h.flags & CAM_CDB_POINTER) 1214 command = ccb->csio.cdb_io.cdb_ptr[0]; 1215 else 1216 command = ccb->csio.cdb_io.cdb_bytes[0]; 1217 1218 if (command == INQUIRY) { 1219 if (ccb->ccb_h.status == CAM_REQ_CMP) { 1220 device = ccb->csio.data_ptr[0] & 0x1f; 1221 /* 1222 * We want DASD and PROC devices to only be 1223 * visible through the pass device. 1224 */ 1225 if ((device == T_DIRECT && 1226 !(sc->aac_feature_bits & AAC_SUPPL_SUPPORTED_JBOD)) || 1227 (device == T_PROCESSOR)) 1228 ccb->csio.data_ptr[0] = 1229 ((device & 0xe0) | T_NODEVICE); 1230 1231 /* handle phys. components of a log. drive */ 1232 if (ccb->csio.data_ptr[0] & 0x20) { 1233 if (sc->hint_flags & 8) { 1234 /* expose phys. device (daXX) */ 1235 ccb->csio.data_ptr[0] &= 0xdf; 1236 } else { 1237 /* phys. device only visible through pass device (passXX) */ 1238 ccb->csio.data_ptr[0] |= 0x10; 1239 } 1240 } 1241 } else if (ccb->ccb_h.status == CAM_SEL_TIMEOUT && 1242 ccb->ccb_h.target_lun != 0) { 1243 /* fix for INQUIRYs on Lun>0 */ 1244 ccb->ccb_h.status = CAM_DEV_NOT_THERE; 1245 } 1246 } 1247 } 1248 } 1249 1250 aacraid_release_command(cm); 1251 xpt_done(ccb); 1252 } 1253 1254 static u_int32_t 1255 aac_cam_reset_bus(struct cam_sim *sim, union ccb *ccb) 1256 { 1257 struct aac_command *cm; 1258 struct aac_fib *fib; 1259 struct aac_softc *sc; 1260 struct aac_cam *camsc; 1261 struct aac_vmioctl *vmi; 1262 struct aac_resetbus *rbc; 1263 u_int32_t rval; 1264 1265 camsc = (struct aac_cam *)cam_sim_softc(sim); 1266 sc = camsc->inf->aac_sc; 1267 1268 if (sc == NULL) { 1269 printf("aac: Null sc?\n"); 1270 return (CAM_REQ_ABORTED); 1271 } 1272 1273 if (aacraid_alloc_command(sc, &cm)) { 1274 struct aac_event *event; 1275 1276 xpt_freeze_simq(sim, 1); 1277 ccb->ccb_h.status = CAM_RESRC_UNAVAIL; 1278 ccb->ccb_h.sim_priv.entries[0].ptr = camsc; 1279 event = malloc(sizeof(struct aac_event), M_AACRAIDCAM, 1280 M_NOWAIT | M_ZERO); 1281 if (event == NULL) { 1282 device_printf(sc->aac_dev, 1283 "Warning, out of memory for event\n"); 1284 return (CAM_REQ_ABORTED); 1285 } 1286 event->ev_callback = aac_cam_event; 1287 event->ev_arg = ccb; 1288 event->ev_type = AAC_EVENT_CMFREE; 1289 aacraid_add_event(sc, event); 1290 return (CAM_REQ_ABORTED); 1291 } 1292 1293 fib = cm->cm_fib; 1294 cm->cm_timestamp = time_uptime; 1295 cm->cm_datalen = 0; 1296 1297 fib->Header.Size = 1298 sizeof(struct aac_fib_header) + sizeof(struct aac_vmioctl); 1299 fib->Header.XferState = 1300 AAC_FIBSTATE_HOSTOWNED | 1301 AAC_FIBSTATE_INITIALISED | 1302 AAC_FIBSTATE_EMPTY | 1303 AAC_FIBSTATE_FROMHOST | 1304 AAC_FIBSTATE_REXPECTED | 1305 AAC_FIBSTATE_NORM | 1306 AAC_FIBSTATE_ASYNC | 1307 AAC_FIBSTATE_FAST_RESPONSE; 1308 fib->Header.Command = ContainerCommand; 1309 1310 vmi = (struct aac_vmioctl *)&fib->data[0]; 1311 bzero(vmi, sizeof(struct aac_vmioctl)); 1312 1313 vmi->Command = VM_Ioctl; 1314 vmi->ObjType = FT_DRIVE; 1315 vmi->MethId = sc->scsi_method_id; 1316 vmi->ObjId = 0; 1317 vmi->IoctlCmd = ResetBus; 1318 1319 rbc = (struct aac_resetbus *)&vmi->IoctlBuf[0]; 1320 rbc->BusNumber = camsc->inf->BusNumber - 1; 1321 1322 if (aacraid_wait_command(cm) != 0) { 1323 device_printf(sc->aac_dev,"Error sending ResetBus command\n"); 1324 rval = CAM_REQ_ABORTED; 1325 } else { 1326 rval = CAM_REQ_CMP; 1327 } 1328 aacraid_release_command(cm); 1329 return (rval); 1330 } 1331 1332 static u_int32_t 1333 aac_cam_abort_ccb(struct cam_sim *sim, union ccb *ccb) 1334 { 1335 return (CAM_UA_ABORT); 1336 } 1337 1338 static u_int32_t 1339 aac_cam_term_io(struct cam_sim *sim, union ccb *ccb) 1340 { 1341 return (CAM_UA_TERMIO); 1342 } 1343 1344 static int 1345 aac_load_map_command_sg(struct aac_softc *sc, struct aac_command *cm) 1346 { 1347 int error; 1348 1349 fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, ""); 1350 error = bus_dmamap_load(sc->aac_buffer_dmat, 1351 cm->cm_datamap, cm->cm_data, cm->cm_datalen, 1352 aacraid_map_command_sg, cm, 0); 1353 if (error == EINPROGRESS) { 1354 fwprintf(sc, HBA_FLAGS_DBG_INIT_B, "freezing queue\n"); 1355 sc->flags |= AAC_QUEUE_FRZN; 1356 error = 0; 1357 } else if (error != 0) { 1358 panic("aac_load_map_command_sg: unexpected error %d from " 1359 "busdma", error); 1360 } 1361 return(error); 1362 } 1363 1364 /* 1365 * Start as much queued I/O as possible on the controller 1366 */ 1367 void 1368 aacraid_startio(struct aac_softc *sc) 1369 { 1370 struct aac_command *cm; 1371 1372 fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, ""); 1373 1374 for (;;) { 1375 if (sc->aac_state & AAC_STATE_RESET) { 1376 fwprintf(sc, HBA_FLAGS_DBG_ERROR_B, "AAC_STATE_RESET"); 1377 break; 1378 } 1379 /* 1380 * This flag might be set if the card is out of resources. 1381 * Checking it here prevents an infinite loop of deferrals. 1382 */ 1383 if (sc->flags & AAC_QUEUE_FRZN) { 1384 fwprintf(sc, HBA_FLAGS_DBG_ERROR_B, "AAC_QUEUE_FRZN"); 1385 break; 1386 } 1387 1388 /* 1389 * Try to get a command that's been put off for lack of 1390 * resources 1391 */ 1392 if (sc->flags & AAC_FLAGS_SYNC_MODE) { 1393 /* sync. transfer mode */ 1394 if (sc->aac_sync_cm) 1395 break; 1396 cm = aac_dequeue_ready(sc); 1397 sc->aac_sync_cm = cm; 1398 } else { 1399 cm = aac_dequeue_ready(sc); 1400 } 1401 1402 /* nothing to do? */ 1403 if (cm == NULL) 1404 break; 1405 1406 /* don't map more than once */ 1407 if (cm->cm_flags & AAC_CMD_MAPPED) 1408 panic("aac: command %p already mapped", cm); 1409 1410 /* 1411 * Set up the command to go to the controller. If there are no 1412 * data buffers associated with the command then it can bypass 1413 * busdma. 1414 */ 1415 if (cm->cm_datalen) 1416 aac_load_map_command_sg(sc, cm); 1417 else 1418 aacraid_map_command_sg(cm, NULL, 0, 0); 1419 } 1420 } 1421