1 /* 2 * SPDX-License-Identifier: BSD-2-Clause-FreeBSD 3 * 4 * Copyright (c) 2010 LSI Corp. 5 * All rights reserved. 6 * Author : Manjunath Ranganathaiah <manjunath.ranganathaiah@lsi.com> 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 * $FreeBSD$ 30 */ 31 32 #include <dev/tws/tws.h> 33 #include <dev/tws/tws_services.h> 34 #include <dev/tws/tws_hdm.h> 35 #include <dev/tws/tws_user.h> 36 #include <cam/cam.h> 37 #include <cam/cam_ccb.h> 38 #include <cam/cam_sim.h> 39 #include <cam/cam_xpt_sim.h> 40 #include <cam/cam_debug.h> 41 #include <cam/cam_periph.h> 42 43 #include <cam/scsi/scsi_all.h> 44 #include <cam/scsi/scsi_message.h> 45 46 static int tws_cam_depth=(TWS_MAX_REQS - TWS_RESERVED_REQS); 47 static char tws_sev_str[5][8]={"","ERROR","WARNING","INFO","DEBUG"}; 48 49 static void tws_action(struct cam_sim *sim, union ccb *ccb); 50 static void tws_poll(struct cam_sim *sim); 51 static void tws_scsi_complete(struct tws_request *req); 52 53 54 55 void tws_unmap_request(struct tws_softc *sc, struct tws_request *req); 56 int32_t tws_map_request(struct tws_softc *sc, struct tws_request *req); 57 int tws_bus_scan(struct tws_softc *sc); 58 int tws_cam_attach(struct tws_softc *sc); 59 void tws_cam_detach(struct tws_softc *sc); 60 void tws_reset(void *arg); 61 62 static void tws_reset_cb(void *arg); 63 static void tws_reinit(void *arg); 64 static int32_t tws_execute_scsi(struct tws_softc *sc, union ccb *ccb); 65 static void tws_freeze_simq(struct tws_softc *sc, struct tws_request *req); 66 static void tws_dmamap_data_load_cbfn(void *arg, bus_dma_segment_t *segs, 67 int nseg, int error); 68 static void tws_fill_sg_list(struct tws_softc *sc, void *sgl_src, 69 void *sgl_dest, u_int16_t num_sgl_entries); 70 static void tws_err_complete(struct tws_softc *sc, u_int64_t mfa); 71 static void tws_scsi_err_complete(struct tws_request *req, 72 struct tws_command_header *hdr); 73 static void tws_passthru_err_complete(struct tws_request *req, 74 struct tws_command_header *hdr); 75 76 77 void tws_timeout(void *arg); 78 static void tws_intr_attn_aen(struct tws_softc *sc); 79 static void tws_intr_attn_error(struct tws_softc *sc); 80 static void tws_intr_resp(struct tws_softc *sc); 81 void tws_intr(void *arg); 82 void tws_cmd_complete(struct tws_request *req); 83 void tws_aen_complete(struct tws_request *req); 84 int tws_send_scsi_cmd(struct tws_softc *sc, int cmd); 85 void tws_getset_param_complete(struct tws_request *req); 86 int tws_set_param(struct tws_softc *sc, u_int32_t table_id, u_int32_t param_id, 87 u_int32_t param_size, void *data); 88 int tws_get_param(struct tws_softc *sc, u_int32_t table_id, u_int32_t param_id, 89 u_int32_t param_size, void *data); 90 91 92 extern struct tws_request *tws_get_request(struct tws_softc *sc, 93 u_int16_t type); 94 extern void *tws_release_request(struct tws_request *req); 95 extern int tws_submit_command(struct tws_softc *sc, struct tws_request *req); 96 extern boolean tws_get_response(struct tws_softc *sc, 97 u_int16_t *req_id, u_int64_t *mfa); 98 extern void tws_q_insert_tail(struct tws_softc *sc, struct tws_request *req, 99 u_int8_t q_type ); 100 extern struct tws_request * tws_q_remove_request(struct tws_softc *sc, 101 struct tws_request *req, u_int8_t q_type ); 102 extern void tws_send_event(struct tws_softc *sc, u_int8_t event); 103 104 extern struct tws_sense * 105 tws_find_sense_from_mfa(struct tws_softc *sc, u_int64_t mfa); 106 107 extern void tws_fetch_aen(void *arg); 108 extern void tws_disable_db_intr(struct tws_softc *sc); 109 extern void tws_enable_db_intr(struct tws_softc *sc); 110 extern void tws_passthru_complete(struct tws_request *req); 111 extern void tws_aen_synctime_with_host(struct tws_softc *sc); 112 extern void tws_circular_aenq_insert(struct tws_softc *sc, 113 struct tws_circular_q *cq, struct tws_event_packet *aen); 114 extern int tws_use_32bit_sgls; 115 extern boolean tws_ctlr_reset(struct tws_softc *sc); 116 extern struct tws_request * tws_q_remove_tail(struct tws_softc *sc, 117 u_int8_t q_type ); 118 extern void tws_turn_off_interrupts(struct tws_softc *sc); 119 extern void tws_turn_on_interrupts(struct tws_softc *sc); 120 extern int tws_init_connect(struct tws_softc *sc, u_int16_t mc); 121 extern void tws_init_obfl_q(struct tws_softc *sc); 122 extern uint8_t tws_get_state(struct tws_softc *sc); 123 extern void tws_assert_soft_reset(struct tws_softc *sc); 124 extern boolean tws_ctlr_ready(struct tws_softc *sc); 125 extern u_int16_t tws_poll4_response(struct tws_softc *sc, u_int64_t *mfa); 126 extern int tws_setup_intr(struct tws_softc *sc, int irqs); 127 extern int tws_teardown_intr(struct tws_softc *sc); 128 129 130 131 int 132 tws_cam_attach(struct tws_softc *sc) 133 { 134 struct cam_devq *devq; 135 136 TWS_TRACE_DEBUG(sc, "entry", 0, sc); 137 /* Create a device queue for sim */ 138 139 /* 140 * if the user sets cam depth to less than 1 141 * cam may get confused 142 */ 143 if ( tws_cam_depth < 1 ) 144 tws_cam_depth = 1; 145 if ( tws_cam_depth > (tws_queue_depth - TWS_RESERVED_REQS) ) 146 tws_cam_depth = tws_queue_depth - TWS_RESERVED_REQS; 147 148 TWS_TRACE_DEBUG(sc, "depths,ctlr,cam", tws_queue_depth, tws_cam_depth); 149 150 if ((devq = cam_simq_alloc(tws_cam_depth)) == NULL) { 151 tws_log(sc, CAM_SIMQ_ALLOC); 152 return(ENOMEM); 153 } 154 155 /* 156 * Create a SIM entry. Though we can support tws_cam_depth 157 * simultaneous requests, we claim to be able to handle only 158 * (tws_cam_depth), so that we always have reserved requests 159 * packet available to service ioctls and internal commands. 160 */ 161 sc->sim = cam_sim_alloc(tws_action, tws_poll, "tws", sc, 162 device_get_unit(sc->tws_dev), 163 #if (__FreeBSD_version >= 700000) 164 &sc->sim_lock, 165 #endif 166 tws_cam_depth, 1, devq); 167 /* 1, 1, devq); */ 168 if (sc->sim == NULL) { 169 cam_simq_free(devq); 170 tws_log(sc, CAM_SIM_ALLOC); 171 } 172 /* Register the bus. */ 173 mtx_lock(&sc->sim_lock); 174 if (xpt_bus_register(sc->sim, 175 #if (__FreeBSD_version >= 700000) 176 sc->tws_dev, 177 #endif 178 0) != CAM_SUCCESS) { 179 cam_sim_free(sc->sim, TRUE); /* passing true will free the devq */ 180 sc->sim = NULL; /* so cam_detach will not try to free it */ 181 mtx_unlock(&sc->sim_lock); 182 tws_log(sc, TWS_XPT_BUS_REGISTER); 183 return(ENXIO); 184 } 185 if (xpt_create_path(&sc->path, NULL, cam_sim_path(sc->sim), 186 CAM_TARGET_WILDCARD, 187 CAM_LUN_WILDCARD) != CAM_REQ_CMP) { 188 xpt_bus_deregister(cam_sim_path(sc->sim)); 189 /* Passing TRUE to cam_sim_free will free the devq as well. */ 190 cam_sim_free(sc->sim, TRUE); 191 tws_log(sc, TWS_XPT_CREATE_PATH); 192 mtx_unlock(&sc->sim_lock); 193 return(ENXIO); 194 } 195 mtx_unlock(&sc->sim_lock); 196 197 return(0); 198 } 199 200 void 201 tws_cam_detach(struct tws_softc *sc) 202 { 203 TWS_TRACE_DEBUG(sc, "entry", 0, 0); 204 mtx_lock(&sc->sim_lock); 205 if (sc->path) 206 xpt_free_path(sc->path); 207 if (sc->sim) { 208 xpt_bus_deregister(cam_sim_path(sc->sim)); 209 cam_sim_free(sc->sim, TRUE); 210 } 211 mtx_unlock(&sc->sim_lock); 212 } 213 214 int 215 tws_bus_scan(struct tws_softc *sc) 216 { 217 union ccb *ccb; 218 219 TWS_TRACE_DEBUG(sc, "entry", sc, 0); 220 if (!(sc->sim)) 221 return(ENXIO); 222 ccb = xpt_alloc_ccb(); 223 mtx_lock(&sc->sim_lock); 224 if (xpt_create_path(&ccb->ccb_h.path, NULL, cam_sim_path(sc->sim), 225 CAM_TARGET_WILDCARD, CAM_LUN_WILDCARD) != CAM_REQ_CMP) { 226 mtx_unlock(&sc->sim_lock); 227 xpt_free_ccb(ccb); 228 return(EIO); 229 } 230 xpt_rescan(ccb); 231 mtx_unlock(&sc->sim_lock); 232 return(0); 233 } 234 235 static void 236 tws_action(struct cam_sim *sim, union ccb *ccb) 237 { 238 struct tws_softc *sc = (struct tws_softc *)cam_sim_softc(sim); 239 240 241 switch( ccb->ccb_h.func_code ) { 242 case XPT_SCSI_IO: 243 { 244 if ( tws_execute_scsi(sc, ccb) ) 245 TWS_TRACE_DEBUG(sc, "execute scsi failed", 0, 0); 246 break; 247 } 248 case XPT_ABORT: 249 { 250 TWS_TRACE_DEBUG(sc, "abort i/o", 0, 0); 251 ccb->ccb_h.status = CAM_UA_ABORT; 252 xpt_done(ccb); 253 break; 254 } 255 case XPT_RESET_BUS: 256 { 257 TWS_TRACE_DEBUG(sc, "reset bus", sim, ccb); 258 break; 259 } 260 case XPT_SET_TRAN_SETTINGS: 261 { 262 TWS_TRACE_DEBUG(sc, "set tran settings", sim, ccb); 263 ccb->ccb_h.status = CAM_FUNC_NOTAVAIL; 264 xpt_done(ccb); 265 266 break; 267 } 268 case XPT_GET_TRAN_SETTINGS: 269 { 270 TWS_TRACE_DEBUG(sc, "get tran settings", sim, ccb); 271 272 #if (__FreeBSD_version >= 700000 ) 273 ccb->cts.protocol = PROTO_SCSI; 274 ccb->cts.protocol_version = SCSI_REV_2; 275 ccb->cts.transport = XPORT_SPI; 276 ccb->cts.transport_version = 2; 277 278 ccb->cts.xport_specific.spi.valid = CTS_SPI_VALID_DISC; 279 ccb->cts.xport_specific.spi.flags = CTS_SPI_FLAGS_DISC_ENB; 280 ccb->cts.proto_specific.scsi.valid = CTS_SCSI_VALID_TQ; 281 ccb->cts.proto_specific.scsi.flags = CTS_SCSI_FLAGS_TAG_ENB; 282 #else 283 ccb->cts.valid = (CCB_TRANS_DISC_VALID | CCB_TRANS_TQ_VALID); 284 ccb->cts.flags &= ~(CCB_TRANS_DISC_ENB | CCB_TRANS_TAG_ENB); 285 #endif 286 ccb->ccb_h.status = CAM_REQ_CMP; 287 xpt_done(ccb); 288 289 break; 290 } 291 case XPT_CALC_GEOMETRY: 292 { 293 TWS_TRACE_DEBUG(sc, "calc geometry(ccb,block-size)", ccb, 294 ccb->ccg.block_size); 295 cam_calc_geometry(&ccb->ccg, 1/* extended */); 296 xpt_done(ccb); 297 298 break; 299 } 300 case XPT_PATH_INQ: 301 { 302 TWS_TRACE_DEBUG(sc, "path inquiry", sim, ccb); 303 ccb->cpi.version_num = 1; 304 ccb->cpi.hba_inquiry = 0; 305 ccb->cpi.target_sprt = 0; 306 ccb->cpi.hba_misc = 0; 307 ccb->cpi.hba_eng_cnt = 0; 308 ccb->cpi.max_target = TWS_MAX_NUM_UNITS; 309 ccb->cpi.max_lun = TWS_MAX_NUM_LUNS - 1; 310 ccb->cpi.unit_number = cam_sim_unit(sim); 311 ccb->cpi.bus_id = cam_sim_bus(sim); 312 ccb->cpi.initiator_id = TWS_SCSI_INITIATOR_ID; 313 ccb->cpi.base_transfer_speed = 6000000; 314 strlcpy(ccb->cpi.sim_vid, "FreeBSD", SIM_IDLEN); 315 strlcpy(ccb->cpi.hba_vid, "3ware", HBA_IDLEN); 316 strlcpy(ccb->cpi.dev_name, cam_sim_name(sim), DEV_IDLEN); 317 #if (__FreeBSD_version >= 700000 ) 318 ccb->cpi.transport = XPORT_SPI; 319 ccb->cpi.transport_version = 2; 320 ccb->cpi.protocol = PROTO_SCSI; 321 ccb->cpi.protocol_version = SCSI_REV_2; 322 ccb->cpi.maxio = TWS_MAX_IO_SIZE; 323 #endif 324 ccb->ccb_h.status = CAM_REQ_CMP; 325 xpt_done(ccb); 326 327 break; 328 } 329 default: 330 TWS_TRACE_DEBUG(sc, "default", sim, ccb); 331 ccb->ccb_h.status = CAM_REQ_INVALID; 332 xpt_done(ccb); 333 break; 334 } 335 } 336 337 static void 338 tws_scsi_complete(struct tws_request *req) 339 { 340 struct tws_softc *sc = req->sc; 341 342 mtx_lock(&sc->q_lock); 343 tws_q_remove_request(sc, req, TWS_BUSY_Q); 344 mtx_unlock(&sc->q_lock); 345 346 callout_stop(&req->timeout); 347 tws_unmap_request(req->sc, req); 348 349 350 req->ccb_ptr->ccb_h.status = CAM_REQ_CMP; 351 mtx_lock(&sc->sim_lock); 352 xpt_done(req->ccb_ptr); 353 mtx_unlock(&sc->sim_lock); 354 355 mtx_lock(&sc->q_lock); 356 tws_q_insert_tail(sc, req, TWS_FREE_Q); 357 mtx_unlock(&sc->q_lock); 358 } 359 360 void 361 tws_getset_param_complete(struct tws_request *req) 362 { 363 struct tws_softc *sc = req->sc; 364 365 TWS_TRACE_DEBUG(sc, "getset complete", req, req->request_id); 366 367 callout_stop(&req->timeout); 368 tws_unmap_request(sc, req); 369 370 free(req->data, M_TWS); 371 372 req->state = TWS_REQ_STATE_FREE; 373 } 374 375 void 376 tws_aen_complete(struct tws_request *req) 377 { 378 struct tws_softc *sc = req->sc; 379 struct tws_command_header *sense; 380 struct tws_event_packet event; 381 u_int16_t aen_code=0; 382 383 TWS_TRACE_DEBUG(sc, "aen complete", 0, req->request_id); 384 385 callout_stop(&req->timeout); 386 tws_unmap_request(sc, req); 387 388 sense = (struct tws_command_header *)req->data; 389 390 TWS_TRACE_DEBUG(sc,"sense code, key",sense->sense_data[0], 391 sense->sense_data[2]); 392 TWS_TRACE_DEBUG(sc,"sense rid, seve",sense->header_desc.request_id, 393 sense->status_block.res__severity); 394 TWS_TRACE_DEBUG(sc,"sense srcnum, error",sense->status_block.srcnum, 395 sense->status_block.error); 396 TWS_TRACE_DEBUG(sc,"sense shdr, ssense",sense->header_desc.size_header, 397 sense->header_desc.size_sense); 398 399 aen_code = sense->status_block.error; 400 401 switch ( aen_code ) { 402 case TWS_AEN_SYNC_TIME_WITH_HOST : 403 tws_aen_synctime_with_host(sc); 404 break; 405 case TWS_AEN_QUEUE_EMPTY : 406 break; 407 default : 408 bzero(&event, sizeof(struct tws_event_packet)); 409 event.sequence_id = sc->seq_id; 410 event.time_stamp_sec = (u_int32_t)TWS_LOCAL_TIME; 411 event.aen_code = sense->status_block.error; 412 event.severity = sense->status_block.res__severity & 0x7; 413 event.event_src = TWS_SRC_CTRL_EVENT; 414 strcpy(event.severity_str, tws_sev_str[event.severity]); 415 event.retrieved = TWS_AEN_NOT_RETRIEVED; 416 417 bcopy(sense->err_specific_desc, event.parameter_data, 418 TWS_ERROR_SPECIFIC_DESC_LEN); 419 event.parameter_data[TWS_ERROR_SPECIFIC_DESC_LEN - 1] = '\0'; 420 event.parameter_len = (u_int8_t)strlen(event.parameter_data)+1; 421 422 if ( event.parameter_len < TWS_ERROR_SPECIFIC_DESC_LEN ) { 423 event.parameter_len += ((u_int8_t)strlen(event.parameter_data + 424 event.parameter_len) + 1); 425 } 426 427 device_printf(sc->tws_dev, "%s: (0x%02X: 0x%04X): %s: %s\n", 428 event.severity_str, 429 event.event_src, 430 event.aen_code, 431 event.parameter_data + 432 (strlen(event.parameter_data) + 1), 433 event.parameter_data); 434 435 mtx_lock(&sc->gen_lock); 436 tws_circular_aenq_insert(sc, &sc->aen_q, &event); 437 sc->seq_id++; 438 mtx_unlock(&sc->gen_lock); 439 break; 440 441 } 442 443 free(req->data, M_TWS); 444 445 req->state = TWS_REQ_STATE_FREE; 446 447 if ( aen_code != TWS_AEN_QUEUE_EMPTY ) { 448 /* timeout(tws_fetch_aen, sc, 1);*/ 449 sc->stats.num_aens++; 450 tws_fetch_aen((void *)sc); 451 } 452 } 453 454 void 455 tws_cmd_complete(struct tws_request *req) 456 { 457 struct tws_softc *sc = req->sc; 458 459 callout_stop(&req->timeout); 460 tws_unmap_request(sc, req); 461 } 462 463 static void 464 tws_err_complete(struct tws_softc *sc, u_int64_t mfa) 465 { 466 struct tws_command_header *hdr; 467 struct tws_sense *sen; 468 struct tws_request *req; 469 u_int16_t req_id; 470 u_int32_t reg, status; 471 472 if ( !mfa ) { 473 TWS_TRACE_DEBUG(sc, "null mfa", 0, mfa); 474 return; 475 } else { 476 /* lookup the sense */ 477 sen = tws_find_sense_from_mfa(sc, mfa); 478 if ( sen == NULL ) { 479 TWS_TRACE_DEBUG(sc, "found null req", 0, mfa); 480 return; 481 } 482 hdr = sen->hdr; 483 TWS_TRACE_DEBUG(sc, "sen, hdr", sen, hdr); 484 req_id = hdr->header_desc.request_id; 485 req = &sc->reqs[req_id]; 486 TWS_TRACE_DEBUG(sc, "req, id", req, req_id); 487 if ( req->error_code != TWS_REQ_RET_SUBMIT_SUCCESS ) 488 TWS_TRACE_DEBUG(sc, "submit failure?", 0, req->error_code); 489 } 490 491 switch (req->type) { 492 case TWS_REQ_TYPE_PASSTHRU : 493 tws_passthru_err_complete(req, hdr); 494 break; 495 case TWS_REQ_TYPE_GETSET_PARAM : 496 tws_getset_param_complete(req); 497 break; 498 case TWS_REQ_TYPE_SCSI_IO : 499 tws_scsi_err_complete(req, hdr); 500 break; 501 502 } 503 504 mtx_lock(&sc->io_lock); 505 hdr->header_desc.size_header = 128; 506 reg = (u_int32_t)( mfa>>32); 507 tws_write_reg(sc, TWS_I2O0_HOBQPH, reg, 4); 508 reg = (u_int32_t)(mfa); 509 tws_write_reg(sc, TWS_I2O0_HOBQPL, reg, 4); 510 511 status = tws_read_reg(sc, TWS_I2O0_STATUS, 4); 512 if ( status & TWS_BIT13 ) { 513 device_printf(sc->tws_dev, "OBFL Overrun\n"); 514 sc->obfl_q_overrun = true; 515 } 516 mtx_unlock(&sc->io_lock); 517 } 518 519 static void 520 tws_scsi_err_complete(struct tws_request *req, struct tws_command_header *hdr) 521 { 522 u_int8_t *sense_data; 523 struct tws_softc *sc = req->sc; 524 union ccb *ccb = req->ccb_ptr; 525 526 TWS_TRACE_DEBUG(sc, "sbe, cmd_status", hdr->status_block.error, 527 req->cmd_pkt->cmd.pkt_a.status); 528 if ( hdr->status_block.error == TWS_ERROR_LOGICAL_UNIT_NOT_SUPPORTED || 529 hdr->status_block.error == TWS_ERROR_UNIT_OFFLINE ) { 530 531 if ( ccb->ccb_h.target_lun ) { 532 TWS_TRACE_DEBUG(sc, "invalid lun error",0,0); 533 ccb->ccb_h.status |= CAM_DEV_NOT_THERE; 534 } else { 535 TWS_TRACE_DEBUG(sc, "invalid target error",0,0); 536 ccb->ccb_h.status |= CAM_SEL_TIMEOUT; 537 } 538 539 } else { 540 TWS_TRACE_DEBUG(sc, "scsi status error",0,0); 541 ccb->ccb_h.status |= CAM_SCSI_STATUS_ERROR; 542 if (((ccb->csio.cdb_io.cdb_bytes[0] == 0x1A) && 543 (hdr->status_block.error == TWS_ERROR_NOT_SUPPORTED))) { 544 ccb->ccb_h.status |= CAM_SCSI_STATUS_ERROR | CAM_AUTOSNS_VALID; 545 TWS_TRACE_DEBUG(sc, "page mode not supported",0,0); 546 } 547 } 548 549 /* if there were no error simply mark complete error */ 550 if (ccb->ccb_h.status == 0) 551 ccb->ccb_h.status = CAM_REQ_CMP_ERR; 552 553 sense_data = (u_int8_t *)&ccb->csio.sense_data; 554 if (sense_data) { 555 memcpy(sense_data, hdr->sense_data, TWS_SENSE_DATA_LENGTH ); 556 ccb->csio.sense_len = TWS_SENSE_DATA_LENGTH; 557 ccb->ccb_h.status |= CAM_AUTOSNS_VALID; 558 } 559 ccb->csio.scsi_status = req->cmd_pkt->cmd.pkt_a.status; 560 561 ccb->ccb_h.status &= ~CAM_SIM_QUEUED; 562 mtx_lock(&sc->sim_lock); 563 xpt_done(ccb); 564 mtx_unlock(&sc->sim_lock); 565 566 callout_stop(&req->timeout); 567 tws_unmap_request(req->sc, req); 568 mtx_lock(&sc->q_lock); 569 tws_q_remove_request(sc, req, TWS_BUSY_Q); 570 tws_q_insert_tail(sc, req, TWS_FREE_Q); 571 mtx_unlock(&sc->q_lock); 572 } 573 574 static void 575 tws_passthru_err_complete(struct tws_request *req, 576 struct tws_command_header *hdr) 577 { 578 TWS_TRACE_DEBUG(req->sc, "entry", hdr, req->request_id); 579 req->error_code = hdr->status_block.error; 580 memcpy(&(req->cmd_pkt->hdr), hdr, sizeof(struct tws_command_header)); 581 tws_passthru_complete(req); 582 } 583 584 static void 585 tws_drain_busy_queue(struct tws_softc *sc) 586 { 587 struct tws_request *req; 588 union ccb *ccb; 589 TWS_TRACE_DEBUG(sc, "entry", 0, 0); 590 591 mtx_lock(&sc->q_lock); 592 req = tws_q_remove_tail(sc, TWS_BUSY_Q); 593 mtx_unlock(&sc->q_lock); 594 while ( req ) { 595 TWS_TRACE_DEBUG(sc, "moved to TWS_COMPLETE_Q", 0, req->request_id); 596 callout_stop(&req->timeout); 597 598 req->error_code = TWS_REQ_RET_RESET; 599 ccb = (union ccb *)(req->ccb_ptr); 600 601 ccb->ccb_h.status &= ~CAM_SIM_QUEUED; 602 ccb->ccb_h.status |= CAM_REQUEUE_REQ; 603 ccb->ccb_h.status |= CAM_SCSI_BUS_RESET; 604 605 tws_unmap_request(req->sc, req); 606 607 mtx_lock(&sc->sim_lock); 608 xpt_done(req->ccb_ptr); 609 mtx_unlock(&sc->sim_lock); 610 611 mtx_lock(&sc->q_lock); 612 tws_q_insert_tail(sc, req, TWS_FREE_Q); 613 req = tws_q_remove_tail(sc, TWS_BUSY_Q); 614 mtx_unlock(&sc->q_lock); 615 } 616 } 617 618 619 static void 620 tws_drain_reserved_reqs(struct tws_softc *sc) 621 { 622 struct tws_request *r; 623 624 r = &sc->reqs[TWS_REQ_TYPE_AEN_FETCH]; 625 if ( r->state != TWS_REQ_STATE_FREE ) { 626 TWS_TRACE_DEBUG(sc, "reset aen req", 0, 0); 627 callout_stop(&r->timeout); 628 tws_unmap_request(sc, r); 629 free(r->data, M_TWS); 630 r->state = TWS_REQ_STATE_FREE; 631 r->error_code = TWS_REQ_RET_RESET; 632 } 633 634 r = &sc->reqs[TWS_REQ_TYPE_PASSTHRU]; 635 if ( r->state == TWS_REQ_STATE_BUSY ) { 636 TWS_TRACE_DEBUG(sc, "reset passthru req", 0, 0); 637 r->error_code = TWS_REQ_RET_RESET; 638 } 639 640 r = &sc->reqs[TWS_REQ_TYPE_GETSET_PARAM]; 641 if ( r->state != TWS_REQ_STATE_FREE ) { 642 TWS_TRACE_DEBUG(sc, "reset setparam req", 0, 0); 643 callout_stop(&r->timeout); 644 tws_unmap_request(sc, r); 645 free(r->data, M_TWS); 646 r->state = TWS_REQ_STATE_FREE; 647 r->error_code = TWS_REQ_RET_RESET; 648 } 649 } 650 651 static void 652 tws_drain_response_queue(struct tws_softc *sc) 653 { 654 u_int16_t req_id; 655 u_int64_t mfa; 656 while ( tws_get_response(sc, &req_id, &mfa) ); 657 } 658 659 660 static int32_t 661 tws_execute_scsi(struct tws_softc *sc, union ccb *ccb) 662 { 663 struct tws_command_packet *cmd_pkt; 664 struct tws_request *req; 665 struct ccb_hdr *ccb_h = &(ccb->ccb_h); 666 struct ccb_scsiio *csio = &(ccb->csio); 667 int error; 668 u_int16_t lun; 669 670 mtx_assert(&sc->sim_lock, MA_OWNED); 671 if (ccb_h->target_id >= TWS_MAX_NUM_UNITS) { 672 TWS_TRACE_DEBUG(sc, "traget id too big", ccb_h->target_id, ccb_h->target_lun); 673 ccb_h->status |= CAM_TID_INVALID; 674 xpt_done(ccb); 675 return(0); 676 } 677 if (ccb_h->target_lun >= TWS_MAX_NUM_LUNS) { 678 TWS_TRACE_DEBUG(sc, "target lun 2 big", ccb_h->target_id, ccb_h->target_lun); 679 ccb_h->status |= CAM_LUN_INVALID; 680 xpt_done(ccb); 681 return(0); 682 } 683 684 if(ccb_h->flags & CAM_CDB_PHYS) { 685 TWS_TRACE_DEBUG(sc, "cdb phy", ccb_h->target_id, ccb_h->target_lun); 686 ccb_h->status = CAM_REQ_INVALID; 687 xpt_done(ccb); 688 return(0); 689 } 690 691 /* 692 * We are going to work on this request. Mark it as enqueued (though 693 * we don't actually queue it...) 694 */ 695 ccb_h->status |= CAM_SIM_QUEUED; 696 697 req = tws_get_request(sc, TWS_REQ_TYPE_SCSI_IO); 698 if ( !req ) { 699 TWS_TRACE_DEBUG(sc, "no reqs", ccb_h->target_id, ccb_h->target_lun); 700 ccb_h->status |= CAM_REQUEUE_REQ; 701 xpt_done(ccb); 702 return(0); 703 } 704 705 if((ccb_h->flags & CAM_DIR_MASK) != CAM_DIR_NONE) { 706 if(ccb_h->flags & CAM_DIR_IN) 707 req->flags |= TWS_DIR_IN; 708 if(ccb_h->flags & CAM_DIR_OUT) 709 req->flags |= TWS_DIR_OUT; 710 } else { 711 req->flags = TWS_DIR_NONE; /* no data */ 712 } 713 714 req->type = TWS_REQ_TYPE_SCSI_IO; 715 req->cb = tws_scsi_complete; 716 717 cmd_pkt = req->cmd_pkt; 718 /* cmd_pkt->hdr.header_desc.size_header = 128; */ 719 cmd_pkt->cmd.pkt_a.res__opcode = TWS_FW_CMD_EXECUTE_SCSI; 720 cmd_pkt->cmd.pkt_a.unit = ccb_h->target_id; 721 cmd_pkt->cmd.pkt_a.status = 0; 722 cmd_pkt->cmd.pkt_a.sgl_offset = 16; 723 724 /* lower nibble */ 725 lun = ccb_h->target_lun & 0XF; 726 lun = lun << 12; 727 cmd_pkt->cmd.pkt_a.lun_l4__req_id = lun | req->request_id; 728 /* upper nibble */ 729 lun = ccb_h->target_lun & 0XF0; 730 lun = lun << 8; 731 cmd_pkt->cmd.pkt_a.lun_h4__sgl_entries = lun; 732 733 #ifdef TWS_DEBUG 734 if ( csio->cdb_len > 16 ) 735 TWS_TRACE(sc, "cdb len too big", ccb_h->target_id, csio->cdb_len); 736 #endif 737 738 if(ccb_h->flags & CAM_CDB_POINTER) 739 bcopy(csio->cdb_io.cdb_ptr, cmd_pkt->cmd.pkt_a.cdb, csio->cdb_len); 740 else 741 bcopy(csio->cdb_io.cdb_bytes, cmd_pkt->cmd.pkt_a.cdb, csio->cdb_len); 742 743 req->data = ccb; 744 req->flags |= TWS_DATA_CCB; 745 /* save ccb ptr */ 746 req->ccb_ptr = ccb; 747 /* 748 * tws_map_load_data_callback will fill in the SGL, 749 * and submit the I/O. 750 */ 751 sc->stats.scsi_ios++; 752 callout_reset_sbt(&req->timeout, SBT_1MS * ccb->ccb_h.timeout, 0, 753 tws_timeout, req, 0); 754 error = tws_map_request(sc, req); 755 return(error); 756 } 757 758 759 int 760 tws_send_scsi_cmd(struct tws_softc *sc, int cmd) 761 { 762 struct tws_request *req; 763 struct tws_command_packet *cmd_pkt; 764 int error; 765 766 TWS_TRACE_DEBUG(sc, "entry",sc, cmd); 767 req = tws_get_request(sc, TWS_REQ_TYPE_AEN_FETCH); 768 769 if ( req == NULL ) 770 return(ENOMEM); 771 772 req->cb = tws_aen_complete; 773 774 cmd_pkt = req->cmd_pkt; 775 cmd_pkt->cmd.pkt_a.res__opcode = TWS_FW_CMD_EXECUTE_SCSI; 776 cmd_pkt->cmd.pkt_a.status = 0; 777 cmd_pkt->cmd.pkt_a.unit = 0; 778 cmd_pkt->cmd.pkt_a.sgl_offset = 16; 779 cmd_pkt->cmd.pkt_a.lun_l4__req_id = req->request_id; 780 781 cmd_pkt->cmd.pkt_a.cdb[0] = (u_int8_t)cmd; 782 cmd_pkt->cmd.pkt_a.cdb[4] = 128; 783 784 req->length = TWS_SECTOR_SIZE; 785 req->data = malloc(TWS_SECTOR_SIZE, M_TWS, M_NOWAIT); 786 if ( req->data == NULL ) 787 return(ENOMEM); 788 bzero(req->data, TWS_SECTOR_SIZE); 789 req->flags = TWS_DIR_IN; 790 791 callout_reset(&req->timeout, (TWS_IO_TIMEOUT * hz), tws_timeout, req); 792 error = tws_map_request(sc, req); 793 return(error); 794 795 } 796 797 int 798 tws_set_param(struct tws_softc *sc, u_int32_t table_id, u_int32_t param_id, 799 u_int32_t param_size, void *data) 800 { 801 struct tws_request *req; 802 struct tws_command_packet *cmd_pkt; 803 union tws_command_giga *cmd; 804 struct tws_getset_param *param; 805 int error; 806 807 req = tws_get_request(sc, TWS_REQ_TYPE_GETSET_PARAM); 808 if ( req == NULL ) { 809 TWS_TRACE_DEBUG(sc, "null req", 0, 0); 810 return(ENOMEM); 811 } 812 813 req->length = TWS_SECTOR_SIZE; 814 req->data = malloc(TWS_SECTOR_SIZE, M_TWS, M_NOWAIT); 815 if ( req->data == NULL ) 816 return(ENOMEM); 817 bzero(req->data, TWS_SECTOR_SIZE); 818 param = (struct tws_getset_param *)req->data; 819 820 req->cb = tws_getset_param_complete; 821 req->flags = TWS_DIR_OUT; 822 cmd_pkt = req->cmd_pkt; 823 824 cmd = &cmd_pkt->cmd.pkt_g; 825 cmd->param.sgl_off__opcode = 826 BUILD_SGL_OFF__OPCODE(2, TWS_FW_CMD_SET_PARAM); 827 cmd->param.request_id = (u_int8_t)req->request_id; 828 cmd->param.host_id__unit = 0; 829 cmd->param.param_count = 1; 830 cmd->param.size = 2; /* map routine will add sgls */ 831 832 /* Specify which parameter we want to set. */ 833 param->table_id = (table_id | TWS_9K_PARAM_DESCRIPTOR); 834 param->parameter_id = (u_int8_t)(param_id); 835 param->parameter_size_bytes = (u_int16_t)param_size; 836 memcpy(param->data, data, param_size); 837 838 callout_reset(&req->timeout, (TWS_IOCTL_TIMEOUT * hz), tws_timeout, req); 839 error = tws_map_request(sc, req); 840 return(error); 841 842 } 843 844 int 845 tws_get_param(struct tws_softc *sc, u_int32_t table_id, u_int32_t param_id, 846 u_int32_t param_size, void *data) 847 { 848 struct tws_request *req; 849 struct tws_command_packet *cmd_pkt; 850 union tws_command_giga *cmd; 851 struct tws_getset_param *param; 852 u_int16_t reqid; 853 u_int64_t mfa; 854 int error = SUCCESS; 855 856 857 req = tws_get_request(sc, TWS_REQ_TYPE_GETSET_PARAM); 858 if ( req == NULL ) { 859 TWS_TRACE_DEBUG(sc, "null req", 0, 0); 860 return(FAILURE); 861 } 862 863 req->length = TWS_SECTOR_SIZE; 864 req->data = malloc(TWS_SECTOR_SIZE, M_TWS, M_NOWAIT); 865 if ( req->data == NULL ) 866 return(FAILURE); 867 bzero(req->data, TWS_SECTOR_SIZE); 868 param = (struct tws_getset_param *)req->data; 869 870 req->cb = NULL; 871 req->flags = TWS_DIR_IN; 872 cmd_pkt = req->cmd_pkt; 873 874 cmd = &cmd_pkt->cmd.pkt_g; 875 cmd->param.sgl_off__opcode = 876 BUILD_SGL_OFF__OPCODE(2, TWS_FW_CMD_GET_PARAM); 877 cmd->param.request_id = (u_int8_t)req->request_id; 878 cmd->param.host_id__unit = 0; 879 cmd->param.param_count = 1; 880 cmd->param.size = 2; /* map routine will add sgls */ 881 882 /* Specify which parameter we want to set. */ 883 param->table_id = (table_id | TWS_9K_PARAM_DESCRIPTOR); 884 param->parameter_id = (u_int8_t)(param_id); 885 param->parameter_size_bytes = (u_int16_t)param_size; 886 887 error = tws_map_request(sc, req); 888 if (!error) { 889 reqid = tws_poll4_response(sc, &mfa); 890 tws_unmap_request(sc, req); 891 892 if ( reqid == TWS_REQ_TYPE_GETSET_PARAM ) { 893 memcpy(data, param->data, param_size); 894 } else { 895 error = FAILURE; 896 } 897 } 898 899 free(req->data, M_TWS); 900 req->state = TWS_REQ_STATE_FREE; 901 return(error); 902 903 } 904 905 void 906 tws_unmap_request(struct tws_softc *sc, struct tws_request *req) 907 { 908 if (req->data != NULL) { 909 if ( req->flags & TWS_DIR_IN ) 910 bus_dmamap_sync(sc->data_tag, req->dma_map, 911 BUS_DMASYNC_POSTREAD); 912 if ( req->flags & TWS_DIR_OUT ) 913 bus_dmamap_sync(sc->data_tag, req->dma_map, 914 BUS_DMASYNC_POSTWRITE); 915 mtx_lock(&sc->io_lock); 916 bus_dmamap_unload(sc->data_tag, req->dma_map); 917 mtx_unlock(&sc->io_lock); 918 } 919 } 920 921 int32_t 922 tws_map_request(struct tws_softc *sc, struct tws_request *req) 923 { 924 int32_t error = 0; 925 926 927 /* If the command involves data, map that too. */ 928 if (req->data != NULL) { 929 int my_flags = ((req->type == TWS_REQ_TYPE_SCSI_IO) ? BUS_DMA_WAITOK : BUS_DMA_NOWAIT); 930 931 /* 932 * Map the data buffer into bus space and build the SG list. 933 */ 934 mtx_lock(&sc->io_lock); 935 if (req->flags & TWS_DATA_CCB) 936 error = bus_dmamap_load_ccb(sc->data_tag, req->dma_map, 937 req->data, 938 tws_dmamap_data_load_cbfn, req, 939 my_flags); 940 else 941 error = bus_dmamap_load(sc->data_tag, req->dma_map, 942 req->data, req->length, 943 tws_dmamap_data_load_cbfn, req, 944 my_flags); 945 mtx_unlock(&sc->io_lock); 946 947 if (error == EINPROGRESS) { 948 TWS_TRACE(sc, "in progress", 0, error); 949 tws_freeze_simq(sc, req); 950 error = 0; // EINPROGRESS is not a fatal error. 951 } 952 } else { /* no data involved */ 953 error = tws_submit_command(sc, req); 954 } 955 return(error); 956 } 957 958 959 static void 960 tws_dmamap_data_load_cbfn(void *arg, bus_dma_segment_t *segs, 961 int nseg, int error) 962 { 963 struct tws_request *req = (struct tws_request *)arg; 964 struct tws_softc *sc = req->sc; 965 u_int16_t sgls = nseg; 966 void *sgl_ptr; 967 struct tws_cmd_generic *gcmd; 968 969 970 if ( error ) { 971 TWS_TRACE(sc, "SOMETHING BAD HAPPENED! error = %d\n", error, 0); 972 } 973 974 if ( error == EFBIG ) { 975 TWS_TRACE(sc, "not enough data segs", 0, nseg); 976 req->error_code = error; 977 req->ccb_ptr->ccb_h.status = CAM_REQ_TOO_BIG; 978 return; 979 } 980 981 if ( req->flags & TWS_DIR_IN ) 982 bus_dmamap_sync(req->sc->data_tag, req->dma_map, 983 BUS_DMASYNC_PREREAD); 984 if ( req->flags & TWS_DIR_OUT ) 985 bus_dmamap_sync(req->sc->data_tag, req->dma_map, 986 BUS_DMASYNC_PREWRITE); 987 if ( segs ) { 988 if ( (req->type == TWS_REQ_TYPE_PASSTHRU && 989 GET_OPCODE(req->cmd_pkt->cmd.pkt_a.res__opcode) != 990 TWS_FW_CMD_EXECUTE_SCSI) || 991 req->type == TWS_REQ_TYPE_GETSET_PARAM) { 992 gcmd = &req->cmd_pkt->cmd.pkt_g.generic; 993 sgl_ptr = (u_int32_t *)(gcmd) + gcmd->size; 994 gcmd->size += sgls * 995 ((req->sc->is64bit && !tws_use_32bit_sgls) ? 4 : 2 ); 996 tws_fill_sg_list(req->sc, (void *)segs, sgl_ptr, sgls); 997 998 } else { 999 tws_fill_sg_list(req->sc, (void *)segs, 1000 (void *)&(req->cmd_pkt->cmd.pkt_a.sg_list), sgls); 1001 req->cmd_pkt->cmd.pkt_a.lun_h4__sgl_entries |= sgls ; 1002 } 1003 } 1004 1005 1006 req->error_code = tws_submit_command(req->sc, req); 1007 1008 } 1009 1010 1011 static void 1012 tws_fill_sg_list(struct tws_softc *sc, void *sgl_src, void *sgl_dest, 1013 u_int16_t num_sgl_entries) 1014 { 1015 int i; 1016 1017 if ( sc->is64bit ) { 1018 struct tws_sg_desc64 *sgl_s = (struct tws_sg_desc64 *)sgl_src; 1019 1020 if ( !tws_use_32bit_sgls ) { 1021 struct tws_sg_desc64 *sgl_d = (struct tws_sg_desc64 *)sgl_dest; 1022 if ( num_sgl_entries > TWS_MAX_64BIT_SG_ELEMENTS ) 1023 TWS_TRACE(sc, "64bit sg overflow", num_sgl_entries, 0); 1024 for (i = 0; i < num_sgl_entries; i++) { 1025 sgl_d[i].address = sgl_s->address; 1026 sgl_d[i].length = sgl_s->length; 1027 sgl_d[i].flag = 0; 1028 sgl_d[i].reserved = 0; 1029 sgl_s = (struct tws_sg_desc64 *) (((u_int8_t *)sgl_s) + 1030 sizeof(bus_dma_segment_t)); 1031 } 1032 } else { 1033 struct tws_sg_desc32 *sgl_d = (struct tws_sg_desc32 *)sgl_dest; 1034 if ( num_sgl_entries > TWS_MAX_32BIT_SG_ELEMENTS ) 1035 TWS_TRACE(sc, "32bit sg overflow", num_sgl_entries, 0); 1036 for (i = 0; i < num_sgl_entries; i++) { 1037 sgl_d[i].address = sgl_s->address; 1038 sgl_d[i].length = sgl_s->length; 1039 sgl_d[i].flag = 0; 1040 sgl_s = (struct tws_sg_desc64 *) (((u_int8_t *)sgl_s) + 1041 sizeof(bus_dma_segment_t)); 1042 } 1043 } 1044 } else { 1045 struct tws_sg_desc32 *sgl_s = (struct tws_sg_desc32 *)sgl_src; 1046 struct tws_sg_desc32 *sgl_d = (struct tws_sg_desc32 *)sgl_dest; 1047 1048 if ( num_sgl_entries > TWS_MAX_32BIT_SG_ELEMENTS ) 1049 TWS_TRACE(sc, "32bit sg overflow", num_sgl_entries, 0); 1050 1051 1052 for (i = 0; i < num_sgl_entries; i++) { 1053 sgl_d[i].address = sgl_s[i].address; 1054 sgl_d[i].length = sgl_s[i].length; 1055 sgl_d[i].flag = 0; 1056 } 1057 } 1058 } 1059 1060 1061 void 1062 tws_intr(void *arg) 1063 { 1064 struct tws_softc *sc = (struct tws_softc *)arg; 1065 u_int32_t histat=0, db=0; 1066 1067 if (!(sc)) { 1068 device_printf(sc->tws_dev, "null softc!!!\n"); 1069 return; 1070 } 1071 1072 if ( tws_get_state(sc) == TWS_RESET ) { 1073 return; 1074 } 1075 1076 if ( tws_get_state(sc) != TWS_ONLINE ) { 1077 return; 1078 } 1079 1080 sc->stats.num_intrs++; 1081 histat = tws_read_reg(sc, TWS_I2O0_HISTAT, 4); 1082 if ( histat & TWS_BIT2 ) { 1083 TWS_TRACE_DEBUG(sc, "door bell :)", histat, TWS_I2O0_HISTAT); 1084 db = tws_read_reg(sc, TWS_I2O0_IOBDB, 4); 1085 if ( db & TWS_BIT21 ) { 1086 tws_intr_attn_error(sc); 1087 return; 1088 } 1089 if ( db & TWS_BIT18 ) { 1090 tws_intr_attn_aen(sc); 1091 } 1092 } 1093 1094 if ( histat & TWS_BIT3 ) { 1095 tws_intr_resp(sc); 1096 } 1097 } 1098 1099 static void 1100 tws_intr_attn_aen(struct tws_softc *sc) 1101 { 1102 u_int32_t db=0; 1103 1104 /* maskoff db intrs until all the aens are fetched */ 1105 /* tws_disable_db_intr(sc); */ 1106 tws_fetch_aen((void *)sc); 1107 tws_write_reg(sc, TWS_I2O0_HOBDBC, TWS_BIT18, 4); 1108 db = tws_read_reg(sc, TWS_I2O0_IOBDB, 4); 1109 1110 } 1111 1112 static void 1113 tws_intr_attn_error(struct tws_softc *sc) 1114 { 1115 u_int32_t db=0; 1116 1117 TWS_TRACE(sc, "attn error", 0, 0); 1118 tws_write_reg(sc, TWS_I2O0_HOBDBC, ~0, 4); 1119 db = tws_read_reg(sc, TWS_I2O0_IOBDB, 4); 1120 device_printf(sc->tws_dev, "Micro controller error.\n"); 1121 tws_reset(sc); 1122 } 1123 1124 static void 1125 tws_intr_resp(struct tws_softc *sc) 1126 { 1127 u_int16_t req_id; 1128 u_int64_t mfa; 1129 1130 while ( tws_get_response(sc, &req_id, &mfa) ) { 1131 sc->stats.reqs_out++; 1132 if ( req_id == TWS_INVALID_REQID ) { 1133 TWS_TRACE_DEBUG(sc, "invalid req_id", mfa, req_id); 1134 sc->stats.reqs_errored++; 1135 tws_err_complete(sc, mfa); 1136 continue; 1137 } 1138 sc->reqs[req_id].cb(&sc->reqs[req_id]); 1139 } 1140 1141 } 1142 1143 1144 static void 1145 tws_poll(struct cam_sim *sim) 1146 { 1147 struct tws_softc *sc = (struct tws_softc *)cam_sim_softc(sim); 1148 TWS_TRACE_DEBUG(sc, "entry", 0, 0); 1149 tws_intr((void *) sc); 1150 } 1151 1152 void 1153 tws_timeout(void *arg) 1154 { 1155 struct tws_request *req = (struct tws_request *)arg; 1156 struct tws_softc *sc = req->sc; 1157 1158 1159 if ( req->error_code == TWS_REQ_RET_RESET ) { 1160 return; 1161 } 1162 1163 mtx_lock(&sc->gen_lock); 1164 if ( req->error_code == TWS_REQ_RET_RESET ) { 1165 mtx_unlock(&sc->gen_lock); 1166 return; 1167 } 1168 1169 if ( tws_get_state(sc) == TWS_RESET ) { 1170 mtx_unlock(&sc->gen_lock); 1171 return; 1172 } 1173 1174 xpt_freeze_simq(sc->sim, 1); 1175 1176 tws_send_event(sc, TWS_RESET_START); 1177 1178 if (req->type == TWS_REQ_TYPE_SCSI_IO) { 1179 device_printf(sc->tws_dev, "I/O Request timed out... Resetting controller\n"); 1180 } else if (req->type == TWS_REQ_TYPE_PASSTHRU) { 1181 device_printf(sc->tws_dev, "IOCTL Request timed out... Resetting controller\n"); 1182 } else { 1183 device_printf(sc->tws_dev, "Internal Request timed out... Resetting controller\n"); 1184 } 1185 1186 tws_assert_soft_reset(sc); 1187 tws_turn_off_interrupts(sc); 1188 tws_reset_cb( (void*) sc ); 1189 tws_reinit( (void*) sc ); 1190 1191 // device_printf(sc->tws_dev, "Controller Reset complete!\n"); 1192 tws_send_event(sc, TWS_RESET_COMPLETE); 1193 mtx_unlock(&sc->gen_lock); 1194 1195 xpt_release_simq(sc->sim, 1); 1196 } 1197 1198 void 1199 tws_reset(void *arg) 1200 { 1201 struct tws_softc *sc = (struct tws_softc *)arg; 1202 1203 mtx_lock(&sc->gen_lock); 1204 if ( tws_get_state(sc) == TWS_RESET ) { 1205 mtx_unlock(&sc->gen_lock); 1206 return; 1207 } 1208 1209 xpt_freeze_simq(sc->sim, 1); 1210 1211 tws_send_event(sc, TWS_RESET_START); 1212 1213 device_printf(sc->tws_dev, "Resetting controller\n"); 1214 1215 tws_assert_soft_reset(sc); 1216 tws_turn_off_interrupts(sc); 1217 tws_reset_cb( (void*) sc ); 1218 tws_reinit( (void*) sc ); 1219 1220 // device_printf(sc->tws_dev, "Controller Reset complete!\n"); 1221 tws_send_event(sc, TWS_RESET_COMPLETE); 1222 mtx_unlock(&sc->gen_lock); 1223 1224 xpt_release_simq(sc->sim, 1); 1225 } 1226 1227 static void 1228 tws_reset_cb(void *arg) 1229 { 1230 struct tws_softc *sc = (struct tws_softc *)arg; 1231 time_t endt; 1232 int found = 0; 1233 u_int32_t reg; 1234 1235 if ( tws_get_state(sc) != TWS_RESET ) { 1236 return; 1237 } 1238 1239 // device_printf(sc->tws_dev, "Draining Busy Queue\n"); 1240 tws_drain_busy_queue(sc); 1241 // device_printf(sc->tws_dev, "Draining Reserved Reqs\n"); 1242 tws_drain_reserved_reqs(sc); 1243 // device_printf(sc->tws_dev, "Draining Response Queue\n"); 1244 tws_drain_response_queue(sc); 1245 1246 // device_printf(sc->tws_dev, "Looking for controller ready flag...\n"); 1247 endt = TWS_LOCAL_TIME + TWS_POLL_TIMEOUT; 1248 while ((TWS_LOCAL_TIME <= endt) && (!found)) { 1249 reg = tws_read_reg(sc, TWS_I2O0_SCRPD3, 4); 1250 if ( reg & TWS_BIT13 ) { 1251 found = 1; 1252 // device_printf(sc->tws_dev, " ... Got it!\n"); 1253 } 1254 } 1255 if ( !found ) 1256 device_printf(sc->tws_dev, " ... Controller ready flag NOT found!\n"); 1257 } 1258 1259 static void 1260 tws_reinit(void *arg) 1261 { 1262 struct tws_softc *sc = (struct tws_softc *)arg; 1263 int timeout_val=0; 1264 int try=2; 1265 int done=0; 1266 1267 1268 // device_printf(sc->tws_dev, "Waiting for Controller Ready\n"); 1269 while ( !done && try ) { 1270 if ( tws_ctlr_ready(sc) ) { 1271 done = 1; 1272 break; 1273 } else { 1274 timeout_val += 5; 1275 if ( timeout_val >= TWS_RESET_TIMEOUT ) { 1276 timeout_val = 0; 1277 if ( try ) 1278 tws_assert_soft_reset(sc); 1279 try--; 1280 } 1281 mtx_sleep(sc, &sc->gen_lock, 0, "tws_reinit", 5*hz); 1282 } 1283 } 1284 1285 if (!done) { 1286 device_printf(sc->tws_dev, "FAILED to get Controller Ready!\n"); 1287 return; 1288 } 1289 1290 sc->obfl_q_overrun = false; 1291 // device_printf(sc->tws_dev, "Sending initConnect\n"); 1292 if ( tws_init_connect(sc, tws_queue_depth) ) { 1293 TWS_TRACE_DEBUG(sc, "initConnect failed", 0, sc->is64bit); 1294 } 1295 tws_init_obfl_q(sc); 1296 1297 tws_turn_on_interrupts(sc); 1298 1299 wakeup_one(sc); 1300 } 1301 1302 1303 static void 1304 tws_freeze_simq(struct tws_softc *sc, struct tws_request *req) 1305 { 1306 /* Only for IO commands */ 1307 if (req->type == TWS_REQ_TYPE_SCSI_IO) { 1308 union ccb *ccb = (union ccb *)(req->ccb_ptr); 1309 1310 xpt_freeze_simq(sc->sim, 1); 1311 ccb->ccb_h.status |= CAM_RELEASE_SIMQ; 1312 ccb->ccb_h.status |= CAM_REQUEUE_REQ; 1313 } 1314 } 1315 1316 1317 TUNABLE_INT("hw.tws.cam_depth", &tws_cam_depth); 1318