twe.c revision 91449
1/*- 2 * Copyright (c) 2000 Michael Smith 3 * Copyright (c) 2000 BSDi 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25 * SUCH DAMAGE. 26 * 27 * $FreeBSD: head/sys/dev/twe/twe.c 91449 2002-02-27 23:59:35Z peter $ 28 */ 29 30/* 31 * Driver for the 3ware Escalade family of IDE RAID controllers. 32 */ 33 34#include <dev/twe/twe_compat.h> 35#include <dev/twe/twereg.h> 36#include <dev/twe/tweio.h> 37#include <dev/twe/twevar.h> 38#define TWE_DEFINE_TABLES 39#include <dev/twe/twe_tables.h> 40 41/* 42 * Command submission. 43 */ 44static int twe_get_param_1(struct twe_softc *sc, int table_id, int param_id, u_int8_t *result); 45static int twe_get_param_2(struct twe_softc *sc, int table_id, int param_id, u_int16_t *result); 46static int twe_get_param_4(struct twe_softc *sc, int table_id, int param_id, u_int32_t *result); 47static void *twe_get_param(struct twe_softc *sc, int table_id, int parameter_id, size_t size, 48 void (* func)(struct twe_request *tr)); 49#ifdef TWE_SHUTDOWN_NOTIFICATION 50static int twe_set_param_1(struct twe_softc *sc, int table_id, int param_id, u_int8_t value); 51#endif 52#if 0 53static int twe_set_param_2(struct twe_softc *sc, int table_id, int param_id, u_int16_t value); 54static int twe_set_param_4(struct twe_softc *sc, int table_id, int param_id, u_int32_t value); 55#endif 56static int twe_set_param(struct twe_softc *sc, int table_id, int param_id, int param_size, 57 void *data); 58static int twe_init_connection(struct twe_softc *sc, int mode); 59static int twe_wait_request(struct twe_request *tr); 60static int twe_immediate_request(struct twe_request *tr); 61static void twe_completeio(struct twe_request *tr); 62static void twe_reset(struct twe_softc *sc); 63 64/* 65 * Command I/O to controller. 66 */ 67static int twe_start(struct twe_request *tr); 68static void twe_done(struct twe_softc *sc); 69static void twe_complete(struct twe_softc *sc); 70static int twe_wait_status(struct twe_softc *sc, u_int32_t status, int timeout); 71static int twe_drain_response_queue(struct twe_softc *sc); 72static int twe_check_bits(struct twe_softc *sc, u_int32_t status_reg); 73static int twe_soft_reset(struct twe_softc *sc); 74 75/* 76 * Interrupt handling. 77 */ 78static void twe_host_intr(struct twe_softc *sc); 79static void twe_attention_intr(struct twe_softc *sc); 80static void twe_command_intr(struct twe_softc *sc); 81 82/* 83 * Asynchronous event handling. 84 */ 85static int twe_fetch_aen(struct twe_softc *sc); 86static void twe_handle_aen(struct twe_request *tr); 87static void twe_enqueue_aen(struct twe_softc *sc, u_int16_t aen); 88static int twe_dequeue_aen(struct twe_softc *sc); 89static int twe_drain_aen_queue(struct twe_softc *sc); 90static int twe_find_aen(struct twe_softc *sc, u_int16_t aen); 91 92/* 93 * Command buffer management. 94 */ 95static int twe_get_request(struct twe_softc *sc, struct twe_request **tr); 96static void twe_release_request(struct twe_request *tr); 97 98/* 99 * Debugging. 100 */ 101static char *twe_format_aen(struct twe_softc *sc, u_int16_t aen); 102static int twe_report_request(struct twe_request *tr); 103static void twe_panic(struct twe_softc *sc, char *reason); 104 105/******************************************************************************** 106 ******************************************************************************** 107 Public Interfaces 108 ******************************************************************************** 109 ********************************************************************************/ 110 111/******************************************************************************** 112 * Initialise the controller, set up driver data structures. 113 */ 114int 115twe_setup(struct twe_softc *sc) 116{ 117 struct twe_request *tr; 118 int i; 119 120 debug_called(4); 121 122 /* 123 * Initialise request queues. 124 */ 125 twe_initq_free(sc); 126 twe_initq_bio(sc); 127 twe_initq_ready(sc); 128 twe_initq_busy(sc); 129 twe_initq_complete(sc); 130 sc->twe_wait_aen = -1; 131 132 /* 133 * Allocate request structures up front. 134 */ 135 for (i = 0; i < TWE_Q_LENGTH; i++) { 136 if ((tr = twe_allocate_request(sc)) == NULL) 137 return(ENOMEM); 138 /* 139 * Set global defaults that won't change. 140 */ 141 tr->tr_command.generic.host_id = sc->twe_host_id; /* controller-assigned host ID */ 142 tr->tr_command.generic.request_id = i; /* our index number */ 143 sc->twe_lookup[i] = tr; 144 145 /* 146 * Put command onto the freelist. 147 */ 148 twe_release_request(tr); 149 } 150 151 /* 152 * Wait for the controller to come ready. 153 */ 154 if (twe_wait_status(sc, TWE_STATUS_MICROCONTROLLER_READY, 60)) { 155 twe_printf(sc, "microcontroller not ready\n"); 156 return(ENXIO); 157 } 158 159 /* 160 * Disable interrupts from the card. 161 */ 162 twe_disable_interrupts(sc); 163 164 /* 165 * Soft reset the controller, look for the AEN acknowledging the reset, 166 * check for errors, drain the response queue. 167 */ 168 for (i = 0; i < TWE_MAX_RESET_TRIES; i++) { 169 170 if (i > 0) 171 twe_printf(sc, "reset %d failed, trying again\n", i); 172 173 if (!twe_soft_reset(sc)) 174 break; /* reset process complete */ 175 } 176 /* did we give up? */ 177 if (i >= TWE_MAX_RESET_TRIES) { 178 twe_printf(sc, "can't initialise controller, giving up\n"); 179 return(ENXIO); 180 } 181 182 return(0); 183} 184 185/******************************************************************************** 186 * Locate disk devices and attach children to them. 187 */ 188void 189twe_init(struct twe_softc *sc) 190{ 191 struct twe_drive *dr; 192 int i, table; 193 u_int16_t dsize; 194 TWE_Param *drives, *param; 195 TWE_Unit_Descriptor *ud; 196 197 198 /* 199 * The controller is in a safe state, so try to find drives attached to it. 200 */ 201 if ((drives = twe_get_param(sc, TWE_PARAM_UNITSUMMARY, TWE_PARAM_UNITSUMMARY_Status, 202 TWE_MAX_UNITS, NULL)) == NULL) { 203 twe_printf(sc, "can't detect attached units\n"); 204 return; 205 } 206 207 /* 208 * For each detected unit, create a child device. 209 */ 210 for (i = 0, dr = &sc->twe_drive[0]; i < TWE_MAX_UNITS; i++, dr++) { 211 212 /* check that the drive is online */ 213 if (!(drives->data[i] & TWE_PARAM_UNITSTATUS_Online)) 214 continue; 215 216 table = TWE_PARAM_UNITINFO + i; 217 218 if (twe_get_param_4(sc, table, TWE_PARAM_UNITINFO_Capacity, &dr->td_size)) { 219 twe_printf(sc, "error fetching capacity for unit %d\n", i); 220 continue; 221 } 222 if (twe_get_param_1(sc, table, TWE_PARAM_UNITINFO_Status, &dr->td_state)) { 223 twe_printf(sc, "error fetching state for unit %d\n", i); 224 continue; 225 } 226 if (twe_get_param_2(sc, table, TWE_PARAM_UNITINFO_DescriptorSize, &dsize)) { 227 twe_printf(sc, "error fetching descriptor size for unit %d\n", i); 228 continue; 229 } 230 if ((param = twe_get_param(sc, table, TWE_PARAM_UNITINFO_Descriptor, dsize - 3, NULL)) == NULL) { 231 twe_printf(sc, "error fetching descriptor for unit %d\n", i); 232 continue; 233 } 234 ud = (TWE_Unit_Descriptor *)param->data; 235 dr->td_type = ud->configuration; 236 free(param, M_DEVBUF); 237 238 /* build synthetic geometry as per controller internal rules */ 239 if (dr->td_size > 0x200000) { 240 dr->td_heads = 255; 241 dr->td_sectors = 63; 242 } else { 243 dr->td_heads = 64; 244 dr->td_sectors = 32; 245 } 246 dr->td_cylinders = dr->td_size / (dr->td_heads * dr->td_sectors); 247 dr->td_unit = i; 248 249 twe_attach_drive(sc, dr); 250 } 251 free(drives, M_DEVBUF); 252 253 /* 254 * Initialise connection with controller. 255 */ 256 twe_init_connection(sc, TWE_INIT_MESSAGE_CREDITS); 257 258#ifdef TWE_SHUTDOWN_NOTIFICATION 259 /* 260 * Tell the controller we support shutdown notification. 261 */ 262 twe_set_param_1(sc, TWE_PARAM_FEATURES, TWE_PARAM_FEATURES_DriverShutdown, 1); 263#endif 264 265 /* 266 * Mark controller up and ready to run. 267 */ 268 sc->twe_state &= ~TWE_STATE_SHUTDOWN; 269 270 /* 271 * Finally enable interrupts. 272 */ 273 twe_enable_interrupts(sc); 274} 275 276/******************************************************************************** 277 * Stop the controller 278 */ 279void 280twe_deinit(struct twe_softc *sc) 281{ 282 /* 283 * Mark the controller as shutting down, and disable any further interrupts. 284 */ 285 sc->twe_state |= TWE_STATE_SHUTDOWN; 286 twe_disable_interrupts(sc); 287 288#ifdef TWE_SHUTDOWN_NOTIFICATION 289 /* 290 * Disconnect from the controller 291 */ 292 twe_init_connection(sc, TWE_SHUTDOWN_MESSAGE_CREDITS); 293#endif 294} 295 296/******************************************************************************* 297 * Take an interrupt, or be poked by other code to look for interrupt-worthy 298 * status. 299 */ 300void 301twe_intr(struct twe_softc *sc) 302{ 303 u_int32_t status_reg; 304 305 debug_called(4); 306 307 /* 308 * Collect current interrupt status. 309 */ 310 status_reg = TWE_STATUS(sc); 311 twe_check_bits(sc, status_reg); 312 313 /* 314 * Dispatch based on interrupt status 315 */ 316 if (status_reg & TWE_STATUS_HOST_INTERRUPT) 317 twe_host_intr(sc); 318 if (status_reg & TWE_STATUS_ATTENTION_INTERRUPT) 319 twe_attention_intr(sc); 320 if (status_reg & TWE_STATUS_COMMAND_INTERRUPT) 321 twe_command_intr(sc); 322 if (status_reg & TWE_STATUS_RESPONSE_INTERRUPT) 323 twe_done(sc); 324}; 325 326/******************************************************************************** 327 * Pull as much work off the softc's work queue as possible and give it to the 328 * controller. 329 */ 330void 331twe_startio(struct twe_softc *sc) 332{ 333 struct twe_request *tr; 334 TWE_Command *cmd; 335 twe_bio *bp; 336 int error; 337 338 debug_called(4); 339 340 /* spin until something prevents us from doing any work */ 341 for (;;) { 342 343 /* try to get a command that's already ready to go */ 344 tr = twe_dequeue_ready(sc); 345 346 /* build a command from an outstanding bio */ 347 if (tr == NULL) { 348 349 /* see if there's work to be done */ 350 if ((bp = twe_dequeue_bio(sc)) == NULL) 351 break; 352 353 /* get a command to handle the bio with */ 354 if (twe_get_request(sc, &tr)) { 355 twe_enqueue_bio(sc, bp); /* failed, put the bio back */ 356 break; 357 } 358 359 /* connect the bio to the command */ 360 tr->tr_complete = twe_completeio; 361 tr->tr_private = bp; 362 tr->tr_data = TWE_BIO_DATA(bp); 363 tr->tr_length = TWE_BIO_LENGTH(bp); 364 cmd = &tr->tr_command; 365 if (TWE_BIO_IS_READ(bp)) { 366 tr->tr_flags |= TWE_CMD_DATAIN; 367 cmd->io.opcode = TWE_OP_READ; 368 } else { 369 tr->tr_flags |= TWE_CMD_DATAOUT; 370 cmd->io.opcode = TWE_OP_WRITE; 371 } 372 373 /* build a suitable I/O command (assumes 512-byte rounded transfers) */ 374 cmd->io.size = 3; 375 cmd->io.unit = TWE_BIO_UNIT(bp); 376 cmd->io.block_count = (tr->tr_length + TWE_BLOCK_SIZE - 1) / TWE_BLOCK_SIZE; 377 cmd->io.lba = TWE_BIO_LBA(bp); 378 379 /* map the command so the controller can work with it */ 380 twe_map_request(tr); 381 } 382 383 /* did we find something to do? */ 384 if (tr == NULL) 385 break; 386 387 /* try to give command to controller */ 388 error = twe_start(tr); 389 390 if (error != 0) { 391 if (error == EBUSY) { 392 twe_requeue_ready(tr); /* try it again later */ 393 break; /* don't try anything more for now */ 394 } 395 /* we don't support any other return from twe_start */ 396 twe_panic(sc, "twe_start returned nonsense"); 397 } 398 } 399} 400 401/******************************************************************************** 402 * Write blocks from memory to disk, for system crash dumps. 403 */ 404int 405twe_dump_blocks(struct twe_softc *sc, int unit, u_int32_t lba, void *data, int nblks) 406{ 407 struct twe_request *tr; 408 TWE_Command *cmd; 409 int error; 410 411 if (twe_get_request(sc, &tr)) 412 return(ENOMEM); 413 414 tr->tr_data = data; 415 tr->tr_status = TWE_CMD_SETUP; 416 tr->tr_length = nblks * TWE_BLOCK_SIZE; 417 tr->tr_flags = TWE_CMD_DATAOUT; 418 419 cmd = &tr->tr_command; 420 cmd->io.opcode = TWE_OP_WRITE; 421 cmd->io.size = 3; 422 cmd->io.unit = unit; 423 cmd->io.block_count = nblks; 424 cmd->io.lba = lba; 425 426 twe_map_request(tr); 427 error = twe_immediate_request(tr); 428 if (error == 0) 429 if (twe_report_request(tr)) 430 error = EIO; 431 twe_release_request(tr); 432 return(error); 433} 434 435/******************************************************************************** 436 * Handle controller-specific control operations. 437 */ 438int 439twe_ioctl(struct twe_softc *sc, int cmd, void *addr) 440{ 441 struct twe_usercommand *tu = (struct twe_usercommand *)addr; 442 struct twe_paramcommand *tp = (struct twe_paramcommand *)addr; 443 union twe_statrequest *ts = (union twe_statrequest *)addr; 444 TWE_Param *param; 445 void *data; 446 int *arg = (int *)addr; 447 struct twe_request *tr; 448 u_int8_t srid; 449 int s, error; 450 451 error = 0; 452 switch(cmd) { 453 /* handle a command from userspace */ 454 case TWEIO_COMMAND: 455 /* get a request */ 456 if (twe_get_request(sc, &tr)) { 457 error = EBUSY; 458 goto cmd_done; 459 } 460 461 /* 462 * Save the command's request ID, copy the user-supplied command in, 463 * restore the request ID. 464 */ 465 srid = tr->tr_command.generic.request_id; 466 bcopy(&tu->tu_command, &tr->tr_command, sizeof(TWE_Command)); 467 tr->tr_command.generic.request_id = srid; 468 469 /* if there's a data buffer, allocate and copy it in */ 470 tr->tr_length = tu->tu_size; 471 if (tr->tr_length > 0) { 472 if ((tr->tr_data = malloc(tr->tr_length, M_DEVBUF, M_WAITOK)) == NULL) { 473 error = ENOMEM; 474 goto cmd_done; 475 } 476 if ((error = copyin(tu->tu_data, tr->tr_data, tr->tr_length)) != 0) 477 goto cmd_done; 478 tr->tr_flags |= TWE_CMD_DATAIN | TWE_CMD_DATAOUT; 479 } 480 481 /* run the command */ 482 twe_map_request(tr); 483 twe_wait_request(tr); 484 485 /* copy the command out again */ 486 bcopy(&tr->tr_command, &tu->tu_command, sizeof(TWE_Command)); 487 488 /* if there was a data buffer, copy it out */ 489 if (tr->tr_length > 0) 490 error = copyout(tr->tr_data, tu->tu_data, tr->tr_length); 491 492 cmd_done: 493 /* free resources */ 494 if (tr->tr_data != NULL) 495 free(tr->tr_data, M_DEVBUF); 496 if (tr != NULL) 497 twe_release_request(tr); 498 499 break; 500 501 /* fetch statistics counter */ 502 case TWEIO_STATS: 503 switch (ts->ts_item) { 504#ifdef TWE_PERFORMANCE_MONITOR 505 case TWEQ_FREE: 506 case TWEQ_BIO: 507 case TWEQ_READY: 508 case TWEQ_BUSY: 509 case TWEQ_COMPLETE: 510 bcopy(&sc->twe_qstat[ts->ts_item], &ts->ts_qstat, sizeof(struct twe_qstat)); 511 break; 512#endif 513 default: 514 error = ENOENT; 515 break; 516 } 517 break; 518 519 /* poll for an AEN */ 520 case TWEIO_AEN_POLL: 521 *arg = twe_dequeue_aen(sc); 522 if (*arg == -1) 523 error = ENOENT; 524 break; 525 526 /* wait for another AEN to show up */ 527 case TWEIO_AEN_WAIT: 528 s = splbio(); 529 while ((*arg = twe_dequeue_aen(sc)) == -1) { 530 error = tsleep(&sc->twe_aen_queue, PRIBIO | PCATCH, "tweaen", 0); 531 if (error == EINTR) 532 break; 533 } 534 splx(s); 535 break; 536 537 case TWEIO_GET_PARAM: 538 if ((param = twe_get_param(sc, tp->tp_table_id, tp->tp_param_id, tp->tp_size, NULL)) == NULL) { 539 twe_printf(sc, "TWEIO_GET_PARAM failed for 0x%x/0x%x/%d\n", 540 tp->tp_table_id, tp->tp_param_id, tp->tp_size); 541 error = EINVAL; 542 } else { 543 if (param->parameter_size_bytes > tp->tp_size) { 544 twe_printf(sc, "TWEIO_GET_PARAM parameter too large (%d > %d)\n", 545 param->parameter_size_bytes, tp->tp_size); 546 error = EFAULT; 547 } else { 548 error = copyout(param->data, tp->tp_data, param->parameter_size_bytes); 549 } 550 free(param, M_DEVBUF); 551 } 552 break; 553 554 case TWEIO_SET_PARAM: 555 if ((data = malloc(tp->tp_size, M_DEVBUF, M_WAITOK)) == NULL) { 556 error = ENOMEM; 557 } else { 558 error = copyin(tp->tp_data, data, tp->tp_size); 559 if (error == 0) 560 error = twe_set_param(sc, tp->tp_table_id, tp->tp_param_id, tp->tp_size, data); 561 free(data, M_DEVBUF); 562 } 563 break; 564 565 case TWEIO_RESET: 566 twe_reset(sc); 567 break; 568 569 /* nothing we understand */ 570 default: 571 error = ENOTTY; 572 } 573 574 return(error); 575} 576 577/******************************************************************************** 578 * Enable the useful interrupts from the controller. 579 */ 580void 581twe_enable_interrupts(struct twe_softc *sc) 582{ 583 sc->twe_state |= TWE_STATE_INTEN; 584 TWE_CONTROL(sc, 585 TWE_CONTROL_CLEAR_ATTENTION_INTERRUPT | 586 TWE_CONTROL_UNMASK_RESPONSE_INTERRUPT | 587 TWE_CONTROL_ENABLE_INTERRUPTS); 588} 589 590/******************************************************************************** 591 * Disable interrupts from the controller. 592 */ 593void 594twe_disable_interrupts(struct twe_softc *sc) 595{ 596 TWE_CONTROL(sc, TWE_CONTROL_DISABLE_INTERRUPTS); 597 sc->twe_state &= ~TWE_STATE_INTEN; 598} 599 600/******************************************************************************** 601 ******************************************************************************** 602 Command Submission 603 ******************************************************************************** 604 ********************************************************************************/ 605 606/******************************************************************************** 607 * Read integer parameter table entries. 608 */ 609static int 610twe_get_param_1(struct twe_softc *sc, int table_id, int param_id, u_int8_t *result) 611{ 612 TWE_Param *param; 613 614 if ((param = twe_get_param(sc, table_id, param_id, 1, NULL)) == NULL) 615 return(ENOENT); 616 *result = *(u_int8_t *)param->data; 617 free(param, M_DEVBUF); 618 return(0); 619} 620 621static int 622twe_get_param_2(struct twe_softc *sc, int table_id, int param_id, u_int16_t *result) 623{ 624 TWE_Param *param; 625 626 if ((param = twe_get_param(sc, table_id, param_id, 2, NULL)) == NULL) 627 return(ENOENT); 628 *result = *(u_int16_t *)param->data; 629 free(param, M_DEVBUF); 630 return(0); 631} 632 633static int 634twe_get_param_4(struct twe_softc *sc, int table_id, int param_id, u_int32_t *result) 635{ 636 TWE_Param *param; 637 638 if ((param = twe_get_param(sc, table_id, param_id, 4, NULL)) == NULL) 639 return(ENOENT); 640 *result = *(u_int32_t *)param->data; 641 free(param, M_DEVBUF); 642 return(0); 643} 644 645/******************************************************************************** 646 * Perform a TWE_OP_GET_PARAM command. If a callback function is provided, it 647 * will be called with the command when it's completed. If no callback is 648 * provided, we will wait for the command to complete and then return just the data. 649 * The caller is responsible for freeing the data when done with it. 650 */ 651static void * 652twe_get_param(struct twe_softc *sc, int table_id, int param_id, size_t param_size, 653 void (* func)(struct twe_request *tr)) 654{ 655 struct twe_request *tr; 656 TWE_Command *cmd; 657 TWE_Param *param; 658 int error; 659 660 debug_called(4); 661 662 tr = NULL; 663 param = NULL; 664 665 /* get a command */ 666 if (twe_get_request(sc, &tr)) 667 goto err; 668 669 /* get a buffer */ 670 if ((param = (TWE_Param *)malloc(TWE_SECTOR_SIZE, M_DEVBUF, M_NOWAIT)) == NULL) 671 goto err; 672 tr->tr_data = param; 673 tr->tr_length = TWE_SECTOR_SIZE; 674 tr->tr_flags = TWE_CMD_DATAIN | TWE_CMD_DATAOUT; 675 676 /* build the command for the controller */ 677 cmd = &tr->tr_command; 678 cmd->param.opcode = TWE_OP_GET_PARAM; 679 cmd->param.size = 2; 680 cmd->param.unit = 0; 681 cmd->param.param_count = 1; 682 683 /* map the command/data into controller-visible space */ 684 twe_map_request(tr); 685 686 /* fill in the outbound parameter data */ 687 param->table_id = table_id; 688 param->parameter_id = param_id; 689 param->parameter_size_bytes = param_size; 690 691 /* submit the command and either wait or let the callback handle it */ 692 if (func == NULL) { 693 /* XXX could use twe_wait_request here if interrupts were enabled? */ 694 error = twe_immediate_request(tr); 695 if (error == 0) { 696 if (twe_report_request(tr)) 697 goto err; 698 } 699 twe_release_request(tr); 700 return(param); 701 } else { 702 tr->tr_complete = func; 703 error = twe_start(tr); 704 if (error == 0) 705 return(func); 706 } 707 708 /* something failed */ 709err: 710 debug(1, "failed"); 711 if (tr != NULL) 712 twe_release_request(tr); 713 if (param != NULL) 714 free(param, M_DEVBUF); 715 return(NULL); 716} 717 718/******************************************************************************** 719 * Set integer parameter table entries. 720 */ 721#ifdef TWE_SHUTDOWN_NOTIFICATION 722static int 723twe_set_param_1(struct twe_softc *sc, int table_id, int param_id, u_int8_t value) 724{ 725 return(twe_set_param(sc, table_id, param_id, sizeof(value), &value)); 726} 727#endif 728 729#if 0 730static int 731twe_set_param_2(struct twe_softc *sc, int table_id, int param_id, u_int16_t value) 732{ 733 return(twe_set_param(sc, table_id, param_id, sizeof(value), &value)); 734} 735 736static int 737twe_set_param_4(struct twe_softc *sc, int table_id, int param_id, u_int32_t value) 738{ 739 return(twe_set_param(sc, table_id, param_id, sizeof(value), &value)); 740} 741#endif 742 743/******************************************************************************** 744 * Perform a TWE_OP_SET_PARAM command, returns nonzero on error. 745 */ 746static int 747twe_set_param(struct twe_softc *sc, int table_id, int param_id, int param_size, void *data) 748{ 749 struct twe_request *tr; 750 TWE_Command *cmd; 751 TWE_Param *param; 752 int error; 753 754 debug_called(4); 755 756 tr = NULL; 757 param = NULL; 758 error = ENOMEM; 759 760 /* get a command */ 761 if (twe_get_request(sc, &tr)) 762 goto out; 763 764 /* get a buffer */ 765 if ((param = (TWE_Param *)malloc(TWE_SECTOR_SIZE, M_DEVBUF, M_NOWAIT)) == NULL) 766 goto out; 767 tr->tr_data = param; 768 tr->tr_length = TWE_SECTOR_SIZE; 769 tr->tr_flags = TWE_CMD_DATAIN | TWE_CMD_DATAOUT; 770 771 /* build the command for the controller */ 772 cmd = &tr->tr_command; 773 cmd->param.opcode = TWE_OP_SET_PARAM; 774 cmd->param.size = 2; 775 cmd->param.unit = 0; 776 cmd->param.param_count = 1; 777 778 /* map the command/data into controller-visible space */ 779 twe_map_request(tr); 780 781 /* fill in the outbound parameter data */ 782 param->table_id = table_id; 783 param->parameter_id = param_id; 784 param->parameter_size_bytes = param_size; 785 bcopy(data, param->data, param_size); 786 787 /* XXX could use twe_wait_request here if interrupts were enabled? */ 788 error = twe_immediate_request(tr); 789 if (error == 0) { 790 if (twe_report_request(tr)) 791 error = EIO; 792 } 793 794out: 795 if (tr != NULL) 796 twe_release_request(tr); 797 if (param != NULL) 798 free(param, M_DEVBUF); 799 return(error); 800} 801 802/******************************************************************************** 803 * Perform a TWE_OP_INIT_CONNECTION command, returns nonzero on error. 804 * 805 * Typically called with interrupts disabled. 806 */ 807static int 808twe_init_connection(struct twe_softc *sc, int mode) 809{ 810 struct twe_request *tr; 811 TWE_Command *cmd; 812 int error; 813 814 debug_called(4); 815 816 /* get a command */ 817 if (twe_get_request(sc, &tr)) 818 return(NULL); 819 820 /* build the command */ 821 cmd = &tr->tr_command; 822 cmd->initconnection.opcode = TWE_OP_INIT_CONNECTION; 823 cmd->initconnection.size = 3; 824 cmd->initconnection.host_id = 0; 825 cmd->initconnection.message_credits = mode; 826 cmd->initconnection.response_queue_pointer = 0; 827 828 /* map the command into controller-visible space */ 829 twe_map_request(tr); 830 831 /* submit the command */ 832 error = twe_immediate_request(tr); 833 /* XXX check command result? */ 834 twe_unmap_request(tr); 835 twe_release_request(tr); 836 837 if (mode == TWE_INIT_MESSAGE_CREDITS) 838 sc->twe_host_id = cmd->initconnection.host_id; 839 return(error); 840} 841 842/******************************************************************************** 843 * Start the command (tr) and sleep waiting for it to complete. 844 * 845 * Successfully completed commands are dequeued. 846 */ 847static int 848twe_wait_request(struct twe_request *tr) 849{ 850 int s; 851 852 debug_called(4); 853 854 tr->tr_flags |= TWE_CMD_SLEEPER; 855 tr->tr_status = TWE_CMD_BUSY; 856 twe_enqueue_ready(tr); 857 twe_startio(tr->tr_sc); 858 s = splbio(); 859 while (tr->tr_status == TWE_CMD_BUSY) 860 tsleep(tr, PRIBIO, "twewait", 0); 861 splx(s); 862 863 return(0); 864} 865 866/******************************************************************************** 867 * Start the command (tr) and busy-wait for it to complete. 868 * This should only be used when interrupts are actually disabled (although it 869 * will work if they are not). 870 */ 871static int 872twe_immediate_request(struct twe_request *tr) 873{ 874 int error; 875 876 debug_called(4); 877 878 error = 0; 879 880 if ((error = twe_start(tr)) != 0) 881 return(error); 882 while (tr->tr_status == TWE_CMD_BUSY){ 883 twe_done(tr->tr_sc); 884 } 885 return(tr->tr_status != TWE_CMD_COMPLETE); 886} 887 888/******************************************************************************** 889 * Handle completion of an I/O command. 890 */ 891static void 892twe_completeio(struct twe_request *tr) 893{ 894 struct twe_softc *sc = tr->tr_sc; 895 twe_bio *bp = (twe_bio *)tr->tr_private; 896 897 debug_called(4); 898 899 if (tr->tr_status == TWE_CMD_COMPLETE) { 900 901 if (twe_report_request(tr)) 902 TWE_BIO_SET_ERROR(bp, EIO); 903 904 } else { 905 twe_panic(sc, "twe_completeio on incomplete command"); 906 } 907 tr->tr_private = NULL; 908 twed_intr(bp); 909 twe_release_request(tr); 910} 911 912/******************************************************************************** 913 * Reset the controller and pull all the active commands back onto the ready 914 * queue. Used to restart a controller that's exhibiting bad behaviour. 915 */ 916static void 917twe_reset(struct twe_softc *sc) 918{ 919 struct twe_request *tr; 920 int i, s; 921 922 twe_printf(sc, "controller reset in progress...\n"); 923 924 /* 925 * Disable interrupts from the controller, and mask any accidental entry 926 * into our interrupt handler. 927 */ 928 twe_disable_interrupts(sc); 929 s = splbio(); 930 931 /* 932 * Try to soft-reset the controller. 933 */ 934 for (i = 0; i < TWE_MAX_RESET_TRIES; i++) { 935 936 if (i > 0) 937 twe_printf(sc, "reset %d failed, trying again\n", i); 938 939 if (!twe_soft_reset(sc)) 940 break; /* reset process complete */ 941 } 942 /* did we give up? */ 943 if (i >= TWE_MAX_RESET_TRIES) { 944 twe_printf(sc, "can't reset controller, giving up\n"); 945 goto out; 946 } 947 948 /* 949 * Move all of the commands that were busy back to the ready queue. 950 */ 951 i = 0; 952 while ((tr = twe_dequeue_busy(sc)) != NULL) { 953 twe_enqueue_ready(tr); 954 i++; 955 } 956 957 /* 958 * Kick the controller to start things going again, then re-enable interrupts. 959 */ 960 twe_startio(sc); 961 twe_enable_interrupts(sc); 962 twe_printf(sc, "controller reset done, %d commands restarted\n", i); 963 964out: 965 splx(s); 966 twe_enable_interrupts(sc); 967} 968 969/******************************************************************************** 970 ******************************************************************************** 971 Command I/O to Controller 972 ******************************************************************************** 973 ********************************************************************************/ 974 975/******************************************************************************** 976 * Try to deliver (tr) to the controller. 977 * 978 * Can be called at any interrupt level, with or without interrupts enabled. 979 */ 980static int 981twe_start(struct twe_request *tr) 982{ 983 struct twe_softc *sc = tr->tr_sc; 984 int i, s, done; 985 u_int32_t status_reg; 986 987 debug_called(4); 988 989 /* mark the command as currently being processed */ 990 tr->tr_status = TWE_CMD_BUSY; 991 992 /* 993 * Spin briefly waiting for the controller to come ready 994 * 995 * XXX it might be more efficient to return EBUSY immediately 996 * and let the command be rescheduled. 997 */ 998 for (i = 100000, done = 0; (i > 0) && !done; i--) { 999 s = splbio(); 1000 1001 /* check to see if we can post a command */ 1002 status_reg = TWE_STATUS(sc); 1003 twe_check_bits(sc, status_reg); 1004 1005 if (!(status_reg & TWE_STATUS_COMMAND_QUEUE_FULL)) { 1006 TWE_COMMAND_QUEUE(sc, tr->tr_cmdphys); 1007 done = 1; 1008 /* move command to work queue */ 1009 twe_enqueue_busy(tr); 1010#ifdef TWE_DEBUG 1011 if (tr->tr_complete != NULL) { 1012 debug(3, "queued request %d with callback %p", tr->tr_command.generic.request_id, tr->tr_complete); 1013 } else if (tr->tr_flags & TWE_CMD_SLEEPER) { 1014 debug(3, "queued request %d with wait channel %p", tr->tr_command.generic.request_id, tr); 1015 } else { 1016 debug(3, "queued request %d for polling caller", tr->tr_command.generic.request_id); 1017 } 1018#endif 1019 } 1020 splx(s); /* drop spl to allow completion interrupts */ 1021 } 1022 1023 /* command is enqueued */ 1024 if (done) 1025 return(0); 1026 1027 /* 1028 * We couldn't get the controller to take the command; try submitting it again later. 1029 * This should only happen if something is wrong with the controller, or if we have 1030 * overestimated the number of commands it can accept. (Should we actually reject 1031 * the command at this point?) 1032 */ 1033 return(EBUSY); 1034} 1035 1036/******************************************************************************** 1037 * Poll the controller (sc) for completed commands. 1038 * 1039 * Can be called at any interrupt level, with or without interrupts enabled. 1040 */ 1041static void 1042twe_done(struct twe_softc *sc) 1043{ 1044 TWE_Response_Queue rq; 1045 struct twe_request *tr; 1046 int s, found; 1047 u_int32_t status_reg; 1048 1049 debug_called(5); 1050 1051 /* loop collecting completed commands */ 1052 found = 0; 1053 s = splbio(); 1054 for (;;) { 1055 status_reg = TWE_STATUS(sc); 1056 twe_check_bits(sc, status_reg); /* XXX should this fail? */ 1057 1058 if (!(status_reg & TWE_STATUS_RESPONSE_QUEUE_EMPTY)) { 1059 found = 1; 1060 rq = TWE_RESPONSE_QUEUE(sc); 1061 tr = sc->twe_lookup[rq.u.response_id]; /* find command */ 1062 if (tr->tr_status != TWE_CMD_BUSY) 1063 twe_printf(sc, "completion event for nonbusy command\n"); 1064 tr->tr_status = TWE_CMD_COMPLETE; 1065 debug(3, "completed request id %d with status %d", 1066 tr->tr_command.generic.request_id, tr->tr_command.generic.status); 1067 /* move to completed queue */ 1068 twe_remove_busy(tr); 1069 twe_enqueue_complete(tr); 1070 } else { 1071 break; /* no response ready */ 1072 } 1073 } 1074 splx(s); 1075 1076 /* if we've completed any commands, try posting some more */ 1077 if (found) 1078 twe_startio(sc); 1079 1080 /* handle completion and timeouts */ 1081 twe_complete(sc); /* XXX use deferred completion? */ 1082} 1083 1084/******************************************************************************** 1085 * Perform post-completion processing for commands on (sc). 1086 * 1087 * This is split from twe_done as it can be safely deferred and run at a lower 1088 * priority level should facilities for such a thing become available. 1089 */ 1090static void 1091twe_complete(struct twe_softc *sc) 1092{ 1093 struct twe_request *tr; 1094 1095 debug_called(5); 1096 1097 /* 1098 * Pull commands off the completed list, dispatch them appropriately 1099 */ 1100 while ((tr = twe_dequeue_complete(sc)) != NULL) { 1101 1102 /* unmap the command's data buffer */ 1103 twe_unmap_request(tr); 1104 1105 /* dispatch to suit command originator */ 1106 if (tr->tr_complete != NULL) { /* completion callback */ 1107 debug(2, "call completion handler %p", tr->tr_complete); 1108 tr->tr_complete(tr); 1109 1110 } else if (tr->tr_flags & TWE_CMD_SLEEPER) { /* caller is asleep waiting */ 1111 debug(2, "wake up command owner on %p", tr); 1112 wakeup_one(tr); 1113 1114 } else { /* caller is polling command */ 1115 debug(2, "command left for owner"); 1116 } 1117 } 1118} 1119 1120/******************************************************************************** 1121 * Wait for (status) to be set in the controller status register for up to 1122 * (timeout) seconds. Returns 0 if found, nonzero if we time out. 1123 * 1124 * Note: this busy-waits, rather than sleeping, since we may be called with 1125 * eg. clock interrupts masked. 1126 */ 1127static int 1128twe_wait_status(struct twe_softc *sc, u_int32_t status, int timeout) 1129{ 1130 time_t expiry; 1131 u_int32_t status_reg; 1132 1133 debug_called(4); 1134 1135 expiry = time_second + timeout; 1136 1137 do { 1138 status_reg = TWE_STATUS(sc); 1139 if (status_reg & status) /* got the required bit(s)? */ 1140 return(0); 1141 DELAY(100000); 1142 } while (time_second <= expiry); 1143 1144 return(1); 1145} 1146 1147/******************************************************************************** 1148 * Drain the response queue, which may contain responses to commands we know 1149 * nothing about. 1150 */ 1151static int 1152twe_drain_response_queue(struct twe_softc *sc) 1153{ 1154 TWE_Response_Queue rq; 1155 u_int32_t status_reg; 1156 1157 debug_called(4); 1158 1159 for (;;) { /* XXX give up eventually? */ 1160 status_reg = TWE_STATUS(sc); 1161 if (twe_check_bits(sc, status_reg)) 1162 return(1); 1163 if (status_reg & TWE_STATUS_RESPONSE_QUEUE_EMPTY) 1164 return(0); 1165 rq = TWE_RESPONSE_QUEUE(sc); 1166 } 1167} 1168 1169/******************************************************************************** 1170 * Soft-reset the controller 1171 */ 1172static int 1173twe_soft_reset(struct twe_softc *sc) 1174{ 1175 u_int32_t status_reg; 1176 1177 debug_called(2); 1178 1179 TWE_SOFT_RESET(sc); 1180 1181 if (twe_wait_status(sc, TWE_STATUS_ATTENTION_INTERRUPT, 15)) { 1182 twe_printf(sc, "no attention interrupt\n"); 1183 return(1); 1184 } 1185 if (twe_drain_aen_queue(sc)) { 1186 twe_printf(sc, "can't drain AEN queue\n"); 1187 return(1); 1188 } 1189 if (twe_find_aen(sc, TWE_AEN_SOFT_RESET)) { 1190 twe_printf(sc, "reset not reported\n"); 1191 return(1); 1192 } 1193 status_reg = TWE_STATUS(sc); 1194 if (TWE_STATUS_ERRORS(status_reg) || twe_check_bits(sc, status_reg)) { 1195 twe_printf(sc, "controller errors detected\n"); 1196 return(1); 1197 } 1198 if (twe_drain_response_queue(sc)) { 1199 twe_printf(sc, "can't drain response queue\n"); 1200 return(1); 1201 } 1202 return(0); 1203} 1204 1205/******************************************************************************** 1206 ******************************************************************************** 1207 Interrupt Handling 1208 ******************************************************************************** 1209 ********************************************************************************/ 1210 1211/******************************************************************************** 1212 * Host interrupt. 1213 * 1214 * XXX what does this mean? 1215 */ 1216static void 1217twe_host_intr(struct twe_softc *sc) 1218{ 1219 debug_called(4); 1220 1221 twe_printf(sc, "host interrupt\n"); 1222 TWE_CONTROL(sc, TWE_CONTROL_CLEAR_HOST_INTERRUPT); 1223} 1224 1225/******************************************************************************** 1226 * Attention interrupt. 1227 * 1228 * Signalled when the controller has one or more AENs for us. 1229 */ 1230static void 1231twe_attention_intr(struct twe_softc *sc) 1232{ 1233 debug_called(4); 1234 1235 /* instigate a poll for AENs */ 1236 if (twe_fetch_aen(sc)) { 1237 twe_printf(sc, "error polling for signalled AEN\n"); 1238 } else { 1239 TWE_CONTROL(sc, TWE_CONTROL_CLEAR_ATTENTION_INTERRUPT); 1240 } 1241} 1242 1243/******************************************************************************** 1244 * Command interrupt. 1245 * 1246 * Signalled when the controller can handle more commands. 1247 */ 1248static void 1249twe_command_intr(struct twe_softc *sc) 1250{ 1251 debug_called(4); 1252 1253 /* 1254 * We don't use this, rather we try to submit commands when we receive 1255 * them, and when other commands have completed. Mask it so we don't get 1256 * another one. 1257 */ 1258 twe_printf(sc, "command interrupt\n"); 1259 TWE_CONTROL(sc, TWE_CONTROL_MASK_COMMAND_INTERRUPT); 1260} 1261 1262/******************************************************************************** 1263 ******************************************************************************** 1264 Asynchronous Event Handling 1265 ******************************************************************************** 1266 ********************************************************************************/ 1267 1268/******************************************************************************** 1269 * Request an AEN from the controller. 1270 */ 1271static int 1272twe_fetch_aen(struct twe_softc *sc) 1273{ 1274 1275 debug_called(4); 1276 1277 if ((twe_get_param(sc, TWE_PARAM_AEN, TWE_PARAM_AEN_UnitCode, 2, twe_handle_aen)) == NULL) 1278 return(EIO); 1279 return(0); 1280} 1281 1282/******************************************************************************** 1283 * Handle an AEN returned by the controller. 1284 */ 1285static void 1286twe_handle_aen(struct twe_request *tr) 1287{ 1288 struct twe_softc *sc = tr->tr_sc; 1289 TWE_Param *param; 1290 u_int16_t aen; 1291 1292 debug_called(4); 1293 1294 /* XXX check for command success somehow? */ 1295 1296 param = (TWE_Param *)tr->tr_data; 1297 aen = *(u_int16_t *)(param->data); 1298 1299 free(tr->tr_data, M_DEVBUF); 1300 twe_release_request(tr); 1301 twe_enqueue_aen(sc, aen); 1302 1303 /* XXX poll for more AENs? */ 1304} 1305 1306/******************************************************************************** 1307 * Pull AENs out of the controller and park them in the queue, in a context where 1308 * interrupts aren't active. Return nonzero if we encounter any errors in the 1309 * process of obtaining all the available AENs. 1310 */ 1311static int 1312twe_drain_aen_queue(struct twe_softc *sc) 1313{ 1314 u_int16_t aen; 1315 1316 for (;;) { 1317 if (twe_get_param_2(sc, TWE_PARAM_AEN, TWE_PARAM_AEN_UnitCode, &aen)) 1318 return(1); 1319 if (aen == TWE_AEN_QUEUE_EMPTY) 1320 return(0); 1321 twe_enqueue_aen(sc, aen); 1322 } 1323} 1324 1325/******************************************************************************** 1326 * Push an AEN that we've received onto the queue. 1327 * 1328 * Note that we have to lock this against reentrance, since it may be called 1329 * from both interrupt and non-interrupt context. 1330 * 1331 * If someone is waiting for the AEN we have, wake them up. 1332 */ 1333static void 1334twe_enqueue_aen(struct twe_softc *sc, u_int16_t aen) 1335{ 1336 char *msg; 1337 int s, next, nextnext; 1338 1339 debug_called(4); 1340 1341 if ((msg = twe_format_aen(sc, aen)) != NULL) 1342 twe_printf(sc, "AEN: <%s>\n", msg); 1343 1344 s = splbio(); 1345 /* enqueue the AEN */ 1346 next = ((sc->twe_aen_head + 1) % TWE_Q_LENGTH); 1347 nextnext = ((sc->twe_aen_head + 2) % TWE_Q_LENGTH); 1348 1349 /* check to see if this is the last free slot, and subvert the AEN if it is */ 1350 if (nextnext == sc->twe_aen_tail) 1351 aen = TWE_AEN_QUEUE_FULL; 1352 1353 /* look to see if there's room for this AEN */ 1354 if (next != sc->twe_aen_tail) { 1355 sc->twe_aen_queue[sc->twe_aen_head] = aen; 1356 sc->twe_aen_head = next; 1357 } 1358 1359 /* wake up anyone asleep on the queue */ 1360 wakeup(&sc->twe_aen_queue); 1361 1362 /* anyone looking for this AEN? */ 1363 if (sc->twe_wait_aen == aen) { 1364 sc->twe_wait_aen = -1; 1365 wakeup(&sc->twe_wait_aen); 1366 } 1367 splx(s); 1368} 1369 1370/******************************************************************************** 1371 * Pop an AEN off the queue, or return -1 if there are none left. 1372 * 1373 * We are more or less interrupt-safe, so don't block interrupts. 1374 */ 1375static int 1376twe_dequeue_aen(struct twe_softc *sc) 1377{ 1378 int result; 1379 1380 debug_called(4); 1381 1382 if (sc->twe_aen_tail == sc->twe_aen_head) { 1383 result = -1; 1384 } else { 1385 result = sc->twe_aen_queue[sc->twe_aen_tail]; 1386 sc->twe_aen_tail = ((sc->twe_aen_tail + 1) % TWE_Q_LENGTH); 1387 } 1388 return(result); 1389} 1390 1391/******************************************************************************** 1392 * Check to see if the requested AEN is in the queue. 1393 * 1394 * XXX we could probably avoid masking interrupts here 1395 */ 1396static int 1397twe_find_aen(struct twe_softc *sc, u_int16_t aen) 1398{ 1399 int i, s, missing; 1400 1401 missing = 1; 1402 s = splbio(); 1403 for (i = sc->twe_aen_tail; (i != sc->twe_aen_head) && missing; i = (i + 1) % TWE_Q_LENGTH) { 1404 if (sc->twe_aen_queue[i] == aen) 1405 missing = 0; 1406 } 1407 splx(s); 1408 return(missing); 1409} 1410 1411 1412#if 0 /* currently unused */ 1413/******************************************************************************** 1414 * Sleep waiting for at least (timeout) seconds until we see (aen) as 1415 * requested. Returns nonzero on timeout or failure. 1416 * 1417 * XXX: this should not be used in cases where there may be more than one sleeper 1418 * without a mechanism for registering multiple sleepers. 1419 */ 1420static int 1421twe_wait_aen(struct twe_softc *sc, int aen, int timeout) 1422{ 1423 time_t expiry; 1424 int found, s; 1425 1426 debug_called(4); 1427 1428 expiry = time_second + timeout; 1429 found = 0; 1430 1431 s = splbio(); 1432 sc->twe_wait_aen = aen; 1433 do { 1434 twe_fetch_aen(sc); 1435 tsleep(&sc->twe_wait_aen, PZERO, "twewaen", hz); 1436 if (sc->twe_wait_aen == -1) 1437 found = 1; 1438 } while ((time_second <= expiry) && !found); 1439 splx(s); 1440 return(!found); 1441} 1442#endif 1443 1444/******************************************************************************** 1445 ******************************************************************************** 1446 Command Buffer Management 1447 ******************************************************************************** 1448 ********************************************************************************/ 1449 1450/******************************************************************************** 1451 * Get a new command buffer. 1452 * 1453 * This will return NULL if all command buffers are in use. 1454 */ 1455static int 1456twe_get_request(struct twe_softc *sc, struct twe_request **tr) 1457{ 1458 debug_called(4); 1459 1460 /* try to reuse an old buffer */ 1461 *tr = twe_dequeue_free(sc); 1462 1463 /* initialise some fields to their defaults */ 1464 if (*tr != NULL) { 1465 (*tr)->tr_data = NULL; 1466 (*tr)->tr_private = NULL; 1467 (*tr)->tr_status = TWE_CMD_SETUP; /* command is in setup phase */ 1468 (*tr)->tr_flags = 0; 1469 (*tr)->tr_complete = NULL; 1470 (*tr)->tr_command.generic.status = 0; /* before submission to controller */ 1471 (*tr)->tr_command.generic.flags = 0; /* not used */ 1472 } 1473 return(*tr == NULL); 1474} 1475 1476/******************************************************************************** 1477 * Release a command buffer for reuse. 1478 * 1479 */ 1480static void 1481twe_release_request(struct twe_request *tr) 1482{ 1483 debug_called(4); 1484 1485 if (tr->tr_private != NULL) 1486 twe_panic(tr->tr_sc, "tr_private != NULL"); 1487 twe_enqueue_free(tr); 1488} 1489 1490/******************************************************************************** 1491 ******************************************************************************** 1492 Debugging 1493 ******************************************************************************** 1494 ********************************************************************************/ 1495 1496/******************************************************************************** 1497 * Print some information about the controller 1498 */ 1499void 1500twe_describe_controller(struct twe_softc *sc) 1501{ 1502 TWE_Param *p[6]; 1503 u_int8_t ports; 1504 u_int32_t size; 1505 int i; 1506 1507 debug_called(2); 1508 1509 /* get the port count */ 1510 twe_get_param_1(sc, TWE_PARAM_CONTROLLER, TWE_PARAM_CONTROLLER_PortCount, &ports); 1511 1512 /* get version strings */ 1513 p[0] = twe_get_param(sc, TWE_PARAM_VERSION, TWE_PARAM_VERSION_Mon, 16, NULL); 1514 p[1] = twe_get_param(sc, TWE_PARAM_VERSION, TWE_PARAM_VERSION_FW, 16, NULL); 1515 p[2] = twe_get_param(sc, TWE_PARAM_VERSION, TWE_PARAM_VERSION_BIOS, 16, NULL); 1516 p[3] = twe_get_param(sc, TWE_PARAM_VERSION, TWE_PARAM_VERSION_PCB, 8, NULL); 1517 p[4] = twe_get_param(sc, TWE_PARAM_VERSION, TWE_PARAM_VERSION_ATA, 8, NULL); 1518 p[5] = twe_get_param(sc, TWE_PARAM_VERSION, TWE_PARAM_VERSION_PCI, 8, NULL); 1519 1520 twe_printf(sc, "%d ports, Firmware %.16s, BIOS %.16s\n", ports, p[1]->data, p[2]->data); 1521 if (bootverbose) 1522 twe_printf(sc, "Monitor %.16s, PCB %.8s, Achip %.8s, Pchip %.8s\n", p[0]->data, p[3]->data, 1523 p[4]->data, p[5]->data); 1524 free(p[0], M_DEVBUF); 1525 free(p[1], M_DEVBUF); 1526 free(p[2], M_DEVBUF); 1527 free(p[3], M_DEVBUF); 1528 free(p[4], M_DEVBUF); 1529 free(p[5], M_DEVBUF); 1530 1531 /* print attached drives */ 1532 if (bootverbose) { 1533 p[0] = twe_get_param(sc, TWE_PARAM_DRIVESUMMARY, TWE_PARAM_DRIVESUMMARY_Status, 16, NULL); 1534 for (i = 0; i < ports; i++) { 1535 if (p[0]->data[i] != TWE_PARAM_DRIVESTATUS_Present) 1536 continue; 1537 twe_get_param_4(sc, TWE_PARAM_DRIVEINFO + i, TWE_PARAM_DRIVEINFO_Size, &size); 1538 p[1] = twe_get_param(sc, TWE_PARAM_DRIVEINFO + i, TWE_PARAM_DRIVEINFO_Model, 40, NULL); 1539 if (p[1] != NULL) { 1540 twe_printf(sc, "port %d: %.40s %dMB\n", i, p[1]->data, size / 2048); 1541 free(p[1], M_DEVBUF); 1542 } else { 1543 twe_printf(sc, "port %d, drive status unavailable\n", i); 1544 } 1545 } 1546 free(p[0], M_DEVBUF); 1547 } 1548} 1549 1550/******************************************************************************** 1551 * Complain if the status bits aren't what we're expecting. 1552 * 1553 * Rate-limit the complaints to at most one of each every five seconds, but 1554 * always return the correct status. 1555 */ 1556static int 1557twe_check_bits(struct twe_softc *sc, u_int32_t status_reg) 1558{ 1559 int result; 1560 static time_t lastwarn[2] = {0, 0}; 1561 1562 /* 1563 * This can be a little problematic, as twe_panic may call twe_reset if 1564 * TWE_DEBUG is not set, which will call us again as part of the soft reset. 1565 */ 1566 if ((status_reg & TWE_STATUS_PANIC_BITS) != 0) { 1567 twe_printf(sc, "FATAL STATUS BIT(S) %b\n", status_reg & TWE_STATUS_PANIC_BITS, 1568 TWE_STATUS_BITS_DESCRIPTION); 1569 twe_panic(sc, "fatal status bits"); 1570 } 1571 1572 result = 0; 1573 if ((status_reg & TWE_STATUS_EXPECTED_BITS) != TWE_STATUS_EXPECTED_BITS) { 1574 if (time_second > (lastwarn[0] + 5)) { 1575 twe_printf(sc, "missing expected status bit(s) %b\n", ~status_reg & TWE_STATUS_EXPECTED_BITS, 1576 TWE_STATUS_BITS_DESCRIPTION); 1577 lastwarn[0] = time_second; 1578 } 1579 result = 1; 1580 } 1581 1582 if ((status_reg & TWE_STATUS_UNEXPECTED_BITS) != 0) { 1583 if (time_second > (lastwarn[1] + 5)) { 1584 twe_printf(sc, "unexpected status bit(s) %b\n", status_reg & TWE_STATUS_UNEXPECTED_BITS, 1585 TWE_STATUS_BITS_DESCRIPTION); 1586 lastwarn[1] = time_second; 1587 } 1588 result = 1; 1589 } 1590 1591 return(result); 1592} 1593 1594/******************************************************************************** 1595 * Return a string describing (aen). 1596 * 1597 * The low 8 bits of the aen are the code, the high 8 bits give the unit number 1598 * where an AEN is specific to a unit. 1599 * 1600 * Note that we could expand this routine to handle eg. up/downgrading the status 1601 * of a drive if we had some idea of what the drive's initial status was. 1602 */ 1603 1604static char * 1605twe_format_aen(struct twe_softc *sc, u_int16_t aen) 1606{ 1607 static char buf[80]; 1608 device_t child; 1609 char *code, *msg; 1610 1611 code = twe_describe_code(twe_table_aen, TWE_AEN_CODE(aen)); 1612 msg = code + 2; 1613 1614 switch (*code) { 1615 case 'q': 1616 if (!bootverbose) 1617 return(NULL); 1618 /* FALLTHROUGH */ 1619 case 'p': 1620 return(msg); 1621 1622 case 'c': 1623 if ((child = sc->twe_drive[TWE_AEN_UNIT(aen)].td_disk) != NULL) { 1624 sprintf(buf, "twed%d: %s", device_get_unit(child), msg); 1625 } else { 1626 sprintf(buf, "twe%d: %s for unknown unit %d", device_get_unit(sc->twe_dev), 1627 msg, TWE_AEN_UNIT(aen)); 1628 } 1629 return(buf); 1630 1631 case 'x': 1632 default: 1633 break; 1634 } 1635 sprintf(buf, "unknown AEN 0x%x", aen); 1636 return(buf); 1637} 1638 1639/******************************************************************************** 1640 * Print a diagnostic if the status of the command warrants it, and return 1641 * either zero (command was ok) or nonzero (command failed). 1642 */ 1643static int 1644twe_report_request(struct twe_request *tr) 1645{ 1646 struct twe_softc *sc = tr->tr_sc; 1647 TWE_Command *cmd = &tr->tr_command; 1648 int result = 0; 1649 1650 /* 1651 * Check the command status value and handle accordingly. 1652 */ 1653 if (cmd->generic.status == TWE_STATUS_RESET) { 1654 /* 1655 * The status code 0xff requests a controller reset. 1656 */ 1657 twe_printf(sc, "command returned with controller rest request\n"); 1658 twe_reset(sc); 1659 result = 1; 1660 } else if (cmd->generic.status > TWE_STATUS_FATAL) { 1661 /* 1662 * Fatal errors that don't require controller reset. 1663 */ 1664 twe_printf(sc, "command returned fatal status - %s (flags = 0x%x)\n", 1665 twe_describe_code(twe_table_status, cmd->generic.status), 1666 cmd->generic.flags); 1667 result = 1; 1668 } else if (cmd->generic.status > TWE_STATUS_WARNING) { 1669 /* 1670 * Warning level status. 1671 */ 1672 twe_printf(sc, "command returned warning status - %s (flags = 0x%x)\n", 1673 twe_describe_code(twe_table_status, cmd->generic.status), 1674 cmd->generic.flags); 1675 } else if (cmd->generic.status > 0x40) { 1676 /* 1677 * Info level status. 1678 */ 1679 twe_printf(sc, "command returned info status: %s (flags = 0x%x)\n", 1680 twe_describe_code(twe_table_status, cmd->generic.status), 1681 cmd->generic.flags); 1682 } 1683 1684 return(result); 1685} 1686 1687/******************************************************************************** 1688 * Print some controller state to aid in debugging error/panic conditions 1689 */ 1690void 1691twe_print_controller(struct twe_softc *sc) 1692{ 1693 u_int32_t status_reg; 1694 1695 status_reg = TWE_STATUS(sc); 1696 twe_printf(sc, "status %b\n", status_reg, TWE_STATUS_BITS_DESCRIPTION); 1697 twe_printf(sc, " current max\n"); 1698 twe_printf(sc, "free %04d %04d\n", sc->twe_qstat[TWEQ_FREE].q_length, sc->twe_qstat[TWEQ_FREE].q_max); 1699 twe_printf(sc, "ready %04d %04d\n", sc->twe_qstat[TWEQ_READY].q_length, sc->twe_qstat[TWEQ_READY].q_max); 1700 twe_printf(sc, "busy %04d %04d\n", sc->twe_qstat[TWEQ_BUSY].q_length, sc->twe_qstat[TWEQ_BUSY].q_max); 1701 twe_printf(sc, "complete %04d %04d\n", sc->twe_qstat[TWEQ_COMPLETE].q_length, sc->twe_qstat[TWEQ_COMPLETE].q_max); 1702 twe_printf(sc, "bioq %04d %04d\n", sc->twe_qstat[TWEQ_BIO].q_length, sc->twe_qstat[TWEQ_BIO].q_max); 1703 twe_printf(sc, "AEN queue head %d tail %d\n", sc->twe_aen_head, sc->twe_aen_tail); 1704} 1705 1706static void 1707twe_panic(struct twe_softc *sc, char *reason) 1708{ 1709 twe_print_controller(sc); 1710#ifdef TWE_DEBUG 1711 panic(reason); 1712#else 1713 twe_reset(sc); 1714#endif 1715} 1716 1717#if 0 1718/******************************************************************************** 1719 * Print a request/command in human-readable format. 1720 */ 1721static void 1722twe_print_request(struct twe_request *tr) 1723{ 1724 struct twe_softc *sc = tr->tr_sc; 1725 TWE_Command *cmd = &tr->tr_command; 1726 int i; 1727 1728 twe_printf(sc, "CMD: request_id %d opcode <%s> size %d unit %d host_id %d\n", 1729 cmd->generic.request_id, twe_describe_code(twe_table_opcode, cmd->generic.opcode), cmd->generic.size, 1730 cmd->generic.unit, cmd->generic.host_id); 1731 twe_printf(sc, " status %d flags 0x%x count %d sgl_offset %d\n", 1732 cmd->generic.status, cmd->generic.flags, cmd->generic.count, cmd->generic.sgl_offset); 1733 1734 switch(cmd->generic.opcode) { /* XXX add more opcodes? */ 1735 case TWE_OP_READ: 1736 case TWE_OP_WRITE: 1737 twe_printf(sc, " lba %d\n", cmd->io.lba); 1738 for (i = 0; (i < TWE_MAX_SGL_LENGTH) && (cmd->io.sgl[i].length != 0); i++) 1739 twe_printf(sc, " %d: 0x%x/%d\n", 1740 i, cmd->io.sgl[i].address, cmd->io.sgl[i].length); 1741 break; 1742 1743 case TWE_OP_GET_PARAM: 1744 case TWE_OP_SET_PARAM: 1745 for (i = 0; (i < TWE_MAX_SGL_LENGTH) && (cmd->param.sgl[i].length != 0); i++) 1746 twe_printf(sc, " %d: 0x%x/%d\n", 1747 i, cmd->param.sgl[i].address, cmd->param.sgl[i].length); 1748 break; 1749 1750 case TWE_OP_INIT_CONNECTION: 1751 twe_printf(sc, " response queue pointer 0x%x\n", 1752 cmd->initconnection.response_queue_pointer); 1753 break; 1754 1755 default: 1756 break; 1757 } 1758 twe_printf(sc, " tr_command %p/0x%x tr_data %p/0x%x,%d\n", 1759 tr, tr->tr_cmdphys, tr->tr_data, tr->tr_dataphys, tr->tr_length); 1760 twe_printf(sc, " tr_status %d tr_flags 0x%x tr_complete %p tr_private %p\n", 1761 tr->tr_status, tr->tr_flags, tr->tr_complete, tr->tr_private); 1762} 1763 1764#endif 1765