7902 lines · c
1/*2 * Core routines and tables shareable across OS platforms.3 *4 * Copyright (c) 1994-2002 Justin T. Gibbs.5 * Copyright (c) 2000-2002 Adaptec Inc.6 * All rights reserved.7 *8 * Redistribution and use in source and binary forms, with or without9 * modification, are permitted provided that the following conditions10 * are met:11 * 1. Redistributions of source code must retain the above copyright12 * notice, this list of conditions, and the following disclaimer,13 * without modification.14 * 2. Redistributions in binary form must reproduce at minimum a disclaimer15 * substantially similar to the "NO WARRANTY" disclaimer below16 * ("Disclaimer") and any redistribution must be conditioned upon17 * including a substantially similar Disclaimer requirement for further18 * binary redistribution.19 * 3. Neither the names of the above-listed copyright holders nor the names20 * of any contributors may be used to endorse or promote products derived21 * from this software without specific prior written permission.22 *23 * Alternatively, this software may be distributed under the terms of the24 * GNU General Public License ("GPL") version 2 as published by the Free25 * Software Foundation.26 *27 * NO WARRANTY28 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS29 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT30 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR31 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT32 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL33 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS34 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)35 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,36 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING37 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE38 * POSSIBILITY OF SUCH DAMAGES.39 *40 * $Id: //depot/aic7xxx/aic7xxx/aic7xxx.c#155 $41 */42 43#include "aic7xxx_osm.h"44#include "aic7xxx_inline.h"45#include "aicasm/aicasm_insformat.h"46 47/***************************** Lookup Tables **********************************/48static const char *const ahc_chip_names[] = {49 "NONE",50 "aic7770",51 "aic7850",52 "aic7855",53 "aic7859",54 "aic7860",55 "aic7870",56 "aic7880",57 "aic7895",58 "aic7895C",59 "aic7890/91",60 "aic7896/97",61 "aic7892",62 "aic7899"63};64 65/*66 * Hardware error codes.67 */68struct ahc_hard_error_entry {69 uint8_t errno;70 const char *errmesg;71};72 73static const struct ahc_hard_error_entry ahc_hard_errors[] = {74 { ILLHADDR, "Illegal Host Access" },75 { ILLSADDR, "Illegal Sequencer Address referenced" },76 { ILLOPCODE, "Illegal Opcode in sequencer program" },77 { SQPARERR, "Sequencer Parity Error" },78 { DPARERR, "Data-path Parity Error" },79 { MPARERR, "Scratch or SCB Memory Parity Error" },80 { PCIERRSTAT, "PCI Error detected" },81 { CIOPARERR, "CIOBUS Parity Error" },82};83static const u_int num_errors = ARRAY_SIZE(ahc_hard_errors);84 85static const struct ahc_phase_table_entry ahc_phase_table[] =86{87 { P_DATAOUT, NOP, "in Data-out phase" },88 { P_DATAIN, INITIATOR_ERROR, "in Data-in phase" },89 { P_DATAOUT_DT, NOP, "in DT Data-out phase" },90 { P_DATAIN_DT, INITIATOR_ERROR, "in DT Data-in phase" },91 { P_COMMAND, NOP, "in Command phase" },92 { P_MESGOUT, NOP, "in Message-out phase" },93 { P_STATUS, INITIATOR_ERROR, "in Status phase" },94 { P_MESGIN, MSG_PARITY_ERROR, "in Message-in phase" },95 { P_BUSFREE, NOP, "while idle" },96 { 0, NOP, "in unknown phase" }97};98 99/*100 * In most cases we only wish to itterate over real phases, so101 * exclude the last element from the count.102 */103static const u_int num_phases = ARRAY_SIZE(ahc_phase_table) - 1;104 105/*106 * Valid SCSIRATE values. (p. 3-17)107 * Provides a mapping of tranfer periods in ns to the proper value to108 * stick in the scsixfer reg.109 */110static const struct ahc_syncrate ahc_syncrates[] =111{112 /* ultra2 fast/ultra period rate */113 { 0x42, 0x000, 9, "80.0" },114 { 0x03, 0x000, 10, "40.0" },115 { 0x04, 0x000, 11, "33.0" },116 { 0x05, 0x100, 12, "20.0" },117 { 0x06, 0x110, 15, "16.0" },118 { 0x07, 0x120, 18, "13.4" },119 { 0x08, 0x000, 25, "10.0" },120 { 0x19, 0x010, 31, "8.0" },121 { 0x1a, 0x020, 37, "6.67" },122 { 0x1b, 0x030, 43, "5.7" },123 { 0x1c, 0x040, 50, "5.0" },124 { 0x00, 0x050, 56, "4.4" },125 { 0x00, 0x060, 62, "4.0" },126 { 0x00, 0x070, 68, "3.6" },127 { 0x00, 0x000, 0, NULL }128};129 130/* Our Sequencer Program */131#include "aic7xxx_seq.h"132 133/**************************** Function Declarations ***************************/134static void ahc_force_renegotiation(struct ahc_softc *ahc,135 struct ahc_devinfo *devinfo);136static struct ahc_tmode_tstate*137 ahc_alloc_tstate(struct ahc_softc *ahc,138 u_int scsi_id, char channel);139#ifdef AHC_TARGET_MODE140static void ahc_free_tstate(struct ahc_softc *ahc,141 u_int scsi_id, char channel, int force);142#endif143static const struct ahc_syncrate*144 ahc_devlimited_syncrate(struct ahc_softc *ahc,145 struct ahc_initiator_tinfo *,146 u_int *period,147 u_int *ppr_options,148 role_t role);149static void ahc_update_pending_scbs(struct ahc_softc *ahc);150static void ahc_fetch_devinfo(struct ahc_softc *ahc,151 struct ahc_devinfo *devinfo);152static void ahc_scb_devinfo(struct ahc_softc *ahc,153 struct ahc_devinfo *devinfo,154 struct scb *scb);155static void ahc_assert_atn(struct ahc_softc *ahc);156static void ahc_setup_initiator_msgout(struct ahc_softc *ahc,157 struct ahc_devinfo *devinfo,158 struct scb *scb);159static void ahc_build_transfer_msg(struct ahc_softc *ahc,160 struct ahc_devinfo *devinfo);161static void ahc_construct_sdtr(struct ahc_softc *ahc,162 struct ahc_devinfo *devinfo,163 u_int period, u_int offset);164static void ahc_construct_wdtr(struct ahc_softc *ahc,165 struct ahc_devinfo *devinfo,166 u_int bus_width);167static void ahc_construct_ppr(struct ahc_softc *ahc,168 struct ahc_devinfo *devinfo,169 u_int period, u_int offset,170 u_int bus_width, u_int ppr_options);171static void ahc_clear_msg_state(struct ahc_softc *ahc);172static void ahc_handle_proto_violation(struct ahc_softc *ahc);173static void ahc_handle_message_phase(struct ahc_softc *ahc);174typedef enum {175 AHCMSG_1B,176 AHCMSG_2B,177 AHCMSG_EXT178} ahc_msgtype;179static int ahc_sent_msg(struct ahc_softc *ahc, ahc_msgtype type,180 u_int msgval, int full);181static int ahc_parse_msg(struct ahc_softc *ahc,182 struct ahc_devinfo *devinfo);183static int ahc_handle_msg_reject(struct ahc_softc *ahc,184 struct ahc_devinfo *devinfo);185static void ahc_handle_ign_wide_residue(struct ahc_softc *ahc,186 struct ahc_devinfo *devinfo);187static void ahc_reinitialize_dataptrs(struct ahc_softc *ahc);188static void ahc_handle_devreset(struct ahc_softc *ahc,189 struct ahc_devinfo *devinfo,190 cam_status status, char *message,191 int verbose_level);192#ifdef AHC_TARGET_MODE193static void ahc_setup_target_msgin(struct ahc_softc *ahc,194 struct ahc_devinfo *devinfo,195 struct scb *scb);196#endif197 198static bus_dmamap_callback_t ahc_dmamap_cb;199static void ahc_build_free_scb_list(struct ahc_softc *ahc);200static int ahc_init_scbdata(struct ahc_softc *ahc);201static void ahc_fini_scbdata(struct ahc_softc *ahc);202static void ahc_qinfifo_requeue(struct ahc_softc *ahc,203 struct scb *prev_scb,204 struct scb *scb);205static int ahc_qinfifo_count(struct ahc_softc *ahc);206static u_int ahc_rem_scb_from_disc_list(struct ahc_softc *ahc,207 u_int prev, u_int scbptr);208static void ahc_add_curscb_to_free_list(struct ahc_softc *ahc);209static u_int ahc_rem_wscb(struct ahc_softc *ahc,210 u_int scbpos, u_int prev);211static void ahc_reset_current_bus(struct ahc_softc *ahc);212#ifdef AHC_DUMP_SEQ213static void ahc_dumpseq(struct ahc_softc *ahc);214#endif215static int ahc_loadseq(struct ahc_softc *ahc);216static int ahc_check_patch(struct ahc_softc *ahc,217 const struct patch **start_patch,218 u_int start_instr, u_int *skip_addr);219static void ahc_download_instr(struct ahc_softc *ahc,220 u_int instrptr, uint8_t *dconsts);221#ifdef AHC_TARGET_MODE222static void ahc_queue_lstate_event(struct ahc_softc *ahc,223 struct ahc_tmode_lstate *lstate,224 u_int initiator_id,225 u_int event_type,226 u_int event_arg);227static void ahc_update_scsiid(struct ahc_softc *ahc,228 u_int targid_mask);229static int ahc_handle_target_cmd(struct ahc_softc *ahc,230 struct target_cmd *cmd);231#endif232 233static u_int ahc_index_busy_tcl(struct ahc_softc *ahc, u_int tcl);234static void ahc_unbusy_tcl(struct ahc_softc *ahc, u_int tcl);235static void ahc_busy_tcl(struct ahc_softc *ahc,236 u_int tcl, u_int busyid);237 238/************************** SCB and SCB queue management **********************/239static void ahc_run_untagged_queues(struct ahc_softc *ahc);240static void ahc_run_untagged_queue(struct ahc_softc *ahc,241 struct scb_tailq *queue);242 243/****************************** Initialization ********************************/244static void ahc_alloc_scbs(struct ahc_softc *ahc);245static void ahc_shutdown(void *arg);246 247/*************************** Interrupt Services *******************************/248static void ahc_clear_intstat(struct ahc_softc *ahc);249static void ahc_run_qoutfifo(struct ahc_softc *ahc);250#ifdef AHC_TARGET_MODE251static void ahc_run_tqinfifo(struct ahc_softc *ahc, int paused);252#endif253static void ahc_handle_brkadrint(struct ahc_softc *ahc);254static void ahc_handle_seqint(struct ahc_softc *ahc, u_int intstat);255static void ahc_handle_scsiint(struct ahc_softc *ahc,256 u_int intstat);257static void ahc_clear_critical_section(struct ahc_softc *ahc);258 259/***************************** Error Recovery *********************************/260static void ahc_freeze_devq(struct ahc_softc *ahc, struct scb *scb);261static int ahc_abort_scbs(struct ahc_softc *ahc, int target,262 char channel, int lun, u_int tag,263 role_t role, uint32_t status);264static void ahc_calc_residual(struct ahc_softc *ahc,265 struct scb *scb);266 267/*********************** Untagged Transaction Routines ************************/268static inline void ahc_freeze_untagged_queues(struct ahc_softc *ahc);269static inline void ahc_release_untagged_queues(struct ahc_softc *ahc);270 271/*272 * Block our completion routine from starting the next untagged273 * transaction for this target or target lun.274 */275static inline void276ahc_freeze_untagged_queues(struct ahc_softc *ahc)277{278 if ((ahc->flags & AHC_SCB_BTT) == 0)279 ahc->untagged_queue_lock++;280}281 282/*283 * Allow the next untagged transaction for this target or target lun284 * to be executed. We use a counting semaphore to allow the lock285 * to be acquired recursively. Once the count drops to zero, the286 * transaction queues will be run.287 */288static inline void289ahc_release_untagged_queues(struct ahc_softc *ahc)290{291 if ((ahc->flags & AHC_SCB_BTT) == 0) {292 ahc->untagged_queue_lock--;293 if (ahc->untagged_queue_lock == 0)294 ahc_run_untagged_queues(ahc);295 }296}297 298/************************* Sequencer Execution Control ************************/299/*300 * Work around any chip bugs related to halting sequencer execution.301 * On Ultra2 controllers, we must clear the CIOBUS stretch signal by302 * reading a register that will set this signal and deassert it.303 * Without this workaround, if the chip is paused, by an interrupt or304 * manual pause while accessing scb ram, accesses to certain registers305 * will hang the system (infinite pci retries).306 */307static void308ahc_pause_bug_fix(struct ahc_softc *ahc)309{310 if ((ahc->features & AHC_ULTRA2) != 0)311 (void)ahc_inb(ahc, CCSCBCTL);312}313 314/*315 * Determine whether the sequencer has halted code execution.316 * Returns non-zero status if the sequencer is stopped.317 */318int319ahc_is_paused(struct ahc_softc *ahc)320{321 return ((ahc_inb(ahc, HCNTRL) & PAUSE) != 0);322}323 324/*325 * Request that the sequencer stop and wait, indefinitely, for it326 * to stop. The sequencer will only acknowledge that it is paused327 * once it has reached an instruction boundary and PAUSEDIS is328 * cleared in the SEQCTL register. The sequencer may use PAUSEDIS329 * for critical sections.330 */331void332ahc_pause(struct ahc_softc *ahc)333{334 ahc_outb(ahc, HCNTRL, ahc->pause);335 336 /*337 * Since the sequencer can disable pausing in a critical section, we338 * must loop until it actually stops.339 */340 while (ahc_is_paused(ahc) == 0)341 ;342 343 ahc_pause_bug_fix(ahc);344}345 346/*347 * Allow the sequencer to continue program execution.348 * We check here to ensure that no additional interrupt349 * sources that would cause the sequencer to halt have been350 * asserted. If, for example, a SCSI bus reset is detected351 * while we are fielding a different, pausing, interrupt type,352 * we don't want to release the sequencer before going back353 * into our interrupt handler and dealing with this new354 * condition.355 */356void357ahc_unpause(struct ahc_softc *ahc)358{359 if ((ahc_inb(ahc, INTSTAT) & (SCSIINT | SEQINT | BRKADRINT)) == 0)360 ahc_outb(ahc, HCNTRL, ahc->unpause);361}362 363/************************** Memory mapping routines ***************************/364static struct ahc_dma_seg *365ahc_sg_bus_to_virt(struct scb *scb, uint32_t sg_busaddr)366{367 int sg_index;368 369 sg_index = (sg_busaddr - scb->sg_list_phys)/sizeof(struct ahc_dma_seg);370 /* sg_list_phys points to entry 1, not 0 */371 sg_index++;372 373 return (&scb->sg_list[sg_index]);374}375 376static uint32_t377ahc_sg_virt_to_bus(struct scb *scb, struct ahc_dma_seg *sg)378{379 int sg_index;380 381 /* sg_list_phys points to entry 1, not 0 */382 sg_index = sg - &scb->sg_list[1];383 384 return (scb->sg_list_phys + (sg_index * sizeof(*scb->sg_list)));385}386 387static uint32_t388ahc_hscb_busaddr(struct ahc_softc *ahc, u_int index)389{390 return (ahc->scb_data->hscb_busaddr391 + (sizeof(struct hardware_scb) * index));392}393 394static void395ahc_sync_scb(struct ahc_softc *ahc, struct scb *scb, int op)396{397 ahc_dmamap_sync(ahc, ahc->scb_data->hscb_dmat,398 ahc->scb_data->hscb_dmamap,399 /*offset*/(scb->hscb - ahc->hscbs) * sizeof(*scb->hscb),400 /*len*/sizeof(*scb->hscb), op);401}402 403void404ahc_sync_sglist(struct ahc_softc *ahc, struct scb *scb, int op)405{406 if (scb->sg_count == 0)407 return;408 409 ahc_dmamap_sync(ahc, ahc->scb_data->sg_dmat, scb->sg_map->sg_dmamap,410 /*offset*/(scb->sg_list - scb->sg_map->sg_vaddr)411 * sizeof(struct ahc_dma_seg),412 /*len*/sizeof(struct ahc_dma_seg) * scb->sg_count, op);413}414 415#ifdef AHC_TARGET_MODE416static uint32_t417ahc_targetcmd_offset(struct ahc_softc *ahc, u_int index)418{419 return (((uint8_t *)&ahc->targetcmds[index]) - ahc->qoutfifo);420}421#endif422 423/*********************** Miscellaneous Support Functions ***********************/424/*425 * Determine whether the sequencer reported a residual426 * for this SCB/transaction.427 */428static void429ahc_update_residual(struct ahc_softc *ahc, struct scb *scb)430{431 uint32_t sgptr;432 433 sgptr = ahc_le32toh(scb->hscb->sgptr);434 if ((sgptr & SG_RESID_VALID) != 0)435 ahc_calc_residual(ahc, scb);436}437 438/*439 * Return pointers to the transfer negotiation information440 * for the specified our_id/remote_id pair.441 */442struct ahc_initiator_tinfo *443ahc_fetch_transinfo(struct ahc_softc *ahc, char channel, u_int our_id,444 u_int remote_id, struct ahc_tmode_tstate **tstate)445{446 /*447 * Transfer data structures are stored from the perspective448 * of the target role. Since the parameters for a connection449 * in the initiator role to a given target are the same as450 * when the roles are reversed, we pretend we are the target.451 */452 if (channel == 'B')453 our_id += 8;454 *tstate = ahc->enabled_targets[our_id];455 return (&(*tstate)->transinfo[remote_id]);456}457 458uint16_t459ahc_inw(struct ahc_softc *ahc, u_int port)460{461 uint16_t r = ahc_inb(ahc, port+1) << 8;462 return r | ahc_inb(ahc, port);463}464 465void466ahc_outw(struct ahc_softc *ahc, u_int port, u_int value)467{468 ahc_outb(ahc, port, value & 0xFF);469 ahc_outb(ahc, port+1, (value >> 8) & 0xFF);470}471 472uint32_t473ahc_inl(struct ahc_softc *ahc, u_int port)474{475 return ((ahc_inb(ahc, port))476 | (ahc_inb(ahc, port+1) << 8)477 | (ahc_inb(ahc, port+2) << 16)478 | (ahc_inb(ahc, port+3) << 24));479}480 481void482ahc_outl(struct ahc_softc *ahc, u_int port, uint32_t value)483{484 ahc_outb(ahc, port, (value) & 0xFF);485 ahc_outb(ahc, port+1, ((value) >> 8) & 0xFF);486 ahc_outb(ahc, port+2, ((value) >> 16) & 0xFF);487 ahc_outb(ahc, port+3, ((value) >> 24) & 0xFF);488}489 490uint64_t491ahc_inq(struct ahc_softc *ahc, u_int port)492{493 return ((ahc_inb(ahc, port))494 | (ahc_inb(ahc, port+1) << 8)495 | (ahc_inb(ahc, port+2) << 16)496 | (((uint64_t)ahc_inb(ahc, port+3)) << 24)497 | (((uint64_t)ahc_inb(ahc, port+4)) << 32)498 | (((uint64_t)ahc_inb(ahc, port+5)) << 40)499 | (((uint64_t)ahc_inb(ahc, port+6)) << 48)500 | (((uint64_t)ahc_inb(ahc, port+7)) << 56));501}502 503void504ahc_outq(struct ahc_softc *ahc, u_int port, uint64_t value)505{506 ahc_outb(ahc, port, value & 0xFF);507 ahc_outb(ahc, port+1, (value >> 8) & 0xFF);508 ahc_outb(ahc, port+2, (value >> 16) & 0xFF);509 ahc_outb(ahc, port+3, (value >> 24) & 0xFF);510 ahc_outb(ahc, port+4, (value >> 32) & 0xFF);511 ahc_outb(ahc, port+5, (value >> 40) & 0xFF);512 ahc_outb(ahc, port+6, (value >> 48) & 0xFF);513 ahc_outb(ahc, port+7, (value >> 56) & 0xFF);514}515 516/*517 * Get a free scb. If there are none, see if we can allocate a new SCB.518 */519struct scb *520ahc_get_scb(struct ahc_softc *ahc)521{522 struct scb *scb;523 524 if ((scb = SLIST_FIRST(&ahc->scb_data->free_scbs)) == NULL) {525 ahc_alloc_scbs(ahc);526 scb = SLIST_FIRST(&ahc->scb_data->free_scbs);527 if (scb == NULL)528 return (NULL);529 }530 SLIST_REMOVE_HEAD(&ahc->scb_data->free_scbs, links.sle);531 return (scb);532}533 534/*535 * Return an SCB resource to the free list.536 */537void538ahc_free_scb(struct ahc_softc *ahc, struct scb *scb)539{540 struct hardware_scb *hscb;541 542 hscb = scb->hscb;543 /* Clean up for the next user */544 ahc->scb_data->scbindex[hscb->tag] = NULL;545 scb->flags = SCB_FREE;546 hscb->control = 0;547 548 SLIST_INSERT_HEAD(&ahc->scb_data->free_scbs, scb, links.sle);549 550 /* Notify the OSM that a resource is now available. */551 ahc_platform_scb_free(ahc, scb);552}553 554struct scb *555ahc_lookup_scb(struct ahc_softc *ahc, u_int tag)556{557 struct scb* scb;558 559 scb = ahc->scb_data->scbindex[tag];560 if (scb != NULL)561 ahc_sync_scb(ahc, scb,562 BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE);563 return (scb);564}565 566static void567ahc_swap_with_next_hscb(struct ahc_softc *ahc, struct scb *scb)568{569 struct hardware_scb *q_hscb;570 u_int saved_tag;571 572 /*573 * Our queuing method is a bit tricky. The card574 * knows in advance which HSCB to download, and we575 * can't disappoint it. To achieve this, the next576 * SCB to download is saved off in ahc->next_queued_scb.577 * When we are called to queue "an arbitrary scb",578 * we copy the contents of the incoming HSCB to the one579 * the sequencer knows about, swap HSCB pointers and580 * finally assign the SCB to the tag indexed location581 * in the scb_array. This makes sure that we can still582 * locate the correct SCB by SCB_TAG.583 */584 q_hscb = ahc->next_queued_scb->hscb;585 saved_tag = q_hscb->tag;586 memcpy(q_hscb, scb->hscb, sizeof(*scb->hscb));587 if ((scb->flags & SCB_CDB32_PTR) != 0) {588 q_hscb->shared_data.cdb_ptr =589 ahc_htole32(ahc_hscb_busaddr(ahc, q_hscb->tag)590 + offsetof(struct hardware_scb, cdb32));591 }592 q_hscb->tag = saved_tag;593 q_hscb->next = scb->hscb->tag;594 595 /* Now swap HSCB pointers. */596 ahc->next_queued_scb->hscb = scb->hscb;597 scb->hscb = q_hscb;598 599 /* Now define the mapping from tag to SCB in the scbindex */600 ahc->scb_data->scbindex[scb->hscb->tag] = scb;601}602 603/*604 * Tell the sequencer about a new transaction to execute.605 */606void607ahc_queue_scb(struct ahc_softc *ahc, struct scb *scb)608{609 ahc_swap_with_next_hscb(ahc, scb);610 611 if (scb->hscb->tag == SCB_LIST_NULL612 || scb->hscb->next == SCB_LIST_NULL)613 panic("Attempt to queue invalid SCB tag %x:%x\n",614 scb->hscb->tag, scb->hscb->next);615 616 /*617 * Setup data "oddness".618 */619 scb->hscb->lun &= LID;620 if (ahc_get_transfer_length(scb) & 0x1)621 scb->hscb->lun |= SCB_XFERLEN_ODD;622 623 /*624 * Keep a history of SCBs we've downloaded in the qinfifo.625 */626 ahc->qinfifo[ahc->qinfifonext++] = scb->hscb->tag;627 628 /*629 * Make sure our data is consistent from the630 * perspective of the adapter.631 */632 ahc_sync_scb(ahc, scb, BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);633 634 /* Tell the adapter about the newly queued SCB */635 if ((ahc->features & AHC_QUEUE_REGS) != 0) {636 ahc_outb(ahc, HNSCB_QOFF, ahc->qinfifonext);637 } else {638 if ((ahc->features & AHC_AUTOPAUSE) == 0)639 ahc_pause(ahc);640 ahc_outb(ahc, KERNEL_QINPOS, ahc->qinfifonext);641 if ((ahc->features & AHC_AUTOPAUSE) == 0)642 ahc_unpause(ahc);643 }644}645 646struct scsi_sense_data *647ahc_get_sense_buf(struct ahc_softc *ahc, struct scb *scb)648{649 int offset;650 651 offset = scb - ahc->scb_data->scbarray;652 return (&ahc->scb_data->sense[offset]);653}654 655static uint32_t656ahc_get_sense_bufaddr(struct ahc_softc *ahc, struct scb *scb)657{658 int offset;659 660 offset = scb - ahc->scb_data->scbarray;661 return (ahc->scb_data->sense_busaddr662 + (offset * sizeof(struct scsi_sense_data)));663}664 665/************************** Interrupt Processing ******************************/666static void667ahc_sync_qoutfifo(struct ahc_softc *ahc, int op)668{669 ahc_dmamap_sync(ahc, ahc->shared_data_dmat, ahc->shared_data_dmamap,670 /*offset*/0, /*len*/256, op);671}672 673static void674ahc_sync_tqinfifo(struct ahc_softc *ahc, int op)675{676#ifdef AHC_TARGET_MODE677 if ((ahc->flags & AHC_TARGETROLE) != 0) {678 ahc_dmamap_sync(ahc, ahc->shared_data_dmat,679 ahc->shared_data_dmamap,680 ahc_targetcmd_offset(ahc, 0),681 sizeof(struct target_cmd) * AHC_TMODE_CMDS,682 op);683 }684#endif685}686 687/*688 * See if the firmware has posted any completed commands689 * into our in-core command complete fifos.690 */691#define AHC_RUN_QOUTFIFO 0x1692#define AHC_RUN_TQINFIFO 0x2693static u_int694ahc_check_cmdcmpltqueues(struct ahc_softc *ahc)695{696 u_int retval;697 698 retval = 0;699 ahc_dmamap_sync(ahc, ahc->shared_data_dmat, ahc->shared_data_dmamap,700 /*offset*/ahc->qoutfifonext, /*len*/1,701 BUS_DMASYNC_POSTREAD);702 if (ahc->qoutfifo[ahc->qoutfifonext] != SCB_LIST_NULL)703 retval |= AHC_RUN_QOUTFIFO;704#ifdef AHC_TARGET_MODE705 if ((ahc->flags & AHC_TARGETROLE) != 0706 && (ahc->flags & AHC_TQINFIFO_BLOCKED) == 0) {707 ahc_dmamap_sync(ahc, ahc->shared_data_dmat,708 ahc->shared_data_dmamap,709 ahc_targetcmd_offset(ahc, ahc->tqinfifofnext),710 /*len*/sizeof(struct target_cmd),711 BUS_DMASYNC_POSTREAD);712 if (ahc->targetcmds[ahc->tqinfifonext].cmd_valid != 0)713 retval |= AHC_RUN_TQINFIFO;714 }715#endif716 return (retval);717}718 719/*720 * Catch an interrupt from the adapter721 */722int723ahc_intr(struct ahc_softc *ahc)724{725 u_int intstat;726 727 if ((ahc->pause & INTEN) == 0) {728 /*729 * Our interrupt is not enabled on the chip730 * and may be disabled for re-entrancy reasons,731 * so just return. This is likely just a shared732 * interrupt.733 */734 return (0);735 }736 /*737 * Instead of directly reading the interrupt status register,738 * infer the cause of the interrupt by checking our in-core739 * completion queues. This avoids a costly PCI bus read in740 * most cases.741 */742 if ((ahc->flags & (AHC_ALL_INTERRUPTS|AHC_EDGE_INTERRUPT)) == 0743 && (ahc_check_cmdcmpltqueues(ahc) != 0))744 intstat = CMDCMPLT;745 else {746 intstat = ahc_inb(ahc, INTSTAT);747 }748 749 if ((intstat & INT_PEND) == 0) {750#if AHC_PCI_CONFIG > 0751 if (ahc->unsolicited_ints > 500) {752 ahc->unsolicited_ints = 0;753 if ((ahc->chip & AHC_PCI) != 0754 && (ahc_inb(ahc, ERROR) & PCIERRSTAT) != 0)755 ahc->bus_intr(ahc);756 }757#endif758 ahc->unsolicited_ints++;759 return (0);760 }761 ahc->unsolicited_ints = 0;762 763 if (intstat & CMDCMPLT) {764 ahc_outb(ahc, CLRINT, CLRCMDINT);765 766 /*767 * Ensure that the chip sees that we've cleared768 * this interrupt before we walk the output fifo.769 * Otherwise, we may, due to posted bus writes,770 * clear the interrupt after we finish the scan,771 * and after the sequencer has added new entries772 * and asserted the interrupt again.773 */774 ahc_flush_device_writes(ahc);775 ahc_run_qoutfifo(ahc);776#ifdef AHC_TARGET_MODE777 if ((ahc->flags & AHC_TARGETROLE) != 0)778 ahc_run_tqinfifo(ahc, /*paused*/FALSE);779#endif780 }781 782 /*783 * Handle statuses that may invalidate our cached784 * copy of INTSTAT separately.785 */786 if (intstat == 0xFF && (ahc->features & AHC_REMOVABLE) != 0) {787 /* Hot eject. Do nothing */788 } else if (intstat & BRKADRINT) {789 ahc_handle_brkadrint(ahc);790 } else if ((intstat & (SEQINT|SCSIINT)) != 0) {791 792 ahc_pause_bug_fix(ahc);793 794 if ((intstat & SEQINT) != 0)795 ahc_handle_seqint(ahc, intstat);796 797 if ((intstat & SCSIINT) != 0)798 ahc_handle_scsiint(ahc, intstat);799 }800 return (1);801}802 803/************************* Sequencer Execution Control ************************/804/*805 * Restart the sequencer program from address zero806 */807static void808ahc_restart(struct ahc_softc *ahc)809{810 uint8_t sblkctl;811 812 ahc_pause(ahc);813 814 /* No more pending messages. */815 ahc_clear_msg_state(ahc);816 817 ahc_outb(ahc, SCSISIGO, 0); /* De-assert BSY */818 ahc_outb(ahc, MSG_OUT, NOP); /* No message to send */819 ahc_outb(ahc, SXFRCTL1, ahc_inb(ahc, SXFRCTL1) & ~BITBUCKET);820 ahc_outb(ahc, LASTPHASE, P_BUSFREE);821 ahc_outb(ahc, SAVED_SCSIID, 0xFF);822 ahc_outb(ahc, SAVED_LUN, 0xFF);823 824 /*825 * Ensure that the sequencer's idea of TQINPOS826 * matches our own. The sequencer increments TQINPOS827 * only after it sees a DMA complete and a reset could828 * occur before the increment leaving the kernel to believe829 * the command arrived but the sequencer to not.830 */831 ahc_outb(ahc, TQINPOS, ahc->tqinfifonext);832 833 /* Always allow reselection */834 ahc_outb(ahc, SCSISEQ,835 ahc_inb(ahc, SCSISEQ_TEMPLATE) & (ENSELI|ENRSELI|ENAUTOATNP));836 if ((ahc->features & AHC_CMD_CHAN) != 0) {837 /* Ensure that no DMA operations are in progress */838 ahc_outb(ahc, CCSCBCNT, 0);839 ahc_outb(ahc, CCSGCTL, 0);840 ahc_outb(ahc, CCSCBCTL, 0);841 }842 /*843 * If we were in the process of DMA'ing SCB data into844 * an SCB, replace that SCB on the free list. This prevents845 * an SCB leak.846 */847 if ((ahc_inb(ahc, SEQ_FLAGS2) & SCB_DMA) != 0) {848 ahc_add_curscb_to_free_list(ahc);849 ahc_outb(ahc, SEQ_FLAGS2,850 ahc_inb(ahc, SEQ_FLAGS2) & ~SCB_DMA);851 }852 853 /*854 * Clear any pending sequencer interrupt. It is no855 * longer relevant since we're resetting the Program856 * Counter.857 */858 ahc_outb(ahc, CLRINT, CLRSEQINT);859 860 ahc_outb(ahc, MWI_RESIDUAL, 0);861 ahc_outb(ahc, SEQCTL, ahc->seqctl);862 ahc_outb(ahc, SEQADDR0, 0);863 ahc_outb(ahc, SEQADDR1, 0);864 865 /*866 * Take the LED out of diagnostic mode on PM resume, too867 */868 sblkctl = ahc_inb(ahc, SBLKCTL);869 ahc_outb(ahc, SBLKCTL, (sblkctl & ~(DIAGLEDEN|DIAGLEDON)));870 871 ahc_unpause(ahc);872}873 874/************************* Input/Output Queues ********************************/875static void876ahc_run_qoutfifo(struct ahc_softc *ahc)877{878 struct scb *scb;879 u_int scb_index;880 881 ahc_sync_qoutfifo(ahc, BUS_DMASYNC_POSTREAD);882 while (ahc->qoutfifo[ahc->qoutfifonext] != SCB_LIST_NULL) {883 884 scb_index = ahc->qoutfifo[ahc->qoutfifonext];885 if ((ahc->qoutfifonext & 0x03) == 0x03) {886 u_int modnext;887 888 /*889 * Clear 32bits of QOUTFIFO at a time890 * so that we don't clobber an incoming891 * byte DMA to the array on architectures892 * that only support 32bit load and store893 * operations.894 */895 modnext = ahc->qoutfifonext & ~0x3;896 *((uint32_t *)(&ahc->qoutfifo[modnext])) = 0xFFFFFFFFUL;897 ahc_dmamap_sync(ahc, ahc->shared_data_dmat,898 ahc->shared_data_dmamap,899 /*offset*/modnext, /*len*/4,900 BUS_DMASYNC_PREREAD);901 }902 ahc->qoutfifonext++;903 904 scb = ahc_lookup_scb(ahc, scb_index);905 if (scb == NULL) {906 printk("%s: WARNING no command for scb %d "907 "(cmdcmplt)\nQOUTPOS = %d\n",908 ahc_name(ahc), scb_index,909 (ahc->qoutfifonext - 1) & 0xFF);910 continue;911 }912 913 /*914 * Save off the residual915 * if there is one.916 */917 ahc_update_residual(ahc, scb);918 ahc_done(ahc, scb);919 }920}921 922static void923ahc_run_untagged_queues(struct ahc_softc *ahc)924{925 int i;926 927 for (i = 0; i < 16; i++)928 ahc_run_untagged_queue(ahc, &ahc->untagged_queues[i]);929}930 931static void932ahc_run_untagged_queue(struct ahc_softc *ahc, struct scb_tailq *queue)933{934 struct scb *scb;935 936 if (ahc->untagged_queue_lock != 0)937 return;938 939 if ((scb = TAILQ_FIRST(queue)) != NULL940 && (scb->flags & SCB_ACTIVE) == 0) {941 scb->flags |= SCB_ACTIVE;942 ahc_queue_scb(ahc, scb);943 }944}945 946/************************* Interrupt Handling *********************************/947static void948ahc_handle_brkadrint(struct ahc_softc *ahc)949{950 /*951 * We upset the sequencer :-(952 * Lookup the error message953 */954 int i;955 int error;956 957 error = ahc_inb(ahc, ERROR);958 for (i = 0; error != 1 && i < num_errors; i++)959 error >>= 1;960 printk("%s: brkadrint, %s at seqaddr = 0x%x\n",961 ahc_name(ahc), ahc_hard_errors[i].errmesg,962 ahc_inb(ahc, SEQADDR0) |963 (ahc_inb(ahc, SEQADDR1) << 8));964 965 ahc_dump_card_state(ahc);966 967 /* Tell everyone that this HBA is no longer available */968 ahc_abort_scbs(ahc, CAM_TARGET_WILDCARD, ALL_CHANNELS,969 CAM_LUN_WILDCARD, SCB_LIST_NULL, ROLE_UNKNOWN,970 CAM_NO_HBA);971 972 /* Disable all interrupt sources by resetting the controller */973 ahc_shutdown(ahc);974}975 976static void977ahc_handle_seqint(struct ahc_softc *ahc, u_int intstat)978{979 struct scb *scb;980 struct ahc_devinfo devinfo;981 982 ahc_fetch_devinfo(ahc, &devinfo);983 984 /*985 * Clear the upper byte that holds SEQINT status986 * codes and clear the SEQINT bit. We will unpause987 * the sequencer, if appropriate, after servicing988 * the request.989 */990 ahc_outb(ahc, CLRINT, CLRSEQINT);991 switch (intstat & SEQINT_MASK) {992 case BAD_STATUS:993 {994 u_int scb_index;995 struct hardware_scb *hscb;996 997 /*998 * Set the default return value to 0 (don't999 * send sense). The sense code will change1000 * this if needed.1001 */1002 ahc_outb(ahc, RETURN_1, 0);1003 1004 /*1005 * The sequencer will notify us when a command1006 * has an error that would be of interest to1007 * the kernel. This allows us to leave the sequencer1008 * running in the common case of command completes1009 * without error. The sequencer will already have1010 * dma'd the SCB back up to us, so we can reference1011 * the in kernel copy directly.1012 */1013 scb_index = ahc_inb(ahc, SCB_TAG);1014 scb = ahc_lookup_scb(ahc, scb_index);1015 if (scb == NULL) {1016 ahc_print_devinfo(ahc, &devinfo);1017 printk("ahc_intr - referenced scb "1018 "not valid during seqint 0x%x scb(%d)\n",1019 intstat, scb_index);1020 ahc_dump_card_state(ahc);1021 panic("for safety");1022 goto unpause;1023 }1024 1025 hscb = scb->hscb;1026 1027 /* Don't want to clobber the original sense code */1028 if ((scb->flags & SCB_SENSE) != 0) {1029 /*1030 * Clear the SCB_SENSE Flag and have1031 * the sequencer do a normal command1032 * complete.1033 */1034 scb->flags &= ~SCB_SENSE;1035 ahc_set_transaction_status(scb, CAM_AUTOSENSE_FAIL);1036 break;1037 }1038 ahc_set_transaction_status(scb, CAM_SCSI_STATUS_ERROR);1039 /* Freeze the queue until the client sees the error. */1040 ahc_freeze_devq(ahc, scb);1041 ahc_freeze_scb(scb);1042 ahc_set_scsi_status(scb, hscb->shared_data.status.scsi_status);1043 switch (hscb->shared_data.status.scsi_status) {1044 case SAM_STAT_GOOD:1045 printk("%s: Interrupted for status of 0???\n",1046 ahc_name(ahc));1047 break;1048 case SAM_STAT_COMMAND_TERMINATED:1049 case SAM_STAT_CHECK_CONDITION:1050 {1051 struct ahc_dma_seg *sg;1052 struct scsi_sense *sc;1053 struct ahc_initiator_tinfo *targ_info;1054 struct ahc_tmode_tstate *tstate;1055 struct ahc_transinfo *tinfo;1056#ifdef AHC_DEBUG1057 if (ahc_debug & AHC_SHOW_SENSE) {1058 ahc_print_path(ahc, scb);1059 printk("SCB %d: requests Check Status\n",1060 scb->hscb->tag);1061 }1062#endif1063 1064 if (ahc_perform_autosense(scb) == 0)1065 break;1066 1067 targ_info = ahc_fetch_transinfo(ahc,1068 devinfo.channel,1069 devinfo.our_scsiid,1070 devinfo.target,1071 &tstate);1072 tinfo = &targ_info->curr;1073 sg = scb->sg_list;1074 sc = (struct scsi_sense *)(&hscb->shared_data.cdb);1075 /*1076 * Save off the residual if there is one.1077 */1078 ahc_update_residual(ahc, scb);1079#ifdef AHC_DEBUG1080 if (ahc_debug & AHC_SHOW_SENSE) {1081 ahc_print_path(ahc, scb);1082 printk("Sending Sense\n");1083 }1084#endif1085 sg->addr = ahc_get_sense_bufaddr(ahc, scb);1086 sg->len = ahc_get_sense_bufsize(ahc, scb);1087 sg->len |= AHC_DMA_LAST_SEG;1088 1089 /* Fixup byte order */1090 sg->addr = ahc_htole32(sg->addr);1091 sg->len = ahc_htole32(sg->len);1092 1093 sc->opcode = REQUEST_SENSE;1094 sc->byte2 = 0;1095 if (tinfo->protocol_version <= SCSI_REV_21096 && SCB_GET_LUN(scb) < 8)1097 sc->byte2 = SCB_GET_LUN(scb) << 5;1098 sc->unused[0] = 0;1099 sc->unused[1] = 0;1100 sc->length = sg->len;1101 sc->control = 0;1102 1103 /*1104 * We can't allow the target to disconnect.1105 * This will be an untagged transaction and1106 * having the target disconnect will make this1107 * transaction indestinguishable from outstanding1108 * tagged transactions.1109 */1110 hscb->control = 0;1111 1112 /*1113 * This request sense could be because the1114 * the device lost power or in some other1115 * way has lost our transfer negotiations.1116 * Renegotiate if appropriate. Unit attention1117 * errors will be reported before any data1118 * phases occur.1119 */1120 if (ahc_get_residual(scb)1121 == ahc_get_transfer_length(scb)) {1122 ahc_update_neg_request(ahc, &devinfo,1123 tstate, targ_info,1124 AHC_NEG_IF_NON_ASYNC);1125 }1126 if (tstate->auto_negotiate & devinfo.target_mask) {1127 hscb->control |= MK_MESSAGE;1128 scb->flags &= ~SCB_NEGOTIATE;1129 scb->flags |= SCB_AUTO_NEGOTIATE;1130 }1131 hscb->cdb_len = sizeof(*sc);1132 hscb->dataptr = sg->addr;1133 hscb->datacnt = sg->len;1134 hscb->sgptr = scb->sg_list_phys | SG_FULL_RESID;1135 hscb->sgptr = ahc_htole32(hscb->sgptr);1136 scb->sg_count = 1;1137 scb->flags |= SCB_SENSE;1138 ahc_qinfifo_requeue_tail(ahc, scb);1139 ahc_outb(ahc, RETURN_1, SEND_SENSE);1140 /*1141 * Ensure we have enough time to actually1142 * retrieve the sense.1143 */1144 ahc_scb_timer_reset(scb, 5 * 1000000);1145 break;1146 }1147 default:1148 break;1149 }1150 break;1151 }1152 case NO_MATCH:1153 {1154 /* Ensure we don't leave the selection hardware on */1155 ahc_outb(ahc, SCSISEQ,1156 ahc_inb(ahc, SCSISEQ) & (ENSELI|ENRSELI|ENAUTOATNP));1157 1158 printk("%s:%c:%d: no active SCB for reconnecting "1159 "target - issuing BUS DEVICE RESET\n",1160 ahc_name(ahc), devinfo.channel, devinfo.target);1161 printk("SAVED_SCSIID == 0x%x, SAVED_LUN == 0x%x, "1162 "ARG_1 == 0x%x ACCUM = 0x%x\n",1163 ahc_inb(ahc, SAVED_SCSIID), ahc_inb(ahc, SAVED_LUN),1164 ahc_inb(ahc, ARG_1), ahc_inb(ahc, ACCUM));1165 printk("SEQ_FLAGS == 0x%x, SCBPTR == 0x%x, BTT == 0x%x, "1166 "SINDEX == 0x%x\n",1167 ahc_inb(ahc, SEQ_FLAGS), ahc_inb(ahc, SCBPTR),1168 ahc_index_busy_tcl(ahc,1169 BUILD_TCL(ahc_inb(ahc, SAVED_SCSIID),1170 ahc_inb(ahc, SAVED_LUN))),1171 ahc_inb(ahc, SINDEX));1172 printk("SCSIID == 0x%x, SCB_SCSIID == 0x%x, SCB_LUN == 0x%x, "1173 "SCB_TAG == 0x%x, SCB_CONTROL == 0x%x\n",1174 ahc_inb(ahc, SCSIID), ahc_inb(ahc, SCB_SCSIID),1175 ahc_inb(ahc, SCB_LUN), ahc_inb(ahc, SCB_TAG),1176 ahc_inb(ahc, SCB_CONTROL));1177 printk("SCSIBUSL == 0x%x, SCSISIGI == 0x%x\n",1178 ahc_inb(ahc, SCSIBUSL), ahc_inb(ahc, SCSISIGI));1179 printk("SXFRCTL0 == 0x%x\n", ahc_inb(ahc, SXFRCTL0));1180 printk("SEQCTL == 0x%x\n", ahc_inb(ahc, SEQCTL));1181 ahc_dump_card_state(ahc);1182 ahc->msgout_buf[0] = TARGET_RESET;1183 ahc->msgout_len = 1;1184 ahc->msgout_index = 0;1185 ahc->msg_type = MSG_TYPE_INITIATOR_MSGOUT;1186 ahc_outb(ahc, MSG_OUT, HOST_MSG);1187 ahc_assert_atn(ahc);1188 break;1189 }1190 case SEND_REJECT:1191 {1192 u_int rejbyte = ahc_inb(ahc, ACCUM);1193 printk("%s:%c:%d: Warning - unknown message received from "1194 "target (0x%x). Rejecting\n",1195 ahc_name(ahc), devinfo.channel, devinfo.target, rejbyte);1196 break;1197 }1198 case PROTO_VIOLATION:1199 {1200 ahc_handle_proto_violation(ahc);1201 break;1202 }1203 case IGN_WIDE_RES:1204 ahc_handle_ign_wide_residue(ahc, &devinfo);1205 break;1206 case PDATA_REINIT:1207 ahc_reinitialize_dataptrs(ahc);1208 break;1209 case BAD_PHASE:1210 {1211 u_int lastphase;1212 1213 lastphase = ahc_inb(ahc, LASTPHASE);1214 printk("%s:%c:%d: unknown scsi bus phase %x, "1215 "lastphase = 0x%x. Attempting to continue\n",1216 ahc_name(ahc), devinfo.channel, devinfo.target,1217 lastphase, ahc_inb(ahc, SCSISIGI));1218 break;1219 }1220 case MISSED_BUSFREE:1221 {1222 u_int lastphase;1223 1224 lastphase = ahc_inb(ahc, LASTPHASE);1225 printk("%s:%c:%d: Missed busfree. "1226 "Lastphase = 0x%x, Curphase = 0x%x\n",1227 ahc_name(ahc), devinfo.channel, devinfo.target,1228 lastphase, ahc_inb(ahc, SCSISIGI));1229 ahc_restart(ahc);1230 return;1231 }1232 case HOST_MSG_LOOP:1233 {1234 /*1235 * The sequencer has encountered a message phase1236 * that requires host assistance for completion.1237 * While handling the message phase(s), we will be1238 * notified by the sequencer after each byte is1239 * transferred so we can track bus phase changes.1240 *1241 * If this is the first time we've seen a HOST_MSG_LOOP1242 * interrupt, initialize the state of the host message1243 * loop.1244 */1245 if (ahc->msg_type == MSG_TYPE_NONE) {1246 struct scb *scb;1247 u_int scb_index;1248 u_int bus_phase;1249 1250 bus_phase = ahc_inb(ahc, SCSISIGI) & PHASE_MASK;1251 if (bus_phase != P_MESGIN1252 && bus_phase != P_MESGOUT) {1253 printk("ahc_intr: HOST_MSG_LOOP bad "1254 "phase 0x%x\n",1255 bus_phase);1256 /*1257 * Probably transitioned to bus free before1258 * we got here. Just punt the message.1259 */1260 ahc_clear_intstat(ahc);1261 ahc_restart(ahc);1262 return;1263 }1264 1265 scb_index = ahc_inb(ahc, SCB_TAG);1266 scb = ahc_lookup_scb(ahc, scb_index);1267 if (devinfo.role == ROLE_INITIATOR) {1268 if (bus_phase == P_MESGOUT) {1269 if (scb == NULL)1270 panic("HOST_MSG_LOOP with "1271 "invalid SCB %x\n",1272 scb_index);1273 1274 ahc_setup_initiator_msgout(ahc,1275 &devinfo,1276 scb);1277 } else {1278 ahc->msg_type =1279 MSG_TYPE_INITIATOR_MSGIN;1280 ahc->msgin_index = 0;1281 }1282 }1283#ifdef AHC_TARGET_MODE1284 else {1285 if (bus_phase == P_MESGOUT) {1286 ahc->msg_type =1287 MSG_TYPE_TARGET_MSGOUT;1288 ahc->msgin_index = 0;1289 } else1290 ahc_setup_target_msgin(ahc,1291 &devinfo,1292 scb);1293 }1294#endif1295 }1296 1297 ahc_handle_message_phase(ahc);1298 break;1299 }1300 case PERR_DETECTED:1301 {1302 /*1303 * If we've cleared the parity error interrupt1304 * but the sequencer still believes that SCSIPERR1305 * is true, it must be that the parity error is1306 * for the currently presented byte on the bus,1307 * and we are not in a phase (data-in) where we will1308 * eventually ack this byte. Ack the byte and1309 * throw it away in the hope that the target will1310 * take us to message out to deliver the appropriate1311 * error message.1312 */1313 if ((intstat & SCSIINT) == 01314 && (ahc_inb(ahc, SSTAT1) & SCSIPERR) != 0) {1315 1316 if ((ahc->features & AHC_DT) == 0) {1317 u_int curphase;1318 1319 /*1320 * The hardware will only let you ack bytes1321 * if the expected phase in SCSISIGO matches1322 * the current phase. Make sure this is1323 * currently the case.1324 */1325 curphase = ahc_inb(ahc, SCSISIGI) & PHASE_MASK;1326 ahc_outb(ahc, LASTPHASE, curphase);1327 ahc_outb(ahc, SCSISIGO, curphase);1328 }1329 if ((ahc_inb(ahc, SCSISIGI) & (CDI|MSGI)) == 0) {1330 int wait;1331 1332 /*1333 * In a data phase. Faster to bitbucket1334 * the data than to individually ack each1335 * byte. This is also the only strategy1336 * that will work with AUTOACK enabled.1337 */1338 ahc_outb(ahc, SXFRCTL1,1339 ahc_inb(ahc, SXFRCTL1) | BITBUCKET);1340 wait = 5000;1341 while (--wait != 0) {1342 if ((ahc_inb(ahc, SCSISIGI)1343 & (CDI|MSGI)) != 0)1344 break;1345 ahc_delay(100);1346 }1347 ahc_outb(ahc, SXFRCTL1,1348 ahc_inb(ahc, SXFRCTL1) & ~BITBUCKET);1349 if (wait == 0) {1350 struct scb *scb;1351 u_int scb_index;1352 1353 ahc_print_devinfo(ahc, &devinfo);1354 printk("Unable to clear parity error. "1355 "Resetting bus.\n");1356 scb_index = ahc_inb(ahc, SCB_TAG);1357 scb = ahc_lookup_scb(ahc, scb_index);1358 if (scb != NULL)1359 ahc_set_transaction_status(scb,1360 CAM_UNCOR_PARITY);1361 ahc_reset_channel(ahc, devinfo.channel,1362 /*init reset*/TRUE);1363 }1364 } else {1365 ahc_inb(ahc, SCSIDATL);1366 }1367 }1368 break;1369 }1370 case DATA_OVERRUN:1371 {1372 /*1373 * When the sequencer detects an overrun, it1374 * places the controller in "BITBUCKET" mode1375 * and allows the target to complete its transfer.1376 * Unfortunately, none of the counters get updated1377 * when the controller is in this mode, so we have1378 * no way of knowing how large the overrun was.1379 */1380 u_int scbindex = ahc_inb(ahc, SCB_TAG);1381 u_int lastphase = ahc_inb(ahc, LASTPHASE);1382 u_int i;1383 1384 scb = ahc_lookup_scb(ahc, scbindex);1385 for (i = 0; i < num_phases; i++) {1386 if (lastphase == ahc_phase_table[i].phase)1387 break;1388 }1389 ahc_print_path(ahc, scb);1390 printk("data overrun detected %s."1391 " Tag == 0x%x.\n",1392 ahc_phase_table[i].phasemsg,1393 scb->hscb->tag);1394 ahc_print_path(ahc, scb);1395 printk("%s seen Data Phase. Length = %ld. NumSGs = %d.\n",1396 ahc_inb(ahc, SEQ_FLAGS) & DPHASE ? "Have" : "Haven't",1397 ahc_get_transfer_length(scb), scb->sg_count);1398 if (scb->sg_count > 0) {1399 for (i = 0; i < scb->sg_count; i++) {1400 1401 printk("sg[%d] - Addr 0x%x%x : Length %d\n",1402 i,1403 (ahc_le32toh(scb->sg_list[i].len) >> 241404 & SG_HIGH_ADDR_BITS),1405 ahc_le32toh(scb->sg_list[i].addr),1406 ahc_le32toh(scb->sg_list[i].len)1407 & AHC_SG_LEN_MASK);1408 }1409 }1410 /*1411 * Set this and it will take effect when the1412 * target does a command complete.1413 */1414 ahc_freeze_devq(ahc, scb);1415 if ((scb->flags & SCB_SENSE) == 0) {1416 ahc_set_transaction_status(scb, CAM_DATA_RUN_ERR);1417 } else {1418 scb->flags &= ~SCB_SENSE;1419 ahc_set_transaction_status(scb, CAM_AUTOSENSE_FAIL);1420 }1421 ahc_freeze_scb(scb);1422 1423 if ((ahc->features & AHC_ULTRA2) != 0) {1424 /*1425 * Clear the channel in case we return1426 * to data phase later.1427 */1428 ahc_outb(ahc, SXFRCTL0,1429 ahc_inb(ahc, SXFRCTL0) | CLRSTCNT|CLRCHN);1430 ahc_outb(ahc, SXFRCTL0,1431 ahc_inb(ahc, SXFRCTL0) | CLRSTCNT|CLRCHN);1432 }1433 if ((ahc->flags & AHC_39BIT_ADDRESSING) != 0) {1434 u_int dscommand1;1435 1436 /* Ensure HHADDR is 0 for future DMA operations. */1437 dscommand1 = ahc_inb(ahc, DSCOMMAND1);1438 ahc_outb(ahc, DSCOMMAND1, dscommand1 | HADDLDSEL0);1439 ahc_outb(ahc, HADDR, 0);1440 ahc_outb(ahc, DSCOMMAND1, dscommand1);1441 }1442 break;1443 }1444 case MKMSG_FAILED:1445 {1446 u_int scbindex;1447 1448 printk("%s:%c:%d:%d: Attempt to issue message failed\n",1449 ahc_name(ahc), devinfo.channel, devinfo.target,1450 devinfo.lun);1451 scbindex = ahc_inb(ahc, SCB_TAG);1452 scb = ahc_lookup_scb(ahc, scbindex);1453 if (scb != NULL1454 && (scb->flags & SCB_RECOVERY_SCB) != 0)1455 /*1456 * Ensure that we didn't put a second instance of this1457 * SCB into the QINFIFO.1458 */1459 ahc_search_qinfifo(ahc, SCB_GET_TARGET(ahc, scb),1460 SCB_GET_CHANNEL(ahc, scb),1461 SCB_GET_LUN(scb), scb->hscb->tag,1462 ROLE_INITIATOR, /*status*/0,1463 SEARCH_REMOVE);1464 break;1465 }1466 case NO_FREE_SCB:1467 {1468 printk("%s: No free or disconnected SCBs\n", ahc_name(ahc));1469 ahc_dump_card_state(ahc);1470 panic("for safety");1471 break;1472 }1473 case SCB_MISMATCH:1474 {1475 u_int scbptr;1476 1477 scbptr = ahc_inb(ahc, SCBPTR);1478 printk("Bogus TAG after DMA. SCBPTR %d, tag %d, our tag %d\n",1479 scbptr, ahc_inb(ahc, ARG_1),1480 ahc->scb_data->hscbs[scbptr].tag);1481 ahc_dump_card_state(ahc);1482 panic("for safety");1483 break;1484 }1485 case OUT_OF_RANGE:1486 {1487 printk("%s: BTT calculation out of range\n", ahc_name(ahc));1488 printk("SAVED_SCSIID == 0x%x, SAVED_LUN == 0x%x, "1489 "ARG_1 == 0x%x ACCUM = 0x%x\n",1490 ahc_inb(ahc, SAVED_SCSIID), ahc_inb(ahc, SAVED_LUN),1491 ahc_inb(ahc, ARG_1), ahc_inb(ahc, ACCUM));1492 printk("SEQ_FLAGS == 0x%x, SCBPTR == 0x%x, BTT == 0x%x, "1493 "SINDEX == 0x%x\n, A == 0x%x\n",1494 ahc_inb(ahc, SEQ_FLAGS), ahc_inb(ahc, SCBPTR),1495 ahc_index_busy_tcl(ahc,1496 BUILD_TCL(ahc_inb(ahc, SAVED_SCSIID),1497 ahc_inb(ahc, SAVED_LUN))),1498 ahc_inb(ahc, SINDEX),1499 ahc_inb(ahc, ACCUM));1500 printk("SCSIID == 0x%x, SCB_SCSIID == 0x%x, SCB_LUN == 0x%x, "1501 "SCB_TAG == 0x%x, SCB_CONTROL == 0x%x\n",1502 ahc_inb(ahc, SCSIID), ahc_inb(ahc, SCB_SCSIID),1503 ahc_inb(ahc, SCB_LUN), ahc_inb(ahc, SCB_TAG),1504 ahc_inb(ahc, SCB_CONTROL));1505 printk("SCSIBUSL == 0x%x, SCSISIGI == 0x%x\n",1506 ahc_inb(ahc, SCSIBUSL), ahc_inb(ahc, SCSISIGI));1507 ahc_dump_card_state(ahc);1508 panic("for safety");1509 break;1510 }1511 default:1512 printk("ahc_intr: seqint, "1513 "intstat == 0x%x, scsisigi = 0x%x\n",1514 intstat, ahc_inb(ahc, SCSISIGI));1515 break;1516 }1517unpause:1518 /*1519 * The sequencer is paused immediately on1520 * a SEQINT, so we should restart it when1521 * we're done.1522 */1523 ahc_unpause(ahc);1524}1525 1526static void1527ahc_handle_scsiint(struct ahc_softc *ahc, u_int intstat)1528{1529 u_int scb_index;1530 u_int status0;1531 u_int status;1532 struct scb *scb;1533 char cur_channel;1534 char intr_channel;1535 1536 if ((ahc->features & AHC_TWIN) != 01537 && ((ahc_inb(ahc, SBLKCTL) & SELBUSB) != 0))1538 cur_channel = 'B';1539 else1540 cur_channel = 'A';1541 intr_channel = cur_channel;1542 1543 if ((ahc->features & AHC_ULTRA2) != 0)1544 status0 = ahc_inb(ahc, SSTAT0) & IOERR;1545 else1546 status0 = 0;1547 status = ahc_inb(ahc, SSTAT1) & (SELTO|SCSIRSTI|BUSFREE|SCSIPERR);1548 if (status == 0 && status0 == 0) {1549 if ((ahc->features & AHC_TWIN) != 0) {1550 /* Try the other channel */1551 ahc_outb(ahc, SBLKCTL, ahc_inb(ahc, SBLKCTL) ^ SELBUSB);1552 status = ahc_inb(ahc, SSTAT1)1553 & (SELTO|SCSIRSTI|BUSFREE|SCSIPERR);1554 intr_channel = (cur_channel == 'A') ? 'B' : 'A';1555 }1556 if (status == 0) {1557 printk("%s: Spurious SCSI interrupt\n", ahc_name(ahc));1558 ahc_outb(ahc, CLRINT, CLRSCSIINT);1559 ahc_unpause(ahc);1560 return;1561 }1562 }1563 1564 /* Make sure the sequencer is in a safe location. */1565 ahc_clear_critical_section(ahc);1566 1567 scb_index = ahc_inb(ahc, SCB_TAG);1568 scb = ahc_lookup_scb(ahc, scb_index);1569 if (scb != NULL1570 && (ahc_inb(ahc, SEQ_FLAGS) & NOT_IDENTIFIED) != 0)1571 scb = NULL;1572 1573 if ((ahc->features & AHC_ULTRA2) != 01574 && (status0 & IOERR) != 0) {1575 int now_lvd;1576 1577 now_lvd = ahc_inb(ahc, SBLKCTL) & ENAB40;1578 printk("%s: Transceiver State Has Changed to %s mode\n",1579 ahc_name(ahc), now_lvd ? "LVD" : "SE");1580 ahc_outb(ahc, CLRSINT0, CLRIOERR);1581 /*1582 * When transitioning to SE mode, the reset line1583 * glitches, triggering an arbitration bug in some1584 * Ultra2 controllers. This bug is cleared when we1585 * assert the reset line. Since a reset glitch has1586 * already occurred with this transition and a1587 * transceiver state change is handled just like1588 * a bus reset anyway, asserting the reset line1589 * ourselves is safe.1590 */1591 ahc_reset_channel(ahc, intr_channel,1592 /*Initiate Reset*/now_lvd == 0);1593 } else if ((status & SCSIRSTI) != 0) {1594 printk("%s: Someone reset channel %c\n",1595 ahc_name(ahc), intr_channel);1596 if (intr_channel != cur_channel)1597 ahc_outb(ahc, SBLKCTL, ahc_inb(ahc, SBLKCTL) ^ SELBUSB);1598 ahc_reset_channel(ahc, intr_channel, /*Initiate Reset*/FALSE);1599 } else if ((status & SCSIPERR) != 0) {1600 /*1601 * Determine the bus phase and queue an appropriate message.1602 * SCSIPERR is latched true as soon as a parity error1603 * occurs. If the sequencer acked the transfer that1604 * caused the parity error and the currently presented1605 * transfer on the bus has correct parity, SCSIPERR will1606 * be cleared by CLRSCSIPERR. Use this to determine if1607 * we should look at the last phase the sequencer recorded,1608 * or the current phase presented on the bus.1609 */1610 struct ahc_devinfo devinfo;1611 u_int mesg_out;1612 u_int curphase;1613 u_int errorphase;1614 u_int lastphase;1615 u_int scsirate;1616 u_int i;1617 u_int sstat2;1618 int silent;1619 1620 lastphase = ahc_inb(ahc, LASTPHASE);1621 curphase = ahc_inb(ahc, SCSISIGI) & PHASE_MASK;1622 sstat2 = ahc_inb(ahc, SSTAT2);1623 ahc_outb(ahc, CLRSINT1, CLRSCSIPERR);1624 /*1625 * For all phases save DATA, the sequencer won't1626 * automatically ack a byte that has a parity error1627 * in it. So the only way that the current phase1628 * could be 'data-in' is if the parity error is for1629 * an already acked byte in the data phase. During1630 * synchronous data-in transfers, we may actually1631 * ack bytes before latching the current phase in1632 * LASTPHASE, leading to the discrepancy between1633 * curphase and lastphase.1634 */1635 if ((ahc_inb(ahc, SSTAT1) & SCSIPERR) != 01636 || curphase == P_DATAIN || curphase == P_DATAIN_DT)1637 errorphase = curphase;1638 else1639 errorphase = lastphase;1640 1641 for (i = 0; i < num_phases; i++) {1642 if (errorphase == ahc_phase_table[i].phase)1643 break;1644 }1645 mesg_out = ahc_phase_table[i].mesg_out;1646 silent = FALSE;1647 if (scb != NULL) {1648 if (SCB_IS_SILENT(scb))1649 silent = TRUE;1650 else1651 ahc_print_path(ahc, scb);1652 scb->flags |= SCB_TRANSMISSION_ERROR;1653 } else1654 printk("%s:%c:%d: ", ahc_name(ahc), intr_channel,1655 SCSIID_TARGET(ahc, ahc_inb(ahc, SAVED_SCSIID)));1656 scsirate = ahc_inb(ahc, SCSIRATE);1657 if (silent == FALSE) {1658 printk("parity error detected %s. "1659 "SEQADDR(0x%x) SCSIRATE(0x%x)\n",1660 ahc_phase_table[i].phasemsg,1661 ahc_inw(ahc, SEQADDR0),1662 scsirate);1663 if ((ahc->features & AHC_DT) != 0) {1664 if ((sstat2 & CRCVALERR) != 0)1665 printk("\tCRC Value Mismatch\n");1666 if ((sstat2 & CRCENDERR) != 0)1667 printk("\tNo terminal CRC packet "1668 "received\n");1669 if ((sstat2 & CRCREQERR) != 0)1670 printk("\tIllegal CRC packet "1671 "request\n");1672 if ((sstat2 & DUAL_EDGE_ERR) != 0)1673 printk("\tUnexpected %sDT Data Phase\n",1674 (scsirate & SINGLE_EDGE)1675 ? "" : "non-");1676 }1677 }1678 1679 if ((ahc->features & AHC_DT) != 01680 && (sstat2 & DUAL_EDGE_ERR) != 0) {1681 /*1682 * This error applies regardless of1683 * data direction, so ignore the value1684 * in the phase table.1685 */1686 mesg_out = INITIATOR_ERROR;1687 }1688 1689 /*1690 * We've set the hardware to assert ATN if we1691 * get a parity error on "in" phases, so all we1692 * need to do is stuff the message buffer with1693 * the appropriate message. "In" phases have set1694 * mesg_out to something other than MSG_NOP.1695 */1696 if (mesg_out != NOP) {1697 if (ahc->msg_type != MSG_TYPE_NONE)1698 ahc->send_msg_perror = TRUE;1699 else1700 ahc_outb(ahc, MSG_OUT, mesg_out);1701 }1702 /*1703 * Force a renegotiation with this target just in1704 * case we are out of sync for some external reason1705 * unknown (or unreported) by the target.1706 */1707 ahc_fetch_devinfo(ahc, &devinfo);1708 ahc_force_renegotiation(ahc, &devinfo);1709 1710 ahc_outb(ahc, CLRINT, CLRSCSIINT);1711 ahc_unpause(ahc);1712 } else if ((status & SELTO) != 0) {1713 u_int scbptr;1714 1715 /* Stop the selection */1716 ahc_outb(ahc, SCSISEQ, 0);1717 1718 /* No more pending messages */1719 ahc_clear_msg_state(ahc);1720 1721 /* Clear interrupt state */1722 ahc_outb(ahc, SIMODE1, ahc_inb(ahc, SIMODE1) & ~ENBUSFREE);1723 ahc_outb(ahc, CLRSINT1, CLRSELTIMEO|CLRBUSFREE|CLRSCSIPERR);1724 1725 /*1726 * Although the driver does not care about the1727 * 'Selection in Progress' status bit, the busy1728 * LED does. SELINGO is only cleared by a successful1729 * selection, so we must manually clear it to insure1730 * the LED turns off just incase no future successful1731 * selections occur (e.g. no devices on the bus).1732 */1733 ahc_outb(ahc, CLRSINT0, CLRSELINGO);1734 1735 scbptr = ahc_inb(ahc, WAITING_SCBH);1736 ahc_outb(ahc, SCBPTR, scbptr);1737 scb_index = ahc_inb(ahc, SCB_TAG);1738 1739 scb = ahc_lookup_scb(ahc, scb_index);1740 if (scb == NULL) {1741 printk("%s: ahc_intr - referenced scb not "1742 "valid during SELTO scb(%d, %d)\n",1743 ahc_name(ahc), scbptr, scb_index);1744 ahc_dump_card_state(ahc);1745 } else {1746 struct ahc_devinfo devinfo;1747#ifdef AHC_DEBUG1748 if ((ahc_debug & AHC_SHOW_SELTO) != 0) {1749 ahc_print_path(ahc, scb);1750 printk("Saw Selection Timeout for SCB 0x%x\n",1751 scb_index);1752 }1753#endif1754 ahc_scb_devinfo(ahc, &devinfo, scb);1755 ahc_set_transaction_status(scb, CAM_SEL_TIMEOUT);1756 ahc_freeze_devq(ahc, scb);1757 1758 /*1759 * Cancel any pending transactions on the device1760 * now that it seems to be missing. This will1761 * also revert us to async/narrow transfers until1762 * we can renegotiate with the device.1763 */1764 ahc_handle_devreset(ahc, &devinfo,1765 CAM_SEL_TIMEOUT,1766 "Selection Timeout",1767 /*verbose_level*/1);1768 }1769 ahc_outb(ahc, CLRINT, CLRSCSIINT);1770 ahc_restart(ahc);1771 } else if ((status & BUSFREE) != 01772 && (ahc_inb(ahc, SIMODE1) & ENBUSFREE) != 0) {1773 struct ahc_devinfo devinfo;1774 u_int lastphase;1775 u_int saved_scsiid;1776 u_int saved_lun;1777 u_int target;1778 u_int initiator_role_id;1779 char channel;1780 int printerror;1781 1782 /*1783 * Clear our selection hardware as soon as possible.1784 * We may have an entry in the waiting Q for this target,1785 * that is affected by this busfree and we don't want to1786 * go about selecting the target while we handle the event.1787 */1788 ahc_outb(ahc, SCSISEQ,1789 ahc_inb(ahc, SCSISEQ) & (ENSELI|ENRSELI|ENAUTOATNP));1790 1791 /*1792 * Disable busfree interrupts and clear the busfree1793 * interrupt status. We do this here so that several1794 * bus transactions occur prior to clearing the SCSIINT1795 * latch. It can take a bit for the clearing to take effect.1796 */1797 ahc_outb(ahc, SIMODE1, ahc_inb(ahc, SIMODE1) & ~ENBUSFREE);1798 ahc_outb(ahc, CLRSINT1, CLRBUSFREE|CLRSCSIPERR);1799 1800 /*1801 * Look at what phase we were last in.1802 * If its message out, chances are pretty good1803 * that the busfree was in response to one of1804 * our abort requests.1805 */1806 lastphase = ahc_inb(ahc, LASTPHASE);1807 saved_scsiid = ahc_inb(ahc, SAVED_SCSIID);1808 saved_lun = ahc_inb(ahc, SAVED_LUN);1809 target = SCSIID_TARGET(ahc, saved_scsiid);1810 initiator_role_id = SCSIID_OUR_ID(saved_scsiid);1811 channel = SCSIID_CHANNEL(ahc, saved_scsiid);1812 ahc_compile_devinfo(&devinfo, initiator_role_id,1813 target, saved_lun, channel, ROLE_INITIATOR);1814 printerror = 1;1815 1816 if (lastphase == P_MESGOUT) {1817 u_int tag;1818 1819 tag = SCB_LIST_NULL;1820 if (ahc_sent_msg(ahc, AHCMSG_1B, ABORT_TASK, TRUE)1821 || ahc_sent_msg(ahc, AHCMSG_1B, ABORT_TASK_SET, TRUE)) {1822 if (ahc->msgout_buf[ahc->msgout_index - 1]1823 == ABORT_TASK)1824 tag = scb->hscb->tag;1825 ahc_print_path(ahc, scb);1826 printk("SCB %d - Abort%s Completed.\n",1827 scb->hscb->tag, tag == SCB_LIST_NULL ?1828 "" : " Tag");1829 ahc_abort_scbs(ahc, target, channel,1830 saved_lun, tag,1831 ROLE_INITIATOR,1832 CAM_REQ_ABORTED);1833 printerror = 0;1834 } else if (ahc_sent_msg(ahc, AHCMSG_1B,1835 TARGET_RESET, TRUE)) {1836 ahc_compile_devinfo(&devinfo,1837 initiator_role_id,1838 target,1839 CAM_LUN_WILDCARD,1840 channel,1841 ROLE_INITIATOR);1842 ahc_handle_devreset(ahc, &devinfo,1843 CAM_BDR_SENT,1844 "Bus Device Reset",1845 /*verbose_level*/0);1846 printerror = 0;1847 } else if (ahc_sent_msg(ahc, AHCMSG_EXT,1848 EXTENDED_PPR, FALSE)) {1849 struct ahc_initiator_tinfo *tinfo;1850 struct ahc_tmode_tstate *tstate;1851 1852 /*1853 * PPR Rejected. Try non-ppr negotiation1854 * and retry command.1855 */1856 tinfo = ahc_fetch_transinfo(ahc,1857 devinfo.channel,1858 devinfo.our_scsiid,1859 devinfo.target,1860 &tstate);1861 tinfo->curr.transport_version = 2;1862 tinfo->goal.transport_version = 2;1863 tinfo->goal.ppr_options = 0;1864 ahc_qinfifo_requeue_tail(ahc, scb);1865 printerror = 0;1866 } else if (ahc_sent_msg(ahc, AHCMSG_EXT,1867 EXTENDED_WDTR, FALSE)) {1868 /*1869 * Negotiation Rejected. Go-narrow and1870 * retry command.1871 */1872 ahc_set_width(ahc, &devinfo,1873 MSG_EXT_WDTR_BUS_8_BIT,1874 AHC_TRANS_CUR|AHC_TRANS_GOAL,1875 /*paused*/TRUE);1876 ahc_qinfifo_requeue_tail(ahc, scb);1877 printerror = 0;1878 } else if (ahc_sent_msg(ahc, AHCMSG_EXT,1879 EXTENDED_SDTR, FALSE)) {1880 /*1881 * Negotiation Rejected. Go-async and1882 * retry command.1883 */1884 ahc_set_syncrate(ahc, &devinfo,1885 /*syncrate*/NULL,1886 /*period*/0, /*offset*/0,1887 /*ppr_options*/0,1888 AHC_TRANS_CUR|AHC_TRANS_GOAL,1889 /*paused*/TRUE);1890 ahc_qinfifo_requeue_tail(ahc, scb);1891 printerror = 0;1892 }1893 }1894 if (printerror != 0) {1895 u_int i;1896 1897 if (scb != NULL) {1898 u_int tag;1899 1900 if ((scb->hscb->control & TAG_ENB) != 0)1901 tag = scb->hscb->tag;1902 else1903 tag = SCB_LIST_NULL;1904 ahc_print_path(ahc, scb);1905 ahc_abort_scbs(ahc, target, channel,1906 SCB_GET_LUN(scb), tag,1907 ROLE_INITIATOR,1908 CAM_UNEXP_BUSFREE);1909 } else {1910 /*1911 * We had not fully identified this connection,1912 * so we cannot abort anything.1913 */1914 printk("%s: ", ahc_name(ahc));1915 }1916 for (i = 0; i < num_phases; i++) {1917 if (lastphase == ahc_phase_table[i].phase)1918 break;1919 }1920 if (lastphase != P_BUSFREE) {1921 /*1922 * Renegotiate with this device at the1923 * next opportunity just in case this busfree1924 * is due to a negotiation mismatch with the1925 * device.1926 */1927 ahc_force_renegotiation(ahc, &devinfo);1928 }1929 printk("Unexpected busfree %s\n"1930 "SEQADDR == 0x%x\n",1931 ahc_phase_table[i].phasemsg,1932 ahc_inb(ahc, SEQADDR0)1933 | (ahc_inb(ahc, SEQADDR1) << 8));1934 }1935 ahc_outb(ahc, CLRINT, CLRSCSIINT);1936 ahc_restart(ahc);1937 } else {1938 printk("%s: Missing case in ahc_handle_scsiint. status = %x\n",1939 ahc_name(ahc), status);1940 ahc_outb(ahc, CLRINT, CLRSCSIINT);1941 }1942}1943 1944/*1945 * Force renegotiation to occur the next time we initiate1946 * a command to the current device.1947 */1948static void1949ahc_force_renegotiation(struct ahc_softc *ahc, struct ahc_devinfo *devinfo)1950{1951 struct ahc_initiator_tinfo *targ_info;1952 struct ahc_tmode_tstate *tstate;1953 1954 targ_info = ahc_fetch_transinfo(ahc,1955 devinfo->channel,1956 devinfo->our_scsiid,1957 devinfo->target,1958 &tstate);1959 ahc_update_neg_request(ahc, devinfo, tstate,1960 targ_info, AHC_NEG_IF_NON_ASYNC);1961}1962 1963#define AHC_MAX_STEPS 20001964static void1965ahc_clear_critical_section(struct ahc_softc *ahc)1966{1967 int stepping;1968 int steps;1969 u_int simode0;1970 u_int simode1;1971 1972 if (ahc->num_critical_sections == 0)1973 return;1974 1975 stepping = FALSE;1976 steps = 0;1977 simode0 = 0;1978 simode1 = 0;1979 for (;;) {1980 struct cs *cs;1981 u_int seqaddr;1982 u_int i;1983 1984 seqaddr = ahc_inb(ahc, SEQADDR0)1985 | (ahc_inb(ahc, SEQADDR1) << 8);1986 1987 /*1988 * Seqaddr represents the next instruction to execute,1989 * so we are really executing the instruction just1990 * before it.1991 */1992 if (seqaddr != 0)1993 seqaddr -= 1;1994 cs = ahc->critical_sections;1995 for (i = 0; i < ahc->num_critical_sections; i++, cs++) {1996 if (cs->begin < seqaddr && cs->end >= seqaddr)1997 break;1998 }1999 2000 if (i == ahc->num_critical_sections)2001 break;2002 2003 if (steps > AHC_MAX_STEPS) {2004 printk("%s: Infinite loop in critical section\n",2005 ahc_name(ahc));2006 ahc_dump_card_state(ahc);2007 panic("critical section loop");2008 }2009 2010 steps++;2011 if (stepping == FALSE) {2012 2013 /*2014 * Disable all interrupt sources so that the2015 * sequencer will not be stuck by a pausing2016 * interrupt condition while we attempt to2017 * leave a critical section.2018 */2019 simode0 = ahc_inb(ahc, SIMODE0);2020 ahc_outb(ahc, SIMODE0, 0);2021 simode1 = ahc_inb(ahc, SIMODE1);2022 if ((ahc->features & AHC_DT) != 0)2023 /*2024 * On DT class controllers, we2025 * use the enhanced busfree logic.2026 * Unfortunately we cannot re-enable2027 * busfree detection within the2028 * current connection, so we must2029 * leave it on while single stepping.2030 */2031 ahc_outb(ahc, SIMODE1, simode1 & ENBUSFREE);2032 else2033 ahc_outb(ahc, SIMODE1, 0);2034 ahc_outb(ahc, CLRINT, CLRSCSIINT);2035 ahc_outb(ahc, SEQCTL, ahc->seqctl | STEP);2036 stepping = TRUE;2037 }2038 if ((ahc->features & AHC_DT) != 0) {2039 ahc_outb(ahc, CLRSINT1, CLRBUSFREE);2040 ahc_outb(ahc, CLRINT, CLRSCSIINT);2041 }2042 ahc_outb(ahc, HCNTRL, ahc->unpause);2043 while (!ahc_is_paused(ahc))2044 ahc_delay(200);2045 }2046 if (stepping) {2047 ahc_outb(ahc, SIMODE0, simode0);2048 ahc_outb(ahc, SIMODE1, simode1);2049 ahc_outb(ahc, SEQCTL, ahc->seqctl);2050 }2051}2052 2053/*2054 * Clear any pending interrupt status.2055 */2056static void2057ahc_clear_intstat(struct ahc_softc *ahc)2058{2059 /* Clear any interrupt conditions this may have caused */2060 ahc_outb(ahc, CLRSINT1, CLRSELTIMEO|CLRATNO|CLRSCSIRSTI2061 |CLRBUSFREE|CLRSCSIPERR|CLRPHASECHG|2062 CLRREQINIT);2063 ahc_flush_device_writes(ahc);2064 ahc_outb(ahc, CLRSINT0, CLRSELDO|CLRSELDI|CLRSELINGO);2065 ahc_flush_device_writes(ahc);2066 ahc_outb(ahc, CLRINT, CLRSCSIINT);2067 ahc_flush_device_writes(ahc);2068}2069 2070/**************************** Debugging Routines ******************************/2071#ifdef AHC_DEBUG2072uint32_t ahc_debug = AHC_DEBUG_OPTS;2073#endif2074 2075#if 0 /* unused */2076static void2077ahc_print_scb(struct scb *scb)2078{2079 int i;2080 2081 struct hardware_scb *hscb = scb->hscb;2082 2083 printk("scb:%p control:0x%x scsiid:0x%x lun:%d cdb_len:%d\n",2084 (void *)scb,2085 hscb->control,2086 hscb->scsiid,2087 hscb->lun,2088 hscb->cdb_len);2089 printk("Shared Data: ");2090 for (i = 0; i < sizeof(hscb->shared_data.cdb); i++)2091 printk("%#02x", hscb->shared_data.cdb[i]);2092 printk(" dataptr:%#x datacnt:%#x sgptr:%#x tag:%#x\n",2093 ahc_le32toh(hscb->dataptr),2094 ahc_le32toh(hscb->datacnt),2095 ahc_le32toh(hscb->sgptr),2096 hscb->tag);2097 if (scb->sg_count > 0) {2098 for (i = 0; i < scb->sg_count; i++) {2099 printk("sg[%d] - Addr 0x%x%x : Length %d\n",2100 i,2101 (ahc_le32toh(scb->sg_list[i].len) >> 242102 & SG_HIGH_ADDR_BITS),2103 ahc_le32toh(scb->sg_list[i].addr),2104 ahc_le32toh(scb->sg_list[i].len));2105 }2106 }2107}2108#endif2109 2110/************************* Transfer Negotiation *******************************/2111/*2112 * Allocate per target mode instance (ID we respond to as a target)2113 * transfer negotiation data structures.2114 */2115static struct ahc_tmode_tstate *2116ahc_alloc_tstate(struct ahc_softc *ahc, u_int scsi_id, char channel)2117{2118 struct ahc_tmode_tstate *master_tstate;2119 struct ahc_tmode_tstate *tstate;2120 int i;2121 2122 master_tstate = ahc->enabled_targets[ahc->our_id];2123 if (channel == 'B') {2124 scsi_id += 8;2125 master_tstate = ahc->enabled_targets[ahc->our_id_b + 8];2126 }2127 if (ahc->enabled_targets[scsi_id] != NULL2128 && ahc->enabled_targets[scsi_id] != master_tstate)2129 panic("%s: ahc_alloc_tstate - Target already allocated",2130 ahc_name(ahc));2131 tstate = kmalloc(sizeof(*tstate), GFP_ATOMIC);2132 if (tstate == NULL)2133 return (NULL);2134 2135 /*2136 * If we have allocated a master tstate, copy user settings from2137 * the master tstate (taken from SRAM or the EEPROM) for this2138 * channel, but reset our current and goal settings to async/narrow2139 * until an initiator talks to us.2140 */2141 if (master_tstate != NULL) {2142 memcpy(tstate, master_tstate, sizeof(*tstate));2143 memset(tstate->enabled_luns, 0, sizeof(tstate->enabled_luns));2144 tstate->ultraenb = 0;2145 for (i = 0; i < AHC_NUM_TARGETS; i++) {2146 memset(&tstate->transinfo[i].curr, 0,2147 sizeof(tstate->transinfo[i].curr));2148 memset(&tstate->transinfo[i].goal, 0,2149 sizeof(tstate->transinfo[i].goal));2150 }2151 } else2152 memset(tstate, 0, sizeof(*tstate));2153 ahc->enabled_targets[scsi_id] = tstate;2154 return (tstate);2155}2156 2157#ifdef AHC_TARGET_MODE2158/*2159 * Free per target mode instance (ID we respond to as a target)2160 * transfer negotiation data structures.2161 */2162static void2163ahc_free_tstate(struct ahc_softc *ahc, u_int scsi_id, char channel, int force)2164{2165 struct ahc_tmode_tstate *tstate;2166 2167 /*2168 * Don't clean up our "master" tstate.2169 * It has our default user settings.2170 */2171 if (((channel == 'B' && scsi_id == ahc->our_id_b)2172 || (channel == 'A' && scsi_id == ahc->our_id))2173 && force == FALSE)2174 return;2175 2176 if (channel == 'B')2177 scsi_id += 8;2178 tstate = ahc->enabled_targets[scsi_id];2179 kfree(tstate);2180 ahc->enabled_targets[scsi_id] = NULL;2181}2182#endif2183 2184/*2185 * Called when we have an active connection to a target on the bus,2186 * this function finds the nearest syncrate to the input period limited2187 * by the capabilities of the bus connectivity of and sync settings for2188 * the target.2189 */2190static const struct ahc_syncrate *2191ahc_devlimited_syncrate(struct ahc_softc *ahc,2192 struct ahc_initiator_tinfo *tinfo,2193 u_int *period, u_int *ppr_options, role_t role)2194{2195 struct ahc_transinfo *transinfo;2196 u_int maxsync;2197 2198 if ((ahc->features & AHC_ULTRA2) != 0) {2199 if ((ahc_inb(ahc, SBLKCTL) & ENAB40) != 02200 && (ahc_inb(ahc, SSTAT2) & EXP_ACTIVE) == 0) {2201 maxsync = AHC_SYNCRATE_DT;2202 } else {2203 maxsync = AHC_SYNCRATE_ULTRA;2204 /* Can't do DT on an SE bus */2205 *ppr_options &= ~MSG_EXT_PPR_DT_REQ;2206 }2207 } else if ((ahc->features & AHC_ULTRA) != 0) {2208 maxsync = AHC_SYNCRATE_ULTRA;2209 } else {2210 maxsync = AHC_SYNCRATE_FAST;2211 }2212 /*2213 * Never allow a value higher than our current goal2214 * period otherwise we may allow a target initiated2215 * negotiation to go above the limit as set by the2216 * user. In the case of an initiator initiated2217 * sync negotiation, we limit based on the user2218 * setting. This allows the system to still accept2219 * incoming negotiations even if target initiated2220 * negotiation is not performed.2221 */2222 if (role == ROLE_TARGET)2223 transinfo = &tinfo->user;2224 else2225 transinfo = &tinfo->goal;2226 *ppr_options &= transinfo->ppr_options;2227 if (transinfo->width == MSG_EXT_WDTR_BUS_8_BIT) {2228 maxsync = max(maxsync, (u_int)AHC_SYNCRATE_ULTRA2);2229 *ppr_options &= ~MSG_EXT_PPR_DT_REQ;2230 }2231 if (transinfo->period == 0) {2232 *period = 0;2233 *ppr_options = 0;2234 return (NULL);2235 }2236 *period = max(*period, (u_int)transinfo->period);2237 return (ahc_find_syncrate(ahc, period, ppr_options, maxsync));2238}2239 2240/*2241 * Look up the valid period to SCSIRATE conversion in our table.2242 * Return the period and offset that should be sent to the target2243 * if this was the beginning of an SDTR.2244 */2245const struct ahc_syncrate *2246ahc_find_syncrate(struct ahc_softc *ahc, u_int *period,2247 u_int *ppr_options, u_int maxsync)2248{2249 const struct ahc_syncrate *syncrate;2250 2251 if ((ahc->features & AHC_DT) == 0)2252 *ppr_options &= ~MSG_EXT_PPR_DT_REQ;2253 2254 /* Skip all DT only entries if DT is not available */2255 if ((*ppr_options & MSG_EXT_PPR_DT_REQ) == 02256 && maxsync < AHC_SYNCRATE_ULTRA2)2257 maxsync = AHC_SYNCRATE_ULTRA2;2258 2259 /* Now set the maxsync based on the card capabilities2260 * DT is already done above */2261 if ((ahc->features & (AHC_DT | AHC_ULTRA2)) == 02262 && maxsync < AHC_SYNCRATE_ULTRA)2263 maxsync = AHC_SYNCRATE_ULTRA;2264 if ((ahc->features & (AHC_DT | AHC_ULTRA2 | AHC_ULTRA)) == 02265 && maxsync < AHC_SYNCRATE_FAST)2266 maxsync = AHC_SYNCRATE_FAST;2267 2268 for (syncrate = &ahc_syncrates[maxsync];2269 syncrate->rate != NULL;2270 syncrate++) {2271 2272 /*2273 * The Ultra2 table doesn't go as low2274 * as for the Fast/Ultra cards.2275 */2276 if ((ahc->features & AHC_ULTRA2) != 02277 && (syncrate->sxfr_u2 == 0))2278 break;2279 2280 if (*period <= syncrate->period) {2281 /*2282 * When responding to a target that requests2283 * sync, the requested rate may fall between2284 * two rates that we can output, but still be2285 * a rate that we can receive. Because of this,2286 * we want to respond to the target with2287 * the same rate that it sent to us even2288 * if the period we use to send data to it2289 * is lower. Only lower the response period2290 * if we must.2291 */2292 if (syncrate == &ahc_syncrates[maxsync])2293 *period = syncrate->period;2294 2295 /*2296 * At some speeds, we only support2297 * ST transfers.2298 */2299 if ((syncrate->sxfr_u2 & ST_SXFR) != 0)2300 *ppr_options &= ~MSG_EXT_PPR_DT_REQ;2301 break;2302 }2303 }2304 2305 if ((*period == 0)2306 || (syncrate->rate == NULL)2307 || ((ahc->features & AHC_ULTRA2) != 02308 && (syncrate->sxfr_u2 == 0))) {2309 /* Use asynchronous transfers. */2310 *period = 0;2311 syncrate = NULL;2312 *ppr_options &= ~MSG_EXT_PPR_DT_REQ;2313 }2314 return (syncrate);2315}2316 2317/*2318 * Convert from an entry in our syncrate table to the SCSI equivalent2319 * sync "period" factor.2320 */2321u_int2322ahc_find_period(struct ahc_softc *ahc, u_int scsirate, u_int maxsync)2323{2324 const struct ahc_syncrate *syncrate;2325 2326 if ((ahc->features & AHC_ULTRA2) != 0)2327 scsirate &= SXFR_ULTRA2;2328 else2329 scsirate &= SXFR;2330 2331 /* now set maxsync based on card capabilities */2332 if ((ahc->features & AHC_DT) == 0 && maxsync < AHC_SYNCRATE_ULTRA2)2333 maxsync = AHC_SYNCRATE_ULTRA2;2334 if ((ahc->features & (AHC_DT | AHC_ULTRA2)) == 02335 && maxsync < AHC_SYNCRATE_ULTRA)2336 maxsync = AHC_SYNCRATE_ULTRA;2337 if ((ahc->features & (AHC_DT | AHC_ULTRA2 | AHC_ULTRA)) == 02338 && maxsync < AHC_SYNCRATE_FAST)2339 maxsync = AHC_SYNCRATE_FAST;2340 2341 2342 syncrate = &ahc_syncrates[maxsync];2343 while (syncrate->rate != NULL) {2344 2345 if ((ahc->features & AHC_ULTRA2) != 0) {2346 if (syncrate->sxfr_u2 == 0)2347 break;2348 else if (scsirate == (syncrate->sxfr_u2 & SXFR_ULTRA2))2349 return (syncrate->period);2350 } else if (scsirate == (syncrate->sxfr & SXFR)) {2351 return (syncrate->period);2352 }2353 syncrate++;2354 }2355 return (0); /* async */2356}2357 2358/*2359 * Truncate the given synchronous offset to a value the2360 * current adapter type and syncrate are capable of.2361 */2362static void2363ahc_validate_offset(struct ahc_softc *ahc,2364 struct ahc_initiator_tinfo *tinfo,2365 const struct ahc_syncrate *syncrate,2366 u_int *offset, int wide, role_t role)2367{2368 u_int maxoffset;2369 2370 /* Limit offset to what we can do */2371 if (syncrate == NULL) {2372 maxoffset = 0;2373 } else if ((ahc->features & AHC_ULTRA2) != 0) {2374 maxoffset = MAX_OFFSET_ULTRA2;2375 } else {2376 if (wide)2377 maxoffset = MAX_OFFSET_16BIT;2378 else2379 maxoffset = MAX_OFFSET_8BIT;2380 }2381 *offset = min(*offset, maxoffset);2382 if (tinfo != NULL) {2383 if (role == ROLE_TARGET)2384 *offset = min(*offset, (u_int)tinfo->user.offset);2385 else2386 *offset = min(*offset, (u_int)tinfo->goal.offset);2387 }2388}2389 2390/*2391 * Truncate the given transfer width parameter to a value the2392 * current adapter type is capable of.2393 */2394static void2395ahc_validate_width(struct ahc_softc *ahc, struct ahc_initiator_tinfo *tinfo,2396 u_int *bus_width, role_t role)2397{2398 switch (*bus_width) {2399 default:2400 if (ahc->features & AHC_WIDE) {2401 /* Respond Wide */2402 *bus_width = MSG_EXT_WDTR_BUS_16_BIT;2403 break;2404 }2405 fallthrough;2406 case MSG_EXT_WDTR_BUS_8_BIT:2407 *bus_width = MSG_EXT_WDTR_BUS_8_BIT;2408 break;2409 }2410 if (tinfo != NULL) {2411 if (role == ROLE_TARGET)2412 *bus_width = min((u_int)tinfo->user.width, *bus_width);2413 else2414 *bus_width = min((u_int)tinfo->goal.width, *bus_width);2415 }2416}2417 2418/*2419 * Update the bitmask of targets for which the controller should2420 * negotiate with at the next convenient opportunity. This currently2421 * means the next time we send the initial identify messages for2422 * a new transaction.2423 */2424int2425ahc_update_neg_request(struct ahc_softc *ahc, struct ahc_devinfo *devinfo,2426 struct ahc_tmode_tstate *tstate,2427 struct ahc_initiator_tinfo *tinfo, ahc_neg_type neg_type)2428{2429 u_int auto_negotiate_orig;2430 2431 auto_negotiate_orig = tstate->auto_negotiate;2432 if (neg_type == AHC_NEG_ALWAYS) {2433 /*2434 * Force our "current" settings to be2435 * unknown so that unless a bus reset2436 * occurs the need to renegotiate is2437 * recorded persistently.2438 */2439 if ((ahc->features & AHC_WIDE) != 0)2440 tinfo->curr.width = AHC_WIDTH_UNKNOWN;2441 tinfo->curr.period = AHC_PERIOD_UNKNOWN;2442 tinfo->curr.offset = AHC_OFFSET_UNKNOWN;2443 }2444 if (tinfo->curr.period != tinfo->goal.period2445 || tinfo->curr.width != tinfo->goal.width2446 || tinfo->curr.offset != tinfo->goal.offset2447 || tinfo->curr.ppr_options != tinfo->goal.ppr_options2448 || (neg_type == AHC_NEG_IF_NON_ASYNC2449 && (tinfo->goal.offset != 02450 || tinfo->goal.width != MSG_EXT_WDTR_BUS_8_BIT2451 || tinfo->goal.ppr_options != 0)))2452 tstate->auto_negotiate |= devinfo->target_mask;2453 else2454 tstate->auto_negotiate &= ~devinfo->target_mask;2455 2456 return (auto_negotiate_orig != tstate->auto_negotiate);2457}2458 2459/*2460 * Update the user/goal/curr tables of synchronous negotiation2461 * parameters as well as, in the case of a current or active update,2462 * any data structures on the host controller. In the case of an2463 * active update, the specified target is currently talking to us on2464 * the bus, so the transfer parameter update must take effect2465 * immediately.2466 */2467void2468ahc_set_syncrate(struct ahc_softc *ahc, struct ahc_devinfo *devinfo,2469 const struct ahc_syncrate *syncrate, u_int period,2470 u_int offset, u_int ppr_options, u_int type, int paused)2471{2472 struct ahc_initiator_tinfo *tinfo;2473 struct ahc_tmode_tstate *tstate;2474 u_int old_period;2475 u_int old_offset;2476 u_int old_ppr;2477 int active;2478 int update_needed;2479 2480 active = (type & AHC_TRANS_ACTIVE) == AHC_TRANS_ACTIVE;2481 update_needed = 0;2482 2483 if (syncrate == NULL) {2484 period = 0;2485 offset = 0;2486 }2487 2488 tinfo = ahc_fetch_transinfo(ahc, devinfo->channel, devinfo->our_scsiid,2489 devinfo->target, &tstate);2490 2491 if ((type & AHC_TRANS_USER) != 0) {2492 tinfo->user.period = period;2493 tinfo->user.offset = offset;2494 tinfo->user.ppr_options = ppr_options;2495 }2496 2497 if ((type & AHC_TRANS_GOAL) != 0) {2498 tinfo->goal.period = period;2499 tinfo->goal.offset = offset;2500 tinfo->goal.ppr_options = ppr_options;2501 }2502 2503 old_period = tinfo->curr.period;2504 old_offset = tinfo->curr.offset;2505 old_ppr = tinfo->curr.ppr_options;2506 2507 if ((type & AHC_TRANS_CUR) != 02508 && (old_period != period2509 || old_offset != offset2510 || old_ppr != ppr_options)) {2511 u_int scsirate;2512 2513 update_needed++;2514 scsirate = tinfo->scsirate;2515 if ((ahc->features & AHC_ULTRA2) != 0) {2516 2517 scsirate &= ~(SXFR_ULTRA2|SINGLE_EDGE|ENABLE_CRC);2518 if (syncrate != NULL) {2519 scsirate |= syncrate->sxfr_u2;2520 if ((ppr_options & MSG_EXT_PPR_DT_REQ) != 0)2521 scsirate |= ENABLE_CRC;2522 else2523 scsirate |= SINGLE_EDGE;2524 }2525 } else {2526 2527 scsirate &= ~(SXFR|SOFS);2528 /*2529 * Ensure Ultra mode is set properly for2530 * this target.2531 */2532 tstate->ultraenb &= ~devinfo->target_mask;2533 if (syncrate != NULL) {2534 if (syncrate->sxfr & ULTRA_SXFR) {2535 tstate->ultraenb |=2536 devinfo->target_mask;2537 }2538 scsirate |= syncrate->sxfr & SXFR;2539 scsirate |= offset & SOFS;2540 }2541 if (active) {2542 u_int sxfrctl0;2543 2544 sxfrctl0 = ahc_inb(ahc, SXFRCTL0);2545 sxfrctl0 &= ~FAST20;2546 if (tstate->ultraenb & devinfo->target_mask)2547 sxfrctl0 |= FAST20;2548 ahc_outb(ahc, SXFRCTL0, sxfrctl0);2549 }2550 }2551 if (active) {2552 ahc_outb(ahc, SCSIRATE, scsirate);2553 if ((ahc->features & AHC_ULTRA2) != 0)2554 ahc_outb(ahc, SCSIOFFSET, offset);2555 }2556 2557 tinfo->scsirate = scsirate;2558 tinfo->curr.period = period;2559 tinfo->curr.offset = offset;2560 tinfo->curr.ppr_options = ppr_options;2561 2562 ahc_send_async(ahc, devinfo->channel, devinfo->target,2563 CAM_LUN_WILDCARD, AC_TRANSFER_NEG);2564 if (bootverbose) {2565 if (offset != 0) {2566 printk("%s: target %d synchronous at %sMHz%s, "2567 "offset = 0x%x\n", ahc_name(ahc),2568 devinfo->target, syncrate->rate,2569 (ppr_options & MSG_EXT_PPR_DT_REQ)2570 ? " DT" : "", offset);2571 } else {2572 printk("%s: target %d using "2573 "asynchronous transfers\n",2574 ahc_name(ahc), devinfo->target);2575 }2576 }2577 }2578 2579 update_needed += ahc_update_neg_request(ahc, devinfo, tstate,2580 tinfo, AHC_NEG_TO_GOAL);2581 2582 if (update_needed)2583 ahc_update_pending_scbs(ahc);2584}2585 2586/*2587 * Update the user/goal/curr tables of wide negotiation2588 * parameters as well as, in the case of a current or active update,2589 * any data structures on the host controller. In the case of an2590 * active update, the specified target is currently talking to us on2591 * the bus, so the transfer parameter update must take effect2592 * immediately.2593 */2594void2595ahc_set_width(struct ahc_softc *ahc, struct ahc_devinfo *devinfo,2596 u_int width, u_int type, int paused)2597{2598 struct ahc_initiator_tinfo *tinfo;2599 struct ahc_tmode_tstate *tstate;2600 u_int oldwidth;2601 int active;2602 int update_needed;2603 2604 active = (type & AHC_TRANS_ACTIVE) == AHC_TRANS_ACTIVE;2605 update_needed = 0;2606 tinfo = ahc_fetch_transinfo(ahc, devinfo->channel, devinfo->our_scsiid,2607 devinfo->target, &tstate);2608 2609 if ((type & AHC_TRANS_USER) != 0)2610 tinfo->user.width = width;2611 2612 if ((type & AHC_TRANS_GOAL) != 0)2613 tinfo->goal.width = width;2614 2615 oldwidth = tinfo->curr.width;2616 if ((type & AHC_TRANS_CUR) != 0 && oldwidth != width) {2617 u_int scsirate;2618 2619 update_needed++;2620 scsirate = tinfo->scsirate;2621 scsirate &= ~WIDEXFER;2622 if (width == MSG_EXT_WDTR_BUS_16_BIT)2623 scsirate |= WIDEXFER;2624 2625 tinfo->scsirate = scsirate;2626 2627 if (active)2628 ahc_outb(ahc, SCSIRATE, scsirate);2629 2630 tinfo->curr.width = width;2631 2632 ahc_send_async(ahc, devinfo->channel, devinfo->target,2633 CAM_LUN_WILDCARD, AC_TRANSFER_NEG);2634 if (bootverbose) {2635 printk("%s: target %d using %dbit transfers\n",2636 ahc_name(ahc), devinfo->target,2637 8 * (0x01 << width));2638 }2639 }2640 2641 update_needed += ahc_update_neg_request(ahc, devinfo, tstate,2642 tinfo, AHC_NEG_TO_GOAL);2643 if (update_needed)2644 ahc_update_pending_scbs(ahc);2645}2646 2647/*2648 * Update the current state of tagged queuing for a given target.2649 */2650static void2651ahc_set_tags(struct ahc_softc *ahc, struct scsi_cmnd *cmd,2652 struct ahc_devinfo *devinfo, ahc_queue_alg alg)2653{2654 struct scsi_device *sdev = cmd->device;2655 2656 ahc_platform_set_tags(ahc, sdev, devinfo, alg);2657 ahc_send_async(ahc, devinfo->channel, devinfo->target,2658 devinfo->lun, AC_TRANSFER_NEG);2659}2660 2661/*2662 * When the transfer settings for a connection change, update any2663 * in-transit SCBs to contain the new data so the hardware will2664 * be set correctly during future (re)selections.2665 */2666static void2667ahc_update_pending_scbs(struct ahc_softc *ahc)2668{2669 struct scb *pending_scb;2670 int pending_scb_count;2671 int i;2672 int paused;2673 u_int saved_scbptr;2674 2675 /*2676 * Traverse the pending SCB list and ensure that all of the2677 * SCBs there have the proper settings.2678 */2679 pending_scb_count = 0;2680 LIST_FOREACH(pending_scb, &ahc->pending_scbs, pending_links) {2681 struct ahc_devinfo devinfo;2682 struct hardware_scb *pending_hscb;2683 struct ahc_initiator_tinfo *tinfo;2684 struct ahc_tmode_tstate *tstate;2685 2686 ahc_scb_devinfo(ahc, &devinfo, pending_scb);2687 tinfo = ahc_fetch_transinfo(ahc, devinfo.channel,2688 devinfo.our_scsiid,2689 devinfo.target, &tstate);2690 pending_hscb = pending_scb->hscb;2691 pending_hscb->control &= ~ULTRAENB;2692 if ((tstate->ultraenb & devinfo.target_mask) != 0)2693 pending_hscb->control |= ULTRAENB;2694 pending_hscb->scsirate = tinfo->scsirate;2695 pending_hscb->scsioffset = tinfo->curr.offset;2696 if ((tstate->auto_negotiate & devinfo.target_mask) == 02697 && (pending_scb->flags & SCB_AUTO_NEGOTIATE) != 0) {2698 pending_scb->flags &= ~SCB_AUTO_NEGOTIATE;2699 pending_hscb->control &= ~MK_MESSAGE;2700 }2701 ahc_sync_scb(ahc, pending_scb,2702 BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);2703 pending_scb_count++;2704 }2705 2706 if (pending_scb_count == 0)2707 return;2708 2709 if (ahc_is_paused(ahc)) {2710 paused = 1;2711 } else {2712 paused = 0;2713 ahc_pause(ahc);2714 }2715 2716 saved_scbptr = ahc_inb(ahc, SCBPTR);2717 /* Ensure that the hscbs down on the card match the new information */2718 for (i = 0; i < ahc->scb_data->maxhscbs; i++) {2719 struct hardware_scb *pending_hscb;2720 u_int control;2721 u_int scb_tag;2722 2723 ahc_outb(ahc, SCBPTR, i);2724 scb_tag = ahc_inb(ahc, SCB_TAG);2725 pending_scb = ahc_lookup_scb(ahc, scb_tag);2726 if (pending_scb == NULL)2727 continue;2728 2729 pending_hscb = pending_scb->hscb;2730 control = ahc_inb(ahc, SCB_CONTROL);2731 control &= ~(ULTRAENB|MK_MESSAGE);2732 control |= pending_hscb->control & (ULTRAENB|MK_MESSAGE);2733 ahc_outb(ahc, SCB_CONTROL, control);2734 ahc_outb(ahc, SCB_SCSIRATE, pending_hscb->scsirate);2735 ahc_outb(ahc, SCB_SCSIOFFSET, pending_hscb->scsioffset);2736 }2737 ahc_outb(ahc, SCBPTR, saved_scbptr);2738 2739 if (paused == 0)2740 ahc_unpause(ahc);2741}2742 2743/**************************** Pathing Information *****************************/2744static void2745ahc_fetch_devinfo(struct ahc_softc *ahc, struct ahc_devinfo *devinfo)2746{2747 u_int saved_scsiid;2748 role_t role;2749 int our_id;2750 2751 if (ahc_inb(ahc, SSTAT0) & TARGET)2752 role = ROLE_TARGET;2753 else2754 role = ROLE_INITIATOR;2755 2756 if (role == ROLE_TARGET2757 && (ahc->features & AHC_MULTI_TID) != 02758 && (ahc_inb(ahc, SEQ_FLAGS)2759 & (CMDPHASE_PENDING|TARG_CMD_PENDING|NO_DISCONNECT)) != 0) {2760 /* We were selected, so pull our id from TARGIDIN */2761 our_id = ahc_inb(ahc, TARGIDIN) & OID;2762 } else if ((ahc->features & AHC_ULTRA2) != 0)2763 our_id = ahc_inb(ahc, SCSIID_ULTRA2) & OID;2764 else2765 our_id = ahc_inb(ahc, SCSIID) & OID;2766 2767 saved_scsiid = ahc_inb(ahc, SAVED_SCSIID);2768 ahc_compile_devinfo(devinfo,2769 our_id,2770 SCSIID_TARGET(ahc, saved_scsiid),2771 ahc_inb(ahc, SAVED_LUN),2772 SCSIID_CHANNEL(ahc, saved_scsiid),2773 role);2774}2775 2776static const struct ahc_phase_table_entry*2777ahc_lookup_phase_entry(int phase)2778{2779 const struct ahc_phase_table_entry *entry;2780 const struct ahc_phase_table_entry *last_entry;2781 2782 /*2783 * num_phases doesn't include the default entry which2784 * will be returned if the phase doesn't match.2785 */2786 last_entry = &ahc_phase_table[num_phases];2787 for (entry = ahc_phase_table; entry < last_entry; entry++) {2788 if (phase == entry->phase)2789 break;2790 }2791 return (entry);2792}2793 2794void2795ahc_compile_devinfo(struct ahc_devinfo *devinfo, u_int our_id, u_int target,2796 u_int lun, char channel, role_t role)2797{2798 devinfo->our_scsiid = our_id;2799 devinfo->target = target;2800 devinfo->lun = lun;2801 devinfo->target_offset = target;2802 devinfo->channel = channel;2803 devinfo->role = role;2804 if (channel == 'B')2805 devinfo->target_offset += 8;2806 devinfo->target_mask = (0x01 << devinfo->target_offset);2807}2808 2809void2810ahc_print_devinfo(struct ahc_softc *ahc, struct ahc_devinfo *devinfo)2811{2812 printk("%s:%c:%d:%d: ", ahc_name(ahc), devinfo->channel,2813 devinfo->target, devinfo->lun);2814}2815 2816static void2817ahc_scb_devinfo(struct ahc_softc *ahc, struct ahc_devinfo *devinfo,2818 struct scb *scb)2819{2820 role_t role;2821 int our_id;2822 2823 our_id = SCSIID_OUR_ID(scb->hscb->scsiid);2824 role = ROLE_INITIATOR;2825 if ((scb->flags & SCB_TARGET_SCB) != 0)2826 role = ROLE_TARGET;2827 ahc_compile_devinfo(devinfo, our_id, SCB_GET_TARGET(ahc, scb),2828 SCB_GET_LUN(scb), SCB_GET_CHANNEL(ahc, scb), role);2829}2830 2831 2832/************************ Message Phase Processing ****************************/2833static void2834ahc_assert_atn(struct ahc_softc *ahc)2835{2836 u_int scsisigo;2837 2838 scsisigo = ATNO;2839 if ((ahc->features & AHC_DT) == 0)2840 scsisigo |= ahc_inb(ahc, SCSISIGI);2841 ahc_outb(ahc, SCSISIGO, scsisigo);2842}2843 2844/*2845 * When an initiator transaction with the MK_MESSAGE flag either reconnects2846 * or enters the initial message out phase, we are interrupted. Fill our2847 * outgoing message buffer with the appropriate message and beging handing2848 * the message phase(s) manually.2849 */2850static void2851ahc_setup_initiator_msgout(struct ahc_softc *ahc, struct ahc_devinfo *devinfo,2852 struct scb *scb)2853{2854 /*2855 * To facilitate adding multiple messages together,2856 * each routine should increment the index and len2857 * variables instead of setting them explicitly.2858 */2859 ahc->msgout_index = 0;2860 ahc->msgout_len = 0;2861 2862 if ((scb->flags & SCB_DEVICE_RESET) == 02863 && ahc_inb(ahc, MSG_OUT) == MSG_IDENTIFYFLAG) {2864 u_int identify_msg;2865 2866 identify_msg = MSG_IDENTIFYFLAG | SCB_GET_LUN(scb);2867 if ((scb->hscb->control & DISCENB) != 0)2868 identify_msg |= MSG_IDENTIFY_DISCFLAG;2869 ahc->msgout_buf[ahc->msgout_index++] = identify_msg;2870 ahc->msgout_len++;2871 2872 if ((scb->hscb->control & TAG_ENB) != 0) {2873 ahc->msgout_buf[ahc->msgout_index++] =2874 scb->hscb->control & (TAG_ENB|SCB_TAG_TYPE);2875 ahc->msgout_buf[ahc->msgout_index++] = scb->hscb->tag;2876 ahc->msgout_len += 2;2877 }2878 }2879 2880 if (scb->flags & SCB_DEVICE_RESET) {2881 ahc->msgout_buf[ahc->msgout_index++] = TARGET_RESET;2882 ahc->msgout_len++;2883 ahc_print_path(ahc, scb);2884 printk("Bus Device Reset Message Sent\n");2885 /*2886 * Clear our selection hardware in advance of2887 * the busfree. We may have an entry in the waiting2888 * Q for this target, and we don't want to go about2889 * selecting while we handle the busfree and blow it2890 * away.2891 */2892 ahc_outb(ahc, SCSISEQ, (ahc_inb(ahc, SCSISEQ) & ~ENSELO));2893 } else if ((scb->flags & SCB_ABORT) != 0) {2894 if ((scb->hscb->control & TAG_ENB) != 0)2895 ahc->msgout_buf[ahc->msgout_index++] = ABORT_TASK;2896 else2897 ahc->msgout_buf[ahc->msgout_index++] = ABORT_TASK_SET;2898 ahc->msgout_len++;2899 ahc_print_path(ahc, scb);2900 printk("Abort%s Message Sent\n",2901 (scb->hscb->control & TAG_ENB) != 0 ? " Tag" : "");2902 /*2903 * Clear our selection hardware in advance of2904 * the busfree. We may have an entry in the waiting2905 * Q for this target, and we don't want to go about2906 * selecting while we handle the busfree and blow it2907 * away.2908 */2909 ahc_outb(ahc, SCSISEQ, (ahc_inb(ahc, SCSISEQ) & ~ENSELO));2910 } else if ((scb->flags & (SCB_AUTO_NEGOTIATE|SCB_NEGOTIATE)) != 0) {2911 ahc_build_transfer_msg(ahc, devinfo);2912 } else {2913 printk("ahc_intr: AWAITING_MSG for an SCB that "2914 "does not have a waiting message\n");2915 printk("SCSIID = %x, target_mask = %x\n", scb->hscb->scsiid,2916 devinfo->target_mask);2917 panic("SCB = %d, SCB Control = %x, MSG_OUT = %x "2918 "SCB flags = %x", scb->hscb->tag, scb->hscb->control,2919 ahc_inb(ahc, MSG_OUT), scb->flags);2920 }2921 2922 /*2923 * Clear the MK_MESSAGE flag from the SCB so we aren't2924 * asked to send this message again.2925 */2926 ahc_outb(ahc, SCB_CONTROL, ahc_inb(ahc, SCB_CONTROL) & ~MK_MESSAGE);2927 scb->hscb->control &= ~MK_MESSAGE;2928 ahc->msgout_index = 0;2929 ahc->msg_type = MSG_TYPE_INITIATOR_MSGOUT;2930}2931 2932/*2933 * Build an appropriate transfer negotiation message for the2934 * currently active target.2935 */2936static void2937ahc_build_transfer_msg(struct ahc_softc *ahc, struct ahc_devinfo *devinfo)2938{2939 /*2940 * We need to initiate transfer negotiations.2941 * If our current and goal settings are identical,2942 * we want to renegotiate due to a check condition.2943 */2944 struct ahc_initiator_tinfo *tinfo;2945 struct ahc_tmode_tstate *tstate;2946 const struct ahc_syncrate *rate;2947 int dowide;2948 int dosync;2949 int doppr;2950 u_int period;2951 u_int ppr_options;2952 u_int offset;2953 2954 tinfo = ahc_fetch_transinfo(ahc, devinfo->channel, devinfo->our_scsiid,2955 devinfo->target, &tstate);2956 /*2957 * Filter our period based on the current connection.2958 * If we can't perform DT transfers on this segment (not in LVD2959 * mode for instance), then our decision to issue a PPR message2960 * may change.2961 */2962 period = tinfo->goal.period;2963 offset = tinfo->goal.offset;2964 ppr_options = tinfo->goal.ppr_options;2965 /* Target initiated PPR is not allowed in the SCSI spec */2966 if (devinfo->role == ROLE_TARGET)2967 ppr_options = 0;2968 rate = ahc_devlimited_syncrate(ahc, tinfo, &period,2969 &ppr_options, devinfo->role);2970 dowide = tinfo->curr.width != tinfo->goal.width;2971 dosync = tinfo->curr.offset != offset || tinfo->curr.period != period;2972 /*2973 * Only use PPR if we have options that need it, even if the device2974 * claims to support it. There might be an expander in the way2975 * that doesn't.2976 */2977 doppr = ppr_options != 0;2978 2979 if (!dowide && !dosync && !doppr) {2980 dowide = tinfo->goal.width != MSG_EXT_WDTR_BUS_8_BIT;2981 dosync = tinfo->goal.offset != 0;2982 }2983 2984 if (!dowide && !dosync && !doppr) {2985 /*2986 * Force async with a WDTR message if we have a wide bus,2987 * or just issue an SDTR with a 0 offset.2988 */2989 if ((ahc->features & AHC_WIDE) != 0)2990 dowide = 1;2991 else2992 dosync = 1;2993 2994 if (bootverbose) {2995 ahc_print_devinfo(ahc, devinfo);2996 printk("Ensuring async\n");2997 }2998 }2999 3000 /* Target initiated PPR is not allowed in the SCSI spec */3001 if (devinfo->role == ROLE_TARGET)3002 doppr = 0;3003 3004 /*3005 * Both the PPR message and SDTR message require the3006 * goal syncrate to be limited to what the target device3007 * is capable of handling (based on whether an LVD->SE3008 * expander is on the bus), so combine these two cases.3009 * Regardless, guarantee that if we are using WDTR and SDTR3010 * messages that WDTR comes first.3011 */3012 if (doppr || (dosync && !dowide)) {3013 3014 offset = tinfo->goal.offset;3015 ahc_validate_offset(ahc, tinfo, rate, &offset,3016 doppr ? tinfo->goal.width3017 : tinfo->curr.width,3018 devinfo->role);3019 if (doppr) {3020 ahc_construct_ppr(ahc, devinfo, period, offset,3021 tinfo->goal.width, ppr_options);3022 } else {3023 ahc_construct_sdtr(ahc, devinfo, period, offset);3024 }3025 } else {3026 ahc_construct_wdtr(ahc, devinfo, tinfo->goal.width);3027 }3028}3029 3030/*3031 * Build a synchronous negotiation message in our message3032 * buffer based on the input parameters.3033 */3034static void3035ahc_construct_sdtr(struct ahc_softc *ahc, struct ahc_devinfo *devinfo,3036 u_int period, u_int offset)3037{3038 if (offset == 0)3039 period = AHC_ASYNC_XFER_PERIOD;3040 ahc->msgout_index += spi_populate_sync_msg(3041 ahc->msgout_buf + ahc->msgout_index, period, offset);3042 ahc->msgout_len += 5;3043 if (bootverbose) {3044 printk("(%s:%c:%d:%d): Sending SDTR period %x, offset %x\n",3045 ahc_name(ahc), devinfo->channel, devinfo->target,3046 devinfo->lun, period, offset);3047 }3048}3049 3050/*3051 * Build a wide negotiation message in our message3052 * buffer based on the input parameters.3053 */3054static void3055ahc_construct_wdtr(struct ahc_softc *ahc, struct ahc_devinfo *devinfo,3056 u_int bus_width)3057{3058 ahc->msgout_index += spi_populate_width_msg(3059 ahc->msgout_buf + ahc->msgout_index, bus_width);3060 ahc->msgout_len += 4;3061 if (bootverbose) {3062 printk("(%s:%c:%d:%d): Sending WDTR %x\n",3063 ahc_name(ahc), devinfo->channel, devinfo->target,3064 devinfo->lun, bus_width);3065 }3066}3067 3068/*3069 * Build a parallel protocol request message in our message3070 * buffer based on the input parameters.3071 */3072static void3073ahc_construct_ppr(struct ahc_softc *ahc, struct ahc_devinfo *devinfo,3074 u_int period, u_int offset, u_int bus_width,3075 u_int ppr_options)3076{3077 if (offset == 0)3078 period = AHC_ASYNC_XFER_PERIOD;3079 ahc->msgout_index += spi_populate_ppr_msg(3080 ahc->msgout_buf + ahc->msgout_index, period, offset,3081 bus_width, ppr_options);3082 ahc->msgout_len += 8;3083 if (bootverbose) {3084 printk("(%s:%c:%d:%d): Sending PPR bus_width %x, period %x, "3085 "offset %x, ppr_options %x\n", ahc_name(ahc),3086 devinfo->channel, devinfo->target, devinfo->lun,3087 bus_width, period, offset, ppr_options);3088 }3089}3090 3091/*3092 * Clear any active message state.3093 */3094static void3095ahc_clear_msg_state(struct ahc_softc *ahc)3096{3097 ahc->msgout_len = 0;3098 ahc->msgin_index = 0;3099 ahc->msg_type = MSG_TYPE_NONE;3100 if ((ahc_inb(ahc, SCSISIGI) & ATNI) != 0) {3101 /*3102 * The target didn't care to respond to our3103 * message request, so clear ATN.3104 */3105 ahc_outb(ahc, CLRSINT1, CLRATNO);3106 }3107 ahc_outb(ahc, MSG_OUT, NOP);3108 ahc_outb(ahc, SEQ_FLAGS2,3109 ahc_inb(ahc, SEQ_FLAGS2) & ~TARGET_MSG_PENDING);3110}3111 3112static void3113ahc_handle_proto_violation(struct ahc_softc *ahc)3114{3115 struct ahc_devinfo devinfo;3116 struct scb *scb;3117 u_int scbid;3118 u_int seq_flags;3119 u_int curphase;3120 u_int lastphase;3121 int found;3122 3123 ahc_fetch_devinfo(ahc, &devinfo);3124 scbid = ahc_inb(ahc, SCB_TAG);3125 scb = ahc_lookup_scb(ahc, scbid);3126 seq_flags = ahc_inb(ahc, SEQ_FLAGS);3127 curphase = ahc_inb(ahc, SCSISIGI) & PHASE_MASK;3128 lastphase = ahc_inb(ahc, LASTPHASE);3129 if ((seq_flags & NOT_IDENTIFIED) != 0) {3130 3131 /*3132 * The reconnecting target either did not send an3133 * identify message, or did, but we didn't find an SCB3134 * to match.3135 */3136 ahc_print_devinfo(ahc, &devinfo);3137 printk("Target did not send an IDENTIFY message. "3138 "LASTPHASE = 0x%x.\n", lastphase);3139 scb = NULL;3140 } else if (scb == NULL) {3141 /*3142 * We don't seem to have an SCB active for this3143 * transaction. Print an error and reset the bus.3144 */3145 ahc_print_devinfo(ahc, &devinfo);3146 printk("No SCB found during protocol violation\n");3147 goto proto_violation_reset;3148 } else {3149 ahc_set_transaction_status(scb, CAM_SEQUENCE_FAIL);3150 if ((seq_flags & NO_CDB_SENT) != 0) {3151 ahc_print_path(ahc, scb);3152 printk("No or incomplete CDB sent to device.\n");3153 } else if ((ahc_inb(ahc, SCB_CONTROL) & STATUS_RCVD) == 0) {3154 /*3155 * The target never bothered to provide status to3156 * us prior to completing the command. Since we don't3157 * know the disposition of this command, we must attempt3158 * to abort it. Assert ATN and prepare to send an abort3159 * message.3160 */3161 ahc_print_path(ahc, scb);3162 printk("Completed command without status.\n");3163 } else {3164 ahc_print_path(ahc, scb);3165 printk("Unknown protocol violation.\n");3166 ahc_dump_card_state(ahc);3167 }3168 }3169 if ((lastphase & ~P_DATAIN_DT) == 03170 || lastphase == P_COMMAND) {3171proto_violation_reset:3172 /*3173 * Target either went directly to data/command3174 * phase or didn't respond to our ATN.3175 * The only safe thing to do is to blow3176 * it away with a bus reset.3177 */3178 found = ahc_reset_channel(ahc, 'A', TRUE);3179 printk("%s: Issued Channel %c Bus Reset. "3180 "%d SCBs aborted\n", ahc_name(ahc), 'A', found);3181 } else {3182 /*3183 * Leave the selection hardware off in case3184 * this abort attempt will affect yet to3185 * be sent commands.3186 */3187 ahc_outb(ahc, SCSISEQ,3188 ahc_inb(ahc, SCSISEQ) & ~ENSELO);3189 ahc_assert_atn(ahc);3190 ahc_outb(ahc, MSG_OUT, HOST_MSG);3191 if (scb == NULL) {3192 ahc_print_devinfo(ahc, &devinfo);3193 ahc->msgout_buf[0] = ABORT_TASK;3194 ahc->msgout_len = 1;3195 ahc->msgout_index = 0;3196 ahc->msg_type = MSG_TYPE_INITIATOR_MSGOUT;3197 } else {3198 ahc_print_path(ahc, scb);3199 scb->flags |= SCB_ABORT;3200 }3201 printk("Protocol violation %s. Attempting to abort.\n",3202 ahc_lookup_phase_entry(curphase)->phasemsg);3203 }3204}3205 3206/*3207 * Manual message loop handler.3208 */3209static void3210ahc_handle_message_phase(struct ahc_softc *ahc)3211{3212 struct ahc_devinfo devinfo;3213 u_int bus_phase;3214 int end_session;3215 3216 ahc_fetch_devinfo(ahc, &devinfo);3217 end_session = FALSE;3218 bus_phase = ahc_inb(ahc, SCSISIGI) & PHASE_MASK;3219 3220reswitch:3221 switch (ahc->msg_type) {3222 case MSG_TYPE_INITIATOR_MSGOUT:3223 {3224 int lastbyte;3225 int phasemis;3226 int msgdone;3227 3228 if (ahc->msgout_len == 0)3229 panic("HOST_MSG_LOOP interrupt with no active message");3230 3231#ifdef AHC_DEBUG3232 if ((ahc_debug & AHC_SHOW_MESSAGES) != 0) {3233 ahc_print_devinfo(ahc, &devinfo);3234 printk("INITIATOR_MSG_OUT");3235 }3236#endif3237 phasemis = bus_phase != P_MESGOUT;3238 if (phasemis) {3239#ifdef AHC_DEBUG3240 if ((ahc_debug & AHC_SHOW_MESSAGES) != 0) {3241 printk(" PHASEMIS %s\n",3242 ahc_lookup_phase_entry(bus_phase)3243 ->phasemsg);3244 }3245#endif3246 if (bus_phase == P_MESGIN) {3247 /*3248 * Change gears and see if3249 * this messages is of interest to3250 * us or should be passed back to3251 * the sequencer.3252 */3253 ahc_outb(ahc, CLRSINT1, CLRATNO);3254 ahc->send_msg_perror = FALSE;3255 ahc->msg_type = MSG_TYPE_INITIATOR_MSGIN;3256 ahc->msgin_index = 0;3257 goto reswitch;3258 }3259 end_session = TRUE;3260 break;3261 }3262 3263 if (ahc->send_msg_perror) {3264 ahc_outb(ahc, CLRSINT1, CLRATNO);3265 ahc_outb(ahc, CLRSINT1, CLRREQINIT);3266#ifdef AHC_DEBUG3267 if ((ahc_debug & AHC_SHOW_MESSAGES) != 0)3268 printk(" byte 0x%x\n", ahc->send_msg_perror);3269#endif3270 ahc_outb(ahc, SCSIDATL, MSG_PARITY_ERROR);3271 break;3272 }3273 3274 msgdone = ahc->msgout_index == ahc->msgout_len;3275 if (msgdone) {3276 /*3277 * The target has requested a retry.3278 * Re-assert ATN, reset our message index to3279 * 0, and try again.3280 */3281 ahc->msgout_index = 0;3282 ahc_assert_atn(ahc);3283 }3284 3285 lastbyte = ahc->msgout_index == (ahc->msgout_len - 1);3286 if (lastbyte) {3287 /* Last byte is signified by dropping ATN */3288 ahc_outb(ahc, CLRSINT1, CLRATNO);3289 }3290 3291 /*3292 * Clear our interrupt status and present3293 * the next byte on the bus.3294 */3295 ahc_outb(ahc, CLRSINT1, CLRREQINIT);3296#ifdef AHC_DEBUG3297 if ((ahc_debug & AHC_SHOW_MESSAGES) != 0)3298 printk(" byte 0x%x\n",3299 ahc->msgout_buf[ahc->msgout_index]);3300#endif3301 ahc_outb(ahc, SCSIDATL, ahc->msgout_buf[ahc->msgout_index++]);3302 break;3303 }3304 case MSG_TYPE_INITIATOR_MSGIN:3305 {3306 int phasemis;3307 int message_done;3308 3309#ifdef AHC_DEBUG3310 if ((ahc_debug & AHC_SHOW_MESSAGES) != 0) {3311 ahc_print_devinfo(ahc, &devinfo);3312 printk("INITIATOR_MSG_IN");3313 }3314#endif3315 phasemis = bus_phase != P_MESGIN;3316 if (phasemis) {3317#ifdef AHC_DEBUG3318 if ((ahc_debug & AHC_SHOW_MESSAGES) != 0) {3319 printk(" PHASEMIS %s\n",3320 ahc_lookup_phase_entry(bus_phase)3321 ->phasemsg);3322 }3323#endif3324 ahc->msgin_index = 0;3325 if (bus_phase == P_MESGOUT3326 && (ahc->send_msg_perror == TRUE3327 || (ahc->msgout_len != 03328 && ahc->msgout_index == 0))) {3329 ahc->msg_type = MSG_TYPE_INITIATOR_MSGOUT;3330 goto reswitch;3331 }3332 end_session = TRUE;3333 break;3334 }3335 3336 /* Pull the byte in without acking it */3337 ahc->msgin_buf[ahc->msgin_index] = ahc_inb(ahc, SCSIBUSL);3338#ifdef AHC_DEBUG3339 if ((ahc_debug & AHC_SHOW_MESSAGES) != 0)3340 printk(" byte 0x%x\n",3341 ahc->msgin_buf[ahc->msgin_index]);3342#endif3343 3344 message_done = ahc_parse_msg(ahc, &devinfo);3345 3346 if (message_done) {3347 /*3348 * Clear our incoming message buffer in case there3349 * is another message following this one.3350 */3351 ahc->msgin_index = 0;3352 3353 /*3354 * If this message illicited a response,3355 * assert ATN so the target takes us to the3356 * message out phase.3357 */3358 if (ahc->msgout_len != 0) {3359#ifdef AHC_DEBUG3360 if ((ahc_debug & AHC_SHOW_MESSAGES) != 0) {3361 ahc_print_devinfo(ahc, &devinfo);3362 printk("Asserting ATN for response\n");3363 }3364#endif3365 ahc_assert_atn(ahc);3366 }3367 } else3368 ahc->msgin_index++;3369 3370 if (message_done == MSGLOOP_TERMINATED) {3371 end_session = TRUE;3372 } else {3373 /* Ack the byte */3374 ahc_outb(ahc, CLRSINT1, CLRREQINIT);3375 ahc_inb(ahc, SCSIDATL);3376 }3377 break;3378 }3379 case MSG_TYPE_TARGET_MSGIN:3380 {3381 int msgdone;3382 int msgout_request;3383 3384 if (ahc->msgout_len == 0)3385 panic("Target MSGIN with no active message");3386 3387 /*3388 * If we interrupted a mesgout session, the initiator3389 * will not know this until our first REQ. So, we3390 * only honor mesgout requests after we've sent our3391 * first byte.3392 */3393 if ((ahc_inb(ahc, SCSISIGI) & ATNI) != 03394 && ahc->msgout_index > 0)3395 msgout_request = TRUE;3396 else3397 msgout_request = FALSE;3398 3399 if (msgout_request) {3400 3401 /*3402 * Change gears and see if3403 * this messages is of interest to3404 * us or should be passed back to3405 * the sequencer.3406 */3407 ahc->msg_type = MSG_TYPE_TARGET_MSGOUT;3408 ahc_outb(ahc, SCSISIGO, P_MESGOUT | BSYO);3409 ahc->msgin_index = 0;3410 /* Dummy read to REQ for first byte */3411 ahc_inb(ahc, SCSIDATL);3412 ahc_outb(ahc, SXFRCTL0,3413 ahc_inb(ahc, SXFRCTL0) | SPIOEN);3414 break;3415 }3416 3417 msgdone = ahc->msgout_index == ahc->msgout_len;3418 if (msgdone) {3419 ahc_outb(ahc, SXFRCTL0,3420 ahc_inb(ahc, SXFRCTL0) & ~SPIOEN);3421 end_session = TRUE;3422 break;3423 }3424 3425 /*3426 * Present the next byte on the bus.3427 */3428 ahc_outb(ahc, SXFRCTL0, ahc_inb(ahc, SXFRCTL0) | SPIOEN);3429 ahc_outb(ahc, SCSIDATL, ahc->msgout_buf[ahc->msgout_index++]);3430 break;3431 }3432 case MSG_TYPE_TARGET_MSGOUT:3433 {3434 int lastbyte;3435 int msgdone;3436 3437 /*3438 * The initiator signals that this is3439 * the last byte by dropping ATN.3440 */3441 lastbyte = (ahc_inb(ahc, SCSISIGI) & ATNI) == 0;3442 3443 /*3444 * Read the latched byte, but turn off SPIOEN first3445 * so that we don't inadvertently cause a REQ for the3446 * next byte.3447 */3448 ahc_outb(ahc, SXFRCTL0, ahc_inb(ahc, SXFRCTL0) & ~SPIOEN);3449 ahc->msgin_buf[ahc->msgin_index] = ahc_inb(ahc, SCSIDATL);3450 msgdone = ahc_parse_msg(ahc, &devinfo);3451 if (msgdone == MSGLOOP_TERMINATED) {3452 /*3453 * The message is *really* done in that it caused3454 * us to go to bus free. The sequencer has already3455 * been reset at this point, so pull the ejection3456 * handle.3457 */3458 return;3459 }3460 3461 ahc->msgin_index++;3462 3463 /*3464 * XXX Read spec about initiator dropping ATN too soon3465 * and use msgdone to detect it.3466 */3467 if (msgdone == MSGLOOP_MSGCOMPLETE) {3468 ahc->msgin_index = 0;3469 3470 /*3471 * If this message illicited a response, transition3472 * to the Message in phase and send it.3473 */3474 if (ahc->msgout_len != 0) {3475 ahc_outb(ahc, SCSISIGO, P_MESGIN | BSYO);3476 ahc_outb(ahc, SXFRCTL0,3477 ahc_inb(ahc, SXFRCTL0) | SPIOEN);3478 ahc->msg_type = MSG_TYPE_TARGET_MSGIN;3479 ahc->msgin_index = 0;3480 break;3481 }3482 }3483 3484 if (lastbyte)3485 end_session = TRUE;3486 else {3487 /* Ask for the next byte. */3488 ahc_outb(ahc, SXFRCTL0,3489 ahc_inb(ahc, SXFRCTL0) | SPIOEN);3490 }3491 3492 break;3493 }3494 default:3495 panic("Unknown REQINIT message type");3496 }3497 3498 if (end_session) {3499 ahc_clear_msg_state(ahc);3500 ahc_outb(ahc, RETURN_1, EXIT_MSG_LOOP);3501 } else3502 ahc_outb(ahc, RETURN_1, CONT_MSG_LOOP);3503}3504 3505/*3506 * See if we sent a particular extended message to the target.3507 * If "full" is true, return true only if the target saw the full3508 * message. If "full" is false, return true if the target saw at3509 * least the first byte of the message.3510 */3511static int3512ahc_sent_msg(struct ahc_softc *ahc, ahc_msgtype type, u_int msgval, int full)3513{3514 int found;3515 u_int index;3516 3517 found = FALSE;3518 index = 0;3519 3520 while (index < ahc->msgout_len) {3521 if (ahc->msgout_buf[index] == EXTENDED_MESSAGE) {3522 u_int end_index;3523 3524 end_index = index + 1 + ahc->msgout_buf[index + 1];3525 if (ahc->msgout_buf[index+2] == msgval3526 && type == AHCMSG_EXT) {3527 3528 if (full) {3529 if (ahc->msgout_index > end_index)3530 found = TRUE;3531 } else if (ahc->msgout_index > index)3532 found = TRUE;3533 }3534 index = end_index;3535 } else if (ahc->msgout_buf[index] >= SIMPLE_QUEUE_TAG3536 && ahc->msgout_buf[index] <= IGNORE_WIDE_RESIDUE) {3537 3538 /* Skip tag type and tag id or residue param*/3539 index += 2;3540 } else {3541 /* Single byte message */3542 if (type == AHCMSG_1B3543 && ahc->msgout_buf[index] == msgval3544 && ahc->msgout_index > index)3545 found = TRUE;3546 index++;3547 }3548 3549 if (found)3550 break;3551 }3552 return (found);3553}3554 3555/*3556 * Wait for a complete incoming message, parse it, and respond accordingly.3557 */3558static int3559ahc_parse_msg(struct ahc_softc *ahc, struct ahc_devinfo *devinfo)3560{3561 struct ahc_initiator_tinfo *tinfo;3562 struct ahc_tmode_tstate *tstate;3563 int reject;3564 int done;3565 int response;3566 u_int targ_scsirate;3567 3568 done = MSGLOOP_IN_PROG;3569 response = FALSE;3570 reject = FALSE;3571 tinfo = ahc_fetch_transinfo(ahc, devinfo->channel, devinfo->our_scsiid,3572 devinfo->target, &tstate);3573 targ_scsirate = tinfo->scsirate;3574 3575 /*3576 * Parse as much of the message as is available,3577 * rejecting it if we don't support it. When3578 * the entire message is available and has been3579 * handled, return MSGLOOP_MSGCOMPLETE, indicating3580 * that we have parsed an entire message.3581 *3582 * In the case of extended messages, we accept the length3583 * byte outright and perform more checking once we know the3584 * extended message type.3585 */3586 switch (ahc->msgin_buf[0]) {3587 case DISCONNECT:3588 case SAVE_POINTERS:3589 case COMMAND_COMPLETE:3590 case RESTORE_POINTERS:3591 case IGNORE_WIDE_RESIDUE:3592 /*3593 * End our message loop as these are messages3594 * the sequencer handles on its own.3595 */3596 done = MSGLOOP_TERMINATED;3597 break;3598 case MESSAGE_REJECT:3599 response = ahc_handle_msg_reject(ahc, devinfo);3600 fallthrough;3601 case NOP:3602 done = MSGLOOP_MSGCOMPLETE;3603 break;3604 case EXTENDED_MESSAGE:3605 {3606 /* Wait for enough of the message to begin validation */3607 if (ahc->msgin_index < 2)3608 break;3609 switch (ahc->msgin_buf[2]) {3610 case EXTENDED_SDTR:3611 {3612 const struct ahc_syncrate *syncrate;3613 u_int period;3614 u_int ppr_options;3615 u_int offset;3616 u_int saved_offset;3617 3618 if (ahc->msgin_buf[1] != MSG_EXT_SDTR_LEN) {3619 reject = TRUE;3620 break;3621 }3622 3623 /*3624 * Wait until we have both args before validating3625 * and acting on this message.3626 *3627 * Add one to MSG_EXT_SDTR_LEN to account for3628 * the extended message preamble.3629 */3630 if (ahc->msgin_index < (MSG_EXT_SDTR_LEN + 1))3631 break;3632 3633 period = ahc->msgin_buf[3];3634 ppr_options = 0;3635 saved_offset = offset = ahc->msgin_buf[4];3636 syncrate = ahc_devlimited_syncrate(ahc, tinfo, &period,3637 &ppr_options,3638 devinfo->role);3639 ahc_validate_offset(ahc, tinfo, syncrate, &offset,3640 targ_scsirate & WIDEXFER,3641 devinfo->role);3642 if (bootverbose) {3643 printk("(%s:%c:%d:%d): Received "3644 "SDTR period %x, offset %x\n\t"3645 "Filtered to period %x, offset %x\n",3646 ahc_name(ahc), devinfo->channel,3647 devinfo->target, devinfo->lun,3648 ahc->msgin_buf[3], saved_offset,3649 period, offset);3650 }3651 ahc_set_syncrate(ahc, devinfo,3652 syncrate, period,3653 offset, ppr_options,3654 AHC_TRANS_ACTIVE|AHC_TRANS_GOAL,3655 /*paused*/TRUE);3656 3657 /*3658 * See if we initiated Sync Negotiation3659 * and didn't have to fall down to async3660 * transfers.3661 */3662 if (ahc_sent_msg(ahc, AHCMSG_EXT, EXTENDED_SDTR, TRUE)) {3663 /* We started it */3664 if (saved_offset != offset) {3665 /* Went too low - force async */3666 reject = TRUE;3667 }3668 } else {3669 /*3670 * Send our own SDTR in reply3671 */3672 if (bootverbose3673 && devinfo->role == ROLE_INITIATOR) {3674 printk("(%s:%c:%d:%d): Target "3675 "Initiated SDTR\n",3676 ahc_name(ahc), devinfo->channel,3677 devinfo->target, devinfo->lun);3678 }3679 ahc->msgout_index = 0;3680 ahc->msgout_len = 0;3681 ahc_construct_sdtr(ahc, devinfo,3682 period, offset);3683 ahc->msgout_index = 0;3684 response = TRUE;3685 }3686 done = MSGLOOP_MSGCOMPLETE;3687 break;3688 }3689 case EXTENDED_WDTR:3690 {3691 u_int bus_width;3692 u_int saved_width;3693 u_int sending_reply;3694 3695 sending_reply = FALSE;3696 if (ahc->msgin_buf[1] != MSG_EXT_WDTR_LEN) {3697 reject = TRUE;3698 break;3699 }3700 3701 /*3702 * Wait until we have our arg before validating3703 * and acting on this message.3704 *3705 * Add one to MSG_EXT_WDTR_LEN to account for3706 * the extended message preamble.3707 */3708 if (ahc->msgin_index < (MSG_EXT_WDTR_LEN + 1))3709 break;3710 3711 bus_width = ahc->msgin_buf[3];3712 saved_width = bus_width;3713 ahc_validate_width(ahc, tinfo, &bus_width,3714 devinfo->role);3715 if (bootverbose) {3716 printk("(%s:%c:%d:%d): Received WDTR "3717 "%x filtered to %x\n",3718 ahc_name(ahc), devinfo->channel,3719 devinfo->target, devinfo->lun,3720 saved_width, bus_width);3721 }3722 3723 if (ahc_sent_msg(ahc, AHCMSG_EXT, EXTENDED_WDTR, TRUE)) {3724 /*3725 * Don't send a WDTR back to the3726 * target, since we asked first.3727 * If the width went higher than our3728 * request, reject it.3729 */3730 if (saved_width > bus_width) {3731 reject = TRUE;3732 printk("(%s:%c:%d:%d): requested %dBit "3733 "transfers. Rejecting...\n",3734 ahc_name(ahc), devinfo->channel,3735 devinfo->target, devinfo->lun,3736 8 * (0x01 << bus_width));3737 bus_width = 0;3738 }3739 } else {3740 /*3741 * Send our own WDTR in reply3742 */3743 if (bootverbose3744 && devinfo->role == ROLE_INITIATOR) {3745 printk("(%s:%c:%d:%d): Target "3746 "Initiated WDTR\n",3747 ahc_name(ahc), devinfo->channel,3748 devinfo->target, devinfo->lun);3749 }3750 ahc->msgout_index = 0;3751 ahc->msgout_len = 0;3752 ahc_construct_wdtr(ahc, devinfo, bus_width);3753 ahc->msgout_index = 0;3754 response = TRUE;3755 sending_reply = TRUE;3756 }3757 /*3758 * After a wide message, we are async, but3759 * some devices don't seem to honor this portion3760 * of the spec. Force a renegotiation of the3761 * sync component of our transfer agreement even3762 * if our goal is async. By updating our width3763 * after forcing the negotiation, we avoid3764 * renegotiating for width.3765 */3766 ahc_update_neg_request(ahc, devinfo, tstate,3767 tinfo, AHC_NEG_ALWAYS);3768 ahc_set_width(ahc, devinfo, bus_width,3769 AHC_TRANS_ACTIVE|AHC_TRANS_GOAL,3770 /*paused*/TRUE);3771 if (sending_reply == FALSE && reject == FALSE) {3772 3773 /*3774 * We will always have an SDTR to send.3775 */3776 ahc->msgout_index = 0;3777 ahc->msgout_len = 0;3778 ahc_build_transfer_msg(ahc, devinfo);3779 ahc->msgout_index = 0;3780 response = TRUE;3781 }3782 done = MSGLOOP_MSGCOMPLETE;3783 break;3784 }3785 case EXTENDED_PPR:3786 {3787 const struct ahc_syncrate *syncrate;3788 u_int period;3789 u_int offset;3790 u_int bus_width;3791 u_int ppr_options;3792 u_int saved_width;3793 u_int saved_offset;3794 u_int saved_ppr_options;3795 3796 if (ahc->msgin_buf[1] != MSG_EXT_PPR_LEN) {3797 reject = TRUE;3798 break;3799 }3800 3801 /*3802 * Wait until we have all args before validating3803 * and acting on this message.3804 *3805 * Add one to MSG_EXT_PPR_LEN to account for3806 * the extended message preamble.3807 */3808 if (ahc->msgin_index < (MSG_EXT_PPR_LEN + 1))3809 break;3810 3811 period = ahc->msgin_buf[3];3812 offset = ahc->msgin_buf[5];3813 bus_width = ahc->msgin_buf[6];3814 saved_width = bus_width;3815 ppr_options = ahc->msgin_buf[7];3816 /*3817 * According to the spec, a DT only3818 * period factor with no DT option3819 * set implies async.3820 */3821 if ((ppr_options & MSG_EXT_PPR_DT_REQ) == 03822 && period == 9)3823 offset = 0;3824 saved_ppr_options = ppr_options;3825 saved_offset = offset;3826 3827 /*3828 * Mask out any options we don't support3829 * on any controller. Transfer options are3830 * only available if we are negotiating wide.3831 */3832 ppr_options &= MSG_EXT_PPR_DT_REQ;3833 if (bus_width == 0)3834 ppr_options = 0;3835 3836 ahc_validate_width(ahc, tinfo, &bus_width,3837 devinfo->role);3838 syncrate = ahc_devlimited_syncrate(ahc, tinfo, &period,3839 &ppr_options,3840 devinfo->role);3841 ahc_validate_offset(ahc, tinfo, syncrate,3842 &offset, bus_width,3843 devinfo->role);3844 3845 if (ahc_sent_msg(ahc, AHCMSG_EXT, EXTENDED_PPR, TRUE)) {3846 /*3847 * If we are unable to do any of the3848 * requested options (we went too low),3849 * then we'll have to reject the message.3850 */3851 if (saved_width > bus_width3852 || saved_offset != offset3853 || saved_ppr_options != ppr_options) {3854 reject = TRUE;3855 period = 0;3856 offset = 0;3857 bus_width = 0;3858 ppr_options = 0;3859 syncrate = NULL;3860 }3861 } else {3862 if (devinfo->role != ROLE_TARGET)3863 printk("(%s:%c:%d:%d): Target "3864 "Initiated PPR\n",3865 ahc_name(ahc), devinfo->channel,3866 devinfo->target, devinfo->lun);3867 else3868 printk("(%s:%c:%d:%d): Initiator "3869 "Initiated PPR\n",3870 ahc_name(ahc), devinfo->channel,3871 devinfo->target, devinfo->lun);3872 ahc->msgout_index = 0;3873 ahc->msgout_len = 0;3874 ahc_construct_ppr(ahc, devinfo, period, offset,3875 bus_width, ppr_options);3876 ahc->msgout_index = 0;3877 response = TRUE;3878 }3879 if (bootverbose) {3880 printk("(%s:%c:%d:%d): Received PPR width %x, "3881 "period %x, offset %x,options %x\n"3882 "\tFiltered to width %x, period %x, "3883 "offset %x, options %x\n",3884 ahc_name(ahc), devinfo->channel,3885 devinfo->target, devinfo->lun,3886 saved_width, ahc->msgin_buf[3],3887 saved_offset, saved_ppr_options,3888 bus_width, period, offset, ppr_options);3889 }3890 ahc_set_width(ahc, devinfo, bus_width,3891 AHC_TRANS_ACTIVE|AHC_TRANS_GOAL,3892 /*paused*/TRUE);3893 ahc_set_syncrate(ahc, devinfo,3894 syncrate, period,3895 offset, ppr_options,3896 AHC_TRANS_ACTIVE|AHC_TRANS_GOAL,3897 /*paused*/TRUE);3898 done = MSGLOOP_MSGCOMPLETE;3899 break;3900 }3901 default:3902 /* Unknown extended message. Reject it. */3903 reject = TRUE;3904 break;3905 }3906 break;3907 }3908#ifdef AHC_TARGET_MODE3909 case TARGET_RESET:3910 ahc_handle_devreset(ahc, devinfo,3911 CAM_BDR_SENT,3912 "Bus Device Reset Received",3913 /*verbose_level*/0);3914 ahc_restart(ahc);3915 done = MSGLOOP_TERMINATED;3916 break;3917 case ABORT_TASK:3918 case ABORT_TASK_SET:3919 case CLEAR_QUEUE_TASK_SET:3920 {3921 int tag;3922 3923 /* Target mode messages */3924 if (devinfo->role != ROLE_TARGET) {3925 reject = TRUE;3926 break;3927 }3928 tag = SCB_LIST_NULL;3929 if (ahc->msgin_buf[0] == ABORT_TASK)3930 tag = ahc_inb(ahc, INITIATOR_TAG);3931 ahc_abort_scbs(ahc, devinfo->target, devinfo->channel,3932 devinfo->lun, tag, ROLE_TARGET,3933 CAM_REQ_ABORTED);3934 3935 tstate = ahc->enabled_targets[devinfo->our_scsiid];3936 if (tstate != NULL) {3937 struct ahc_tmode_lstate* lstate;3938 3939 lstate = tstate->enabled_luns[devinfo->lun];3940 if (lstate != NULL) {3941 ahc_queue_lstate_event(ahc, lstate,3942 devinfo->our_scsiid,3943 ahc->msgin_buf[0],3944 /*arg*/tag);3945 ahc_send_lstate_events(ahc, lstate);3946 }3947 }3948 ahc_restart(ahc);3949 done = MSGLOOP_TERMINATED;3950 break;3951 }3952#endif3953 case TERMINATE_IO_PROC:3954 default:3955 reject = TRUE;3956 break;3957 }3958 3959 if (reject) {3960 /*3961 * Setup to reject the message.3962 */3963 ahc->msgout_index = 0;3964 ahc->msgout_len = 1;3965 ahc->msgout_buf[0] = MESSAGE_REJECT;3966 done = MSGLOOP_MSGCOMPLETE;3967 response = TRUE;3968 }3969 3970 if (done != MSGLOOP_IN_PROG && !response)3971 /* Clear the outgoing message buffer */3972 ahc->msgout_len = 0;3973 3974 return (done);3975}3976 3977/*3978 * Process a message reject message.3979 */3980static int3981ahc_handle_msg_reject(struct ahc_softc *ahc, struct ahc_devinfo *devinfo)3982{3983 /*3984 * What we care about here is if we had an3985 * outstanding SDTR or WDTR message for this3986 * target. If we did, this is a signal that3987 * the target is refusing negotiation.3988 */3989 struct scb *scb;3990 struct ahc_initiator_tinfo *tinfo;3991 struct ahc_tmode_tstate *tstate;3992 u_int scb_index;3993 u_int last_msg;3994 int response = 0;3995 3996 scb_index = ahc_inb(ahc, SCB_TAG);3997 scb = ahc_lookup_scb(ahc, scb_index);3998 tinfo = ahc_fetch_transinfo(ahc, devinfo->channel,3999 devinfo->our_scsiid,4000 devinfo->target, &tstate);4001 /* Might be necessary */4002 last_msg = ahc_inb(ahc, LAST_MSG);4003 4004 if (ahc_sent_msg(ahc, AHCMSG_EXT, EXTENDED_PPR, /*full*/FALSE)) {4005 /*4006 * Target does not support the PPR message.4007 * Attempt to negotiate SPI-2 style.4008 */4009 if (bootverbose) {4010 printk("(%s:%c:%d:%d): PPR Rejected. "4011 "Trying WDTR/SDTR\n",4012 ahc_name(ahc), devinfo->channel,4013 devinfo->target, devinfo->lun);4014 }4015 tinfo->goal.ppr_options = 0;4016 tinfo->curr.transport_version = 2;4017 tinfo->goal.transport_version = 2;4018 ahc->msgout_index = 0;4019 ahc->msgout_len = 0;4020 ahc_build_transfer_msg(ahc, devinfo);4021 ahc->msgout_index = 0;4022 response = 1;4023 } else if (ahc_sent_msg(ahc, AHCMSG_EXT, EXTENDED_WDTR, /*full*/FALSE)) {4024 4025 /* note 8bit xfers */4026 printk("(%s:%c:%d:%d): refuses WIDE negotiation. Using "4027 "8bit transfers\n", ahc_name(ahc),4028 devinfo->channel, devinfo->target, devinfo->lun);4029 ahc_set_width(ahc, devinfo, MSG_EXT_WDTR_BUS_8_BIT,4030 AHC_TRANS_ACTIVE|AHC_TRANS_GOAL,4031 /*paused*/TRUE);4032 /*4033 * No need to clear the sync rate. If the target4034 * did not accept the command, our syncrate is4035 * unaffected. If the target started the negotiation,4036 * but rejected our response, we already cleared the4037 * sync rate before sending our WDTR.4038 */4039 if (tinfo->goal.offset != tinfo->curr.offset) {4040 4041 /* Start the sync negotiation */4042 ahc->msgout_index = 0;4043 ahc->msgout_len = 0;4044 ahc_build_transfer_msg(ahc, devinfo);4045 ahc->msgout_index = 0;4046 response = 1;4047 }4048 } else if (ahc_sent_msg(ahc, AHCMSG_EXT, EXTENDED_SDTR, /*full*/FALSE)) {4049 /* note asynch xfers and clear flag */4050 ahc_set_syncrate(ahc, devinfo, /*syncrate*/NULL, /*period*/0,4051 /*offset*/0, /*ppr_options*/0,4052 AHC_TRANS_ACTIVE|AHC_TRANS_GOAL,4053 /*paused*/TRUE);4054 printk("(%s:%c:%d:%d): refuses synchronous negotiation. "4055 "Using asynchronous transfers\n",4056 ahc_name(ahc), devinfo->channel,4057 devinfo->target, devinfo->lun);4058 } else if ((scb->hscb->control & SIMPLE_QUEUE_TAG) != 0) {4059 int tag_type;4060 int mask;4061 4062 tag_type = (scb->hscb->control & SIMPLE_QUEUE_TAG);4063 4064 if (tag_type == SIMPLE_QUEUE_TAG) {4065 printk("(%s:%c:%d:%d): refuses tagged commands. "4066 "Performing non-tagged I/O\n", ahc_name(ahc),4067 devinfo->channel, devinfo->target, devinfo->lun);4068 ahc_set_tags(ahc, scb->io_ctx, devinfo, AHC_QUEUE_NONE);4069 mask = ~0x23;4070 } else {4071 printk("(%s:%c:%d:%d): refuses %s tagged commands. "4072 "Performing simple queue tagged I/O only\n",4073 ahc_name(ahc), devinfo->channel, devinfo->target,4074 devinfo->lun, tag_type == ORDERED_QUEUE_TAG4075 ? "ordered" : "head of queue");4076 ahc_set_tags(ahc, scb->io_ctx, devinfo, AHC_QUEUE_BASIC);4077 mask = ~0x03;4078 }4079 4080 /*4081 * Resend the identify for this CCB as the target4082 * may believe that the selection is invalid otherwise.4083 */4084 ahc_outb(ahc, SCB_CONTROL,4085 ahc_inb(ahc, SCB_CONTROL) & mask);4086 scb->hscb->control &= mask;4087 ahc_set_transaction_tag(scb, /*enabled*/FALSE,4088 /*type*/SIMPLE_QUEUE_TAG);4089 ahc_outb(ahc, MSG_OUT, MSG_IDENTIFYFLAG);4090 ahc_assert_atn(ahc);4091 4092 /*4093 * This transaction is now at the head of4094 * the untagged queue for this target.4095 */4096 if ((ahc->flags & AHC_SCB_BTT) == 0) {4097 struct scb_tailq *untagged_q;4098 4099 untagged_q =4100 &(ahc->untagged_queues[devinfo->target_offset]);4101 TAILQ_INSERT_HEAD(untagged_q, scb, links.tqe);4102 scb->flags |= SCB_UNTAGGEDQ;4103 }4104 ahc_busy_tcl(ahc, BUILD_TCL(scb->hscb->scsiid, devinfo->lun),4105 scb->hscb->tag);4106 4107 /*4108 * Requeue all tagged commands for this target4109 * currently in our possession so they can be4110 * converted to untagged commands.4111 */4112 ahc_search_qinfifo(ahc, SCB_GET_TARGET(ahc, scb),4113 SCB_GET_CHANNEL(ahc, scb),4114 SCB_GET_LUN(scb), /*tag*/SCB_LIST_NULL,4115 ROLE_INITIATOR, CAM_REQUEUE_REQ,4116 SEARCH_COMPLETE);4117 } else {4118 /*4119 * Otherwise, we ignore it.4120 */4121 printk("%s:%c:%d: Message reject for %x -- ignored\n",4122 ahc_name(ahc), devinfo->channel, devinfo->target,4123 last_msg);4124 }4125 return (response);4126}4127 4128/*4129 * Process an ingnore wide residue message.4130 */4131static void4132ahc_handle_ign_wide_residue(struct ahc_softc *ahc, struct ahc_devinfo *devinfo)4133{4134 u_int scb_index;4135 struct scb *scb;4136 4137 scb_index = ahc_inb(ahc, SCB_TAG);4138 scb = ahc_lookup_scb(ahc, scb_index);4139 /*4140 * XXX Actually check data direction in the sequencer?4141 * Perhaps add datadir to some spare bits in the hscb?4142 */4143 if ((ahc_inb(ahc, SEQ_FLAGS) & DPHASE) == 04144 || ahc_get_transfer_dir(scb) != CAM_DIR_IN) {4145 /*4146 * Ignore the message if we haven't4147 * seen an appropriate data phase yet.4148 */4149 } else {4150 /*4151 * If the residual occurred on the last4152 * transfer and the transfer request was4153 * expected to end on an odd count, do4154 * nothing. Otherwise, subtract a byte4155 * and update the residual count accordingly.4156 */4157 uint32_t sgptr;4158 4159 sgptr = ahc_inb(ahc, SCB_RESIDUAL_SGPTR);4160 if ((sgptr & SG_LIST_NULL) != 04161 && (ahc_inb(ahc, SCB_LUN) & SCB_XFERLEN_ODD) != 0) {4162 /*4163 * If the residual occurred on the last4164 * transfer and the transfer request was4165 * expected to end on an odd count, do4166 * nothing.4167 */4168 } else {4169 struct ahc_dma_seg *sg;4170 uint32_t data_cnt;4171 uint32_t data_addr;4172 uint32_t sglen;4173 4174 /* Pull in all of the sgptr */4175 sgptr = ahc_inl(ahc, SCB_RESIDUAL_SGPTR);4176 data_cnt = ahc_inl(ahc, SCB_RESIDUAL_DATACNT);4177 4178 if ((sgptr & SG_LIST_NULL) != 0) {4179 /*4180 * The residual data count is not updated4181 * for the command run to completion case.4182 * Explicitly zero the count.4183 */4184 data_cnt &= ~AHC_SG_LEN_MASK;4185 }4186 4187 data_addr = ahc_inl(ahc, SHADDR);4188 4189 data_cnt += 1;4190 data_addr -= 1;4191 sgptr &= SG_PTR_MASK;4192 4193 sg = ahc_sg_bus_to_virt(scb, sgptr);4194 4195 /*4196 * The residual sg ptr points to the next S/G4197 * to load so we must go back one.4198 */4199 sg--;4200 sglen = ahc_le32toh(sg->len) & AHC_SG_LEN_MASK;4201 if (sg != scb->sg_list4202 && sglen < (data_cnt & AHC_SG_LEN_MASK)) {4203 4204 sg--;4205 sglen = ahc_le32toh(sg->len);4206 /*4207 * Preserve High Address and SG_LIST bits4208 * while setting the count to 1.4209 */4210 data_cnt = 1 | (sglen & (~AHC_SG_LEN_MASK));4211 data_addr = ahc_le32toh(sg->addr)4212 + (sglen & AHC_SG_LEN_MASK) - 1;4213 4214 /*4215 * Increment sg so it points to the4216 * "next" sg.4217 */4218 sg++;4219 sgptr = ahc_sg_virt_to_bus(scb, sg);4220 }4221 ahc_outl(ahc, SCB_RESIDUAL_SGPTR, sgptr);4222 ahc_outl(ahc, SCB_RESIDUAL_DATACNT, data_cnt);4223 /*4224 * Toggle the "oddness" of the transfer length4225 * to handle this mid-transfer ignore wide4226 * residue. This ensures that the oddness is4227 * correct for subsequent data transfers.4228 */4229 ahc_outb(ahc, SCB_LUN,4230 ahc_inb(ahc, SCB_LUN) ^ SCB_XFERLEN_ODD);4231 }4232 }4233}4234 4235 4236/*4237 * Reinitialize the data pointers for the active transfer4238 * based on its current residual.4239 */4240static void4241ahc_reinitialize_dataptrs(struct ahc_softc *ahc)4242{4243 struct scb *scb;4244 struct ahc_dma_seg *sg;4245 u_int scb_index;4246 uint32_t sgptr;4247 uint32_t resid;4248 uint32_t dataptr;4249 4250 scb_index = ahc_inb(ahc, SCB_TAG);4251 scb = ahc_lookup_scb(ahc, scb_index);4252 sgptr = (ahc_inb(ahc, SCB_RESIDUAL_SGPTR + 3) << 24)4253 | (ahc_inb(ahc, SCB_RESIDUAL_SGPTR + 2) << 16)4254 | (ahc_inb(ahc, SCB_RESIDUAL_SGPTR + 1) << 8)4255 | ahc_inb(ahc, SCB_RESIDUAL_SGPTR);4256 4257 sgptr &= SG_PTR_MASK;4258 sg = ahc_sg_bus_to_virt(scb, sgptr);4259 4260 /* The residual sg_ptr always points to the next sg */4261 sg--;4262 4263 resid = (ahc_inb(ahc, SCB_RESIDUAL_DATACNT + 2) << 16)4264 | (ahc_inb(ahc, SCB_RESIDUAL_DATACNT + 1) << 8)4265 | ahc_inb(ahc, SCB_RESIDUAL_DATACNT);4266 4267 dataptr = ahc_le32toh(sg->addr)4268 + (ahc_le32toh(sg->len) & AHC_SG_LEN_MASK)4269 - resid;4270 if ((ahc->flags & AHC_39BIT_ADDRESSING) != 0) {4271 u_int dscommand1;4272 4273 dscommand1 = ahc_inb(ahc, DSCOMMAND1);4274 ahc_outb(ahc, DSCOMMAND1, dscommand1 | HADDLDSEL0);4275 ahc_outb(ahc, HADDR,4276 (ahc_le32toh(sg->len) >> 24) & SG_HIGH_ADDR_BITS);4277 ahc_outb(ahc, DSCOMMAND1, dscommand1);4278 }4279 ahc_outb(ahc, HADDR + 3, dataptr >> 24);4280 ahc_outb(ahc, HADDR + 2, dataptr >> 16);4281 ahc_outb(ahc, HADDR + 1, dataptr >> 8);4282 ahc_outb(ahc, HADDR, dataptr);4283 ahc_outb(ahc, HCNT + 2, resid >> 16);4284 ahc_outb(ahc, HCNT + 1, resid >> 8);4285 ahc_outb(ahc, HCNT, resid);4286 if ((ahc->features & AHC_ULTRA2) == 0) {4287 ahc_outb(ahc, STCNT + 2, resid >> 16);4288 ahc_outb(ahc, STCNT + 1, resid >> 8);4289 ahc_outb(ahc, STCNT, resid);4290 }4291}4292 4293/*4294 * Handle the effects of issuing a bus device reset message.4295 */4296static void4297ahc_handle_devreset(struct ahc_softc *ahc, struct ahc_devinfo *devinfo,4298 cam_status status, char *message, int verbose_level)4299{4300#ifdef AHC_TARGET_MODE4301 struct ahc_tmode_tstate* tstate;4302 u_int lun;4303#endif4304 int found;4305 4306 found = ahc_abort_scbs(ahc, devinfo->target, devinfo->channel,4307 CAM_LUN_WILDCARD, SCB_LIST_NULL, devinfo->role,4308 status);4309 4310#ifdef AHC_TARGET_MODE4311 /*4312 * Send an immediate notify ccb to all target mord peripheral4313 * drivers affected by this action.4314 */4315 tstate = ahc->enabled_targets[devinfo->our_scsiid];4316 if (tstate != NULL) {4317 for (lun = 0; lun < AHC_NUM_LUNS; lun++) {4318 struct ahc_tmode_lstate* lstate;4319 4320 lstate = tstate->enabled_luns[lun];4321 if (lstate == NULL)4322 continue;4323 4324 ahc_queue_lstate_event(ahc, lstate, devinfo->our_scsiid,4325 TARGET_RESET, /*arg*/0);4326 ahc_send_lstate_events(ahc, lstate);4327 }4328 }4329#endif4330 4331 /*4332 * Go back to async/narrow transfers and renegotiate.4333 */4334 ahc_set_width(ahc, devinfo, MSG_EXT_WDTR_BUS_8_BIT,4335 AHC_TRANS_CUR, /*paused*/TRUE);4336 ahc_set_syncrate(ahc, devinfo, /*syncrate*/NULL,4337 /*period*/0, /*offset*/0, /*ppr_options*/0,4338 AHC_TRANS_CUR, /*paused*/TRUE);4339 4340 if (status != CAM_SEL_TIMEOUT)4341 ahc_send_async(ahc, devinfo->channel, devinfo->target,4342 CAM_LUN_WILDCARD, AC_SENT_BDR);4343 4344 if (message != NULL4345 && (verbose_level <= bootverbose))4346 printk("%s: %s on %c:%d. %d SCBs aborted\n", ahc_name(ahc),4347 message, devinfo->channel, devinfo->target, found);4348}4349 4350#ifdef AHC_TARGET_MODE4351static void4352ahc_setup_target_msgin(struct ahc_softc *ahc, struct ahc_devinfo *devinfo,4353 struct scb *scb)4354{4355 4356 /*4357 * To facilitate adding multiple messages together,4358 * each routine should increment the index and len4359 * variables instead of setting them explicitly.4360 */4361 ahc->msgout_index = 0;4362 ahc->msgout_len = 0;4363 4364 if (scb != NULL && (scb->flags & SCB_AUTO_NEGOTIATE) != 0)4365 ahc_build_transfer_msg(ahc, devinfo);4366 else4367 panic("ahc_intr: AWAITING target message with no message");4368 4369 ahc->msgout_index = 0;4370 ahc->msg_type = MSG_TYPE_TARGET_MSGIN;4371}4372#endif4373/**************************** Initialization **********************************/4374/*4375 * Allocate a controller structure for a new device4376 * and perform initial initializion.4377 */4378struct ahc_softc *4379ahc_alloc(void *platform_arg, char *name)4380{4381 struct ahc_softc *ahc;4382 int i;4383 4384 ahc = kzalloc(sizeof(*ahc), GFP_ATOMIC);4385 if (!ahc) {4386 printk("aic7xxx: cannot malloc softc!\n");4387 kfree(name);4388 return NULL;4389 }4390 4391 ahc->seep_config = kmalloc(sizeof(*ahc->seep_config), GFP_ATOMIC);4392 if (ahc->seep_config == NULL) {4393 kfree(ahc);4394 kfree(name);4395 return (NULL);4396 }4397 LIST_INIT(&ahc->pending_scbs);4398 /* We don't know our unit number until the OSM sets it */4399 ahc->name = name;4400 ahc->unit = -1;4401 ahc->description = NULL;4402 ahc->channel = 'A';4403 ahc->channel_b = 'B';4404 ahc->chip = AHC_NONE;4405 ahc->features = AHC_FENONE;4406 ahc->bugs = AHC_BUGNONE;4407 ahc->flags = AHC_FNONE;4408 /*4409 * Default to all error reporting enabled with the4410 * sequencer operating at its fastest speed.4411 * The bus attach code may modify this.4412 */4413 ahc->seqctl = FASTMODE;4414 4415 for (i = 0; i < AHC_NUM_TARGETS; i++)4416 TAILQ_INIT(&ahc->untagged_queues[i]);4417 if (ahc_platform_alloc(ahc, platform_arg) != 0) {4418 ahc_free(ahc);4419 ahc = NULL;4420 }4421 return (ahc);4422}4423 4424int4425ahc_softc_init(struct ahc_softc *ahc)4426{4427 4428 /* The IRQMS bit is only valid on VL and EISA chips */4429 if ((ahc->chip & AHC_PCI) == 0)4430 ahc->unpause = ahc_inb(ahc, HCNTRL) & IRQMS;4431 else4432 ahc->unpause = 0;4433 ahc->pause = ahc->unpause | PAUSE;4434 /* XXX The shared scb data stuff should be deprecated */4435 if (ahc->scb_data == NULL) {4436 ahc->scb_data = kzalloc(sizeof(*ahc->scb_data), GFP_ATOMIC);4437 if (ahc->scb_data == NULL)4438 return (ENOMEM);4439 }4440 4441 return (0);4442}4443 4444void4445ahc_set_unit(struct ahc_softc *ahc, int unit)4446{4447 ahc->unit = unit;4448}4449 4450void4451ahc_set_name(struct ahc_softc *ahc, char *name)4452{4453 kfree(ahc->name);4454 ahc->name = name;4455}4456 4457void4458ahc_free(struct ahc_softc *ahc)4459{4460 int i;4461 4462 switch (ahc->init_level) {4463 default:4464 case 5:4465 ahc_shutdown(ahc);4466 fallthrough;4467 case 4:4468 ahc_dmamap_unload(ahc, ahc->shared_data_dmat,4469 ahc->shared_data_dmamap);4470 fallthrough;4471 case 3:4472 ahc_dmamem_free(ahc, ahc->shared_data_dmat, ahc->qoutfifo,4473 ahc->shared_data_dmamap);4474 ahc_dmamap_destroy(ahc, ahc->shared_data_dmat,4475 ahc->shared_data_dmamap);4476 fallthrough;4477 case 2:4478 ahc_dma_tag_destroy(ahc, ahc->shared_data_dmat);4479 fallthrough;4480 case 1:4481 break;4482 case 0:4483 break;4484 }4485 4486 ahc_platform_free(ahc);4487 ahc_fini_scbdata(ahc);4488 for (i = 0; i < AHC_NUM_TARGETS; i++) {4489 struct ahc_tmode_tstate *tstate;4490 4491 tstate = ahc->enabled_targets[i];4492 if (tstate != NULL) {4493#ifdef AHC_TARGET_MODE4494 int j;4495 4496 for (j = 0; j < AHC_NUM_LUNS; j++) {4497 struct ahc_tmode_lstate *lstate;4498 4499 lstate = tstate->enabled_luns[j];4500 if (lstate != NULL) {4501 xpt_free_path(lstate->path);4502 kfree(lstate);4503 }4504 }4505#endif4506 kfree(tstate);4507 }4508 }4509#ifdef AHC_TARGET_MODE4510 if (ahc->black_hole != NULL) {4511 xpt_free_path(ahc->black_hole->path);4512 kfree(ahc->black_hole);4513 }4514#endif4515 kfree(ahc->name);4516 kfree(ahc->seep_config);4517 kfree(ahc);4518 return;4519}4520 4521static void4522ahc_shutdown(void *arg)4523{4524 struct ahc_softc *ahc;4525 int i;4526 4527 ahc = (struct ahc_softc *)arg;4528 4529 /* This will reset most registers to 0, but not all */4530 ahc_reset(ahc, /*reinit*/FALSE);4531 ahc_outb(ahc, SCSISEQ, 0);4532 ahc_outb(ahc, SXFRCTL0, 0);4533 ahc_outb(ahc, DSPCISTATUS, 0);4534 4535 for (i = TARG_SCSIRATE; i < SCSICONF; i++)4536 ahc_outb(ahc, i, 0);4537}4538 4539/*4540 * Reset the controller and record some information about it4541 * that is only available just after a reset. If "reinit" is4542 * non-zero, this reset occurred after initial configuration4543 * and the caller requests that the chip be fully reinitialized4544 * to a runable state. Chip interrupts are *not* enabled after4545 * a reinitialization. The caller must enable interrupts via4546 * ahc_intr_enable().4547 */4548int4549ahc_reset(struct ahc_softc *ahc, int reinit)4550{4551 u_int sblkctl;4552 u_int sxfrctl1_a, sxfrctl1_b;4553 int error;4554 int wait;4555 4556 /*4557 * Preserve the value of the SXFRCTL1 register for all channels.4558 * It contains settings that affect termination and we don't want4559 * to disturb the integrity of the bus.4560 */4561 ahc_pause(ahc);4562 sxfrctl1_b = 0;4563 if ((ahc->chip & AHC_CHIPID_MASK) == AHC_AIC7770) {4564 u_int sblkctl;4565 4566 /*4567 * Save channel B's settings in case this chip4568 * is setup for TWIN channel operation.4569 */4570 sblkctl = ahc_inb(ahc, SBLKCTL);4571 ahc_outb(ahc, SBLKCTL, sblkctl | SELBUSB);4572 sxfrctl1_b = ahc_inb(ahc, SXFRCTL1);4573 ahc_outb(ahc, SBLKCTL, sblkctl & ~SELBUSB);4574 }4575 sxfrctl1_a = ahc_inb(ahc, SXFRCTL1);4576 4577 ahc_outb(ahc, HCNTRL, CHIPRST | ahc->pause);4578 4579 /*4580 * Ensure that the reset has finished. We delay 1000us4581 * prior to reading the register to make sure the chip4582 * has sufficiently completed its reset to handle register4583 * accesses.4584 */4585 wait = 1000;4586 do {4587 ahc_delay(1000);4588 } while (--wait && !(ahc_inb(ahc, HCNTRL) & CHIPRSTACK));4589 4590 if (wait == 0) {4591 printk("%s: WARNING - Failed chip reset! "4592 "Trying to initialize anyway.\n", ahc_name(ahc));4593 }4594 ahc_outb(ahc, HCNTRL, ahc->pause);4595 4596 /* Determine channel configuration */4597 sblkctl = ahc_inb(ahc, SBLKCTL) & (SELBUSB|SELWIDE);4598 /* No Twin Channel PCI cards */4599 if ((ahc->chip & AHC_PCI) != 0)4600 sblkctl &= ~SELBUSB;4601 switch (sblkctl) {4602 case 0:4603 /* Single Narrow Channel */4604 break;4605 case 2:4606 /* Wide Channel */4607 ahc->features |= AHC_WIDE;4608 break;4609 case 8:4610 /* Twin Channel */4611 ahc->features |= AHC_TWIN;4612 break;4613 default:4614 printk(" Unsupported adapter type. Ignoring\n");4615 return(-1);4616 }4617 4618 /*4619 * Reload sxfrctl1.4620 *4621 * We must always initialize STPWEN to 1 before we4622 * restore the saved values. STPWEN is initialized4623 * to a tri-state condition which can only be cleared4624 * by turning it on.4625 */4626 if ((ahc->features & AHC_TWIN) != 0) {4627 u_int sblkctl;4628 4629 sblkctl = ahc_inb(ahc, SBLKCTL);4630 ahc_outb(ahc, SBLKCTL, sblkctl | SELBUSB);4631 ahc_outb(ahc, SXFRCTL1, sxfrctl1_b);4632 ahc_outb(ahc, SBLKCTL, sblkctl & ~SELBUSB);4633 }4634 ahc_outb(ahc, SXFRCTL1, sxfrctl1_a);4635 4636 error = 0;4637 if (reinit != 0)4638 /*4639 * If a recovery action has forced a chip reset,4640 * re-initialize the chip to our liking.4641 */4642 error = ahc->bus_chip_init(ahc);4643#ifdef AHC_DUMP_SEQ4644 else4645 ahc_dumpseq(ahc);4646#endif4647 4648 return (error);4649}4650 4651/*4652 * Determine the number of SCBs available on the controller4653 */4654int4655ahc_probe_scbs(struct ahc_softc *ahc) {4656 int i;4657 4658 for (i = 0; i < AHC_SCB_MAX; i++) {4659 4660 ahc_outb(ahc, SCBPTR, i);4661 ahc_outb(ahc, SCB_BASE, i);4662 if (ahc_inb(ahc, SCB_BASE) != i)4663 break;4664 ahc_outb(ahc, SCBPTR, 0);4665 if (ahc_inb(ahc, SCB_BASE) != 0)4666 break;4667 }4668 return (i);4669}4670 4671static void4672ahc_dmamap_cb(void *arg, bus_dma_segment_t *segs, int nseg, int error) 4673{4674 dma_addr_t *baddr;4675 4676 baddr = (dma_addr_t *)arg;4677 *baddr = segs->ds_addr;4678}4679 4680static void4681ahc_build_free_scb_list(struct ahc_softc *ahc)4682{4683 int scbsize;4684 int i;4685 4686 scbsize = 32;4687 if ((ahc->flags & AHC_LSCBS_ENABLED) != 0)4688 scbsize = 64;4689 4690 for (i = 0; i < ahc->scb_data->maxhscbs; i++) {4691 int j;4692 4693 ahc_outb(ahc, SCBPTR, i);4694 4695 /*4696 * Touch all SCB bytes to avoid parity errors4697 * should one of our debugging routines read4698 * an otherwise uninitiatlized byte.4699 */4700 for (j = 0; j < scbsize; j++)4701 ahc_outb(ahc, SCB_BASE+j, 0xFF);4702 4703 /* Clear the control byte. */4704 ahc_outb(ahc, SCB_CONTROL, 0);4705 4706 /* Set the next pointer */4707 if ((ahc->flags & AHC_PAGESCBS) != 0)4708 ahc_outb(ahc, SCB_NEXT, i+1);4709 else4710 ahc_outb(ahc, SCB_NEXT, SCB_LIST_NULL);4711 4712 /* Make the tag number, SCSIID, and lun invalid */4713 ahc_outb(ahc, SCB_TAG, SCB_LIST_NULL);4714 ahc_outb(ahc, SCB_SCSIID, 0xFF);4715 ahc_outb(ahc, SCB_LUN, 0xFF);4716 }4717 4718 if ((ahc->flags & AHC_PAGESCBS) != 0) {4719 /* SCB 0 heads the free list. */4720 ahc_outb(ahc, FREE_SCBH, 0);4721 } else {4722 /* No free list. */4723 ahc_outb(ahc, FREE_SCBH, SCB_LIST_NULL);4724 }4725 4726 /* Make sure that the last SCB terminates the free list */4727 ahc_outb(ahc, SCBPTR, i-1);4728 ahc_outb(ahc, SCB_NEXT, SCB_LIST_NULL);4729}4730 4731static int4732ahc_init_scbdata(struct ahc_softc *ahc)4733{4734 struct scb_data *scb_data;4735 4736 scb_data = ahc->scb_data;4737 SLIST_INIT(&scb_data->free_scbs);4738 SLIST_INIT(&scb_data->sg_maps);4739 4740 /* Allocate SCB resources */4741 scb_data->scbarray = kcalloc(AHC_SCB_MAX_ALLOC, sizeof(struct scb),4742 GFP_ATOMIC);4743 if (scb_data->scbarray == NULL)4744 return (ENOMEM);4745 4746 /* Determine the number of hardware SCBs and initialize them */4747 4748 scb_data->maxhscbs = ahc_probe_scbs(ahc);4749 if (ahc->scb_data->maxhscbs == 0) {4750 printk("%s: No SCB space found\n", ahc_name(ahc));4751 return (ENXIO);4752 }4753 4754 /*4755 * Create our DMA tags. These tags define the kinds of device4756 * accessible memory allocations and memory mappings we will4757 * need to perform during normal operation.4758 *4759 * Unless we need to further restrict the allocation, we rely4760 * on the restrictions of the parent dmat, hence the common4761 * use of MAXADDR and MAXSIZE.4762 */4763 4764 /* DMA tag for our hardware scb structures */4765 if (ahc_dma_tag_create(ahc, ahc->parent_dmat, /*alignment*/1,4766 /*boundary*/BUS_SPACE_MAXADDR_32BIT + 1,4767 /*lowaddr*/BUS_SPACE_MAXADDR_32BIT,4768 /*highaddr*/BUS_SPACE_MAXADDR,4769 /*filter*/NULL, /*filterarg*/NULL,4770 AHC_SCB_MAX_ALLOC * sizeof(struct hardware_scb),4771 /*nsegments*/1,4772 /*maxsegsz*/BUS_SPACE_MAXSIZE_32BIT,4773 /*flags*/0, &scb_data->hscb_dmat) != 0) {4774 goto error_exit;4775 }4776 4777 scb_data->init_level++;4778 4779 /* Allocation for our hscbs */4780 if (ahc_dmamem_alloc(ahc, scb_data->hscb_dmat,4781 (void **)&scb_data->hscbs,4782 BUS_DMA_NOWAIT, &scb_data->hscb_dmamap) != 0) {4783 goto error_exit;4784 }4785 4786 scb_data->init_level++;4787 4788 /* And permanently map them */4789 ahc_dmamap_load(ahc, scb_data->hscb_dmat, scb_data->hscb_dmamap,4790 scb_data->hscbs,4791 AHC_SCB_MAX_ALLOC * sizeof(struct hardware_scb),4792 ahc_dmamap_cb, &scb_data->hscb_busaddr, /*flags*/0);4793 4794 scb_data->init_level++;4795 4796 /* DMA tag for our sense buffers */4797 if (ahc_dma_tag_create(ahc, ahc->parent_dmat, /*alignment*/1,4798 /*boundary*/BUS_SPACE_MAXADDR_32BIT + 1,4799 /*lowaddr*/BUS_SPACE_MAXADDR_32BIT,4800 /*highaddr*/BUS_SPACE_MAXADDR,4801 /*filter*/NULL, /*filterarg*/NULL,4802 AHC_SCB_MAX_ALLOC * sizeof(struct scsi_sense_data),4803 /*nsegments*/1,4804 /*maxsegsz*/BUS_SPACE_MAXSIZE_32BIT,4805 /*flags*/0, &scb_data->sense_dmat) != 0) {4806 goto error_exit;4807 }4808 4809 scb_data->init_level++;4810 4811 /* Allocate them */4812 if (ahc_dmamem_alloc(ahc, scb_data->sense_dmat,4813 (void **)&scb_data->sense,4814 BUS_DMA_NOWAIT, &scb_data->sense_dmamap) != 0) {4815 goto error_exit;4816 }4817 4818 scb_data->init_level++;4819 4820 /* And permanently map them */4821 ahc_dmamap_load(ahc, scb_data->sense_dmat, scb_data->sense_dmamap,4822 scb_data->sense,4823 AHC_SCB_MAX_ALLOC * sizeof(struct scsi_sense_data),4824 ahc_dmamap_cb, &scb_data->sense_busaddr, /*flags*/0);4825 4826 scb_data->init_level++;4827 4828 /* DMA tag for our S/G structures. We allocate in page sized chunks */4829 if (ahc_dma_tag_create(ahc, ahc->parent_dmat, /*alignment*/8,4830 /*boundary*/BUS_SPACE_MAXADDR_32BIT + 1,4831 /*lowaddr*/BUS_SPACE_MAXADDR_32BIT,4832 /*highaddr*/BUS_SPACE_MAXADDR,4833 /*filter*/NULL, /*filterarg*/NULL,4834 PAGE_SIZE, /*nsegments*/1,4835 /*maxsegsz*/BUS_SPACE_MAXSIZE_32BIT,4836 /*flags*/0, &scb_data->sg_dmat) != 0) {4837 goto error_exit;4838 }4839 4840 scb_data->init_level++;4841 4842 /* Perform initial CCB allocation */4843 memset(scb_data->hscbs, 0,4844 AHC_SCB_MAX_ALLOC * sizeof(struct hardware_scb));4845 ahc_alloc_scbs(ahc);4846 4847 if (scb_data->numscbs == 0) {4848 printk("%s: ahc_init_scbdata - "4849 "Unable to allocate initial scbs\n",4850 ahc_name(ahc));4851 goto error_exit;4852 }4853 4854 /*4855 * Reserve the next queued SCB.4856 */4857 ahc->next_queued_scb = ahc_get_scb(ahc);4858 4859 /*4860 * Note that we were successful4861 */4862 return (0);4863 4864error_exit:4865 4866 return (ENOMEM);4867}4868 4869static void4870ahc_fini_scbdata(struct ahc_softc *ahc)4871{4872 struct scb_data *scb_data;4873 4874 scb_data = ahc->scb_data;4875 if (scb_data == NULL)4876 return;4877 4878 switch (scb_data->init_level) {4879 default:4880 case 7:4881 {4882 struct sg_map_node *sg_map;4883 4884 while ((sg_map = SLIST_FIRST(&scb_data->sg_maps))!= NULL) {4885 SLIST_REMOVE_HEAD(&scb_data->sg_maps, links);4886 ahc_dmamap_unload(ahc, scb_data->sg_dmat,4887 sg_map->sg_dmamap);4888 ahc_dmamem_free(ahc, scb_data->sg_dmat,4889 sg_map->sg_vaddr,4890 sg_map->sg_dmamap);4891 kfree(sg_map);4892 }4893 ahc_dma_tag_destroy(ahc, scb_data->sg_dmat);4894 }4895 fallthrough;4896 case 6:4897 ahc_dmamap_unload(ahc, scb_data->sense_dmat,4898 scb_data->sense_dmamap);4899 fallthrough;4900 case 5:4901 ahc_dmamem_free(ahc, scb_data->sense_dmat, scb_data->sense,4902 scb_data->sense_dmamap);4903 ahc_dmamap_destroy(ahc, scb_data->sense_dmat,4904 scb_data->sense_dmamap);4905 fallthrough;4906 case 4:4907 ahc_dma_tag_destroy(ahc, scb_data->sense_dmat);4908 fallthrough;4909 case 3:4910 ahc_dmamap_unload(ahc, scb_data->hscb_dmat,4911 scb_data->hscb_dmamap);4912 fallthrough;4913 case 2:4914 ahc_dmamem_free(ahc, scb_data->hscb_dmat, scb_data->hscbs,4915 scb_data->hscb_dmamap);4916 ahc_dmamap_destroy(ahc, scb_data->hscb_dmat,4917 scb_data->hscb_dmamap);4918 fallthrough;4919 case 1:4920 ahc_dma_tag_destroy(ahc, scb_data->hscb_dmat);4921 break;4922 case 0:4923 break;4924 }4925 kfree(scb_data->scbarray);4926}4927 4928static void4929ahc_alloc_scbs(struct ahc_softc *ahc)4930{4931 struct scb_data *scb_data;4932 struct scb *next_scb;4933 struct sg_map_node *sg_map;4934 dma_addr_t physaddr;4935 struct ahc_dma_seg *segs;4936 int newcount;4937 int i;4938 4939 scb_data = ahc->scb_data;4940 if (scb_data->numscbs >= AHC_SCB_MAX_ALLOC)4941 /* Can't allocate any more */4942 return;4943 4944 next_scb = &scb_data->scbarray[scb_data->numscbs];4945 4946 sg_map = kmalloc(sizeof(*sg_map), GFP_ATOMIC);4947 4948 if (sg_map == NULL)4949 return;4950 4951 /* Allocate S/G space for the next batch of SCBS */4952 if (ahc_dmamem_alloc(ahc, scb_data->sg_dmat,4953 (void **)&sg_map->sg_vaddr,4954 BUS_DMA_NOWAIT, &sg_map->sg_dmamap) != 0) {4955 kfree(sg_map);4956 return;4957 }4958 4959 SLIST_INSERT_HEAD(&scb_data->sg_maps, sg_map, links);4960 4961 ahc_dmamap_load(ahc, scb_data->sg_dmat, sg_map->sg_dmamap,4962 sg_map->sg_vaddr, PAGE_SIZE, ahc_dmamap_cb,4963 &sg_map->sg_physaddr, /*flags*/0);4964 4965 segs = sg_map->sg_vaddr;4966 physaddr = sg_map->sg_physaddr;4967 4968 newcount = (PAGE_SIZE / (AHC_NSEG * sizeof(struct ahc_dma_seg)));4969 newcount = min(newcount, (AHC_SCB_MAX_ALLOC - scb_data->numscbs));4970 for (i = 0; i < newcount; i++) {4971 struct scb_platform_data *pdata;4972 4973 pdata = kmalloc(sizeof(*pdata), GFP_ATOMIC);4974 if (pdata == NULL)4975 break;4976 next_scb->platform_data = pdata;4977 next_scb->sg_map = sg_map;4978 next_scb->sg_list = segs;4979 /*4980 * The sequencer always starts with the second entry.4981 * The first entry is embedded in the scb.4982 */4983 next_scb->sg_list_phys = physaddr + sizeof(struct ahc_dma_seg);4984 next_scb->ahc_softc = ahc;4985 next_scb->flags = SCB_FREE;4986 next_scb->hscb = &scb_data->hscbs[scb_data->numscbs];4987 next_scb->hscb->tag = ahc->scb_data->numscbs;4988 SLIST_INSERT_HEAD(&ahc->scb_data->free_scbs,4989 next_scb, links.sle);4990 segs += AHC_NSEG;4991 physaddr += (AHC_NSEG * sizeof(struct ahc_dma_seg));4992 next_scb++;4993 ahc->scb_data->numscbs++;4994 }4995}4996 4997void4998ahc_controller_info(struct ahc_softc *ahc, char *buf)4999{5000 int len;5001 5002 len = sprintf(buf, "%s: ", ahc_chip_names[ahc->chip & AHC_CHIPID_MASK]);5003 buf += len;5004 if ((ahc->features & AHC_TWIN) != 0)5005 len = sprintf(buf, "Twin Channel, A SCSI Id=%d, "5006 "B SCSI Id=%d, primary %c, ",5007 ahc->our_id, ahc->our_id_b,5008 (ahc->flags & AHC_PRIMARY_CHANNEL) + 'A');5009 else {5010 const char *speed;5011 const char *type;5012 5013 speed = "";5014 if ((ahc->features & AHC_ULTRA) != 0) {5015 speed = "Ultra ";5016 } else if ((ahc->features & AHC_DT) != 0) {5017 speed = "Ultra160 ";5018 } else if ((ahc->features & AHC_ULTRA2) != 0) {5019 speed = "Ultra2 ";5020 }5021 if ((ahc->features & AHC_WIDE) != 0) {5022 type = "Wide";5023 } else {5024 type = "Single";5025 }5026 len = sprintf(buf, "%s%s Channel %c, SCSI Id=%d, ",5027 speed, type, ahc->channel, ahc->our_id);5028 }5029 buf += len;5030 5031 if ((ahc->flags & AHC_PAGESCBS) != 0)5032 sprintf(buf, "%d/%d SCBs",5033 ahc->scb_data->maxhscbs, AHC_MAX_QUEUE);5034 else5035 sprintf(buf, "%d SCBs", ahc->scb_data->maxhscbs);5036}5037 5038int5039ahc_chip_init(struct ahc_softc *ahc)5040{5041 int term;5042 int error;5043 u_int i;5044 u_int scsi_conf;5045 u_int scsiseq_template;5046 uint32_t physaddr;5047 5048 ahc_outb(ahc, SEQ_FLAGS, 0);5049 ahc_outb(ahc, SEQ_FLAGS2, 0);5050 5051 /* Set the SCSI Id, SXFRCTL0, SXFRCTL1, and SIMODE1, for both channels*/5052 if (ahc->features & AHC_TWIN) {5053 5054 /*5055 * Setup Channel B first.5056 */5057 ahc_outb(ahc, SBLKCTL, ahc_inb(ahc, SBLKCTL) | SELBUSB);5058 term = (ahc->flags & AHC_TERM_ENB_B) != 0 ? STPWEN : 0;5059 ahc_outb(ahc, SCSIID, ahc->our_id_b);5060 scsi_conf = ahc_inb(ahc, SCSICONF + 1);5061 ahc_outb(ahc, SXFRCTL1, (scsi_conf & (ENSPCHK|STIMESEL))5062 |term|ahc->seltime_b|ENSTIMER|ACTNEGEN);5063 if ((ahc->features & AHC_ULTRA2) != 0)5064 ahc_outb(ahc, SIMODE0, ahc_inb(ahc, SIMODE0)|ENIOERR);5065 ahc_outb(ahc, SIMODE1, ENSELTIMO|ENSCSIRST|ENSCSIPERR);5066 ahc_outb(ahc, SXFRCTL0, DFON|SPIOEN);5067 5068 /* Select Channel A */5069 ahc_outb(ahc, SBLKCTL, ahc_inb(ahc, SBLKCTL) & ~SELBUSB);5070 }5071 term = (ahc->flags & AHC_TERM_ENB_A) != 0 ? STPWEN : 0;5072 if ((ahc->features & AHC_ULTRA2) != 0)5073 ahc_outb(ahc, SCSIID_ULTRA2, ahc->our_id);5074 else5075 ahc_outb(ahc, SCSIID, ahc->our_id);5076 scsi_conf = ahc_inb(ahc, SCSICONF);5077 ahc_outb(ahc, SXFRCTL1, (scsi_conf & (ENSPCHK|STIMESEL))5078 |term|ahc->seltime5079 |ENSTIMER|ACTNEGEN);5080 if ((ahc->features & AHC_ULTRA2) != 0)5081 ahc_outb(ahc, SIMODE0, ahc_inb(ahc, SIMODE0)|ENIOERR);5082 ahc_outb(ahc, SIMODE1, ENSELTIMO|ENSCSIRST|ENSCSIPERR);5083 ahc_outb(ahc, SXFRCTL0, DFON|SPIOEN);5084 5085 /* There are no untagged SCBs active yet. */5086 for (i = 0; i < 16; i++) {5087 ahc_unbusy_tcl(ahc, BUILD_TCL(i << 4, 0));5088 if ((ahc->flags & AHC_SCB_BTT) != 0) {5089 int lun;5090 5091 /*5092 * The SCB based BTT allows an entry per5093 * target and lun pair.5094 */5095 for (lun = 1; lun < AHC_NUM_LUNS; lun++)5096 ahc_unbusy_tcl(ahc, BUILD_TCL(i << 4, lun));5097 }5098 }5099 5100 /* All of our queues are empty */5101 for (i = 0; i < 256; i++)5102 ahc->qoutfifo[i] = SCB_LIST_NULL;5103 ahc_sync_qoutfifo(ahc, BUS_DMASYNC_PREREAD);5104 5105 for (i = 0; i < 256; i++)5106 ahc->qinfifo[i] = SCB_LIST_NULL;5107 5108 if ((ahc->features & AHC_MULTI_TID) != 0) {5109 ahc_outb(ahc, TARGID, 0);5110 ahc_outb(ahc, TARGID + 1, 0);5111 }5112 5113 /*5114 * Tell the sequencer where it can find our arrays in memory.5115 */5116 physaddr = ahc->scb_data->hscb_busaddr;5117 ahc_outb(ahc, HSCB_ADDR, physaddr & 0xFF);5118 ahc_outb(ahc, HSCB_ADDR + 1, (physaddr >> 8) & 0xFF);5119 ahc_outb(ahc, HSCB_ADDR + 2, (physaddr >> 16) & 0xFF);5120 ahc_outb(ahc, HSCB_ADDR + 3, (physaddr >> 24) & 0xFF);5121 5122 physaddr = ahc->shared_data_busaddr;5123 ahc_outb(ahc, SHARED_DATA_ADDR, physaddr & 0xFF);5124 ahc_outb(ahc, SHARED_DATA_ADDR + 1, (physaddr >> 8) & 0xFF);5125 ahc_outb(ahc, SHARED_DATA_ADDR + 2, (physaddr >> 16) & 0xFF);5126 ahc_outb(ahc, SHARED_DATA_ADDR + 3, (physaddr >> 24) & 0xFF);5127 5128 /*5129 * Initialize the group code to command length table.5130 * This overrides the values in TARG_SCSIRATE, so only5131 * setup the table after we have processed that information.5132 */5133 ahc_outb(ahc, CMDSIZE_TABLE, 5);5134 ahc_outb(ahc, CMDSIZE_TABLE + 1, 9);5135 ahc_outb(ahc, CMDSIZE_TABLE + 2, 9);5136 ahc_outb(ahc, CMDSIZE_TABLE + 3, 0);5137 ahc_outb(ahc, CMDSIZE_TABLE + 4, 15);5138 ahc_outb(ahc, CMDSIZE_TABLE + 5, 11);5139 ahc_outb(ahc, CMDSIZE_TABLE + 6, 0);5140 ahc_outb(ahc, CMDSIZE_TABLE + 7, 0);5141 5142 if ((ahc->features & AHC_HS_MAILBOX) != 0)5143 ahc_outb(ahc, HS_MAILBOX, 0);5144 5145 /* Tell the sequencer of our initial queue positions */5146 if ((ahc->features & AHC_TARGETMODE) != 0) {5147 ahc->tqinfifonext = 1;5148 ahc_outb(ahc, KERNEL_TQINPOS, ahc->tqinfifonext - 1);5149 ahc_outb(ahc, TQINPOS, ahc->tqinfifonext);5150 }5151 ahc->qinfifonext = 0;5152 ahc->qoutfifonext = 0;5153 if ((ahc->features & AHC_QUEUE_REGS) != 0) {5154 ahc_outb(ahc, QOFF_CTLSTA, SCB_QSIZE_256);5155 ahc_outb(ahc, HNSCB_QOFF, ahc->qinfifonext);5156 ahc_outb(ahc, SNSCB_QOFF, ahc->qinfifonext);5157 ahc_outb(ahc, SDSCB_QOFF, 0);5158 } else {5159 ahc_outb(ahc, KERNEL_QINPOS, ahc->qinfifonext);5160 ahc_outb(ahc, QINPOS, ahc->qinfifonext);5161 ahc_outb(ahc, QOUTPOS, ahc->qoutfifonext);5162 }5163 5164 /* We don't have any waiting selections */5165 ahc_outb(ahc, WAITING_SCBH, SCB_LIST_NULL);5166 5167 /* Our disconnection list is empty too */5168 ahc_outb(ahc, DISCONNECTED_SCBH, SCB_LIST_NULL);5169 5170 /* Message out buffer starts empty */5171 ahc_outb(ahc, MSG_OUT, NOP);5172 5173 /*5174 * Setup the allowed SCSI Sequences based on operational mode.5175 * If we are a target, we'll enable select in operations once5176 * we've had a lun enabled.5177 */5178 scsiseq_template = ENSELO|ENAUTOATNO|ENAUTOATNP;5179 if ((ahc->flags & AHC_INITIATORROLE) != 0)5180 scsiseq_template |= ENRSELI;5181 ahc_outb(ahc, SCSISEQ_TEMPLATE, scsiseq_template);5182 5183 /* Initialize our list of free SCBs. */5184 ahc_build_free_scb_list(ahc);5185 5186 /*5187 * Tell the sequencer which SCB will be the next one it receives.5188 */5189 ahc_outb(ahc, NEXT_QUEUED_SCB, ahc->next_queued_scb->hscb->tag);5190 5191 /*5192 * Load the Sequencer program and Enable the adapter5193 * in "fast" mode.5194 */5195 if (bootverbose)5196 printk("%s: Downloading Sequencer Program...",5197 ahc_name(ahc));5198 5199 error = ahc_loadseq(ahc);5200 if (error != 0)5201 return (error);5202 5203 if ((ahc->features & AHC_ULTRA2) != 0) {5204 int wait;5205 5206 /*5207 * Wait for up to 500ms for our transceivers5208 * to settle. If the adapter does not have5209 * a cable attached, the transceivers may5210 * never settle, so don't complain if we5211 * fail here.5212 */5213 for (wait = 5000;5214 (ahc_inb(ahc, SBLKCTL) & (ENAB40|ENAB20)) == 0 && wait;5215 wait--)5216 ahc_delay(100);5217 }5218 ahc_restart(ahc);5219 return (0);5220}5221 5222/*5223 * Start the board, ready for normal operation5224 */5225int5226ahc_init(struct ahc_softc *ahc)5227{5228 int max_targ;5229 u_int i;5230 u_int scsi_conf;5231 u_int ultraenb;5232 u_int discenable;5233 u_int tagenable;5234 size_t driver_data_size;5235 5236#ifdef AHC_DEBUG5237 if ((ahc_debug & AHC_DEBUG_SEQUENCER) != 0)5238 ahc->flags |= AHC_SEQUENCER_DEBUG;5239#endif5240 5241#ifdef AHC_PRINT_SRAM5242 printk("Scratch Ram:");5243 for (i = 0x20; i < 0x5f; i++) {5244 if (((i % 8) == 0) && (i != 0)) {5245 printk ("\n ");5246 }5247 printk (" 0x%x", ahc_inb(ahc, i));5248 }5249 if ((ahc->features & AHC_MORE_SRAM) != 0) {5250 for (i = 0x70; i < 0x7f; i++) {5251 if (((i % 8) == 0) && (i != 0)) {5252 printk ("\n ");5253 }5254 printk (" 0x%x", ahc_inb(ahc, i));5255 }5256 }5257 printk ("\n");5258 /*5259 * Reading uninitialized scratch ram may5260 * generate parity errors.5261 */5262 ahc_outb(ahc, CLRINT, CLRPARERR);5263 ahc_outb(ahc, CLRINT, CLRBRKADRINT);5264#endif5265 max_targ = 15;5266 5267 /*5268 * Assume we have a board at this stage and it has been reset.5269 */5270 if ((ahc->flags & AHC_USEDEFAULTS) != 0)5271 ahc->our_id = ahc->our_id_b = 7;5272 5273 /*5274 * Default to allowing initiator operations.5275 */5276 ahc->flags |= AHC_INITIATORROLE;5277 5278 /*5279 * Only allow target mode features if this unit has them enabled.5280 */5281 if ((AHC_TMODE_ENABLE & (0x1 << ahc->unit)) == 0)5282 ahc->features &= ~AHC_TARGETMODE;5283 5284 ahc->init_level++;5285 5286 /*5287 * DMA tag for our command fifos and other data in system memory5288 * the card's sequencer must be able to access. For initiator5289 * roles, we need to allocate space for the qinfifo and qoutfifo.5290 * The qinfifo and qoutfifo are composed of 256 1 byte elements.5291 * When providing for the target mode role, we must additionally5292 * provide space for the incoming target command fifo and an extra5293 * byte to deal with a dma bug in some chip versions.5294 */5295 driver_data_size = 2 * 256 * sizeof(uint8_t);5296 if ((ahc->features & AHC_TARGETMODE) != 0)5297 driver_data_size += AHC_TMODE_CMDS * sizeof(struct target_cmd)5298 + /*DMA WideOdd Bug Buffer*/1;5299 if (ahc_dma_tag_create(ahc, ahc->parent_dmat, /*alignment*/1,5300 /*boundary*/BUS_SPACE_MAXADDR_32BIT + 1,5301 /*lowaddr*/BUS_SPACE_MAXADDR_32BIT,5302 /*highaddr*/BUS_SPACE_MAXADDR,5303 /*filter*/NULL, /*filterarg*/NULL,5304 driver_data_size,5305 /*nsegments*/1,5306 /*maxsegsz*/BUS_SPACE_MAXSIZE_32BIT,5307 /*flags*/0, &ahc->shared_data_dmat) != 0) {5308 return (ENOMEM);5309 }5310 5311 ahc->init_level++;5312 5313 /* Allocation of driver data */5314 if (ahc_dmamem_alloc(ahc, ahc->shared_data_dmat,5315 (void **)&ahc->qoutfifo,5316 BUS_DMA_NOWAIT, &ahc->shared_data_dmamap) != 0) {5317 return (ENOMEM);5318 }5319 5320 ahc->init_level++;5321 5322 /* And permanently map it in */5323 ahc_dmamap_load(ahc, ahc->shared_data_dmat, ahc->shared_data_dmamap,5324 ahc->qoutfifo, driver_data_size, ahc_dmamap_cb,5325 &ahc->shared_data_busaddr, /*flags*/0);5326 5327 if ((ahc->features & AHC_TARGETMODE) != 0) {5328 ahc->targetcmds = (struct target_cmd *)ahc->qoutfifo;5329 ahc->qoutfifo = (uint8_t *)&ahc->targetcmds[AHC_TMODE_CMDS];5330 ahc->dma_bug_buf = ahc->shared_data_busaddr5331 + driver_data_size - 1;5332 /* All target command blocks start out invalid. */5333 for (i = 0; i < AHC_TMODE_CMDS; i++)5334 ahc->targetcmds[i].cmd_valid = 0;5335 ahc_sync_tqinfifo(ahc, BUS_DMASYNC_PREREAD);5336 ahc->qoutfifo = (uint8_t *)&ahc->targetcmds[256];5337 }5338 ahc->qinfifo = &ahc->qoutfifo[256];5339 5340 ahc->init_level++;5341 5342 /* Allocate SCB data now that buffer_dmat is initialized */5343 if (ahc->scb_data->maxhscbs == 0)5344 if (ahc_init_scbdata(ahc) != 0)5345 return (ENOMEM);5346 5347 /*5348 * Allocate a tstate to house information for our5349 * initiator presence on the bus as well as the user5350 * data for any target mode initiator.5351 */5352 if (ahc_alloc_tstate(ahc, ahc->our_id, 'A') == NULL) {5353 printk("%s: unable to allocate ahc_tmode_tstate. "5354 "Failing attach\n", ahc_name(ahc));5355 return (ENOMEM);5356 }5357 5358 if ((ahc->features & AHC_TWIN) != 0) {5359 if (ahc_alloc_tstate(ahc, ahc->our_id_b, 'B') == NULL) {5360 printk("%s: unable to allocate ahc_tmode_tstate. "5361 "Failing attach\n", ahc_name(ahc));5362 return (ENOMEM);5363 }5364 }5365 5366 if (ahc->scb_data->maxhscbs < AHC_SCB_MAX_ALLOC) {5367 ahc->flags |= AHC_PAGESCBS;5368 } else {5369 ahc->flags &= ~AHC_PAGESCBS;5370 }5371 5372#ifdef AHC_DEBUG5373 if (ahc_debug & AHC_SHOW_MISC) {5374 printk("%s: hardware scb %u bytes; kernel scb %u bytes; "5375 "ahc_dma %u bytes\n",5376 ahc_name(ahc),5377 (u_int)sizeof(struct hardware_scb),5378 (u_int)sizeof(struct scb),5379 (u_int)sizeof(struct ahc_dma_seg));5380 }5381#endif /* AHC_DEBUG */5382 5383 /*5384 * Look at the information that board initialization or5385 * the board bios has left us.5386 */5387 if (ahc->features & AHC_TWIN) {5388 scsi_conf = ahc_inb(ahc, SCSICONF + 1);5389 if ((scsi_conf & RESET_SCSI) != 05390 && (ahc->flags & AHC_INITIATORROLE) != 0)5391 ahc->flags |= AHC_RESET_BUS_B;5392 }5393 5394 scsi_conf = ahc_inb(ahc, SCSICONF);5395 if ((scsi_conf & RESET_SCSI) != 05396 && (ahc->flags & AHC_INITIATORROLE) != 0)5397 ahc->flags |= AHC_RESET_BUS_A;5398 5399 ultraenb = 0;5400 tagenable = ALL_TARGETS_MASK;5401 5402 /* Grab the disconnection disable table and invert it for our needs */5403 if ((ahc->flags & AHC_USEDEFAULTS) != 0) {5404 printk("%s: Host Adapter Bios disabled. Using default SCSI "5405 "device parameters\n", ahc_name(ahc));5406 ahc->flags |= AHC_EXTENDED_TRANS_A|AHC_EXTENDED_TRANS_B|5407 AHC_TERM_ENB_A|AHC_TERM_ENB_B;5408 discenable = ALL_TARGETS_MASK;5409 if ((ahc->features & AHC_ULTRA) != 0)5410 ultraenb = ALL_TARGETS_MASK;5411 } else {5412 discenable = ~((ahc_inb(ahc, DISC_DSB + 1) << 8)5413 | ahc_inb(ahc, DISC_DSB));5414 if ((ahc->features & (AHC_ULTRA|AHC_ULTRA2)) != 0)5415 ultraenb = (ahc_inb(ahc, ULTRA_ENB + 1) << 8)5416 | ahc_inb(ahc, ULTRA_ENB);5417 }5418 5419 if ((ahc->features & (AHC_WIDE|AHC_TWIN)) == 0)5420 max_targ = 7;5421 5422 for (i = 0; i <= max_targ; i++) {5423 struct ahc_initiator_tinfo *tinfo;5424 struct ahc_tmode_tstate *tstate;5425 u_int our_id;5426 u_int target_id;5427 char channel;5428 5429 channel = 'A';5430 our_id = ahc->our_id;5431 target_id = i;5432 if (i > 7 && (ahc->features & AHC_TWIN) != 0) {5433 channel = 'B';5434 our_id = ahc->our_id_b;5435 target_id = i % 8;5436 }5437 tinfo = ahc_fetch_transinfo(ahc, channel, our_id,5438 target_id, &tstate);5439 /* Default to async narrow across the board */5440 memset(tinfo, 0, sizeof(*tinfo));5441 if (ahc->flags & AHC_USEDEFAULTS) {5442 if ((ahc->features & AHC_WIDE) != 0)5443 tinfo->user.width = MSG_EXT_WDTR_BUS_16_BIT;5444 5445 /*5446 * These will be truncated when we determine the5447 * connection type we have with the target.5448 */5449 tinfo->user.period = ahc_syncrates->period;5450 tinfo->user.offset = MAX_OFFSET;5451 } else {5452 u_int scsirate;5453 uint16_t mask;5454 5455 /* Take the settings leftover in scratch RAM. */5456 scsirate = ahc_inb(ahc, TARG_SCSIRATE + i);5457 mask = (0x01 << i);5458 if ((ahc->features & AHC_ULTRA2) != 0) {5459 u_int offset;5460 u_int maxsync;5461 5462 if ((scsirate & SOFS) == 0x0F) {5463 /*5464 * Haven't negotiated yet,5465 * so the format is different.5466 */5467 scsirate = (scsirate & SXFR) >> 45468 | (ultraenb & mask)5469 ? 0x08 : 0x05470 | (scsirate & WIDEXFER);5471 offset = MAX_OFFSET_ULTRA2;5472 } else5473 offset = ahc_inb(ahc, TARG_OFFSET + i);5474 if ((scsirate & ~WIDEXFER) == 0 && offset != 0)5475 /* Set to the lowest sync rate, 5MHz */5476 scsirate |= 0x1c;5477 maxsync = AHC_SYNCRATE_ULTRA2;5478 if ((ahc->features & AHC_DT) != 0)5479 maxsync = AHC_SYNCRATE_DT;5480 tinfo->user.period =5481 ahc_find_period(ahc, scsirate, maxsync);5482 if (offset == 0)5483 tinfo->user.period = 0;5484 else5485 tinfo->user.offset = MAX_OFFSET;5486 if ((scsirate & SXFR_ULTRA2) <= 8/*10MHz*/5487 && (ahc->features & AHC_DT) != 0)5488 tinfo->user.ppr_options =5489 MSG_EXT_PPR_DT_REQ;5490 } else if ((scsirate & SOFS) != 0) {5491 if ((scsirate & SXFR) == 0x405492 && (ultraenb & mask) != 0) {5493 /* Treat 10MHz as a non-ultra speed */5494 scsirate &= ~SXFR;5495 ultraenb &= ~mask;5496 }5497 tinfo->user.period =5498 ahc_find_period(ahc, scsirate,5499 (ultraenb & mask)5500 ? AHC_SYNCRATE_ULTRA5501 : AHC_SYNCRATE_FAST);5502 if (tinfo->user.period != 0)5503 tinfo->user.offset = MAX_OFFSET;5504 }5505 if (tinfo->user.period == 0)5506 tinfo->user.offset = 0;5507 if ((scsirate & WIDEXFER) != 05508 && (ahc->features & AHC_WIDE) != 0)5509 tinfo->user.width = MSG_EXT_WDTR_BUS_16_BIT;5510 tinfo->user.protocol_version = 4;5511 if ((ahc->features & AHC_DT) != 0)5512 tinfo->user.transport_version = 3;5513 else5514 tinfo->user.transport_version = 2;5515 tinfo->goal.protocol_version = 2;5516 tinfo->goal.transport_version = 2;5517 tinfo->curr.protocol_version = 2;5518 tinfo->curr.transport_version = 2;5519 }5520 tstate->ultraenb = 0;5521 }5522 ahc->user_discenable = discenable;5523 ahc->user_tagenable = tagenable;5524 5525 return (ahc->bus_chip_init(ahc));5526}5527 5528void5529ahc_intr_enable(struct ahc_softc *ahc, int enable)5530{5531 u_int hcntrl;5532 5533 hcntrl = ahc_inb(ahc, HCNTRL);5534 hcntrl &= ~INTEN;5535 ahc->pause &= ~INTEN;5536 ahc->unpause &= ~INTEN;5537 if (enable) {5538 hcntrl |= INTEN;5539 ahc->pause |= INTEN;5540 ahc->unpause |= INTEN;5541 }5542 ahc_outb(ahc, HCNTRL, hcntrl);5543}5544 5545/*5546 * Ensure that the card is paused in a location5547 * outside of all critical sections and that all5548 * pending work is completed prior to returning.5549 * This routine should only be called from outside5550 * an interrupt context.5551 */5552void5553ahc_pause_and_flushwork(struct ahc_softc *ahc)5554{5555 int intstat;5556 int maxloops;5557 int paused;5558 5559 maxloops = 1000;5560 ahc->flags |= AHC_ALL_INTERRUPTS;5561 paused = FALSE;5562 do {5563 if (paused) {5564 ahc_unpause(ahc);5565 /*5566 * Give the sequencer some time to service5567 * any active selections.5568 */5569 ahc_delay(500);5570 }5571 ahc_intr(ahc);5572 ahc_pause(ahc);5573 paused = TRUE;5574 ahc_outb(ahc, SCSISEQ, ahc_inb(ahc, SCSISEQ) & ~ENSELO);5575 intstat = ahc_inb(ahc, INTSTAT);5576 if ((intstat & INT_PEND) == 0) {5577 ahc_clear_critical_section(ahc);5578 intstat = ahc_inb(ahc, INTSTAT);5579 }5580 } while (--maxloops5581 && (intstat != 0xFF || (ahc->features & AHC_REMOVABLE) == 0)5582 && ((intstat & INT_PEND) != 05583 || (ahc_inb(ahc, SSTAT0) & (SELDO|SELINGO)) != 0));5584 if (maxloops == 0) {5585 printk("Infinite interrupt loop, INTSTAT = %x",5586 ahc_inb(ahc, INTSTAT));5587 }5588 ahc_platform_flushwork(ahc);5589 ahc->flags &= ~AHC_ALL_INTERRUPTS;5590}5591 5592int __maybe_unused5593ahc_suspend(struct ahc_softc *ahc)5594{5595 5596 ahc_pause_and_flushwork(ahc);5597 5598 if (LIST_FIRST(&ahc->pending_scbs) != NULL) {5599 ahc_unpause(ahc);5600 return (EBUSY);5601 }5602 5603#ifdef AHC_TARGET_MODE5604 /*5605 * XXX What about ATIOs that have not yet been serviced?5606 * Perhaps we should just refuse to be suspended if we5607 * are acting in a target role.5608 */5609 if (ahc->pending_device != NULL) {5610 ahc_unpause(ahc);5611 return (EBUSY);5612 }5613#endif5614 ahc_shutdown(ahc);5615 return (0);5616}5617 5618int __maybe_unused5619ahc_resume(struct ahc_softc *ahc)5620{5621 5622 ahc_reset(ahc, /*reinit*/TRUE);5623 ahc_intr_enable(ahc, TRUE);5624 ahc_restart(ahc);5625 return (0);5626}5627/************************** Busy Target Table *********************************/5628/*5629 * Return the untagged transaction id for a given target/channel lun.5630 * Optionally, clear the entry.5631 */5632static u_int5633ahc_index_busy_tcl(struct ahc_softc *ahc, u_int tcl)5634{5635 u_int scbid;5636 u_int target_offset;5637 5638 if ((ahc->flags & AHC_SCB_BTT) != 0) {5639 u_int saved_scbptr;5640 5641 saved_scbptr = ahc_inb(ahc, SCBPTR);5642 ahc_outb(ahc, SCBPTR, TCL_LUN(tcl));5643 scbid = ahc_inb(ahc, SCB_64_BTT + TCL_TARGET_OFFSET(tcl));5644 ahc_outb(ahc, SCBPTR, saved_scbptr);5645 } else {5646 target_offset = TCL_TARGET_OFFSET(tcl);5647 scbid = ahc_inb(ahc, BUSY_TARGETS + target_offset);5648 }5649 5650 return (scbid);5651}5652 5653static void5654ahc_unbusy_tcl(struct ahc_softc *ahc, u_int tcl)5655{5656 u_int target_offset;5657 5658 if ((ahc->flags & AHC_SCB_BTT) != 0) {5659 u_int saved_scbptr;5660 5661 saved_scbptr = ahc_inb(ahc, SCBPTR);5662 ahc_outb(ahc, SCBPTR, TCL_LUN(tcl));5663 ahc_outb(ahc, SCB_64_BTT+TCL_TARGET_OFFSET(tcl), SCB_LIST_NULL);5664 ahc_outb(ahc, SCBPTR, saved_scbptr);5665 } else {5666 target_offset = TCL_TARGET_OFFSET(tcl);5667 ahc_outb(ahc, BUSY_TARGETS + target_offset, SCB_LIST_NULL);5668 }5669}5670 5671static void5672ahc_busy_tcl(struct ahc_softc *ahc, u_int tcl, u_int scbid)5673{5674 u_int target_offset;5675 5676 if ((ahc->flags & AHC_SCB_BTT) != 0) {5677 u_int saved_scbptr;5678 5679 saved_scbptr = ahc_inb(ahc, SCBPTR);5680 ahc_outb(ahc, SCBPTR, TCL_LUN(tcl));5681 ahc_outb(ahc, SCB_64_BTT + TCL_TARGET_OFFSET(tcl), scbid);5682 ahc_outb(ahc, SCBPTR, saved_scbptr);5683 } else {5684 target_offset = TCL_TARGET_OFFSET(tcl);5685 ahc_outb(ahc, BUSY_TARGETS + target_offset, scbid);5686 }5687}5688 5689/************************** SCB and SCB queue management **********************/5690int5691ahc_match_scb(struct ahc_softc *ahc, struct scb *scb, int target,5692 char channel, int lun, u_int tag, role_t role)5693{5694 int targ = SCB_GET_TARGET(ahc, scb);5695 char chan = SCB_GET_CHANNEL(ahc, scb);5696 int slun = SCB_GET_LUN(scb);5697 int match;5698 5699 match = ((chan == channel) || (channel == ALL_CHANNELS));5700 if (match != 0)5701 match = ((targ == target) || (target == CAM_TARGET_WILDCARD));5702 if (match != 0)5703 match = ((lun == slun) || (lun == CAM_LUN_WILDCARD));5704 if (match != 0) {5705#ifdef AHC_TARGET_MODE5706 int group;5707 5708 group = XPT_FC_GROUP(scb->io_ctx->ccb_h.func_code);5709 if (role == ROLE_INITIATOR) {5710 match = (group != XPT_FC_GROUP_TMODE)5711 && ((tag == scb->hscb->tag)5712 || (tag == SCB_LIST_NULL));5713 } else if (role == ROLE_TARGET) {5714 match = (group == XPT_FC_GROUP_TMODE)5715 && ((tag == scb->io_ctx->csio.tag_id)5716 || (tag == SCB_LIST_NULL));5717 }5718#else /* !AHC_TARGET_MODE */5719 match = ((tag == scb->hscb->tag) || (tag == SCB_LIST_NULL));5720#endif /* AHC_TARGET_MODE */5721 }5722 5723 return match;5724}5725 5726static void5727ahc_freeze_devq(struct ahc_softc *ahc, struct scb *scb)5728{5729 int target;5730 char channel;5731 int lun;5732 5733 target = SCB_GET_TARGET(ahc, scb);5734 lun = SCB_GET_LUN(scb);5735 channel = SCB_GET_CHANNEL(ahc, scb);5736 5737 ahc_search_qinfifo(ahc, target, channel, lun,5738 /*tag*/SCB_LIST_NULL, ROLE_UNKNOWN,5739 CAM_REQUEUE_REQ, SEARCH_COMPLETE);5740 5741 ahc_platform_freeze_devq(ahc, scb);5742}5743 5744void5745ahc_qinfifo_requeue_tail(struct ahc_softc *ahc, struct scb *scb)5746{5747 struct scb *prev_scb;5748 5749 prev_scb = NULL;5750 if (ahc_qinfifo_count(ahc) != 0) {5751 u_int prev_tag;5752 uint8_t prev_pos;5753 5754 prev_pos = ahc->qinfifonext - 1;5755 prev_tag = ahc->qinfifo[prev_pos];5756 prev_scb = ahc_lookup_scb(ahc, prev_tag);5757 }5758 ahc_qinfifo_requeue(ahc, prev_scb, scb);5759 if ((ahc->features & AHC_QUEUE_REGS) != 0) {5760 ahc_outb(ahc, HNSCB_QOFF, ahc->qinfifonext);5761 } else {5762 ahc_outb(ahc, KERNEL_QINPOS, ahc->qinfifonext);5763 }5764}5765 5766static void5767ahc_qinfifo_requeue(struct ahc_softc *ahc, struct scb *prev_scb,5768 struct scb *scb)5769{5770 if (prev_scb == NULL) {5771 ahc_outb(ahc, NEXT_QUEUED_SCB, scb->hscb->tag);5772 } else {5773 prev_scb->hscb->next = scb->hscb->tag;5774 ahc_sync_scb(ahc, prev_scb,5775 BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);5776 }5777 ahc->qinfifo[ahc->qinfifonext++] = scb->hscb->tag;5778 scb->hscb->next = ahc->next_queued_scb->hscb->tag;5779 ahc_sync_scb(ahc, scb, BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);5780}5781 5782static int5783ahc_qinfifo_count(struct ahc_softc *ahc)5784{5785 uint8_t qinpos;5786 uint8_t diff;5787 5788 if ((ahc->features & AHC_QUEUE_REGS) != 0) {5789 qinpos = ahc_inb(ahc, SNSCB_QOFF);5790 ahc_outb(ahc, SNSCB_QOFF, qinpos);5791 } else5792 qinpos = ahc_inb(ahc, QINPOS);5793 diff = ahc->qinfifonext - qinpos;5794 return (diff);5795}5796 5797int5798ahc_search_qinfifo(struct ahc_softc *ahc, int target, char channel,5799 int lun, u_int tag, role_t role, uint32_t status,5800 ahc_search_action action)5801{5802 struct scb *scb;5803 struct scb *prev_scb;5804 uint8_t qinstart;5805 uint8_t qinpos;5806 uint8_t qintail;5807 uint8_t next;5808 uint8_t prev;5809 uint8_t curscbptr;5810 int found;5811 int have_qregs;5812 5813 qintail = ahc->qinfifonext;5814 have_qregs = (ahc->features & AHC_QUEUE_REGS) != 0;5815 if (have_qregs) {5816 qinstart = ahc_inb(ahc, SNSCB_QOFF);5817 ahc_outb(ahc, SNSCB_QOFF, qinstart);5818 } else5819 qinstart = ahc_inb(ahc, QINPOS);5820 qinpos = qinstart;5821 found = 0;5822 prev_scb = NULL;5823 5824 if (action == SEARCH_COMPLETE) {5825 /*5826 * Don't attempt to run any queued untagged transactions5827 * until we are done with the abort process.5828 */5829 ahc_freeze_untagged_queues(ahc);5830 }5831 5832 /*5833 * Start with an empty queue. Entries that are not chosen5834 * for removal will be re-added to the queue as we go.5835 */5836 ahc->qinfifonext = qinpos;5837 ahc_outb(ahc, NEXT_QUEUED_SCB, ahc->next_queued_scb->hscb->tag);5838 5839 while (qinpos != qintail) {5840 scb = ahc_lookup_scb(ahc, ahc->qinfifo[qinpos]);5841 if (scb == NULL) {5842 printk("qinpos = %d, SCB index = %d\n",5843 qinpos, ahc->qinfifo[qinpos]);5844 panic("Loop 1\n");5845 }5846 5847 if (ahc_match_scb(ahc, scb, target, channel, lun, tag, role)) {5848 /*5849 * We found an scb that needs to be acted on.5850 */5851 found++;5852 switch (action) {5853 case SEARCH_COMPLETE:5854 {5855 cam_status ostat;5856 cam_status cstat;5857 5858 ostat = ahc_get_transaction_status(scb);5859 if (ostat == CAM_REQ_INPROG)5860 ahc_set_transaction_status(scb, status);5861 cstat = ahc_get_transaction_status(scb);5862 if (cstat != CAM_REQ_CMP)5863 ahc_freeze_scb(scb);5864 if ((scb->flags & SCB_ACTIVE) == 0)5865 printk("Inactive SCB in qinfifo\n");5866 ahc_done(ahc, scb);5867 }5868 fallthrough;5869 case SEARCH_REMOVE:5870 break;5871 case SEARCH_COUNT:5872 ahc_qinfifo_requeue(ahc, prev_scb, scb);5873 prev_scb = scb;5874 break;5875 }5876 } else {5877 ahc_qinfifo_requeue(ahc, prev_scb, scb);5878 prev_scb = scb;5879 }5880 qinpos++;5881 }5882 5883 if ((ahc->features & AHC_QUEUE_REGS) != 0) {5884 ahc_outb(ahc, HNSCB_QOFF, ahc->qinfifonext);5885 } else {5886 ahc_outb(ahc, KERNEL_QINPOS, ahc->qinfifonext);5887 }5888 5889 if (action != SEARCH_COUNT5890 && (found != 0)5891 && (qinstart != ahc->qinfifonext)) {5892 /*5893 * The sequencer may be in the process of dmaing5894 * down the SCB at the beginning of the queue.5895 * This could be problematic if either the first,5896 * or the second SCB is removed from the queue5897 * (the first SCB includes a pointer to the "next"5898 * SCB to dma). If we have removed any entries, swap5899 * the first element in the queue with the next HSCB5900 * so the sequencer will notice that NEXT_QUEUED_SCB5901 * has changed during its dma attempt and will retry5902 * the DMA.5903 */5904 scb = ahc_lookup_scb(ahc, ahc->qinfifo[qinstart]);5905 5906 if (scb == NULL) {5907 printk("found = %d, qinstart = %d, qinfifionext = %d\n",5908 found, qinstart, ahc->qinfifonext);5909 panic("First/Second Qinfifo fixup\n");5910 }5911 /*5912 * ahc_swap_with_next_hscb forces our next pointer to5913 * point to the reserved SCB for future commands. Save5914 * and restore our original next pointer to maintain5915 * queue integrity.5916 */5917 next = scb->hscb->next;5918 ahc->scb_data->scbindex[scb->hscb->tag] = NULL;5919 ahc_swap_with_next_hscb(ahc, scb);5920 scb->hscb->next = next;5921 ahc->qinfifo[qinstart] = scb->hscb->tag;5922 5923 /* Tell the card about the new head of the qinfifo. */5924 ahc_outb(ahc, NEXT_QUEUED_SCB, scb->hscb->tag);5925 5926 /* Fixup the tail "next" pointer. */5927 qintail = ahc->qinfifonext - 1;5928 scb = ahc_lookup_scb(ahc, ahc->qinfifo[qintail]);5929 scb->hscb->next = ahc->next_queued_scb->hscb->tag;5930 }5931 5932 /*5933 * Search waiting for selection list.5934 */5935 curscbptr = ahc_inb(ahc, SCBPTR);5936 next = ahc_inb(ahc, WAITING_SCBH); /* Start at head of list. */5937 prev = SCB_LIST_NULL;5938 5939 while (next != SCB_LIST_NULL) {5940 uint8_t scb_index;5941 5942 ahc_outb(ahc, SCBPTR, next);5943 scb_index = ahc_inb(ahc, SCB_TAG);5944 if (scb_index >= ahc->scb_data->numscbs) {5945 printk("Waiting List inconsistency. "5946 "SCB index == %d, yet numscbs == %d.",5947 scb_index, ahc->scb_data->numscbs);5948 ahc_dump_card_state(ahc);5949 panic("for safety");5950 }5951 scb = ahc_lookup_scb(ahc, scb_index);5952 if (scb == NULL) {5953 printk("scb_index = %d, next = %d\n",5954 scb_index, next);5955 panic("Waiting List traversal\n");5956 }5957 if (ahc_match_scb(ahc, scb, target, channel,5958 lun, SCB_LIST_NULL, role)) {5959 /*5960 * We found an scb that needs to be acted on.5961 */5962 found++;5963 switch (action) {5964 case SEARCH_COMPLETE:5965 {5966 cam_status ostat;5967 cam_status cstat;5968 5969 ostat = ahc_get_transaction_status(scb);5970 if (ostat == CAM_REQ_INPROG)5971 ahc_set_transaction_status(scb,5972 status);5973 cstat = ahc_get_transaction_status(scb);5974 if (cstat != CAM_REQ_CMP)5975 ahc_freeze_scb(scb);5976 if ((scb->flags & SCB_ACTIVE) == 0)5977 printk("Inactive SCB in Waiting List\n");5978 ahc_done(ahc, scb);5979 }5980 fallthrough;5981 case SEARCH_REMOVE:5982 next = ahc_rem_wscb(ahc, next, prev);5983 break;5984 case SEARCH_COUNT:5985 prev = next;5986 next = ahc_inb(ahc, SCB_NEXT);5987 break;5988 }5989 } else {5990 prev = next;5991 next = ahc_inb(ahc, SCB_NEXT);5992 }5993 }5994 ahc_outb(ahc, SCBPTR, curscbptr);5995 5996 found += ahc_search_untagged_queues(ahc, /*ahc_io_ctx_t*/NULL, target,5997 channel, lun, status, action);5998 5999 if (action == SEARCH_COMPLETE)6000 ahc_release_untagged_queues(ahc);6001 return (found);6002}6003 6004int6005ahc_search_untagged_queues(struct ahc_softc *ahc, ahc_io_ctx_t ctx,6006 int target, char channel, int lun, uint32_t status,6007 ahc_search_action action)6008{6009 struct scb *scb;6010 int maxtarget;6011 int found;6012 int i;6013 6014 if (action == SEARCH_COMPLETE) {6015 /*6016 * Don't attempt to run any queued untagged transactions6017 * until we are done with the abort process.6018 */6019 ahc_freeze_untagged_queues(ahc);6020 }6021 6022 found = 0;6023 i = 0;6024 if ((ahc->flags & AHC_SCB_BTT) == 0) {6025 6026 maxtarget = 16;6027 if (target != CAM_TARGET_WILDCARD) {6028 6029 i = target;6030 if (channel == 'B')6031 i += 8;6032 maxtarget = i + 1;6033 }6034 } else {6035 maxtarget = 0;6036 }6037 6038 for (; i < maxtarget; i++) {6039 struct scb_tailq *untagged_q;6040 struct scb *next_scb;6041 6042 untagged_q = &(ahc->untagged_queues[i]);6043 next_scb = TAILQ_FIRST(untagged_q);6044 while (next_scb != NULL) {6045 6046 scb = next_scb;6047 next_scb = TAILQ_NEXT(scb, links.tqe);6048 6049 /*6050 * The head of the list may be the currently6051 * active untagged command for a device.6052 * We're only searching for commands that6053 * have not been started. A transaction6054 * marked active but still in the qinfifo6055 * is removed by the qinfifo scanning code6056 * above.6057 */6058 if ((scb->flags & SCB_ACTIVE) != 0)6059 continue;6060 6061 if (ahc_match_scb(ahc, scb, target, channel, lun,6062 SCB_LIST_NULL, ROLE_INITIATOR) == 06063 || (ctx != NULL && ctx != scb->io_ctx))6064 continue;6065 6066 /*6067 * We found an scb that needs to be acted on.6068 */6069 found++;6070 switch (action) {6071 case SEARCH_COMPLETE:6072 {6073 cam_status ostat;6074 cam_status cstat;6075 6076 ostat = ahc_get_transaction_status(scb);6077 if (ostat == CAM_REQ_INPROG)6078 ahc_set_transaction_status(scb, status);6079 cstat = ahc_get_transaction_status(scb);6080 if (cstat != CAM_REQ_CMP)6081 ahc_freeze_scb(scb);6082 if ((scb->flags & SCB_ACTIVE) == 0)6083 printk("Inactive SCB in untaggedQ\n");6084 ahc_done(ahc, scb);6085 break;6086 }6087 case SEARCH_REMOVE:6088 scb->flags &= ~SCB_UNTAGGEDQ;6089 TAILQ_REMOVE(untagged_q, scb, links.tqe);6090 break;6091 case SEARCH_COUNT:6092 break;6093 }6094 }6095 }6096 6097 if (action == SEARCH_COMPLETE)6098 ahc_release_untagged_queues(ahc);6099 return (found);6100}6101 6102int6103ahc_search_disc_list(struct ahc_softc *ahc, int target, char channel,6104 int lun, u_int tag, int stop_on_first, int remove,6105 int save_state)6106{6107 struct scb *scbp;6108 u_int next;6109 u_int prev;6110 u_int count;6111 u_int active_scb;6112 6113 count = 0;6114 next = ahc_inb(ahc, DISCONNECTED_SCBH);6115 prev = SCB_LIST_NULL;6116 6117 if (save_state) {6118 /* restore this when we're done */6119 active_scb = ahc_inb(ahc, SCBPTR);6120 } else6121 /* Silence compiler */6122 active_scb = SCB_LIST_NULL;6123 6124 while (next != SCB_LIST_NULL) {6125 u_int scb_index;6126 6127 ahc_outb(ahc, SCBPTR, next);6128 scb_index = ahc_inb(ahc, SCB_TAG);6129 if (scb_index >= ahc->scb_data->numscbs) {6130 printk("Disconnected List inconsistency. "6131 "SCB index == %d, yet numscbs == %d.",6132 scb_index, ahc->scb_data->numscbs);6133 ahc_dump_card_state(ahc);6134 panic("for safety");6135 }6136 6137 if (next == prev) {6138 panic("Disconnected List Loop. "6139 "cur SCBPTR == %x, prev SCBPTR == %x.",6140 next, prev);6141 }6142 scbp = ahc_lookup_scb(ahc, scb_index);6143 if (ahc_match_scb(ahc, scbp, target, channel, lun,6144 tag, ROLE_INITIATOR)) {6145 count++;6146 if (remove) {6147 next =6148 ahc_rem_scb_from_disc_list(ahc, prev, next);6149 } else {6150 prev = next;6151 next = ahc_inb(ahc, SCB_NEXT);6152 }6153 if (stop_on_first)6154 break;6155 } else {6156 prev = next;6157 next = ahc_inb(ahc, SCB_NEXT);6158 }6159 }6160 if (save_state)6161 ahc_outb(ahc, SCBPTR, active_scb);6162 return (count);6163}6164 6165/*6166 * Remove an SCB from the on chip list of disconnected transactions.6167 * This is empty/unused if we are not performing SCB paging.6168 */6169static u_int6170ahc_rem_scb_from_disc_list(struct ahc_softc *ahc, u_int prev, u_int scbptr)6171{6172 u_int next;6173 6174 ahc_outb(ahc, SCBPTR, scbptr);6175 next = ahc_inb(ahc, SCB_NEXT);6176 6177 ahc_outb(ahc, SCB_CONTROL, 0);6178 6179 ahc_add_curscb_to_free_list(ahc);6180 6181 if (prev != SCB_LIST_NULL) {6182 ahc_outb(ahc, SCBPTR, prev);6183 ahc_outb(ahc, SCB_NEXT, next);6184 } else6185 ahc_outb(ahc, DISCONNECTED_SCBH, next);6186 6187 return (next);6188}6189 6190/*6191 * Add the SCB as selected by SCBPTR onto the on chip list of6192 * free hardware SCBs. This list is empty/unused if we are not6193 * performing SCB paging.6194 */6195static void6196ahc_add_curscb_to_free_list(struct ahc_softc *ahc)6197{6198 /*6199 * Invalidate the tag so that our abort6200 * routines don't think it's active.6201 */6202 ahc_outb(ahc, SCB_TAG, SCB_LIST_NULL);6203 6204 if ((ahc->flags & AHC_PAGESCBS) != 0) {6205 ahc_outb(ahc, SCB_NEXT, ahc_inb(ahc, FREE_SCBH));6206 ahc_outb(ahc, FREE_SCBH, ahc_inb(ahc, SCBPTR));6207 }6208}6209 6210/*6211 * Manipulate the waiting for selection list and return the6212 * scb that follows the one that we remove.6213 */6214static u_int6215ahc_rem_wscb(struct ahc_softc *ahc, u_int scbpos, u_int prev)6216{6217 u_int curscb, next;6218 6219 /*6220 * Select the SCB we want to abort and6221 * pull the next pointer out of it.6222 */6223 curscb = ahc_inb(ahc, SCBPTR);6224 ahc_outb(ahc, SCBPTR, scbpos);6225 next = ahc_inb(ahc, SCB_NEXT);6226 6227 /* Clear the necessary fields */6228 ahc_outb(ahc, SCB_CONTROL, 0);6229 6230 ahc_add_curscb_to_free_list(ahc);6231 6232 /* update the waiting list */6233 if (prev == SCB_LIST_NULL) {6234 /* First in the list */6235 ahc_outb(ahc, WAITING_SCBH, next);6236 6237 /*6238 * Ensure we aren't attempting to perform6239 * selection for this entry.6240 */6241 ahc_outb(ahc, SCSISEQ, (ahc_inb(ahc, SCSISEQ) & ~ENSELO));6242 } else {6243 /*6244 * Select the scb that pointed to us6245 * and update its next pointer.6246 */6247 ahc_outb(ahc, SCBPTR, prev);6248 ahc_outb(ahc, SCB_NEXT, next);6249 }6250 6251 /*6252 * Point us back at the original scb position.6253 */6254 ahc_outb(ahc, SCBPTR, curscb);6255 return next;6256}6257 6258/******************************** Error Handling ******************************/6259/*6260 * Abort all SCBs that match the given description (target/channel/lun/tag),6261 * setting their status to the passed in status if the status has not already6262 * been modified from CAM_REQ_INPROG. This routine assumes that the sequencer6263 * is paused before it is called.6264 */6265static int6266ahc_abort_scbs(struct ahc_softc *ahc, int target, char channel,6267 int lun, u_int tag, role_t role, uint32_t status)6268{6269 struct scb *scbp;6270 struct scb *scbp_next;6271 u_int active_scb;6272 int i, j;6273 int maxtarget;6274 int minlun;6275 int maxlun;6276 6277 int found;6278 6279 /*6280 * Don't attempt to run any queued untagged transactions6281 * until we are done with the abort process.6282 */6283 ahc_freeze_untagged_queues(ahc);6284 6285 /* restore this when we're done */6286 active_scb = ahc_inb(ahc, SCBPTR);6287 6288 found = ahc_search_qinfifo(ahc, target, channel, lun, SCB_LIST_NULL,6289 role, CAM_REQUEUE_REQ, SEARCH_COMPLETE);6290 6291 /*6292 * Clean out the busy target table for any untagged commands.6293 */6294 i = 0;6295 maxtarget = 16;6296 if (target != CAM_TARGET_WILDCARD) {6297 i = target;6298 if (channel == 'B')6299 i += 8;6300 maxtarget = i + 1;6301 }6302 6303 if (lun == CAM_LUN_WILDCARD) {6304 6305 /*6306 * Unless we are using an SCB based6307 * busy targets table, there is only6308 * one table entry for all luns of6309 * a target.6310 */6311 minlun = 0;6312 maxlun = 1;6313 if ((ahc->flags & AHC_SCB_BTT) != 0)6314 maxlun = AHC_NUM_LUNS;6315 } else {6316 minlun = lun;6317 maxlun = lun + 1;6318 }6319 6320 if (role != ROLE_TARGET) {6321 for (;i < maxtarget; i++) {6322 for (j = minlun;j < maxlun; j++) {6323 u_int scbid;6324 u_int tcl;6325 6326 tcl = BUILD_TCL(i << 4, j);6327 scbid = ahc_index_busy_tcl(ahc, tcl);6328 scbp = ahc_lookup_scb(ahc, scbid);6329 if (scbp == NULL6330 || ahc_match_scb(ahc, scbp, target, channel,6331 lun, tag, role) == 0)6332 continue;6333 ahc_unbusy_tcl(ahc, BUILD_TCL(i << 4, j));6334 }6335 }6336 6337 /*6338 * Go through the disconnected list and remove any entries we6339 * have queued for completion, 0'ing their control byte too.6340 * We save the active SCB and restore it ourselves, so there6341 * is no reason for this search to restore it too.6342 */6343 ahc_search_disc_list(ahc, target, channel, lun, tag,6344 /*stop_on_first*/FALSE, /*remove*/TRUE,6345 /*save_state*/FALSE);6346 }6347 6348 /*6349 * Go through the hardware SCB array looking for commands that6350 * were active but not on any list. In some cases, these remnants6351 * might not still have mappings in the scbindex array (e.g. unexpected6352 * bus free with the same scb queued for an abort). Don't hold this6353 * against them.6354 */6355 for (i = 0; i < ahc->scb_data->maxhscbs; i++) {6356 u_int scbid;6357 6358 ahc_outb(ahc, SCBPTR, i);6359 scbid = ahc_inb(ahc, SCB_TAG);6360 scbp = ahc_lookup_scb(ahc, scbid);6361 if ((scbp == NULL && scbid != SCB_LIST_NULL)6362 || (scbp != NULL6363 && ahc_match_scb(ahc, scbp, target, channel, lun, tag, role)))6364 ahc_add_curscb_to_free_list(ahc);6365 }6366 6367 /*6368 * Go through the pending CCB list and look for6369 * commands for this target that are still active.6370 * These are other tagged commands that were6371 * disconnected when the reset occurred.6372 */6373 scbp_next = LIST_FIRST(&ahc->pending_scbs);6374 while (scbp_next != NULL) {6375 scbp = scbp_next;6376 scbp_next = LIST_NEXT(scbp, pending_links);6377 if (ahc_match_scb(ahc, scbp, target, channel, lun, tag, role)) {6378 cam_status ostat;6379 6380 ostat = ahc_get_transaction_status(scbp);6381 if (ostat == CAM_REQ_INPROG)6382 ahc_set_transaction_status(scbp, status);6383 if (ahc_get_transaction_status(scbp) != CAM_REQ_CMP)6384 ahc_freeze_scb(scbp);6385 if ((scbp->flags & SCB_ACTIVE) == 0)6386 printk("Inactive SCB on pending list\n");6387 ahc_done(ahc, scbp);6388 found++;6389 }6390 }6391 ahc_outb(ahc, SCBPTR, active_scb);6392 ahc_platform_abort_scbs(ahc, target, channel, lun, tag, role, status);6393 ahc_release_untagged_queues(ahc);6394 return found;6395}6396 6397static void6398ahc_reset_current_bus(struct ahc_softc *ahc)6399{6400 uint8_t scsiseq;6401 6402 ahc_outb(ahc, SIMODE1, ahc_inb(ahc, SIMODE1) & ~ENSCSIRST);6403 scsiseq = ahc_inb(ahc, SCSISEQ);6404 ahc_outb(ahc, SCSISEQ, scsiseq | SCSIRSTO);6405 ahc_flush_device_writes(ahc);6406 ahc_delay(AHC_BUSRESET_DELAY);6407 /* Turn off the bus reset */6408 ahc_outb(ahc, SCSISEQ, scsiseq & ~SCSIRSTO);6409 6410 ahc_clear_intstat(ahc);6411 6412 /* Re-enable reset interrupts */6413 ahc_outb(ahc, SIMODE1, ahc_inb(ahc, SIMODE1) | ENSCSIRST);6414}6415 6416int6417ahc_reset_channel(struct ahc_softc *ahc, char channel, int initiate_reset)6418{6419 struct ahc_devinfo devinfo;6420 u_int initiator, target, max_scsiid;6421 u_int sblkctl;6422 u_int scsiseq;6423 u_int simode1;6424 int found;6425 int restart_needed;6426 char cur_channel;6427 6428 ahc->pending_device = NULL;6429 6430 ahc_compile_devinfo(&devinfo,6431 CAM_TARGET_WILDCARD,6432 CAM_TARGET_WILDCARD,6433 CAM_LUN_WILDCARD,6434 channel, ROLE_UNKNOWN);6435 ahc_pause(ahc);6436 6437 /* Make sure the sequencer is in a safe location. */6438 ahc_clear_critical_section(ahc);6439 6440 /*6441 * Run our command complete fifos to ensure that we perform6442 * completion processing on any commands that 'completed'6443 * before the reset occurred.6444 */6445 ahc_run_qoutfifo(ahc);6446#ifdef AHC_TARGET_MODE6447 /*6448 * XXX - In Twin mode, the tqinfifo may have commands6449 * for an unaffected channel in it. However, if6450 * we have run out of ATIO resources to drain that6451 * queue, we may not get them all out here. Further,6452 * the blocked transactions for the reset channel6453 * should just be killed off, irrespecitve of whether6454 * we are blocked on ATIO resources. Write a routine6455 * to compact the tqinfifo appropriately.6456 */6457 if ((ahc->flags & AHC_TARGETROLE) != 0) {6458 ahc_run_tqinfifo(ahc, /*paused*/TRUE);6459 }6460#endif6461 6462 /*6463 * Reset the bus if we are initiating this reset6464 */6465 sblkctl = ahc_inb(ahc, SBLKCTL);6466 cur_channel = 'A';6467 if ((ahc->features & AHC_TWIN) != 06468 && ((sblkctl & SELBUSB) != 0))6469 cur_channel = 'B';6470 scsiseq = ahc_inb(ahc, SCSISEQ_TEMPLATE);6471 if (cur_channel != channel) {6472 /* Case 1: Command for another bus is active6473 * Stealthily reset the other bus without6474 * upsetting the current bus.6475 */6476 ahc_outb(ahc, SBLKCTL, sblkctl ^ SELBUSB);6477 simode1 = ahc_inb(ahc, SIMODE1) & ~(ENBUSFREE|ENSCSIRST);6478#ifdef AHC_TARGET_MODE6479 /*6480 * Bus resets clear ENSELI, so we cannot6481 * defer re-enabling bus reset interrupts6482 * if we are in target mode.6483 */6484 if ((ahc->flags & AHC_TARGETROLE) != 0)6485 simode1 |= ENSCSIRST;6486#endif6487 ahc_outb(ahc, SIMODE1, simode1);6488 if (initiate_reset)6489 ahc_reset_current_bus(ahc);6490 ahc_clear_intstat(ahc);6491 ahc_outb(ahc, SCSISEQ, scsiseq & (ENSELI|ENRSELI|ENAUTOATNP));6492 ahc_outb(ahc, SBLKCTL, sblkctl);6493 restart_needed = FALSE;6494 } else {6495 /* Case 2: A command from this bus is active or we're idle */6496 simode1 = ahc_inb(ahc, SIMODE1) & ~(ENBUSFREE|ENSCSIRST);6497#ifdef AHC_TARGET_MODE6498 /*6499 * Bus resets clear ENSELI, so we cannot6500 * defer re-enabling bus reset interrupts6501 * if we are in target mode.6502 */6503 if ((ahc->flags & AHC_TARGETROLE) != 0)6504 simode1 |= ENSCSIRST;6505#endif6506 ahc_outb(ahc, SIMODE1, simode1);6507 if (initiate_reset)6508 ahc_reset_current_bus(ahc);6509 ahc_clear_intstat(ahc);6510 ahc_outb(ahc, SCSISEQ, scsiseq & (ENSELI|ENRSELI|ENAUTOATNP));6511 restart_needed = TRUE;6512 }6513 6514 /*6515 * Clean up all the state information for the6516 * pending transactions on this bus.6517 */6518 found = ahc_abort_scbs(ahc, CAM_TARGET_WILDCARD, channel,6519 CAM_LUN_WILDCARD, SCB_LIST_NULL,6520 ROLE_UNKNOWN, CAM_SCSI_BUS_RESET);6521 6522 max_scsiid = (ahc->features & AHC_WIDE) ? 15 : 7;6523 6524#ifdef AHC_TARGET_MODE6525 /*6526 * Send an immediate notify ccb to all target more peripheral6527 * drivers affected by this action.6528 */6529 for (target = 0; target <= max_scsiid; target++) {6530 struct ahc_tmode_tstate* tstate;6531 u_int lun;6532 6533 tstate = ahc->enabled_targets[target];6534 if (tstate == NULL)6535 continue;6536 for (lun = 0; lun < AHC_NUM_LUNS; lun++) {6537 struct ahc_tmode_lstate* lstate;6538 6539 lstate = tstate->enabled_luns[lun];6540 if (lstate == NULL)6541 continue;6542 6543 ahc_queue_lstate_event(ahc, lstate, CAM_TARGET_WILDCARD,6544 EVENT_TYPE_BUS_RESET, /*arg*/0);6545 ahc_send_lstate_events(ahc, lstate);6546 }6547 }6548#endif6549 /* Notify the XPT that a bus reset occurred */6550 ahc_send_async(ahc, devinfo.channel, CAM_TARGET_WILDCARD,6551 CAM_LUN_WILDCARD, AC_BUS_RESET);6552 6553 /*6554 * Revert to async/narrow transfers until we renegotiate.6555 */6556 for (target = 0; target <= max_scsiid; target++) {6557 6558 if (ahc->enabled_targets[target] == NULL)6559 continue;6560 for (initiator = 0; initiator <= max_scsiid; initiator++) {6561 struct ahc_devinfo devinfo;6562 6563 ahc_compile_devinfo(&devinfo, target, initiator,6564 CAM_LUN_WILDCARD,6565 channel, ROLE_UNKNOWN);6566 ahc_set_width(ahc, &devinfo, MSG_EXT_WDTR_BUS_8_BIT,6567 AHC_TRANS_CUR, /*paused*/TRUE);6568 ahc_set_syncrate(ahc, &devinfo, /*syncrate*/NULL,6569 /*period*/0, /*offset*/0,6570 /*ppr_options*/0, AHC_TRANS_CUR,6571 /*paused*/TRUE);6572 }6573 }6574 6575 if (restart_needed)6576 ahc_restart(ahc);6577 else6578 ahc_unpause(ahc);6579 return found;6580}6581 6582 6583/***************************** Residual Processing ****************************/6584/*6585 * Calculate the residual for a just completed SCB.6586 */6587static void6588ahc_calc_residual(struct ahc_softc *ahc, struct scb *scb)6589{6590 struct hardware_scb *hscb;6591 struct status_pkt *spkt;6592 uint32_t sgptr;6593 uint32_t resid_sgptr;6594 uint32_t resid;6595 6596 /*6597 * 5 cases.6598 * 1) No residual.6599 * SG_RESID_VALID clear in sgptr.6600 * 2) Transferless command6601 * 3) Never performed any transfers.6602 * sgptr has SG_FULL_RESID set.6603 * 4) No residual but target did not6604 * save data pointers after the6605 * last transfer, so sgptr was6606 * never updated.6607 * 5) We have a partial residual.6608 * Use residual_sgptr to determine6609 * where we are.6610 */6611 6612 hscb = scb->hscb;6613 sgptr = ahc_le32toh(hscb->sgptr);6614 if ((sgptr & SG_RESID_VALID) == 0)6615 /* Case 1 */6616 return;6617 sgptr &= ~SG_RESID_VALID;6618 6619 if ((sgptr & SG_LIST_NULL) != 0)6620 /* Case 2 */6621 return;6622 6623 spkt = &hscb->shared_data.status;6624 resid_sgptr = ahc_le32toh(spkt->residual_sg_ptr);6625 if ((sgptr & SG_FULL_RESID) != 0) {6626 /* Case 3 */6627 resid = ahc_get_transfer_length(scb);6628 } else if ((resid_sgptr & SG_LIST_NULL) != 0) {6629 /* Case 4 */6630 return;6631 } else if ((resid_sgptr & ~SG_PTR_MASK) != 0) {6632 panic("Bogus resid sgptr value 0x%x\n", resid_sgptr);6633 } else {6634 struct ahc_dma_seg *sg;6635 6636 /*6637 * Remainder of the SG where the transfer6638 * stopped.6639 */6640 resid = ahc_le32toh(spkt->residual_datacnt) & AHC_SG_LEN_MASK;6641 sg = ahc_sg_bus_to_virt(scb, resid_sgptr & SG_PTR_MASK);6642 6643 /* The residual sg_ptr always points to the next sg */6644 sg--;6645 6646 /*6647 * Add up the contents of all residual6648 * SG segments that are after the SG where6649 * the transfer stopped.6650 */6651 while ((ahc_le32toh(sg->len) & AHC_DMA_LAST_SEG) == 0) {6652 sg++;6653 resid += ahc_le32toh(sg->len) & AHC_SG_LEN_MASK;6654 }6655 }6656 if ((scb->flags & SCB_SENSE) == 0)6657 ahc_set_residual(scb, resid);6658 else6659 ahc_set_sense_residual(scb, resid);6660 6661#ifdef AHC_DEBUG6662 if ((ahc_debug & AHC_SHOW_MISC) != 0) {6663 ahc_print_path(ahc, scb);6664 printk("Handled %sResidual of %d bytes\n",6665 (scb->flags & SCB_SENSE) ? "Sense " : "", resid);6666 }6667#endif6668}6669 6670/******************************* Target Mode **********************************/6671#ifdef AHC_TARGET_MODE6672/*6673 * Add a target mode event to this lun's queue6674 */6675static void6676ahc_queue_lstate_event(struct ahc_softc *ahc, struct ahc_tmode_lstate *lstate,6677 u_int initiator_id, u_int event_type, u_int event_arg)6678{6679 struct ahc_tmode_event *event;6680 int pending;6681 6682 xpt_freeze_devq(lstate->path, /*count*/1);6683 if (lstate->event_w_idx >= lstate->event_r_idx)6684 pending = lstate->event_w_idx - lstate->event_r_idx;6685 else6686 pending = AHC_TMODE_EVENT_BUFFER_SIZE + 16687 - (lstate->event_r_idx - lstate->event_w_idx);6688 6689 if (event_type == EVENT_TYPE_BUS_RESET6690 || event_type == TARGET_RESET) {6691 /*6692 * Any earlier events are irrelevant, so reset our buffer.6693 * This has the effect of allowing us to deal with reset6694 * floods (an external device holding down the reset line)6695 * without losing the event that is really interesting.6696 */6697 lstate->event_r_idx = 0;6698 lstate->event_w_idx = 0;6699 xpt_release_devq(lstate->path, pending, /*runqueue*/FALSE);6700 }6701 6702 if (pending == AHC_TMODE_EVENT_BUFFER_SIZE) {6703 xpt_print_path(lstate->path);6704 printk("immediate event %x:%x lost\n",6705 lstate->event_buffer[lstate->event_r_idx].event_type,6706 lstate->event_buffer[lstate->event_r_idx].event_arg);6707 lstate->event_r_idx++;6708 if (lstate->event_r_idx == AHC_TMODE_EVENT_BUFFER_SIZE)6709 lstate->event_r_idx = 0;6710 xpt_release_devq(lstate->path, /*count*/1, /*runqueue*/FALSE);6711 }6712 6713 event = &lstate->event_buffer[lstate->event_w_idx];6714 event->initiator_id = initiator_id;6715 event->event_type = event_type;6716 event->event_arg = event_arg;6717 lstate->event_w_idx++;6718 if (lstate->event_w_idx == AHC_TMODE_EVENT_BUFFER_SIZE)6719 lstate->event_w_idx = 0;6720}6721 6722/*6723 * Send any target mode events queued up waiting6724 * for immediate notify resources.6725 */6726void6727ahc_send_lstate_events(struct ahc_softc *ahc, struct ahc_tmode_lstate *lstate)6728{6729 struct ccb_hdr *ccbh;6730 struct ccb_immed_notify *inot;6731 6732 while (lstate->event_r_idx != lstate->event_w_idx6733 && (ccbh = SLIST_FIRST(&lstate->immed_notifies)) != NULL) {6734 struct ahc_tmode_event *event;6735 6736 event = &lstate->event_buffer[lstate->event_r_idx];6737 SLIST_REMOVE_HEAD(&lstate->immed_notifies, sim_links.sle);6738 inot = (struct ccb_immed_notify *)ccbh;6739 switch (event->event_type) {6740 case EVENT_TYPE_BUS_RESET:6741 ccbh->status = CAM_SCSI_BUS_RESET|CAM_DEV_QFRZN;6742 break;6743 default:6744 ccbh->status = CAM_MESSAGE_RECV|CAM_DEV_QFRZN;6745 inot->message_args[0] = event->event_type;6746 inot->message_args[1] = event->event_arg;6747 break;6748 }6749 inot->initiator_id = event->initiator_id;6750 inot->sense_len = 0;6751 xpt_done((union ccb *)inot);6752 lstate->event_r_idx++;6753 if (lstate->event_r_idx == AHC_TMODE_EVENT_BUFFER_SIZE)6754 lstate->event_r_idx = 0;6755 }6756}6757#endif6758 6759/******************** Sequencer Program Patching/Download *********************/6760 6761#ifdef AHC_DUMP_SEQ6762void6763ahc_dumpseq(struct ahc_softc* ahc)6764{6765 int i;6766 6767 ahc_outb(ahc, SEQCTL, PERRORDIS|FAILDIS|FASTMODE|LOADRAM);6768 ahc_outb(ahc, SEQADDR0, 0);6769 ahc_outb(ahc, SEQADDR1, 0);6770 for (i = 0; i < ahc->instruction_ram_size; i++) {6771 uint8_t ins_bytes[4];6772 6773 ahc_insb(ahc, SEQRAM, ins_bytes, 4);6774 printk("0x%08x\n", ins_bytes[0] << 246775 | ins_bytes[1] << 166776 | ins_bytes[2] << 86777 | ins_bytes[3]);6778 }6779}6780#endif6781 6782static int6783ahc_loadseq(struct ahc_softc *ahc)6784{6785 struct cs cs_table[NUM_CRITICAL_SECTIONS];6786 u_int begin_set[NUM_CRITICAL_SECTIONS];6787 u_int end_set[NUM_CRITICAL_SECTIONS];6788 const struct patch *cur_patch;6789 u_int cs_count;6790 u_int cur_cs;6791 u_int i;6792 u_int skip_addr;6793 u_int sg_prefetch_cnt;6794 int downloaded;6795 uint8_t download_consts[7];6796 6797 /*6798 * Start out with 0 critical sections6799 * that apply to this firmware load.6800 */6801 cs_count = 0;6802 cur_cs = 0;6803 memset(begin_set, 0, sizeof(begin_set));6804 memset(end_set, 0, sizeof(end_set));6805 6806 /* Setup downloadable constant table */6807 download_consts[QOUTFIFO_OFFSET] = 0;6808 if (ahc->targetcmds != NULL)6809 download_consts[QOUTFIFO_OFFSET] += 32;6810 download_consts[QINFIFO_OFFSET] = download_consts[QOUTFIFO_OFFSET] + 1;6811 download_consts[CACHESIZE_MASK] = ahc->pci_cachesize - 1;6812 download_consts[INVERTED_CACHESIZE_MASK] = ~(ahc->pci_cachesize - 1);6813 sg_prefetch_cnt = ahc->pci_cachesize;6814 if (sg_prefetch_cnt < (2 * sizeof(struct ahc_dma_seg)))6815 sg_prefetch_cnt = 2 * sizeof(struct ahc_dma_seg);6816 download_consts[SG_PREFETCH_CNT] = sg_prefetch_cnt;6817 download_consts[SG_PREFETCH_ALIGN_MASK] = ~(sg_prefetch_cnt - 1);6818 download_consts[SG_PREFETCH_ADDR_MASK] = (sg_prefetch_cnt - 1);6819 6820 cur_patch = patches;6821 downloaded = 0;6822 skip_addr = 0;6823 ahc_outb(ahc, SEQCTL, PERRORDIS|FAILDIS|FASTMODE|LOADRAM);6824 ahc_outb(ahc, SEQADDR0, 0);6825 ahc_outb(ahc, SEQADDR1, 0);6826 6827 for (i = 0; i < sizeof(seqprog)/4; i++) {6828 if (ahc_check_patch(ahc, &cur_patch, i, &skip_addr) == 0) {6829 /*6830 * Don't download this instruction as it6831 * is in a patch that was removed.6832 */6833 continue;6834 }6835 6836 if (downloaded == ahc->instruction_ram_size) {6837 /*6838 * We're about to exceed the instruction6839 * storage capacity for this chip. Fail6840 * the load.6841 */6842 printk("\n%s: Program too large for instruction memory "6843 "size of %d!\n", ahc_name(ahc),6844 ahc->instruction_ram_size);6845 return (ENOMEM);6846 }6847 6848 /*6849 * Move through the CS table until we find a CS6850 * that might apply to this instruction.6851 */6852 for (; cur_cs < NUM_CRITICAL_SECTIONS; cur_cs++) {6853 if (critical_sections[cur_cs].end <= i) {6854 if (begin_set[cs_count] == TRUE6855 && end_set[cs_count] == FALSE) {6856 cs_table[cs_count].end = downloaded;6857 end_set[cs_count] = TRUE;6858 cs_count++;6859 }6860 continue;6861 }6862 if (critical_sections[cur_cs].begin <= i6863 && begin_set[cs_count] == FALSE) {6864 cs_table[cs_count].begin = downloaded;6865 begin_set[cs_count] = TRUE;6866 }6867 break;6868 }6869 ahc_download_instr(ahc, i, download_consts);6870 downloaded++;6871 }6872 6873 ahc->num_critical_sections = cs_count;6874 if (cs_count != 0) {6875 6876 cs_count *= sizeof(struct cs);6877 ahc->critical_sections = kmemdup(cs_table, cs_count, GFP_ATOMIC);6878 if (ahc->critical_sections == NULL)6879 panic("ahc_loadseq: Could not malloc");6880 }6881 ahc_outb(ahc, SEQCTL, PERRORDIS|FAILDIS|FASTMODE);6882 6883 if (bootverbose) {6884 printk(" %d instructions downloaded\n", downloaded);6885 printk("%s: Features 0x%x, Bugs 0x%x, Flags 0x%x\n",6886 ahc_name(ahc), ahc->features, ahc->bugs, ahc->flags);6887 }6888 return (0);6889}6890 6891static int6892ahc_check_patch(struct ahc_softc *ahc, const struct patch **start_patch,6893 u_int start_instr, u_int *skip_addr)6894{6895 const struct patch *cur_patch;6896 const struct patch *last_patch;6897 u_int num_patches;6898 6899 num_patches = ARRAY_SIZE(patches);6900 last_patch = &patches[num_patches];6901 cur_patch = *start_patch;6902 6903 while (cur_patch < last_patch && start_instr == cur_patch->begin) {6904 6905 if (cur_patch->patch_func(ahc) == 0) {6906 6907 /* Start rejecting code */6908 *skip_addr = start_instr + cur_patch->skip_instr;6909 cur_patch += cur_patch->skip_patch;6910 } else {6911 /* Accepted this patch. Advance to the next6912 * one and wait for our intruction pointer to6913 * hit this point.6914 */6915 cur_patch++;6916 }6917 }6918 6919 *start_patch = cur_patch;6920 if (start_instr < *skip_addr)6921 /* Still skipping */6922 return (0);6923 6924 return (1);6925}6926 6927static void6928ahc_download_instr(struct ahc_softc *ahc, u_int instrptr, uint8_t *dconsts)6929{6930 union ins_formats instr;6931 struct ins_format1 *fmt1_ins;6932 struct ins_format3 *fmt3_ins;6933 u_int opcode;6934 6935 /*6936 * The firmware is always compiled into a little endian format.6937 */6938 instr.integer = ahc_le32toh(*(uint32_t*)&seqprog[instrptr * 4]);6939 6940 fmt1_ins = &instr.format1;6941 fmt3_ins = NULL;6942 6943 /* Pull the opcode */6944 opcode = instr.format1.opcode;6945 switch (opcode) {6946 case AIC_OP_JMP:6947 case AIC_OP_JC:6948 case AIC_OP_JNC:6949 case AIC_OP_CALL:6950 case AIC_OP_JNE:6951 case AIC_OP_JNZ:6952 case AIC_OP_JE:6953 case AIC_OP_JZ:6954 {6955 const struct patch *cur_patch;6956 int address_offset;6957 u_int address;6958 u_int skip_addr;6959 u_int i;6960 6961 fmt3_ins = &instr.format3;6962 address_offset = 0;6963 address = fmt3_ins->address;6964 cur_patch = patches;6965 skip_addr = 0;6966 6967 for (i = 0; i < address;) {6968 6969 ahc_check_patch(ahc, &cur_patch, i, &skip_addr);6970 6971 if (skip_addr > i) {6972 int end_addr;6973 6974 end_addr = min(address, skip_addr);6975 address_offset += end_addr - i;6976 i = skip_addr;6977 } else {6978 i++;6979 }6980 }6981 address -= address_offset;6982 fmt3_ins->address = address;6983 }6984 fallthrough;6985 case AIC_OP_OR:6986 case AIC_OP_AND:6987 case AIC_OP_XOR:6988 case AIC_OP_ADD:6989 case AIC_OP_ADC:6990 case AIC_OP_BMOV:6991 if (fmt1_ins->parity != 0) {6992 fmt1_ins->immediate = dconsts[fmt1_ins->immediate];6993 }6994 fmt1_ins->parity = 0;6995 if ((ahc->features & AHC_CMD_CHAN) == 06996 && opcode == AIC_OP_BMOV) {6997 /*6998 * Block move was added at the same time6999 * as the command channel. Verify that7000 * this is only a move of a single element7001 * and convert the BMOV to a MOV7002 * (AND with an immediate of FF).7003 */7004 if (fmt1_ins->immediate != 1)7005 panic("%s: BMOV not supported\n",7006 ahc_name(ahc));7007 fmt1_ins->opcode = AIC_OP_AND;7008 fmt1_ins->immediate = 0xff;7009 }7010 fallthrough;7011 case AIC_OP_ROL:7012 if ((ahc->features & AHC_ULTRA2) != 0) {7013 int i, count;7014 7015 /* Calculate odd parity for the instruction */7016 for (i = 0, count = 0; i < 31; i++) {7017 uint32_t mask;7018 7019 mask = 0x01 << i;7020 if ((instr.integer & mask) != 0)7021 count++;7022 }7023 if ((count & 0x01) == 0)7024 instr.format1.parity = 1;7025 } else {7026 /* Compress the instruction for older sequencers */7027 if (fmt3_ins != NULL) {7028 instr.integer =7029 fmt3_ins->immediate7030 | (fmt3_ins->source << 8)7031 | (fmt3_ins->address << 16)7032 | (fmt3_ins->opcode << 25);7033 } else {7034 instr.integer =7035 fmt1_ins->immediate7036 | (fmt1_ins->source << 8)7037 | (fmt1_ins->destination << 16)7038 | (fmt1_ins->ret << 24)7039 | (fmt1_ins->opcode << 25);7040 }7041 }7042 /* The sequencer is a little endian cpu */7043 instr.integer = ahc_htole32(instr.integer);7044 ahc_outsb(ahc, SEQRAM, instr.bytes, 4);7045 break;7046 default:7047 panic("Unknown opcode encountered in seq program");7048 break;7049 }7050}7051 7052int7053ahc_print_register(const ahc_reg_parse_entry_t *table, u_int num_entries,7054 const char *name, u_int address, u_int value,7055 u_int *cur_column, u_int wrap_point)7056{7057 int printed;7058 u_int printed_mask;7059 7060 if (cur_column != NULL && *cur_column >= wrap_point) {7061 printk("\n");7062 *cur_column = 0;7063 }7064 printed = printk("%s[0x%x]", name, value);7065 if (table == NULL) {7066 printed += printk(" ");7067 *cur_column += printed;7068 return (printed);7069 }7070 printed_mask = 0;7071 while (printed_mask != 0xFF) {7072 int entry;7073 7074 for (entry = 0; entry < num_entries; entry++) {7075 if (((value & table[entry].mask)7076 != table[entry].value)7077 || ((printed_mask & table[entry].mask)7078 == table[entry].mask))7079 continue;7080 7081 printed += printk("%s%s",7082 printed_mask == 0 ? ":(" : "|",7083 table[entry].name);7084 printed_mask |= table[entry].mask;7085 break;7086 }7087 if (entry >= num_entries)7088 break;7089 }7090 if (printed_mask != 0)7091 printed += printk(") ");7092 else7093 printed += printk(" ");7094 if (cur_column != NULL)7095 *cur_column += printed;7096 return (printed);7097}7098 7099void7100ahc_dump_card_state(struct ahc_softc *ahc)7101{7102 struct scb *scb;7103 struct scb_tailq *untagged_q;7104 u_int cur_col;7105 int paused;7106 int target;7107 int maxtarget;7108 int i;7109 uint8_t last_phase;7110 uint8_t qinpos;7111 uint8_t qintail;7112 uint8_t qoutpos;7113 uint8_t scb_index;7114 uint8_t saved_scbptr;7115 7116 if (ahc_is_paused(ahc)) {7117 paused = 1;7118 } else {7119 paused = 0;7120 ahc_pause(ahc);7121 }7122 7123 saved_scbptr = ahc_inb(ahc, SCBPTR);7124 last_phase = ahc_inb(ahc, LASTPHASE);7125 printk(">>>>>>>>>>>>>>>>>> Dump Card State Begins <<<<<<<<<<<<<<<<<\n"7126 "%s: Dumping Card State %s, at SEQADDR 0x%x\n",7127 ahc_name(ahc), ahc_lookup_phase_entry(last_phase)->phasemsg,7128 ahc_inb(ahc, SEQADDR0) | (ahc_inb(ahc, SEQADDR1) << 8));7129 if (paused)7130 printk("Card was paused\n");7131 printk("ACCUM = 0x%x, SINDEX = 0x%x, DINDEX = 0x%x, ARG_2 = 0x%x\n",7132 ahc_inb(ahc, ACCUM), ahc_inb(ahc, SINDEX), ahc_inb(ahc, DINDEX),7133 ahc_inb(ahc, ARG_2));7134 printk("HCNT = 0x%x SCBPTR = 0x%x\n", ahc_inb(ahc, HCNT),7135 ahc_inb(ahc, SCBPTR));7136 cur_col = 0;7137 if ((ahc->features & AHC_DT) != 0)7138 ahc_scsiphase_print(ahc_inb(ahc, SCSIPHASE), &cur_col, 50);7139 ahc_scsisigi_print(ahc_inb(ahc, SCSISIGI), &cur_col, 50);7140 ahc_error_print(ahc_inb(ahc, ERROR), &cur_col, 50);7141 ahc_scsibusl_print(ahc_inb(ahc, SCSIBUSL), &cur_col, 50);7142 ahc_lastphase_print(ahc_inb(ahc, LASTPHASE), &cur_col, 50);7143 ahc_scsiseq_print(ahc_inb(ahc, SCSISEQ), &cur_col, 50);7144 ahc_sblkctl_print(ahc_inb(ahc, SBLKCTL), &cur_col, 50);7145 ahc_scsirate_print(ahc_inb(ahc, SCSIRATE), &cur_col, 50);7146 ahc_seqctl_print(ahc_inb(ahc, SEQCTL), &cur_col, 50);7147 ahc_seq_flags_print(ahc_inb(ahc, SEQ_FLAGS), &cur_col, 50);7148 ahc_sstat0_print(ahc_inb(ahc, SSTAT0), &cur_col, 50);7149 ahc_sstat1_print(ahc_inb(ahc, SSTAT1), &cur_col, 50);7150 ahc_sstat2_print(ahc_inb(ahc, SSTAT2), &cur_col, 50);7151 ahc_sstat3_print(ahc_inb(ahc, SSTAT3), &cur_col, 50);7152 ahc_simode0_print(ahc_inb(ahc, SIMODE0), &cur_col, 50);7153 ahc_simode1_print(ahc_inb(ahc, SIMODE1), &cur_col, 50);7154 ahc_sxfrctl0_print(ahc_inb(ahc, SXFRCTL0), &cur_col, 50);7155 ahc_dfcntrl_print(ahc_inb(ahc, DFCNTRL), &cur_col, 50);7156 ahc_dfstatus_print(ahc_inb(ahc, DFSTATUS), &cur_col, 50);7157 if (cur_col != 0)7158 printk("\n");7159 printk("STACK:");7160 for (i = 0; i < STACK_SIZE; i++)7161 printk(" 0x%x", ahc_inb(ahc, STACK)|(ahc_inb(ahc, STACK) << 8));7162 printk("\nSCB count = %d\n", ahc->scb_data->numscbs);7163 printk("Kernel NEXTQSCB = %d\n", ahc->next_queued_scb->hscb->tag);7164 printk("Card NEXTQSCB = %d\n", ahc_inb(ahc, NEXT_QUEUED_SCB));7165 /* QINFIFO */7166 printk("QINFIFO entries: ");7167 if ((ahc->features & AHC_QUEUE_REGS) != 0) {7168 qinpos = ahc_inb(ahc, SNSCB_QOFF);7169 ahc_outb(ahc, SNSCB_QOFF, qinpos);7170 } else7171 qinpos = ahc_inb(ahc, QINPOS);7172 qintail = ahc->qinfifonext;7173 while (qinpos != qintail) {7174 printk("%d ", ahc->qinfifo[qinpos]);7175 qinpos++;7176 }7177 printk("\n");7178 7179 printk("Waiting Queue entries: ");7180 scb_index = ahc_inb(ahc, WAITING_SCBH);7181 i = 0;7182 while (scb_index != SCB_LIST_NULL && i++ < 256) {7183 ahc_outb(ahc, SCBPTR, scb_index);7184 printk("%d:%d ", scb_index, ahc_inb(ahc, SCB_TAG));7185 scb_index = ahc_inb(ahc, SCB_NEXT);7186 }7187 printk("\n");7188 7189 printk("Disconnected Queue entries: ");7190 scb_index = ahc_inb(ahc, DISCONNECTED_SCBH);7191 i = 0;7192 while (scb_index != SCB_LIST_NULL && i++ < 256) {7193 ahc_outb(ahc, SCBPTR, scb_index);7194 printk("%d:%d ", scb_index, ahc_inb(ahc, SCB_TAG));7195 scb_index = ahc_inb(ahc, SCB_NEXT);7196 }7197 printk("\n");7198 7199 ahc_sync_qoutfifo(ahc, BUS_DMASYNC_POSTREAD);7200 printk("QOUTFIFO entries: ");7201 qoutpos = ahc->qoutfifonext;7202 i = 0;7203 while (ahc->qoutfifo[qoutpos] != SCB_LIST_NULL && i++ < 256) {7204 printk("%d ", ahc->qoutfifo[qoutpos]);7205 qoutpos++;7206 }7207 printk("\n");7208 7209 printk("Sequencer Free SCB List: ");7210 scb_index = ahc_inb(ahc, FREE_SCBH);7211 i = 0;7212 while (scb_index != SCB_LIST_NULL && i++ < 256) {7213 ahc_outb(ahc, SCBPTR, scb_index);7214 printk("%d ", scb_index);7215 scb_index = ahc_inb(ahc, SCB_NEXT);7216 }7217 printk("\n");7218 7219 printk("Sequencer SCB Info: ");7220 for (i = 0; i < ahc->scb_data->maxhscbs; i++) {7221 ahc_outb(ahc, SCBPTR, i);7222 cur_col = printk("\n%3d ", i);7223 7224 ahc_scb_control_print(ahc_inb(ahc, SCB_CONTROL), &cur_col, 60);7225 ahc_scb_scsiid_print(ahc_inb(ahc, SCB_SCSIID), &cur_col, 60);7226 ahc_scb_lun_print(ahc_inb(ahc, SCB_LUN), &cur_col, 60);7227 ahc_scb_tag_print(ahc_inb(ahc, SCB_TAG), &cur_col, 60);7228 }7229 printk("\n");7230 7231 printk("Pending list: ");7232 i = 0;7233 LIST_FOREACH(scb, &ahc->pending_scbs, pending_links) {7234 if (i++ > 256)7235 break;7236 cur_col = printk("\n%3d ", scb->hscb->tag);7237 ahc_scb_control_print(scb->hscb->control, &cur_col, 60);7238 ahc_scb_scsiid_print(scb->hscb->scsiid, &cur_col, 60);7239 ahc_scb_lun_print(scb->hscb->lun, &cur_col, 60);7240 if ((ahc->flags & AHC_PAGESCBS) == 0) {7241 ahc_outb(ahc, SCBPTR, scb->hscb->tag);7242 printk("(");7243 ahc_scb_control_print(ahc_inb(ahc, SCB_CONTROL),7244 &cur_col, 60);7245 ahc_scb_tag_print(ahc_inb(ahc, SCB_TAG), &cur_col, 60);7246 printk(")");7247 }7248 }7249 printk("\n");7250 7251 printk("Kernel Free SCB list: ");7252 i = 0;7253 SLIST_FOREACH(scb, &ahc->scb_data->free_scbs, links.sle) {7254 if (i++ > 256)7255 break;7256 printk("%d ", scb->hscb->tag);7257 }7258 printk("\n");7259 7260 maxtarget = (ahc->features & (AHC_WIDE|AHC_TWIN)) ? 15 : 7;7261 for (target = 0; target <= maxtarget; target++) {7262 untagged_q = &ahc->untagged_queues[target];7263 if (TAILQ_FIRST(untagged_q) == NULL)7264 continue;7265 printk("Untagged Q(%d): ", target);7266 i = 0;7267 TAILQ_FOREACH(scb, untagged_q, links.tqe) {7268 if (i++ > 256)7269 break;7270 printk("%d ", scb->hscb->tag);7271 }7272 printk("\n");7273 }7274 7275 printk("\n<<<<<<<<<<<<<<<<< Dump Card State Ends >>>>>>>>>>>>>>>>>>\n");7276 ahc_outb(ahc, SCBPTR, saved_scbptr);7277 if (paused == 0)7278 ahc_unpause(ahc);7279}7280 7281/************************* Target Mode ****************************************/7282#ifdef AHC_TARGET_MODE7283cam_status7284ahc_find_tmode_devs(struct ahc_softc *ahc, struct cam_sim *sim, union ccb *ccb,7285 struct ahc_tmode_tstate **tstate,7286 struct ahc_tmode_lstate **lstate,7287 int notfound_failure)7288{7289 7290 if ((ahc->features & AHC_TARGETMODE) == 0)7291 return (CAM_REQ_INVALID);7292 7293 /*7294 * Handle the 'black hole' device that sucks up7295 * requests to unattached luns on enabled targets.7296 */7297 if (ccb->ccb_h.target_id == CAM_TARGET_WILDCARD7298 && ccb->ccb_h.target_lun == CAM_LUN_WILDCARD) {7299 *tstate = NULL;7300 *lstate = ahc->black_hole;7301 } else {7302 u_int max_id;7303 7304 max_id = (ahc->features & AHC_WIDE) ? 16 : 8;7305 if (ccb->ccb_h.target_id >= max_id)7306 return (CAM_TID_INVALID);7307 7308 if (ccb->ccb_h.target_lun >= AHC_NUM_LUNS)7309 return (CAM_LUN_INVALID);7310 7311 *tstate = ahc->enabled_targets[ccb->ccb_h.target_id];7312 *lstate = NULL;7313 if (*tstate != NULL)7314 *lstate =7315 (*tstate)->enabled_luns[ccb->ccb_h.target_lun];7316 }7317 7318 if (notfound_failure != 0 && *lstate == NULL)7319 return (CAM_PATH_INVALID);7320 7321 return (CAM_REQ_CMP);7322}7323 7324void7325ahc_handle_en_lun(struct ahc_softc *ahc, struct cam_sim *sim, union ccb *ccb)7326{7327 struct ahc_tmode_tstate *tstate;7328 struct ahc_tmode_lstate *lstate;7329 struct ccb_en_lun *cel;7330 cam_status status;7331 u_long s;7332 u_int target;7333 u_int lun;7334 u_int target_mask;7335 u_int our_id;7336 int error;7337 char channel;7338 7339 status = ahc_find_tmode_devs(ahc, sim, ccb, &tstate, &lstate,7340 /*notfound_failure*/FALSE);7341 7342 if (status != CAM_REQ_CMP) {7343 ccb->ccb_h.status = status;7344 return;7345 }7346 7347 if (cam_sim_bus(sim) == 0)7348 our_id = ahc->our_id;7349 else7350 our_id = ahc->our_id_b;7351 7352 if (ccb->ccb_h.target_id != our_id) {7353 /*7354 * our_id represents our initiator ID, or7355 * the ID of the first target to have an7356 * enabled lun in target mode. There are7357 * two cases that may preclude enabling a7358 * target id other than our_id.7359 *7360 * o our_id is for an active initiator role.7361 * Since the hardware does not support7362 * reselections to the initiator role at7363 * anything other than our_id, and our_id7364 * is used by the hardware to indicate the7365 * ID to use for both select-out and7366 * reselect-out operations, the only target7367 * ID we can support in this mode is our_id.7368 *7369 * o The MULTARGID feature is not available and7370 * a previous target mode ID has been enabled.7371 */7372 if ((ahc->features & AHC_MULTIROLE) != 0) {7373 7374 if ((ahc->features & AHC_MULTI_TID) != 07375 && (ahc->flags & AHC_INITIATORROLE) != 0) {7376 /*7377 * Only allow additional targets if7378 * the initiator role is disabled.7379 * The hardware cannot handle a re-select-in7380 * on the initiator id during a re-select-out7381 * on a different target id.7382 */7383 status = CAM_TID_INVALID;7384 } else if ((ahc->flags & AHC_INITIATORROLE) != 07385 || ahc->enabled_luns > 0) {7386 /*7387 * Only allow our target id to change7388 * if the initiator role is not configured7389 * and there are no enabled luns which7390 * are attached to the currently registered7391 * scsi id.7392 */7393 status = CAM_TID_INVALID;7394 }7395 } else if ((ahc->features & AHC_MULTI_TID) == 07396 && ahc->enabled_luns > 0) {7397 7398 status = CAM_TID_INVALID;7399 }7400 }7401 7402 if (status != CAM_REQ_CMP) {7403 ccb->ccb_h.status = status;7404 return;7405 }7406 7407 /*7408 * We now have an id that is valid.7409 * If we aren't in target mode, switch modes.7410 */7411 if ((ahc->flags & AHC_TARGETROLE) == 07412 && ccb->ccb_h.target_id != CAM_TARGET_WILDCARD) {7413 u_long s;7414 ahc_flag saved_flags;7415 7416 printk("Configuring Target Mode\n");7417 ahc_lock(ahc, &s);7418 if (LIST_FIRST(&ahc->pending_scbs) != NULL) {7419 ccb->ccb_h.status = CAM_BUSY;7420 ahc_unlock(ahc, &s);7421 return;7422 }7423 saved_flags = ahc->flags;7424 ahc->flags |= AHC_TARGETROLE;7425 if ((ahc->features & AHC_MULTIROLE) == 0)7426 ahc->flags &= ~AHC_INITIATORROLE;7427 ahc_pause(ahc);7428 error = ahc_loadseq(ahc);7429 if (error != 0) {7430 /*7431 * Restore original configuration and notify7432 * the caller that we cannot support target mode.7433 * Since the adapter started out in this7434 * configuration, the firmware load will succeed,7435 * so there is no point in checking ahc_loadseq's7436 * return value.7437 */7438 ahc->flags = saved_flags;7439 (void)ahc_loadseq(ahc);7440 ahc_restart(ahc);7441 ahc_unlock(ahc, &s);7442 ccb->ccb_h.status = CAM_FUNC_NOTAVAIL;7443 return;7444 }7445 ahc_restart(ahc);7446 ahc_unlock(ahc, &s);7447 }7448 cel = &ccb->cel;7449 target = ccb->ccb_h.target_id;7450 lun = ccb->ccb_h.target_lun;7451 channel = SIM_CHANNEL(ahc, sim);7452 target_mask = 0x01 << target;7453 if (channel == 'B')7454 target_mask <<= 8;7455 7456 if (cel->enable != 0) {7457 u_int scsiseq;7458 7459 /* Are we already enabled?? */7460 if (lstate != NULL) {7461 xpt_print_path(ccb->ccb_h.path);7462 printk("Lun already enabled\n");7463 ccb->ccb_h.status = CAM_LUN_ALRDY_ENA;7464 return;7465 }7466 7467 if (cel->grp6_len != 07468 || cel->grp7_len != 0) {7469 /*7470 * Don't (yet?) support vendor7471 * specific commands.7472 */7473 ccb->ccb_h.status = CAM_REQ_INVALID;7474 printk("Non-zero Group Codes\n");7475 return;7476 }7477 7478 /*7479 * Seems to be okay.7480 * Setup our data structures.7481 */7482 if (target != CAM_TARGET_WILDCARD && tstate == NULL) {7483 tstate = ahc_alloc_tstate(ahc, target, channel);7484 if (tstate == NULL) {7485 xpt_print_path(ccb->ccb_h.path);7486 printk("Couldn't allocate tstate\n");7487 ccb->ccb_h.status = CAM_RESRC_UNAVAIL;7488 return;7489 }7490 }7491 lstate = kzalloc(sizeof(*lstate), GFP_ATOMIC);7492 if (lstate == NULL) {7493 xpt_print_path(ccb->ccb_h.path);7494 printk("Couldn't allocate lstate\n");7495 ccb->ccb_h.status = CAM_RESRC_UNAVAIL;7496 return;7497 }7498 status = xpt_create_path(&lstate->path, /*periph*/NULL,7499 xpt_path_path_id(ccb->ccb_h.path),7500 xpt_path_target_id(ccb->ccb_h.path),7501 xpt_path_lun_id(ccb->ccb_h.path));7502 if (status != CAM_REQ_CMP) {7503 kfree(lstate);7504 xpt_print_path(ccb->ccb_h.path);7505 printk("Couldn't allocate path\n");7506 ccb->ccb_h.status = CAM_RESRC_UNAVAIL;7507 return;7508 }7509 SLIST_INIT(&lstate->accept_tios);7510 SLIST_INIT(&lstate->immed_notifies);7511 ahc_lock(ahc, &s);7512 ahc_pause(ahc);7513 if (target != CAM_TARGET_WILDCARD) {7514 tstate->enabled_luns[lun] = lstate;7515 ahc->enabled_luns++;7516 7517 if ((ahc->features & AHC_MULTI_TID) != 0) {7518 u_int targid_mask;7519 7520 targid_mask = ahc_inb(ahc, TARGID)7521 | (ahc_inb(ahc, TARGID + 1) << 8);7522 7523 targid_mask |= target_mask;7524 ahc_outb(ahc, TARGID, targid_mask);7525 ahc_outb(ahc, TARGID+1, (targid_mask >> 8));7526 ahc_update_scsiid(ahc, targid_mask);7527 } else {7528 u_int our_id;7529 char channel;7530 7531 channel = SIM_CHANNEL(ahc, sim);7532 our_id = SIM_SCSI_ID(ahc, sim);7533 7534 /*7535 * This can only happen if selections7536 * are not enabled7537 */7538 if (target != our_id) {7539 u_int sblkctl;7540 char cur_channel;7541 int swap;7542 7543 sblkctl = ahc_inb(ahc, SBLKCTL);7544 cur_channel = (sblkctl & SELBUSB)7545 ? 'B' : 'A';7546 if ((ahc->features & AHC_TWIN) == 0)7547 cur_channel = 'A';7548 swap = cur_channel != channel;7549 if (channel == 'A')7550 ahc->our_id = target;7551 else7552 ahc->our_id_b = target;7553 7554 if (swap)7555 ahc_outb(ahc, SBLKCTL,7556 sblkctl ^ SELBUSB);7557 7558 ahc_outb(ahc, SCSIID, target);7559 7560 if (swap)7561 ahc_outb(ahc, SBLKCTL, sblkctl);7562 }7563 }7564 } else7565 ahc->black_hole = lstate;7566 /* Allow select-in operations */7567 if (ahc->black_hole != NULL && ahc->enabled_luns > 0) {7568 scsiseq = ahc_inb(ahc, SCSISEQ_TEMPLATE);7569 scsiseq |= ENSELI;7570 ahc_outb(ahc, SCSISEQ_TEMPLATE, scsiseq);7571 scsiseq = ahc_inb(ahc, SCSISEQ);7572 scsiseq |= ENSELI;7573 ahc_outb(ahc, SCSISEQ, scsiseq);7574 }7575 ahc_unpause(ahc);7576 ahc_unlock(ahc, &s);7577 ccb->ccb_h.status = CAM_REQ_CMP;7578 xpt_print_path(ccb->ccb_h.path);7579 printk("Lun now enabled for target mode\n");7580 } else {7581 struct scb *scb;7582 int i, empty;7583 7584 if (lstate == NULL) {7585 ccb->ccb_h.status = CAM_LUN_INVALID;7586 return;7587 }7588 7589 ahc_lock(ahc, &s);7590 7591 ccb->ccb_h.status = CAM_REQ_CMP;7592 LIST_FOREACH(scb, &ahc->pending_scbs, pending_links) {7593 struct ccb_hdr *ccbh;7594 7595 ccbh = &scb->io_ctx->ccb_h;7596 if (ccbh->func_code == XPT_CONT_TARGET_IO7597 && !xpt_path_comp(ccbh->path, ccb->ccb_h.path)){7598 printk("CTIO pending\n");7599 ccb->ccb_h.status = CAM_REQ_INVALID;7600 ahc_unlock(ahc, &s);7601 return;7602 }7603 }7604 7605 if (SLIST_FIRST(&lstate->accept_tios) != NULL) {7606 printk("ATIOs pending\n");7607 ccb->ccb_h.status = CAM_REQ_INVALID;7608 }7609 7610 if (SLIST_FIRST(&lstate->immed_notifies) != NULL) {7611 printk("INOTs pending\n");7612 ccb->ccb_h.status = CAM_REQ_INVALID;7613 }7614 7615 if (ccb->ccb_h.status != CAM_REQ_CMP) {7616 ahc_unlock(ahc, &s);7617 return;7618 }7619 7620 xpt_print_path(ccb->ccb_h.path);7621 printk("Target mode disabled\n");7622 xpt_free_path(lstate->path);7623 kfree(lstate);7624 7625 ahc_pause(ahc);7626 /* Can we clean up the target too? */7627 if (target != CAM_TARGET_WILDCARD) {7628 tstate->enabled_luns[lun] = NULL;7629 ahc->enabled_luns--;7630 for (empty = 1, i = 0; i < 8; i++)7631 if (tstate->enabled_luns[i] != NULL) {7632 empty = 0;7633 break;7634 }7635 7636 if (empty) {7637 ahc_free_tstate(ahc, target, channel,7638 /*force*/FALSE);7639 if (ahc->features & AHC_MULTI_TID) {7640 u_int targid_mask;7641 7642 targid_mask = ahc_inb(ahc, TARGID)7643 | (ahc_inb(ahc, TARGID + 1)7644 << 8);7645 7646 targid_mask &= ~target_mask;7647 ahc_outb(ahc, TARGID, targid_mask);7648 ahc_outb(ahc, TARGID+1,7649 (targid_mask >> 8));7650 ahc_update_scsiid(ahc, targid_mask);7651 }7652 }7653 } else {7654 7655 ahc->black_hole = NULL;7656 7657 /*7658 * We can't allow selections without7659 * our black hole device.7660 */7661 empty = TRUE;7662 }7663 if (ahc->enabled_luns == 0) {7664 /* Disallow select-in */7665 u_int scsiseq;7666 7667 scsiseq = ahc_inb(ahc, SCSISEQ_TEMPLATE);7668 scsiseq &= ~ENSELI;7669 ahc_outb(ahc, SCSISEQ_TEMPLATE, scsiseq);7670 scsiseq = ahc_inb(ahc, SCSISEQ);7671 scsiseq &= ~ENSELI;7672 ahc_outb(ahc, SCSISEQ, scsiseq);7673 7674 if ((ahc->features & AHC_MULTIROLE) == 0) {7675 printk("Configuring Initiator Mode\n");7676 ahc->flags &= ~AHC_TARGETROLE;7677 ahc->flags |= AHC_INITIATORROLE;7678 /*7679 * Returning to a configuration that7680 * fit previously will always succeed.7681 */7682 (void)ahc_loadseq(ahc);7683 ahc_restart(ahc);7684 /*7685 * Unpaused. The extra unpause7686 * that follows is harmless.7687 */7688 }7689 }7690 ahc_unpause(ahc);7691 ahc_unlock(ahc, &s);7692 }7693}7694 7695static void7696ahc_update_scsiid(struct ahc_softc *ahc, u_int targid_mask)7697{7698 u_int scsiid_mask;7699 u_int scsiid;7700 7701 if ((ahc->features & AHC_MULTI_TID) == 0)7702 panic("ahc_update_scsiid called on non-multitid unit\n");7703 7704 /*7705 * Since we will rely on the TARGID mask7706 * for selection enables, ensure that OID7707 * in SCSIID is not set to some other ID7708 * that we don't want to allow selections on.7709 */7710 if ((ahc->features & AHC_ULTRA2) != 0)7711 scsiid = ahc_inb(ahc, SCSIID_ULTRA2);7712 else7713 scsiid = ahc_inb(ahc, SCSIID);7714 scsiid_mask = 0x1 << (scsiid & OID);7715 if ((targid_mask & scsiid_mask) == 0) {7716 u_int our_id;7717 7718 /* ffs counts from 1 */7719 our_id = ffs(targid_mask);7720 if (our_id == 0)7721 our_id = ahc->our_id;7722 else7723 our_id--;7724 scsiid &= TID;7725 scsiid |= our_id;7726 }7727 if ((ahc->features & AHC_ULTRA2) != 0)7728 ahc_outb(ahc, SCSIID_ULTRA2, scsiid);7729 else7730 ahc_outb(ahc, SCSIID, scsiid);7731}7732 7733static void7734ahc_run_tqinfifo(struct ahc_softc *ahc, int paused)7735{7736 struct target_cmd *cmd;7737 7738 /*7739 * If the card supports auto-access pause,7740 * we can access the card directly regardless7741 * of whether it is paused or not.7742 */7743 if ((ahc->features & AHC_AUTOPAUSE) != 0)7744 paused = TRUE;7745 7746 ahc_sync_tqinfifo(ahc, BUS_DMASYNC_POSTREAD);7747 while ((cmd = &ahc->targetcmds[ahc->tqinfifonext])->cmd_valid != 0) {7748 7749 /*7750 * Only advance through the queue if we7751 * have the resources to process the command.7752 */7753 if (ahc_handle_target_cmd(ahc, cmd) != 0)7754 break;7755 7756 cmd->cmd_valid = 0;7757 ahc_dmamap_sync(ahc, ahc->shared_data_dmat,7758 ahc->shared_data_dmamap,7759 ahc_targetcmd_offset(ahc, ahc->tqinfifonext),7760 sizeof(struct target_cmd),7761 BUS_DMASYNC_PREREAD);7762 ahc->tqinfifonext++;7763 7764 /*7765 * Lazily update our position in the target mode incoming7766 * command queue as seen by the sequencer.7767 */7768 if ((ahc->tqinfifonext & (HOST_TQINPOS - 1)) == 1) {7769 if ((ahc->features & AHC_HS_MAILBOX) != 0) {7770 u_int hs_mailbox;7771 7772 hs_mailbox = ahc_inb(ahc, HS_MAILBOX);7773 hs_mailbox &= ~HOST_TQINPOS;7774 hs_mailbox |= ahc->tqinfifonext & HOST_TQINPOS;7775 ahc_outb(ahc, HS_MAILBOX, hs_mailbox);7776 } else {7777 if (!paused)7778 ahc_pause(ahc);7779 ahc_outb(ahc, KERNEL_TQINPOS,7780 ahc->tqinfifonext & HOST_TQINPOS);7781 if (!paused)7782 ahc_unpause(ahc);7783 }7784 }7785 }7786}7787 7788static int7789ahc_handle_target_cmd(struct ahc_softc *ahc, struct target_cmd *cmd)7790{7791 struct ahc_tmode_tstate *tstate;7792 struct ahc_tmode_lstate *lstate;7793 struct ccb_accept_tio *atio;7794 uint8_t *byte;7795 int initiator;7796 int target;7797 int lun;7798 7799 initiator = SCSIID_TARGET(ahc, cmd->scsiid);7800 target = SCSIID_OUR_ID(cmd->scsiid);7801 lun = (cmd->identify & MSG_IDENTIFY_LUNMASK);7802 7803 byte = cmd->bytes;7804 tstate = ahc->enabled_targets[target];7805 lstate = NULL;7806 if (tstate != NULL)7807 lstate = tstate->enabled_luns[lun];7808 7809 /*7810 * Commands for disabled luns go to the black hole driver.7811 */7812 if (lstate == NULL)7813 lstate = ahc->black_hole;7814 7815 atio = (struct ccb_accept_tio*)SLIST_FIRST(&lstate->accept_tios);7816 if (atio == NULL) {7817 ahc->flags |= AHC_TQINFIFO_BLOCKED;7818 /*7819 * Wait for more ATIOs from the peripheral driver for this lun.7820 */7821 if (bootverbose)7822 printk("%s: ATIOs exhausted\n", ahc_name(ahc));7823 return (1);7824 } else7825 ahc->flags &= ~AHC_TQINFIFO_BLOCKED;7826#if 07827 printk("Incoming command from %d for %d:%d%s\n",7828 initiator, target, lun,7829 lstate == ahc->black_hole ? "(Black Holed)" : "");7830#endif7831 SLIST_REMOVE_HEAD(&lstate->accept_tios, sim_links.sle);7832 7833 if (lstate == ahc->black_hole) {7834 /* Fill in the wildcards */7835 atio->ccb_h.target_id = target;7836 atio->ccb_h.target_lun = lun;7837 }7838 7839 /*7840 * Package it up and send it off to7841 * whomever has this lun enabled.7842 */7843 atio->sense_len = 0;7844 atio->init_id = initiator;7845 if (byte[0] != 0xFF) {7846 /* Tag was included */7847 atio->tag_action = *byte++;7848 atio->tag_id = *byte++;7849 atio->ccb_h.flags = CAM_TAG_ACTION_VALID;7850 } else {7851 atio->ccb_h.flags = 0;7852 }7853 byte++;7854 7855 /* Okay. Now determine the cdb size based on the command code */7856 switch (*byte >> CMD_GROUP_CODE_SHIFT) {7857 case 0:7858 atio->cdb_len = 6;7859 break;7860 case 1:7861 case 2:7862 atio->cdb_len = 10;7863 break;7864 case 4:7865 atio->cdb_len = 16;7866 break;7867 case 5:7868 atio->cdb_len = 12;7869 break;7870 case 3:7871 default:7872 /* Only copy the opcode. */7873 atio->cdb_len = 1;7874 printk("Reserved or VU command code type encountered\n");7875 break;7876 }7877 7878 memcpy(atio->cdb_io.cdb_bytes, byte, atio->cdb_len);7879 7880 atio->ccb_h.status |= CAM_CDB_RECVD;7881 7882 if ((cmd->identify & MSG_IDENTIFY_DISCFLAG) == 0) {7883 /*7884 * We weren't allowed to disconnect.7885 * We're hanging on the bus until a7886 * continue target I/O comes in response7887 * to this accept tio.7888 */7889#if 07890 printk("Received Immediate Command %d:%d:%d - %p\n",7891 initiator, target, lun, ahc->pending_device);7892#endif7893 ahc->pending_device = lstate;7894 ahc_freeze_ccb((union ccb *)atio);7895 atio->ccb_h.flags |= CAM_DIS_DISCONNECT;7896 }7897 xpt_done((union ccb*)atio);7898 return (0);7899}7900 7901#endif7902