1 /*        $NetBSD: aic79xx.c,v 1.70 2024/02/02 22:39:10 andvar Exp $  */
2 
3 /*
4  * Core routines and tables shareable across OS platforms.
5  *
6  * Copyright (c) 1994-2002 Justin T. Gibbs.
7  * Copyright (c) 2000-2003 Adaptec Inc.
8  * All rights reserved.
9  *
10  * Redistribution and use in source and binary forms, with or without
11  * modification, are permitted provided that the following conditions
12  * are met:
13  * 1. Redistributions of source code must retain the above copyright
14  *    notice, this list of conditions, and the following disclaimer,
15  *    without modification.
16  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
17  *    substantially similar to the "NO WARRANTY" disclaimer below
18  *    ("Disclaimer") and any redistribution must be conditioned upon
19  *    including a substantially similar Disclaimer requirement for further
20  *    binary redistribution.
21  * 3. Neither the names of the above-listed copyright holders nor the names
22  *    of any contributors may be used to endorse or promote products derived
23  *    from this software without specific prior written permission.
24  *
25  * Alternatively, this software may be distributed under the terms of the
26  * GNU General Public License ("GPL") version 2 as published by the Free
27  * Software Foundation.
28  *
29  * NO WARRANTY
30  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
31  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
32  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
33  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
34  * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
35  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
36  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
37  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
38  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
39  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
40  * POSSIBILITY OF SUCH DAMAGES.
41  *
42  * Id: //depot/aic7xxx/aic7xxx/aic79xx.c#202 $
43  *
44  * $FreeBSD: src/sys/dev/aic7xxx/aic79xx.c,v 1.24 2003/06/28 04:46:54 gibbs Exp $
45  */
46 /*
47  * Ported from FreeBSD by Pascal Renauld, Network Storage Solutions, Inc.
48  * - April 2003
49  */
50 
51 #include <sys/cdefs.h>
52 __KERNEL_RCSID(0, "$NetBSD: aic79xx.c,v 1.70 2024/02/02 22:39:10 andvar Exp $");
53 
54 #include <dev/ic/aic79xx_osm.h>
55 #include <dev/ic/aic79xx_inline.h>
56 #include <dev/ic/aic7xxx_cam.h>
57 
58 #include <dev/microcode/aic7xxx/aicasm.h>
59 #include <dev/microcode/aic7xxx/aicasm_insformat.h>
60 
61 
62 /******************************** Globals *************************************/
63 struct ahd_softc_tailq ahd_tailq = TAILQ_HEAD_INITIALIZER(ahd_tailq);
64 
65 /***************************** Lookup Tables **********************************/
66 const char * const ahd_chip_names[] =
67 {
68           "NONE",
69           "aic7901",
70           "aic7902",
71           "aic7901A"
72 };
73 
74 /*
75  * Hardware error codes.
76  */
77 struct ahd_hard_error_entry {
78           uint8_t errno;
79           const char *errmesg;
80 };
81 
82 static struct ahd_hard_error_entry ahd_hard_errors[] = {
83           { DSCTMOUT,         "Discard Timer has timed out" },
84           { ILLOPCODE,        "Illegal Opcode in sequencer program" },
85           { SQPARERR,         "Sequencer Parity Error" },
86           { DPARERR,          "Data-path Parity Error" },
87           { MPARERR,          "Scratch or SCB Memory Parity Error" },
88           { CIOPARERR,        "CIOBUS Parity Error" },
89 };
90 static const u_int num_errors = NUM_ELEMENTS(ahd_hard_errors);
91 
92 static struct ahd_phase_table_entry ahd_phase_table[] =
93 {
94           { P_DATAOUT,        MSG_NOOP,           "in Data-out phase" },
95           { P_DATAIN,         MSG_INITIATOR_DET_ERR,        "in Data-in phase"  },
96           { P_DATAOUT_DT,     MSG_NOOP,           "in DT Data-out phase"        },
97           { P_DATAIN_DT,      MSG_INITIATOR_DET_ERR,        "in DT Data-in phase"         },
98           { P_COMMAND,        MSG_NOOP,           "in Command phase"  },
99           { P_MESGOUT,        MSG_NOOP,           "in Message-out phase"        },
100           { P_STATUS,         MSG_INITIATOR_DET_ERR,        "in Status phase"   },
101           { P_MESGIN,         MSG_PARITY_ERROR,   "in Message-in phase"         },
102           { P_BUSFREE,        MSG_NOOP,           "while idle"                  },
103           { 0,                MSG_NOOP,           "in unknown phase"  }
104 };
105 
106 /*
107  * In most cases we only wish to iterate over real phases, so
108  * exclude the last element from the count.
109  */
110 static const u_int num_phases = NUM_ELEMENTS(ahd_phase_table) - 1;
111 
112 /* Our Sequencer Program */
113 #include <dev/microcode/aic7xxx/aic79xx_seq.h>
114 
115 /**************************** Function Declarations ***************************/
116 static void                   ahd_handle_transmission_error(struct ahd_softc *ahd);
117 static void                   ahd_handle_lqiphase_error(struct ahd_softc *ahd,
118                                                               u_int lqistat1);
119 static int                    ahd_handle_pkt_busfree(struct ahd_softc *ahd,
120                                                          u_int busfreetime);
121 static int                    ahd_handle_nonpkt_busfree(struct ahd_softc *ahd);
122 static void                   ahd_handle_proto_violation(struct ahd_softc *ahd);
123 static void                   ahd_force_renegotiation(struct ahd_softc *ahd,
124                                                             struct ahd_devinfo *devinfo);
125 
126 static struct ahd_tmode_tstate*
127                               ahd_alloc_tstate(struct ahd_softc *ahd,
128                                                    u_int scsi_id, char channel);
129 #ifdef AHD_TARGET_MODE
130 static void                   ahd_free_tstate(struct ahd_softc *ahd,
131                                                   u_int scsi_id, char channel, int force);
132 #endif
133 static void                   ahd_devlimited_syncrate(struct ahd_softc *ahd,
134                                                           struct ahd_initiator_tinfo *,
135                                                             u_int *period,
136                                                             u_int *ppr_options,
137                                                             role_t role);
138 static void                   ahd_update_neg_table(struct ahd_softc *ahd,
139                                                        struct ahd_devinfo *devinfo,
140                                                        struct ahd_transinfo *tinfo);
141 static void                   ahd_update_pending_scbs(struct ahd_softc *ahd);
142 static void                   ahd_fetch_devinfo(struct ahd_softc *ahd,
143                                                     struct ahd_devinfo *devinfo);
144 static void                   ahd_scb_devinfo(struct ahd_softc *ahd,
145                                                   struct ahd_devinfo *devinfo,
146                                                   struct scb *scb);
147 static void                   ahd_setup_initiator_msgout(struct ahd_softc *ahd,
148                                                                struct ahd_devinfo *devinfo,
149                                                                struct scb *scb);
150 static void                   ahd_build_transfer_msg(struct ahd_softc *ahd,
151                                                          struct ahd_devinfo *devinfo);
152 static void                   ahd_construct_sdtr(struct ahd_softc *ahd,
153                                                      struct ahd_devinfo *devinfo,
154                                                      u_int period, u_int offset);
155 static void                   ahd_construct_wdtr(struct ahd_softc *ahd,
156                                                      struct ahd_devinfo *devinfo,
157                                                      u_int bus_width);
158 static void                   ahd_construct_ppr(struct ahd_softc *ahd,
159                                                     struct ahd_devinfo *devinfo,
160                                                     u_int period, u_int offset,
161                                                     u_int bus_width, u_int ppr_options);
162 static void                   ahd_clear_msg_state(struct ahd_softc *ahd);
163 static void                   ahd_handle_message_phase(struct ahd_softc *ahd);
164 typedef enum {
165           AHDMSG_1B,
166           AHDMSG_2B,
167           AHDMSG_EXT
168 } ahd_msgtype;
169 static int                    ahd_sent_msg(struct ahd_softc *ahd, ahd_msgtype type,
170                                              u_int msgval, int full);
171 static int                    ahd_parse_msg(struct ahd_softc *ahd,
172                                               struct ahd_devinfo *devinfo);
173 static int                    ahd_handle_msg_reject(struct ahd_softc *ahd,
174                                                         struct ahd_devinfo *devinfo);
175 static void                   ahd_handle_ign_wide_residue(struct ahd_softc *ahd,
176                                                             struct ahd_devinfo *devinfo);
177 static void                   ahd_reinitialize_dataptrs(struct ahd_softc *ahd);
178 static void                   ahd_handle_devreset(struct ahd_softc *ahd,
179                                                       struct ahd_devinfo *devinfo,
180                                                       u_int lun, cam_status status,
181                                                       const char *message,
182                                                       int verbose_level);
183 #if AHD_TARGET_MODE
184 static void                   ahd_setup_target_msgin(struct ahd_softc *ahd,
185                                                          struct ahd_devinfo *devinfo,
186                                                          struct scb *scb);
187 #endif
188 
189 static u_int                  ahd_sglist_size(struct ahd_softc *ahd);
190 static u_int                  ahd_sglist_allocsize(struct ahd_softc *ahd);
191 static void                   ahd_initialize_hscbs(struct ahd_softc *ahd);
192 static int                    ahd_init_scbdata(struct ahd_softc *ahd);
193 static void                   ahd_fini_scbdata(struct ahd_softc *ahd);
194 static void                   ahd_setup_iocell_workaround(struct ahd_softc *ahd);
195 static void                   ahd_iocell_first_selection(struct ahd_softc *ahd);
196 static void                   ahd_add_col_list(struct ahd_softc *ahd,
197                                                    struct scb *scb, u_int col_idx);
198 static void                   ahd_rem_col_list(struct ahd_softc *ahd,
199                                                    struct scb *scb);
200 static void                   ahd_chip_init(struct ahd_softc *ahd);
201 static void                   ahd_qinfifo_requeue(struct ahd_softc *ahd,
202                                                       struct scb *prev_scb,
203                                                       struct scb *scb);
204 static int                    ahd_qinfifo_count(struct ahd_softc *ahd);
205 static int                    ahd_search_scb_list(struct ahd_softc *ahd, int target,
206                                                       char channel, int lun, u_int tag,
207                                                       role_t role, uint32_t status,
208                                                       ahd_search_action action,
209                                                       u_int *list_head, u_int tid);
210 static void                   ahd_stitch_tid_list(struct ahd_softc *ahd,
211                                                       u_int tid_prev, u_int tid_cur,
212                                                       u_int tid_next);
213 static void                   ahd_add_scb_to_free_list(struct ahd_softc *ahd,
214                                                              u_int scbid);
215 static u_int                  ahd_rem_wscb(struct ahd_softc *ahd, u_int scbid,
216                                              u_int prev, u_int next, u_int tid);
217 static void                   ahd_reset_current_bus(struct ahd_softc *ahd);
218 static ahd_callback_t         ahd_reset_poll;
219 static ahd_callback_t         ahd_stat_timer;
220 #ifdef AHD_DUMP_SEQ
221 static void                   ahd_dumpseq(struct ahd_softc *ahd);
222 #endif
223 static void                   ahd_loadseq(struct ahd_softc *ahd);
224 static int                    ahd_check_patch(struct ahd_softc *ahd,
225                                                   const struct patch **start_patch,
226                                                   u_int start_instr, u_int *skip_addr);
227 static u_int                  ahd_resolve_seqaddr(struct ahd_softc *ahd,
228                                                       u_int address);
229 static void                   ahd_download_instr(struct ahd_softc *ahd,
230                                                      u_int instrptr, uint8_t *dconsts);
231 static int                    ahd_probe_stack_size(struct ahd_softc *ahd);
232 static int                    ahd_scb_active_in_fifo(struct ahd_softc *ahd,
233                                                          struct scb *scb);
234 static void                   ahd_run_data_fifo(struct ahd_softc *ahd,
235                                                     struct scb *scb);
236 
237 #ifdef AHD_TARGET_MODE
238 static void                   ahd_queue_lstate_event(struct ahd_softc *ahd,
239                                                          struct ahd_tmode_lstate *lstate,
240                                                          u_int initiator_id,
241                                                          u_int event_type,
242                                                          u_int event_arg);
243 static void                   ahd_update_scsiid(struct ahd_softc *ahd,
244                                                     u_int targid_mask);
245 static int                    ahd_handle_target_cmd(struct ahd_softc *ahd,
246                                                         struct target_cmd *cmd);
247 #endif
248 
249 /************************** Added for porting to NetBSD ***********************/
250 static int ahd_createdmamem(bus_dma_tag_t tag,
251                                   int size,
252                                   int flags,
253                                   bus_dmamap_t *mapp,
254                                   void **vaddr,
255                                   bus_addr_t *baddr,
256                                   bus_dma_segment_t *seg,
257                                   int *nseg,
258                                   const char *myname, const char *what);
259 
260 static void ahd_freedmamem(bus_dma_tag_t tag,
261                                  int size,
262                                  bus_dmamap_t map,
263                                  void *vaddr,
264                                  bus_dma_segment_t *seg,
265                                  int nseg);
266 
267 /******************************** Private Inlines *****************************/
268 static inline void  ahd_assert_atn(struct ahd_softc *ahd);
269 static inline int   ahd_currently_packetized(struct ahd_softc *ahd);
270 static inline int   ahd_set_active_fifo(struct ahd_softc *ahd);
271 
272 static inline void
ahd_assert_atn(struct ahd_softc * ahd)273 ahd_assert_atn(struct ahd_softc *ahd)
274 {
275           ahd_outb(ahd, SCSISIGO, ATNO);
276 }
277 
278 /*
279  * Determine if the current connection has a packetized
280  * agreement.  This does not necessarily mean that we
281  * are currently in a packetized transfer.  We could
282  * just as easily be sending or receiving a message.
283  */
284 static inline int
ahd_currently_packetized(struct ahd_softc * ahd)285 ahd_currently_packetized(struct ahd_softc *ahd)
286 {
287           ahd_mode_state       saved_modes;
288           int                  packetized;
289 
290           saved_modes = ahd_save_modes(ahd);
291           if ((ahd->bugs & AHD_PKTIZED_STATUS_BUG) != 0) {
292                     /*
293                      * The packetized bit refers to the last
294                      * connection, not the current one.  Check
295                      * for non-zero LQISTATE instead.
296                      */
297                     ahd_set_modes(ahd, AHD_MODE_CFG, AHD_MODE_CFG);
298                     packetized = ahd_inb(ahd, LQISTATE) != 0;
299           } else {
300                     ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI);
301                     packetized = ahd_inb(ahd, LQISTAT2) & PACKETIZED;
302           }
303           ahd_restore_modes(ahd, saved_modes);
304           return (packetized);
305 }
306 
307 static inline int
ahd_set_active_fifo(struct ahd_softc * ahd)308 ahd_set_active_fifo(struct ahd_softc *ahd)
309 {
310           u_int active_fifo;
311 
312           AHD_ASSERT_MODES(ahd, AHD_MODE_SCSI_MSK, AHD_MODE_SCSI_MSK);
313           active_fifo = ahd_inb(ahd, DFFSTAT) & CURRFIFO;
314           switch (active_fifo) {
315           case 0:
316           case 1:
317                     ahd_set_modes(ahd, active_fifo, active_fifo);
318                     return (1);
319           default:
320                     return (0);
321           }
322 }
323 
324 /************************* Sequencer Execution Control ************************/
325 /*
326  * Restart the sequencer program from address zero
327  */
328 void
ahd_restart(struct ahd_softc * ahd)329 ahd_restart(struct ahd_softc *ahd)
330 {
331 
332           ahd_pause(ahd);
333 
334           ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI);
335 
336           /* No more pending messages */
337           ahd_clear_msg_state(ahd);
338           ahd_outb(ahd, SCSISIGO, 0);             /* De-assert BSY */
339           ahd_outb(ahd, MSG_OUT, MSG_NOOP);       /* No message to send */
340           ahd_outb(ahd, SXFRCTL1, ahd_inb(ahd, SXFRCTL1) & ~BITBUCKET);
341           ahd_outb(ahd, SEQINTCTL, 0);
342           ahd_outb(ahd, LASTPHASE, P_BUSFREE);
343           ahd_outb(ahd, SEQ_FLAGS, 0);
344           ahd_outb(ahd, SAVED_SCSIID, 0xFF);
345           ahd_outb(ahd, SAVED_LUN, 0xFF);
346 
347           /*
348            * Ensure that the sequencer's idea of TQINPOS
349            * matches our own.  The sequencer increments TQINPOS
350            * only after it sees a DMA complete and a reset could
351            * occur before the increment leaving the kernel to believe
352            * the command arrived but the sequencer to not.
353            */
354           ahd_outb(ahd, TQINPOS, ahd->tqinfifonext);
355 
356           /* Always allow reselection */
357           ahd_outb(ahd, SCSISEQ1,
358                      ahd_inb(ahd, SCSISEQ_TEMPLATE) & (ENSELI|ENRSELI|ENAUTOATNP));
359           ahd_set_modes(ahd, AHD_MODE_CCHAN, AHD_MODE_CCHAN);
360           ahd_outb(ahd, SEQCTL0, FASTMODE|SEQRESET);
361           ahd_unpause(ahd);
362 }
363 
364 void
ahd_clear_fifo(struct ahd_softc * ahd,u_int fifo)365 ahd_clear_fifo(struct ahd_softc *ahd, u_int fifo)
366 {
367           ahd_mode_state       saved_modes;
368 
369 #ifdef AHD_DEBUG
370           if ((ahd_debug & AHD_SHOW_FIFOS) != 0)
371                     printf("%s: Clearing FIFO %d\n", ahd_name(ahd), fifo);
372 #endif
373           saved_modes = ahd_save_modes(ahd);
374           ahd_set_modes(ahd, fifo, fifo);
375           ahd_outb(ahd, DFFSXFRCTL, RSTCHN|CLRSHCNT);
376           if ((ahd_inb(ahd, SG_STATE) & FETCH_INPROG) != 0)
377                     ahd_outb(ahd, CCSGCTL, CCSGRESET);
378           ahd_outb(ahd, LONGJMP_ADDR + 1, INVALID_ADDR);
379           ahd_outb(ahd, SG_STATE, 0);
380           ahd_restore_modes(ahd, saved_modes);
381 }
382 
383 /************************* Input/Output Queues ********************************/
384 /*
385  * Flush and completed commands that are sitting in the command
386  * complete queues down on the chip but have yet to be DMA'ed back up.
387  */
388 void
ahd_flush_qoutfifo(struct ahd_softc * ahd)389 ahd_flush_qoutfifo(struct ahd_softc *ahd)
390 {
391           struct              scb *scb;
392           ahd_mode_state      saved_modes;
393           u_int               saved_scbptr;
394           u_int               ccscbctl;
395           u_int               scbid;
396           u_int               next_scbid;
397 
398           saved_modes = ahd_save_modes(ahd);
399 
400           /*
401            * Complete any SCBs that just finished being
402            * DMA'ed into the qoutfifo.
403            */
404           ahd_run_qoutfifo(ahd);
405 
406           /*
407            * Flush the good status FIFO for completed packetized commands.
408            */
409           ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI);
410           saved_scbptr = ahd_get_scbptr(ahd);
411           while ((ahd_inb(ahd, LQISTAT2) & LQIGSAVAIL) != 0) {
412                     u_int fifo_mode;
413                     u_int i;
414 
415                     scbid = (ahd_inb(ahd, GSFIFO+1) << 8)
416                           | ahd_inb(ahd, GSFIFO);
417                     scb = ahd_lookup_scb(ahd, scbid);
418                     if (scb == NULL) {
419                               printf("%s: Warning - GSFIFO SCB %d invalid\n",
420                                      ahd_name(ahd), scbid);
421                               continue;
422                     }
423                     /*
424                      * Determine if this transaction is still active in
425                      * any FIFO.  If it is, we must flush that FIFO to
426                      * the host before completing the  command.
427                      */
428                     fifo_mode = 0;
429                     for (i = 0; i < 2; i++) {
430                               /* Toggle to the other mode. */
431                               fifo_mode ^= 1;
432                               ahd_set_modes(ahd, fifo_mode, fifo_mode);
433                               if (ahd_scb_active_in_fifo(ahd, scb) == 0)
434                                         continue;
435 
436                               ahd_run_data_fifo(ahd, scb);
437 
438                               /*
439                                * Clearing this transaction in this FIFO may
440                                * cause a CFG4DATA for this same transaction
441                                * to assert in the other FIFO.  Make sure we
442                                * loop one more time and check the other FIFO.
443                                */
444                               i = 0;
445                     }
446                     ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI);
447                     ahd_set_scbptr(ahd, scbid);
448                     if ((ahd_inb_scbram(ahd, SCB_SGPTR) & SG_LIST_NULL) == 0
449                      && ((ahd_inb_scbram(ahd, SCB_SGPTR) & SG_FULL_RESID) != 0
450                       || (ahd_inb_scbram(ahd, SCB_RESIDUAL_SGPTR)
451                           & SG_LIST_NULL) != 0)) {
452                               u_int comp_head;
453 
454                               /*
455                                * The transfer completed with a residual.
456                                * Place this SCB on the complete DMA list
457                                * so that we Update our in-core copy of the
458                                * SCB before completing the command.
459                                */
460                               ahd_outb(ahd, SCB_SCSI_STATUS, 0);
461                               ahd_outb(ahd, SCB_SGPTR,
462                                          ahd_inb_scbram(ahd, SCB_SGPTR)
463                                          | SG_STATUS_VALID);
464                               ahd_outw(ahd, SCB_TAG, SCB_GET_TAG(scb));
465                               comp_head = ahd_inw(ahd, COMPLETE_DMA_SCB_HEAD);
466                               ahd_outw(ahd, SCB_NEXT_COMPLETE, comp_head);
467                               if (SCBID_IS_NULL(comp_head))
468                                         ahd_outw(ahd, COMPLETE_DMA_SCB_HEAD,
469                                                    SCB_GET_TAG(scb));
470                     } else
471                               ahd_complete_scb(ahd, scb);
472           }
473           ahd_set_scbptr(ahd, saved_scbptr);
474 
475           /*
476            * Setup for command channel portion of flush.
477            */
478           ahd_set_modes(ahd, AHD_MODE_CCHAN, AHD_MODE_CCHAN);
479 
480           /*
481            * Wait for any inprogress DMA to complete and clear DMA state
482            * if this if for an SCB in the qinfifo.
483            */
484           while (((ccscbctl = ahd_inb(ahd, CCSCBCTL)) & (CCARREN|CCSCBEN)) != 0) {
485 
486                     if ((ccscbctl & (CCSCBDIR|CCARREN)) == (CCSCBDIR|CCARREN)) {
487                               if ((ccscbctl & ARRDONE) != 0)
488                                         break;
489                     } else if ((ccscbctl & CCSCBDONE) != 0)
490                               break;
491                     ahd_delay(200);
492           }
493           if ((ccscbctl & CCSCBDIR) != 0)
494                     ahd_outb(ahd, CCSCBCTL, ccscbctl & ~(CCARREN|CCSCBEN));
495 
496           saved_scbptr = ahd_get_scbptr(ahd);
497           /*
498            * Manually update/complete any completed SCBs that are waiting to be
499            * DMA'ed back up to the host.
500            */
501           scbid = ahd_inw(ahd, COMPLETE_DMA_SCB_HEAD);
502           while (!SCBID_IS_NULL(scbid)) {
503                     uint8_t *hscb_ptr;
504                     u_int      i;
505 
506                     ahd_set_scbptr(ahd, scbid);
507                     next_scbid = ahd_inw_scbram(ahd, SCB_NEXT_COMPLETE);
508                     scb = ahd_lookup_scb(ahd, scbid);
509                     if (scb == NULL) {
510                               printf("%s: Warning - DMA-up and complete "
511                                      "SCB %d invalid\n", ahd_name(ahd), scbid);
512                               continue;
513                     }
514                     hscb_ptr = (uint8_t *)scb->hscb;
515                     for (i = 0; i < sizeof(struct hardware_scb); i++)
516                               *hscb_ptr++ = ahd_inb_scbram(ahd, SCB_BASE + i);
517 
518                     ahd_complete_scb(ahd, scb);
519                     scbid = next_scbid;
520           }
521           ahd_outw(ahd, COMPLETE_DMA_SCB_HEAD, SCB_LIST_NULL);
522 
523           scbid = ahd_inw(ahd, COMPLETE_SCB_HEAD);
524           while (!SCBID_IS_NULL(scbid)) {
525 
526                     ahd_set_scbptr(ahd, scbid);
527                     next_scbid = ahd_inw_scbram(ahd, SCB_NEXT_COMPLETE);
528                     scb = ahd_lookup_scb(ahd, scbid);
529                     if (scb == NULL) {
530                               printf("%s: Warning - Complete SCB %d invalid\n",
531                                      ahd_name(ahd), scbid);
532                               continue;
533                     }
534 
535                     ahd_complete_scb(ahd, scb);
536                     scbid = next_scbid;
537           }
538           ahd_outw(ahd, COMPLETE_SCB_HEAD, SCB_LIST_NULL);
539 
540           /*
541            * Restore state.
542            */
543           ahd_set_scbptr(ahd, saved_scbptr);
544           ahd_restore_modes(ahd, saved_modes);
545           ahd->flags |= AHD_UPDATE_PEND_CMDS;
546 }
547 
548 /*
549  * Determine if an SCB for a packetized transaction
550  * is active in a FIFO.
551  */
552 static int
ahd_scb_active_in_fifo(struct ahd_softc * ahd,struct scb * scb)553 ahd_scb_active_in_fifo(struct ahd_softc *ahd, struct scb *scb)
554 {
555 
556           /*
557            * The FIFO is only active for our transaction if
558            * the SCBPTR matches the SCB's ID and the firmware
559            * has installed a handler for the FIFO or we have
560            * a pending SAVEPTRS or CFG4DATA interrupt.
561            */
562           if (ahd_get_scbptr(ahd) != SCB_GET_TAG(scb)
563            || ((ahd_inb(ahd, LONGJMP_ADDR+1) & INVALID_ADDR) != 0
564             && (ahd_inb(ahd, SEQINTSRC) & (CFG4DATA|SAVEPTRS)) == 0))
565                     return (0);
566 
567           return (1);
568 }
569 
570 /*
571  * Run a data fifo to completion for a transaction we know
572  * has completed across the SCSI bus (good status has been
573  * received).  We are already set to the correct FIFO mode
574  * on entry to this routine.
575  *
576  * This function attempts to operate exactly as the firmware
577  * would when running this FIFO.  Care must be taken to update
578  * this routine any time the firmware's FIFO algorithm is
579  * changed.
580  */
581 static void
ahd_run_data_fifo(struct ahd_softc * ahd,struct scb * scb)582 ahd_run_data_fifo(struct ahd_softc *ahd, struct scb *scb)
583 {
584           u_int seqintsrc;
585 
586           while (1) {
587                     seqintsrc = ahd_inb(ahd, SEQINTSRC);
588                     if ((seqintsrc & CFG4DATA) != 0) {
589                               uint32_t datacnt;
590                               uint32_t sgptr;
591 
592                               /*
593                                * Clear full residual flag.
594                                */
595                               sgptr = ahd_inl_scbram(ahd, SCB_SGPTR) & ~SG_FULL_RESID;
596                               ahd_outb(ahd, SCB_SGPTR, sgptr);
597 
598                               /*
599                                * Load datacnt and address.
600                                */
601                               datacnt = ahd_inl_scbram(ahd, SCB_DATACNT);
602                               if ((datacnt & AHD_DMA_LAST_SEG) != 0) {
603                                         sgptr |= LAST_SEG;
604                                         ahd_outb(ahd, SG_STATE, 0);
605                               } else
606                                         ahd_outb(ahd, SG_STATE, LOADING_NEEDED);
607                               ahd_outq(ahd, HADDR, ahd_inq_scbram(ahd, SCB_DATAPTR));
608                               ahd_outl(ahd, HCNT, datacnt & AHD_SG_LEN_MASK);
609                               ahd_outb(ahd, SG_CACHE_PRE, sgptr);
610                               ahd_outb(ahd, DFCNTRL, PRELOADEN|SCSIEN|HDMAEN);
611 
612                               /*
613                                * Initialize Residual Fields.
614                                */
615                               ahd_outb(ahd, SCB_RESIDUAL_DATACNT+3, datacnt >> 24);
616                               ahd_outl(ahd, SCB_RESIDUAL_SGPTR, sgptr & SG_PTR_MASK);
617 
618                               /*
619                                * Mark the SCB as having a FIFO in use.
620                                */
621                               ahd_outb(ahd, SCB_FIFO_USE_COUNT,
622                                          ahd_inb_scbram(ahd, SCB_FIFO_USE_COUNT) + 1);
623 
624                               /*
625                                * Install a "fake" handler for this FIFO.
626                                */
627                               ahd_outw(ahd, LONGJMP_ADDR, 0);
628 
629                               /*
630                                * Notify the hardware that we have satisfied
631                                * this sequencer interrupt.
632                                */
633                               ahd_outb(ahd, CLRSEQINTSRC, CLRCFG4DATA);
634                     } else if ((seqintsrc & SAVEPTRS) != 0) {
635                               uint32_t sgptr;
636                               uint32_t resid;
637 
638                               if ((ahd_inb(ahd, LONGJMP_ADDR+1)&INVALID_ADDR) != 0) {
639                                         /*
640                                          * Snapshot Save Pointers.  Clear
641                                          * the snapshot and continue.
642                                          */
643                                         ahd_outb(ahd, DFFSXFRCTL, CLRCHN);
644                                         continue;
645                               }
646 
647                               /*
648                                * Disable S/G fetch so the DMA engine
649                                * is available to future users.
650                                */
651                               if ((ahd_inb(ahd, SG_STATE) & FETCH_INPROG) != 0)
652                                         ahd_outb(ahd, CCSGCTL, 0);
653                               ahd_outb(ahd, SG_STATE, 0);
654 
655                               /*
656                                * Flush the data FIFO.  Strictly only
657                                * necessary for Rev A parts.
658                                */
659                               ahd_outb(ahd, DFCNTRL,
660                                          ahd_inb(ahd, DFCNTRL) | FIFOFLUSH);
661 
662                               /*
663                                * Calculate residual.
664                                */
665                               sgptr = ahd_inl_scbram(ahd, SCB_RESIDUAL_SGPTR);
666                               resid = ahd_inl(ahd, SHCNT);
667                               resid |=
668                                   ahd_inb_scbram(ahd, SCB_RESIDUAL_DATACNT+3) << 24;
669                               ahd_outl(ahd, SCB_RESIDUAL_DATACNT, resid);
670                               if ((ahd_inb(ahd, SG_CACHE_SHADOW) & LAST_SEG) == 0) {
671                                         /*
672                                          * Must back up to the correct S/G element.
673                                          * Typically this just means resetting our
674                                          * low byte to the offset in the SG_CACHE,
675                                          * but if we wrapped, we have to correct
676                                          * the other bytes of the sgptr too.
677                                          */
678                                         if ((ahd_inb(ahd, SG_CACHE_SHADOW) & 0x80) != 0
679                                          && (sgptr & 0x80) == 0)
680                                                   sgptr -= 0x100;
681                                         sgptr &= ~0xFF;
682                                         sgptr |= ahd_inb(ahd, SG_CACHE_SHADOW)
683                                                & SG_ADDR_MASK;
684                                         ahd_outl(ahd, SCB_RESIDUAL_SGPTR, sgptr);
685                                         ahd_outb(ahd, SCB_RESIDUAL_DATACNT + 3, 0);
686                               } else if ((resid & AHD_SG_LEN_MASK) == 0) {
687                                         ahd_outb(ahd, SCB_RESIDUAL_SGPTR,
688                                                    sgptr | SG_LIST_NULL);
689                               }
690                               /*
691                                * Save Pointers.
692                                */
693                               ahd_outq(ahd, SCB_DATAPTR, ahd_inq(ahd, SHADDR));
694                               ahd_outl(ahd, SCB_DATACNT, resid);
695                               ahd_outl(ahd, SCB_SGPTR, sgptr);
696                               ahd_outb(ahd, CLRSEQINTSRC, CLRSAVEPTRS);
697                               ahd_outb(ahd, SEQIMODE,
698                                          ahd_inb(ahd, SEQIMODE) | ENSAVEPTRS);
699                               /*
700                                * If the data is to the SCSI bus, we are
701                                * done, otherwise wait for FIFOEMP.
702                                */
703                               if ((ahd_inb(ahd, DFCNTRL) & DIRECTION) != 0)
704                                         break;
705                     } else if ((ahd_inb(ahd, SG_STATE) & LOADING_NEEDED) != 0) {
706                               uint32_t sgptr;
707                               uint64_t data_addr;
708                               uint32_t data_len;
709                               u_int      dfcntrl;
710 
711                               /*
712                                * Disable S/G fetch so the DMA engine
713                                * is available to future users.
714                                */
715                               if ((ahd_inb(ahd, SG_STATE) & FETCH_INPROG) != 0) {
716                                         ahd_outb(ahd, CCSGCTL, 0);
717                                         ahd_outb(ahd, SG_STATE, LOADING_NEEDED);
718                               }
719 
720                               /*
721                                * Wait for the DMA engine to notice that the
722                                * host transfer is enabled and that there is
723                                * space in the S/G FIFO for new segments before
724                                * loading more segments.
725                                */
726                               if ((ahd_inb(ahd, DFSTATUS) & PRELOAD_AVAIL) == 0)
727                                         continue;
728                               if ((ahd_inb(ahd, DFCNTRL) & HDMAENACK) == 0)
729                                         continue;
730 
731                               /*
732                                * Determine the offset of the next S/G
733                                * element to load.
734                                */
735                               sgptr = ahd_inl_scbram(ahd, SCB_RESIDUAL_SGPTR);
736                               sgptr &= SG_PTR_MASK;
737                               if ((ahd->flags & AHD_64BIT_ADDRESSING) != 0) {
738                                         struct ahd_dma64_seg *sg;
739 
740                                         sg = ahd_sg_bus_to_virt(ahd, scb, sgptr);
741                                         data_addr = sg->addr;
742                                         data_len = sg->len;
743                                         sgptr += sizeof(*sg);
744                               } else {
745                                         struct    ahd_dma_seg *sg;
746 
747                                         sg = ahd_sg_bus_to_virt(ahd, scb, sgptr);
748                                         data_addr = sg->len & AHD_SG_HIGH_ADDR_MASK;
749                                         data_addr <<= 8;
750                                         data_addr |= sg->addr;
751                                         data_len = sg->len;
752                                         sgptr += sizeof(*sg);
753                               }
754 
755                               /*
756                                * Update residual information.
757                                */
758                               ahd_outb(ahd, SCB_RESIDUAL_DATACNT+3, data_len >> 24);
759                               ahd_outl(ahd, SCB_RESIDUAL_SGPTR, sgptr);
760 
761                               /*
762                                * Load the S/G.
763                                */
764                               if (data_len & AHD_DMA_LAST_SEG) {
765                                         sgptr |= LAST_SEG;
766                                         ahd_outb(ahd, SG_STATE, 0);
767                               }
768                               ahd_outq(ahd, HADDR, data_addr);
769                               ahd_outl(ahd, HCNT, data_len & AHD_SG_LEN_MASK);
770                               ahd_outb(ahd, SG_CACHE_PRE, sgptr & 0xFF);
771 
772                               /*
773                                * Advertise the segment to the hardware.
774                                */
775                               dfcntrl = ahd_inb(ahd, DFCNTRL)|PRELOADEN|HDMAEN;
776                               if ((ahd->features & AHD_NEW_DFCNTRL_OPTS)!=0) {
777                                         /*
778                                          * Use SCSIENWRDIS so that SCSIEN
779                                          * is never modified by this
780                                          * operation.
781                                          */
782                                         dfcntrl |= SCSIENWRDIS;
783                               }
784                               ahd_outb(ahd, DFCNTRL, dfcntrl);
785                     } else if ((ahd_inb(ahd, SG_CACHE_SHADOW)
786                                & LAST_SEG_DONE) != 0) {
787 
788                               /*
789                                * Transfer completed to the end of SG list
790                                * and has flushed to the host.
791                                */
792                               ahd_outb(ahd, SCB_SGPTR,
793                                          ahd_inb_scbram(ahd, SCB_SGPTR) | SG_LIST_NULL);
794                               break;
795                     } else if ((ahd_inb(ahd, DFSTATUS) & FIFOEMP) != 0) {
796                               break;
797                     }
798                     ahd_delay(200);
799           }
800           /*
801            * Clear any handler for this FIFO, decrement
802            * the FIFO use count for the SCB, and release
803            * the FIFO.
804            */
805           ahd_outb(ahd, LONGJMP_ADDR + 1, INVALID_ADDR);
806           ahd_outb(ahd, SCB_FIFO_USE_COUNT,
807                      ahd_inb_scbram(ahd, SCB_FIFO_USE_COUNT) - 1);
808           ahd_outb(ahd, DFFSXFRCTL, CLRCHN);
809 }
810 
811 void
ahd_run_qoutfifo(struct ahd_softc * ahd)812 ahd_run_qoutfifo(struct ahd_softc *ahd)
813 {
814           struct scb *scb;
815           u_int  scb_index;
816 
817           if ((ahd->flags & AHD_RUNNING_QOUTFIFO) != 0)
818                     panic("ahd_run_qoutfifo recursion");
819           ahd->flags |= AHD_RUNNING_QOUTFIFO;
820           ahd_sync_qoutfifo(ahd, BUS_DMASYNC_POSTREAD);
821           while ((ahd->qoutfifo[ahd->qoutfifonext]
822                & QOUTFIFO_ENTRY_VALID_LE) == ahd->qoutfifonext_valid_tag) {
823 
824                     scb_index = ahd_le16toh(ahd->qoutfifo[ahd->qoutfifonext]
825                                               & ~QOUTFIFO_ENTRY_VALID_LE);
826                     scb = ahd_lookup_scb(ahd, scb_index);
827                     if (scb == NULL) {
828                               printf("%s: WARNING no command for scb %d "
829                                      "(cmdcmplt)\nQOUTPOS = %d\n",
830                                      ahd_name(ahd), scb_index,
831                                      ahd->qoutfifonext);
832                               ahd_dump_card_state(ahd);
833                     } else
834                               ahd_complete_scb(ahd, scb);
835 
836                     ahd->qoutfifonext = (ahd->qoutfifonext+1) & (AHD_QOUT_SIZE-1);
837                     if (ahd->qoutfifonext == 0)
838                               ahd->qoutfifonext_valid_tag ^= QOUTFIFO_ENTRY_VALID_LE;
839           }
840           ahd->flags &= ~AHD_RUNNING_QOUTFIFO;
841 }
842 
843 /************************* Interrupt Handling *********************************/
844 void
ahd_handle_hwerrint(struct ahd_softc * ahd)845 ahd_handle_hwerrint(struct ahd_softc *ahd)
846 {
847           /*
848            * Some catastrophic hardware error has occurred.
849            * Print it for the user and disable the controller.
850            */
851           int i;
852           int error;
853 
854           error = ahd_inb(ahd, ERROR);
855           for (i = 0; i < num_errors; i++) {
856                     if ((error & ahd_hard_errors[i].errno) != 0)
857                               printf("%s: hwerrint, %s\n",
858                                      ahd_name(ahd), ahd_hard_errors[i].errmesg);
859           }
860 
861           ahd_dump_card_state(ahd);
862           panic("BRKADRINT");
863 
864           /* Tell everyone that this HBA is no longer available */
865           ahd_abort_scbs(ahd, CAM_TARGET_WILDCARD, ALL_CHANNELS,
866                            CAM_LUN_WILDCARD, SCB_LIST_NULL, ROLE_UNKNOWN,
867                            CAM_NO_HBA);
868 
869           /* Tell the system that this controller has gone away. */
870           ahd_free(ahd);
871 }
872 
873 void
ahd_handle_seqint(struct ahd_softc * ahd,u_int intstat)874 ahd_handle_seqint(struct ahd_softc *ahd, u_int intstat)
875 {
876           u_int seqintcode;
877 
878           /*
879            * Save the sequencer interrupt code and clear the SEQINT
880            * bit. We will unpause the sequencer, if appropriate,
881            * after servicing the request.
882            */
883           seqintcode = ahd_inb(ahd, SEQINTCODE);
884           ahd_outb(ahd, CLRINT, CLRSEQINT);
885           if ((ahd->bugs & AHD_INTCOLLISION_BUG) != 0) {
886                     /*
887                      * Unpause the sequencer and let it clear
888                      * SEQINT by writing NO_SEQINT to it.  This
889                      * will cause the sequencer to be paused again,
890                      * which is the expected state of this routine.
891                      */
892                     ahd_unpause(ahd);
893                     while (!ahd_is_paused(ahd))
894                               ;
895                     ahd_outb(ahd, CLRINT, CLRSEQINT);
896           }
897           ahd_update_modes(ahd);
898 #ifdef AHD_DEBUG
899           if ((ahd_debug & AHD_SHOW_MISC) != 0)
900                     printf("%s: Handle Seqint Called for code %d\n",
901                            ahd_name(ahd), seqintcode);
902 #endif
903           switch (seqintcode) {
904           case BAD_SCB_STATUS:
905           {
906                     struct    scb *scb;
907                     u_int     scbid;
908                     int       cmds_pending;
909 
910                     scbid = ahd_get_scbptr(ahd);
911                     scb = ahd_lookup_scb(ahd, scbid);
912                     if (scb != NULL) {
913                               ahd_complete_scb(ahd, scb);
914                     } else {
915                               printf("%s: WARNING no command for scb %d "
916                                      "(bad status)\n", ahd_name(ahd), scbid);
917                               ahd_dump_card_state(ahd);
918                     }
919                     cmds_pending = ahd_inw(ahd, CMDS_PENDING);
920                     if (cmds_pending > 0)
921                               ahd_outw(ahd, CMDS_PENDING, cmds_pending - 1);
922                     break;
923           }
924           case ENTERING_NONPACK:
925           {
926                     struct    scb *scb;
927                     u_int     scbid;
928 
929                     AHD_ASSERT_MODES(ahd, ~(AHD_MODE_UNKNOWN_MSK|AHD_MODE_CFG_MSK),
930                                          ~(AHD_MODE_UNKNOWN_MSK|AHD_MODE_CFG_MSK));
931                     scbid = ahd_get_scbptr(ahd);
932                     scb = ahd_lookup_scb(ahd, scbid);
933                     if (scb == NULL) {
934                               /*
935                                * Somehow need to know if this
936                                * is from a selection or reselection.
937                                * From that, we can determine target
938                                * ID so we at least have an I_T nexus.
939                                */
940                     } else {
941                               ahd_outb(ahd, SAVED_SCSIID, scb->hscb->scsiid);
942                               ahd_outb(ahd, SAVED_LUN, scb->hscb->lun);
943                               ahd_outb(ahd, SEQ_FLAGS, 0x0);
944                     }
945                     if ((ahd_inb(ahd, LQISTAT2) & LQIPHASE_OUTPKT) != 0
946                      && (ahd_inb(ahd, SCSISIGO) & ATNO) != 0) {
947                               /*
948                                * Phase change after read stream with
949                                * CRC error with P0 asserted on last
950                                * packet.
951                                */
952 #ifdef AHD_DEBUG
953                               if ((ahd_debug & AHD_SHOW_RECOVERY) != 0)
954                                         printf("%s: Assuming LQIPHASE_NLQ with "
955                                                "P0 assertion\n", ahd_name(ahd));
956 #endif
957                     }
958 #ifdef AHD_DEBUG
959                     if ((ahd_debug & AHD_SHOW_RECOVERY) != 0)
960                               printf("%s: Entering NONPACK\n", ahd_name(ahd));
961 #endif
962                     break;
963           }
964           case INVALID_SEQINT:
965                     printf("%s: Invalid Sequencer interrupt occurred.\n",
966                            ahd_name(ahd));
967                     ahd_dump_card_state(ahd);
968                     ahd_reset_channel(ahd, 'A', /*Initiate Reset*/TRUE);
969                     break;
970           case STATUS_OVERRUN:
971           {
972                     struct    scb *scb;
973                     u_int     scbid;
974 
975                     scbid = ahd_get_scbptr(ahd);
976                     scb = ahd_lookup_scb(ahd, scbid);
977                     if (scb != NULL)
978                               ahd_print_path(ahd, scb);
979                     else
980                               printf("%s: ", ahd_name(ahd));
981                     printf("SCB %d Packetized Status Overrun", scbid);
982                     ahd_dump_card_state(ahd);
983                     ahd_reset_channel(ahd, 'A', /*Initiate Reset*/TRUE);
984                     break;
985           }
986           case CFG4ISTAT_INTR:
987           {
988                     struct    scb *scb;
989                     u_int     scbid;
990 
991                     scbid = ahd_get_scbptr(ahd);
992                     scb = ahd_lookup_scb(ahd, scbid);
993                     if (scb == NULL) {
994                               ahd_dump_card_state(ahd);
995                               printf("CFG4ISTAT: Free SCB %d referenced", scbid);
996                               panic("For safety");
997                     }
998                     ahd_outq(ahd, HADDR, scb->sense_busaddr);
999                     ahd_outw(ahd, HCNT, AHD_SENSE_BUFSIZE);
1000                     ahd_outb(ahd, HCNT + 2, 0);
1001                     ahd_outb(ahd, SG_CACHE_PRE, SG_LAST_SEG);
1002                     ahd_outb(ahd, DFCNTRL, PRELOADEN|SCSIEN|HDMAEN);
1003                     break;
1004           }
1005           case ILLEGAL_PHASE:
1006           {
1007                     u_int bus_phase;
1008 
1009                     bus_phase = ahd_inb(ahd, SCSISIGI) & PHASE_MASK;
1010                     printf("%s: ILLEGAL_PHASE 0x%x\n",
1011                            ahd_name(ahd), bus_phase);
1012 
1013                     switch (bus_phase) {
1014                     case P_DATAOUT:
1015                     case P_DATAIN:
1016                     case P_DATAOUT_DT:
1017                     case P_DATAIN_DT:
1018                     case P_MESGOUT:
1019                     case P_STATUS:
1020                     case P_MESGIN:
1021                               ahd_reset_channel(ahd, 'A', /*Initiate Reset*/TRUE);
1022                               printf("%s: Issued Bus Reset.\n", ahd_name(ahd));
1023                               break;
1024                     case P_COMMAND:
1025                     {
1026                               struct    ahd_devinfo devinfo;
1027                               struct    scb *scb;
1028 #ifdef notdef
1029                               struct    ahd_initiator_tinfo *targ_info;
1030                               struct    ahd_tmode_tstate *tstate;
1031 #endif
1032                               u_int     scbid;
1033 
1034                               /*
1035                                * If a target takes us into the command phase
1036                                * assume that it has been externally reset and
1037                                * has thus lost our previous packetized negotiation
1038                                * agreement.  Since we have not sent an identify
1039                                * message and may not have fully qualified the
1040                                * connection, we change our command to TUR, assert
1041                                * ATN and ABORT the task when we go to message in
1042                                * phase.  The OSM will see the REQUEUE_REQUEST
1043                                * status and retry the command.
1044                                */
1045                               scbid = ahd_get_scbptr(ahd);
1046                               scb = ahd_lookup_scb(ahd, scbid);
1047                               if (scb == NULL) {
1048                                         printf("Invalid phase with no valid SCB.  "
1049                                                "Resetting bus.\n");
1050                                         ahd_reset_channel(ahd, 'A',
1051                                                               /*Initiate Reset*/TRUE);
1052                                         break;
1053                               }
1054                               ahd_compile_devinfo(&devinfo, SCB_GET_OUR_ID(scb),
1055                                                       SCB_GET_TARGET(ahd, scb),
1056                                                       SCB_GET_LUN(scb),
1057                                                       SCB_GET_CHANNEL(ahd, scb),
1058                                                       ROLE_INITIATOR);
1059 #ifdef notdef
1060                               targ_info = ahd_fetch_transinfo(ahd,
1061                                                                       devinfo.channel,
1062                                                                       devinfo.our_scsiid,
1063                                                                       devinfo.target,
1064                                                                       &tstate);
1065 #endif
1066                               ahd_set_width(ahd, &devinfo, MSG_EXT_WDTR_BUS_8_BIT,
1067                                               AHD_TRANS_ACTIVE, /*paused*/TRUE);
1068                               ahd_set_syncrate(ahd, &devinfo, /*period*/0,
1069                                                    /*offset*/0, /*ppr_options*/0,
1070                                                    AHD_TRANS_ACTIVE, /*paused*/TRUE);
1071                               ahd_outb(ahd, SCB_CDB_STORE, 0);
1072                               ahd_outb(ahd, SCB_CDB_STORE+1, 0);
1073                               ahd_outb(ahd, SCB_CDB_STORE+2, 0);
1074                               ahd_outb(ahd, SCB_CDB_STORE+3, 0);
1075                               ahd_outb(ahd, SCB_CDB_STORE+4, 0);
1076                               ahd_outb(ahd, SCB_CDB_STORE+5, 0);
1077                               ahd_outb(ahd, SCB_CDB_LEN, 6);
1078                               scb->hscb->control &= ~(TAG_ENB|SCB_TAG_TYPE);
1079                               scb->hscb->control |= MK_MESSAGE;
1080                               ahd_outb(ahd, SCB_CONTROL, scb->hscb->control);
1081                               ahd_outb(ahd, MSG_OUT, HOST_MSG);
1082                               ahd_outb(ahd, SAVED_SCSIID, scb->hscb->scsiid);
1083                               /*
1084                                * The lun is 0, regardless of the SCB's lun
1085                                * as we have not sent an identify message.
1086                                */
1087                               ahd_outb(ahd, SAVED_LUN, 0);
1088                               ahd_outb(ahd, SEQ_FLAGS, 0);
1089                               ahd_assert_atn(ahd);
1090                               scb->flags &= ~(SCB_PACKETIZED);
1091                               scb->flags |= SCB_ABORT|SCB_CMDPHASE_ABORT;
1092                               ahd_freeze_devq(ahd, scb);
1093                               ahd_set_transaction_status(scb, CAM_REQUEUE_REQ);
1094                               ahd_freeze_scb(scb);
1095 
1096                               /*
1097                                * Allow the sequencer to continue with
1098                                * non-pack processing.
1099                                */
1100                               ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI);
1101                               ahd_outb(ahd, CLRLQOINT1, CLRLQOPHACHGINPKT);
1102                               if ((ahd->bugs & AHD_CLRLQO_AUTOCLR_BUG) != 0) {
1103                                         ahd_outb(ahd, CLRLQOINT1, 0);
1104                               }
1105 #ifdef AHD_DEBUG
1106                               if ((ahd_debug & AHD_SHOW_RECOVERY) != 0) {
1107                                         ahd_print_path(ahd, scb);
1108                                         printf("Unexpected command phase from "
1109                                                "packetized target\n");
1110                               }
1111 #endif
1112                               break;
1113                     }
1114                     }
1115                     break;
1116           }
1117           case CFG4OVERRUN:
1118           {
1119                     struct    scb *scb;
1120                     u_int     scb_index;
1121 
1122 #ifdef AHD_DEBUG
1123                     if ((ahd_debug & AHD_SHOW_RECOVERY) != 0) {
1124                               printf("%s: CFG4OVERRUN mode = %x\n", ahd_name(ahd),
1125                                      ahd_inb(ahd, MODE_PTR));
1126                     }
1127 #endif
1128                     scb_index = ahd_get_scbptr(ahd);
1129                     scb = ahd_lookup_scb(ahd, scb_index);
1130                     if (scb == NULL) {
1131                               /*
1132                                * Attempt to transfer to an SCB that is
1133                                * not outstanding.
1134                                */
1135                               ahd_assert_atn(ahd);
1136                               ahd_outb(ahd, MSG_OUT, HOST_MSG);
1137                               ahd->msgout_buf[0] = MSG_ABORT_TASK;
1138                               ahd->msgout_len = 1;
1139                               ahd->msgout_index = 0;
1140                               ahd->msg_type = MSG_TYPE_INITIATOR_MSGOUT;
1141                               /*
1142                                * Clear status received flag to prevent any
1143                                * attempt to complete this bogus SCB.
1144                                */
1145                               ahd_outb(ahd, SCB_CONTROL,
1146                                          ahd_inb_scbram(ahd, SCB_CONTROL)
1147                                          & ~STATUS_RCVD);
1148                     }
1149                     break;
1150           }
1151           case DUMP_CARD_STATE:
1152           {
1153                     ahd_dump_card_state(ahd);
1154                     break;
1155           }
1156           case PDATA_REINIT:
1157           {
1158 #ifdef AHD_DEBUG
1159                     if ((ahd_debug & AHD_SHOW_RECOVERY) != 0) {
1160                               printf("%s: PDATA_REINIT - DFCNTRL = 0x%x "
1161                                      "SG_CACHE_SHADOW = 0x%x\n",
1162                                      ahd_name(ahd), ahd_inb(ahd, DFCNTRL),
1163                                      ahd_inb(ahd, SG_CACHE_SHADOW));
1164                     }
1165 #endif
1166                     ahd_reinitialize_dataptrs(ahd);
1167                     break;
1168           }
1169           case HOST_MSG_LOOP:
1170           {
1171                     struct ahd_devinfo devinfo;
1172 
1173                     /*
1174                      * The sequencer has encountered a message phase
1175                      * that requires host assistance for completion.
1176                      * While handling the message phase(s), we will be
1177                      * notified by the sequencer after each byte is
1178                      * transferred so we can track bus phase changes.
1179                      *
1180                      * If this is the first time we've seen a HOST_MSG_LOOP
1181                      * interrupt, initialize the state of the host message
1182                      * loop.
1183                      */
1184                     ahd_fetch_devinfo(ahd, &devinfo);
1185                     if (ahd->msg_type == MSG_TYPE_NONE) {
1186                               struct scb *scb;
1187                               u_int scb_index;
1188                               u_int bus_phase;
1189 
1190                               bus_phase = ahd_inb(ahd, SCSISIGI) & PHASE_MASK;
1191                               if (bus_phase != P_MESGIN
1192                                && bus_phase != P_MESGOUT) {
1193                                         printf("ahd_intr: HOST_MSG_LOOP bad "
1194                                                "phase 0x%x\n", bus_phase);
1195                                         /*
1196                                          * Probably transitioned to bus free before
1197                                          * we got here.  Just punt the message.
1198                                          */
1199                                         ahd_dump_card_state(ahd);
1200                                         ahd_clear_intstat(ahd);
1201                                         ahd_restart(ahd);
1202                                         return;
1203                               }
1204 
1205                               scb_index = ahd_get_scbptr(ahd);
1206                               scb = ahd_lookup_scb(ahd, scb_index);
1207                               if (devinfo.role == ROLE_INITIATOR) {
1208                                         if (bus_phase == P_MESGOUT)
1209                                                   ahd_setup_initiator_msgout(ahd,
1210                                                                                    &devinfo,
1211                                                                                    scb);
1212                                         else {
1213                                                   ahd->msg_type =
1214                                                       MSG_TYPE_INITIATOR_MSGIN;
1215                                                   ahd->msgin_index = 0;
1216                                         }
1217                               }
1218 #if AHD_TARGET_MODE
1219                               else {
1220                                         if (bus_phase == P_MESGOUT) {
1221                                                   ahd->msg_type =
1222                                                       MSG_TYPE_TARGET_MSGOUT;
1223                                                   ahd->msgin_index = 0;
1224                                         }
1225                                         else
1226                                                   ahd_setup_target_msgin(ahd,
1227                                                                              &devinfo,
1228                                                                              scb);
1229                               }
1230 #endif
1231                     }
1232 
1233                     ahd_handle_message_phase(ahd);
1234                     break;
1235           }
1236           case NO_MATCH:
1237           {
1238                     /* Ensure we don't leave the selection hardware on */
1239                     AHD_ASSERT_MODES(ahd, AHD_MODE_SCSI_MSK, AHD_MODE_SCSI_MSK);
1240                     ahd_outb(ahd, SCSISEQ0, ahd_inb(ahd, SCSISEQ0) & ~ENSELO);
1241 
1242                     printf("%s:%c:%d: no active SCB for reconnecting "
1243                            "target - issuing BUS DEVICE RESET\n",
1244                            ahd_name(ahd), 'A', ahd_inb(ahd, SELID) >> 4);
1245                     printf("SAVED_SCSIID == 0x%x, SAVED_LUN == 0x%x, "
1246                            "REG0 == 0x%x ACCUM = 0x%x\n",
1247                            ahd_inb(ahd, SAVED_SCSIID), ahd_inb(ahd, SAVED_LUN),
1248                            ahd_inw(ahd, REG0), ahd_inb(ahd, ACCUM));
1249                     printf("SEQ_FLAGS == 0x%x, SCBPTR == 0x%x, BTT == 0x%x, "
1250                            "SINDEX == 0x%x\n",
1251                            ahd_inb(ahd, SEQ_FLAGS), ahd_get_scbptr(ahd),
1252                            ahd_find_busy_tcl(ahd,
1253                                                    BUILD_TCL(ahd_inb(ahd, SAVED_SCSIID),
1254                                                                ahd_inb(ahd, SAVED_LUN))),
1255                            ahd_inw(ahd, SINDEX));
1256                     printf("SELID == 0x%x, SCB_SCSIID == 0x%x, SCB_LUN == 0x%x, "
1257                            "SCB_CONTROL == 0x%x\n",
1258                            ahd_inb(ahd, SELID), ahd_inb_scbram(ahd, SCB_SCSIID),
1259                            ahd_inb_scbram(ahd, SCB_LUN),
1260                            ahd_inb_scbram(ahd, SCB_CONTROL));
1261                     printf("SCSIBUS[0] == 0x%x, SCSISIGI == 0x%x\n",
1262                            ahd_inb(ahd, SCSIBUS), ahd_inb(ahd, SCSISIGI));
1263                     printf("SXFRCTL0 == 0x%x\n", ahd_inb(ahd, SXFRCTL0));
1264                     printf("SEQCTL0 == 0x%x\n", ahd_inb(ahd, SEQCTL0));
1265                     ahd_dump_card_state(ahd);
1266                     ahd->msgout_buf[0] = MSG_BUS_DEV_RESET;
1267                     ahd->msgout_len = 1;
1268                     ahd->msgout_index = 0;
1269                     ahd->msg_type = MSG_TYPE_INITIATOR_MSGOUT;
1270                     ahd_outb(ahd, MSG_OUT, HOST_MSG);
1271                     ahd_assert_atn(ahd);
1272                     break;
1273           }
1274           case PROTO_VIOLATION:
1275           {
1276                     ahd_handle_proto_violation(ahd);
1277                     break;
1278           }
1279           case IGN_WIDE_RES:
1280           {
1281                     struct ahd_devinfo devinfo;
1282 
1283                     ahd_fetch_devinfo(ahd, &devinfo);
1284                     ahd_handle_ign_wide_residue(ahd, &devinfo);
1285                     break;
1286           }
1287           case BAD_PHASE:
1288           {
1289                     u_int lastphase;
1290 
1291                     lastphase = ahd_inb(ahd, LASTPHASE);
1292                     printf("%s:%c:%d: unknown scsi bus phase %x, "
1293                            "lastphase = 0x%x.  Attempting to continue\n",
1294                            ahd_name(ahd), 'A',
1295                            SCSIID_TARGET(ahd, ahd_inb(ahd, SAVED_SCSIID)),
1296                            lastphase, ahd_inb(ahd, SCSISIGI));
1297                     break;
1298           }
1299           case MISSED_BUSFREE:
1300           {
1301                     u_int lastphase;
1302 
1303                     lastphase = ahd_inb(ahd, LASTPHASE);
1304                     printf("%s:%c:%d: Missed busfree. "
1305                            "Lastphase = 0x%x, Curphase = 0x%x\n",
1306                            ahd_name(ahd), 'A',
1307                            SCSIID_TARGET(ahd, ahd_inb(ahd, SAVED_SCSIID)),
1308                            lastphase, ahd_inb(ahd, SCSISIGI));
1309                     ahd_restart(ahd);
1310                     return;
1311           }
1312           case DATA_OVERRUN:
1313           {
1314                     /*
1315                      * When the sequencer detects an overrun, it
1316                      * places the controller in "BITBUCKET" mode
1317                      * and allows the target to complete its transfer.
1318                      * Unfortunately, none of the counters get updated
1319                      * when the controller is in this mode, so we have
1320                      * no way of knowing how large the overrun was.
1321                      */
1322                     struct    scb *scb;
1323                     u_int     scbindex;
1324 #ifdef AHD_DEBUG
1325                     u_int     lastphase;
1326 #endif
1327 
1328                     scbindex = ahd_get_scbptr(ahd);
1329                     scb = ahd_lookup_scb(ahd, scbindex);
1330 #ifdef AHD_DEBUG
1331                     lastphase = ahd_inb(ahd, LASTPHASE);
1332                     if ((ahd_debug & AHD_SHOW_RECOVERY) != 0) {
1333                               ahd_print_path(ahd, scb);
1334                               printf("data overrun detected %s.  Tag == 0x%x.\n",
1335                                      ahd_lookup_phase_entry(lastphase)->phasemsg,
1336                                      SCB_GET_TAG(scb));
1337                               ahd_print_path(ahd, scb);
1338                               printf("%s seen Data Phase.  Length = %ld.  "
1339                                      "NumSGs = %d.\n",
1340                                      ahd_inb(ahd, SEQ_FLAGS) & DPHASE
1341                                      ? "Have" : "Haven't",
1342                                      ahd_get_transfer_length(scb), scb->sg_count);
1343                               ahd_dump_sglist(scb);
1344                     }
1345 #endif
1346 
1347                     /*
1348                      * Set this and it will take effect when the
1349                      * target does a command complete.
1350                      */
1351                     ahd_freeze_devq(ahd, scb);
1352                     ahd_set_transaction_status(scb, CAM_DATA_RUN_ERR);
1353                     ahd_freeze_scb(scb);
1354                     break;
1355           }
1356           case MKMSG_FAILED:
1357           {
1358                     struct ahd_devinfo devinfo;
1359                     struct scb *scb;
1360                     u_int scbid;
1361 
1362                     ahd_fetch_devinfo(ahd, &devinfo);
1363                     printf("%s:%c:%d:%d: Attempt to issue message failed\n",
1364                            ahd_name(ahd), devinfo.channel, devinfo.target,
1365                            devinfo.lun);
1366                     scbid = ahd_get_scbptr(ahd);
1367                     scb = ahd_lookup_scb(ahd, scbid);
1368                     if (scb != NULL
1369                      && (scb->flags & SCB_RECOVERY_SCB) != 0)
1370                               /*
1371                                * Ensure that we didn't put a second instance of this
1372                                * SCB into the QINFIFO.
1373                                */
1374                               ahd_search_qinfifo(ahd, SCB_GET_TARGET(ahd, scb),
1375                                                      SCB_GET_CHANNEL(ahd, scb),
1376                                                      SCB_GET_LUN(scb), SCB_GET_TAG(scb),
1377                                                      ROLE_INITIATOR, /*status*/0,
1378                                                      SEARCH_REMOVE);
1379                     ahd_outb(ahd, SCB_CONTROL,
1380                                ahd_inb_scbram(ahd, SCB_CONTROL) & ~MK_MESSAGE);
1381                     break;
1382           }
1383           case TASKMGMT_FUNC_COMPLETE:
1384           {
1385                     u_int     scbid;
1386                     struct    scb *scb;
1387 
1388                     scbid = ahd_get_scbptr(ahd);
1389                     scb = ahd_lookup_scb(ahd, scbid);
1390                     if (scb != NULL) {
1391                               u_int        lun;
1392                               u_int        tag;
1393                               cam_status error;
1394 
1395                               ahd_print_path(ahd, scb);
1396                               printf("Task Management Func 0x%x Complete\n",
1397                                      scb->hscb->task_management);
1398                               lun = CAM_LUN_WILDCARD;
1399                               tag = SCB_LIST_NULL;
1400 
1401                               switch (scb->hscb->task_management) {
1402                               case SIU_TASKMGMT_ABORT_TASK:
1403                                         tag = SCB_GET_TAG(scb);
1404                                         /* FALLTHROUGH */
1405                               case SIU_TASKMGMT_ABORT_TASK_SET:
1406                               case SIU_TASKMGMT_CLEAR_TASK_SET:
1407                                         lun = scb->hscb->lun;
1408                                         error = CAM_REQ_ABORTED;
1409                                         ahd_abort_scbs(ahd, SCB_GET_TARGET(ahd, scb),
1410                                                          'A', lun, tag, ROLE_INITIATOR,
1411                                                          error);
1412                                         break;
1413                               case SIU_TASKMGMT_LUN_RESET:
1414                                         lun = scb->hscb->lun;
1415                                         /* FALLTHROUGH */
1416                               case SIU_TASKMGMT_TARGET_RESET:
1417                               {
1418                                         struct ahd_devinfo devinfo;
1419 
1420                                         ahd_scb_devinfo(ahd, &devinfo, scb);
1421                                         error = CAM_BDR_SENT;
1422                                         ahd_handle_devreset(ahd, &devinfo, lun,
1423                                                                 CAM_BDR_SENT,
1424                                                                 lun != CAM_LUN_WILDCARD
1425                                                                 ? "Lun Reset"
1426                                                                 : "Target Reset",
1427                                                                 /*verbose_level*/0);
1428                                         break;
1429                               }
1430                               default:
1431                                         panic("Unexpected TaskMgmt Func\n");
1432                                         break;
1433                               }
1434                     }
1435                     break;
1436           }
1437           case TASKMGMT_CMD_CMPLT_OKAY:
1438           {
1439                     u_int     scbid;
1440                     struct    scb *scb;
1441 
1442                     /*
1443                      * An ABORT TASK TMF failed to be delivered before
1444                      * the targeted command completed normally.
1445                      */
1446                     scbid = ahd_get_scbptr(ahd);
1447                     scb = ahd_lookup_scb(ahd, scbid);
1448                     if (scb != NULL) {
1449                               /*
1450                                * Remove the second instance of this SCB from
1451                                * the QINFIFO if it is still there.
1452                                */
1453                               ahd_print_path(ahd, scb);
1454                               printf("SCB completes before TMF\n");
1455                               /*
1456                                * Handle losing the race.  Wait until any
1457                                * current selection completes.  We will then
1458                                * set the TMF back to zero in this SCB so that
1459                                * the sequencer doesn't bother to issue another
1460                                * sequencer interrupt for its completion.
1461                                */
1462                               while ((ahd_inb(ahd, SCSISEQ0) & ENSELO) != 0
1463                                   && (ahd_inb(ahd, SSTAT0) & SELDO) == 0
1464                                   && (ahd_inb(ahd, SSTAT1) & SELTO) == 0)
1465                                         ;
1466                               ahd_outb(ahd, SCB_TASK_MANAGEMENT, 0);
1467                               ahd_search_qinfifo(ahd, SCB_GET_TARGET(ahd, scb),
1468                                                      SCB_GET_CHANNEL(ahd, scb),
1469                                                      SCB_GET_LUN(scb), SCB_GET_TAG(scb),
1470                                                      ROLE_INITIATOR, /*status*/0,
1471                                                      SEARCH_REMOVE);
1472                     }
1473                     break;
1474           }
1475           case TRACEPOINT0:
1476           case TRACEPOINT1:
1477           case TRACEPOINT2:
1478           case TRACEPOINT3:
1479                     printf("%s: Tracepoint %d\n", ahd_name(ahd),
1480                            seqintcode - TRACEPOINT0);
1481                     break;
1482           case NO_SEQINT:
1483                     break;
1484           case SAW_HWERR:
1485                     ahd_handle_hwerrint(ahd);
1486                     break;
1487           default:
1488                     printf("%s: Unexpected SEQINTCODE %d\n", ahd_name(ahd),
1489                            seqintcode);
1490                     break;
1491           }
1492           /*
1493            *  The sequencer is paused immediately on
1494            *  a SEQINT, so we should restart it when
1495            *  we're done.
1496            */
1497           ahd_unpause(ahd);
1498 }
1499 
1500 void
ahd_handle_scsiint(struct ahd_softc * ahd,u_int intstat)1501 ahd_handle_scsiint(struct ahd_softc *ahd, u_int intstat)
1502 {
1503           struct scb          *scb;
1504           u_int                status0;
1505           u_int                status3;
1506           u_int                status;
1507           u_int                lqistat1;
1508           u_int                lqostat0;
1509           u_int                scbid;
1510           u_int                busfreetime;
1511 
1512           ahd_update_modes(ahd);
1513           ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI);
1514 
1515           status3 = ahd_inb(ahd, SSTAT3) & (NTRAMPERR|OSRAMPERR);
1516           status0 = ahd_inb(ahd, SSTAT0) & (IOERR|OVERRUN|SELDI|SELDO);
1517           status = ahd_inb(ahd, SSTAT1) & (SELTO|SCSIRSTI|BUSFREE|SCSIPERR);
1518           lqistat1 = ahd_inb(ahd, LQISTAT1);
1519           lqostat0 = ahd_inb(ahd, LQOSTAT0);
1520           busfreetime = ahd_inb(ahd, SSTAT2) & BUSFREETIME;
1521           if ((status0 & (SELDI|SELDO)) != 0) {
1522                     u_int simode0;
1523 
1524                     ahd_set_modes(ahd, AHD_MODE_CFG, AHD_MODE_CFG);
1525                     simode0 = ahd_inb(ahd, SIMODE0);
1526                     status0 &= simode0 & (IOERR|OVERRUN|SELDI|SELDO);
1527                     ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI);
1528           }
1529           scbid = ahd_get_scbptr(ahd);
1530           scb = ahd_lookup_scb(ahd, scbid);
1531           if (scb != NULL
1532            && (ahd_inb(ahd, SEQ_FLAGS) & NOT_IDENTIFIED) != 0)
1533                     scb = NULL;
1534 
1535           /* Make sure the sequencer is in a safe location. */
1536           ahd_clear_critical_section(ahd);
1537 
1538           if ((status0 & IOERR) != 0) {
1539                     u_int now_lvd;
1540 
1541                     now_lvd = ahd_inb(ahd, SBLKCTL) & ENAB40;
1542                     printf("%s: Transceiver State Has Changed to %s mode\n",
1543                            ahd_name(ahd), now_lvd ? "LVD" : "SE");
1544                     ahd_outb(ahd, CLRSINT0, CLRIOERR);
1545                     /*
1546                      * A change in I/O mode is equivalent to a bus reset.
1547                      */
1548                     ahd_reset_channel(ahd, 'A', /*Initiate Reset*/TRUE);
1549                     ahd_pause(ahd);
1550                     ahd_setup_iocell_workaround(ahd);
1551                     ahd_unpause(ahd);
1552           } else if ((status0 & OVERRUN) != 0) {
1553                     printf("%s: SCSI offset overrun detected.  Resetting bus.\n",
1554                            ahd_name(ahd));
1555                     ahd_reset_channel(ahd, 'A', /*Initiate Reset*/TRUE);
1556           } else if ((status & SCSIRSTI) != 0) {
1557                     printf("%s: Someone reset channel A\n", ahd_name(ahd));
1558                     ahd_reset_channel(ahd, 'A', /*Initiate Reset*/FALSE);
1559           } else if ((status & SCSIPERR) != 0) {
1560                     ahd_handle_transmission_error(ahd);
1561           } else if (lqostat0 != 0) {
1562                     printf("%s: lqostat0 == 0x%x!\n", ahd_name(ahd), lqostat0);
1563                     ahd_outb(ahd, CLRLQOINT0, lqostat0);
1564                     if ((ahd->bugs & AHD_CLRLQO_AUTOCLR_BUG) != 0) {
1565                               ahd_outb(ahd, CLRLQOINT1, 0);
1566                     }
1567           } else if ((status & SELTO) != 0) {
1568                     u_int  scbid1;
1569 
1570                     /* Stop the selection */
1571                     ahd_outb(ahd, SCSISEQ0, 0);
1572 
1573                     /* No more pending messages */
1574                     ahd_clear_msg_state(ahd);
1575 
1576                     /* Clear interrupt state */
1577                     ahd_outb(ahd, CLRSINT1, CLRSELTIMEO|CLRBUSFREE|CLRSCSIPERR);
1578 
1579                     /*
1580                      * Although the driver does not care about the
1581                      * 'Selection in Progress' status bit, the busy
1582                      * LED does.  SELINGO is only cleared by a successful
1583                      * selection, so we must manually clear it to insure
1584                      * the LED turns off just incase no future successful
1585                      * selections occur (e.g. no devices on the bus).
1586                      */
1587                     ahd_outb(ahd, CLRSINT0, CLRSELINGO);
1588 
1589                     scbid1 = ahd_inw(ahd, WAITING_TID_HEAD);
1590                     scb = ahd_lookup_scb(ahd, scbid1);
1591                     if (scb == NULL) {
1592                               printf("%s: ahd_intr - referenced scb not "
1593                                      "valid during SELTO scb(0x%x)\n",
1594                                      ahd_name(ahd), scbid1);
1595                               ahd_dump_card_state(ahd);
1596                     } else {
1597                               struct ahd_devinfo devinfo;
1598 #ifdef AHD_DEBUG
1599                               if ((ahd_debug & AHD_SHOW_SELTO) != 0) {
1600                                         ahd_print_path(ahd, scb);
1601                                         printf("Saw Selection Timeout for SCB 0x%x\n",
1602                                                scbid1);
1603                               }
1604 #endif
1605                               /*
1606                                * Force a renegotiation with this target just in
1607                                * case the cable was pulled and will later be
1608                                * re-attached.  The target may forget its negotiation
1609                                * settings with us should it attempt to reselect
1610                                * during the interruption.  The target will not issue
1611                                * a unit attention in this case, so we must always
1612                                * renegotiate.
1613                                */
1614                               ahd_scb_devinfo(ahd, &devinfo, scb);
1615                               ahd_force_renegotiation(ahd, &devinfo);
1616                               ahd_set_transaction_status(scb, CAM_SEL_TIMEOUT);
1617                               ahd_freeze_devq(ahd, scb);
1618                     }
1619                     ahd_outb(ahd, CLRINT, CLRSCSIINT);
1620                     ahd_iocell_first_selection(ahd);
1621                     ahd_unpause(ahd);
1622           } else if ((status0 & (SELDI|SELDO)) != 0) {
1623                     ahd_iocell_first_selection(ahd);
1624                     ahd_unpause(ahd);
1625           } else if (status3 != 0) {
1626                     printf("%s: SCSI Cell parity error SSTAT3 == 0x%x\n",
1627                            ahd_name(ahd), status3);
1628                     ahd_outb(ahd, CLRSINT3, status3);
1629           } else if ((lqistat1 & (LQIPHASE_LQ|LQIPHASE_NLQ)) != 0) {
1630                     ahd_handle_lqiphase_error(ahd, lqistat1);
1631           } else if ((lqistat1 & LQICRCI_NLQ) != 0) {
1632                     /*
1633                      * This status can be delayed during some
1634                      * streaming operations.  The SCSIPHASE
1635                      * handler has already dealt with this case
1636                      * so just clear the error.
1637                      */
1638                     ahd_outb(ahd, CLRLQIINT1, CLRLQICRCI_NLQ);
1639           } else if ((status & BUSFREE) != 0) {
1640                     u_int lqostat1;
1641                     int   restart;
1642                     int   clear_fifo;
1643                     int   packetized;
1644                     u_int mode;
1645 
1646                     /*
1647                      * Clear our selection hardware as soon as possible.
1648                      * We may have an entry in the waiting Q for this target,
1649                      * that is affected by this busfree and we don't want to
1650                      * go about selecting the target while we handle the event.
1651                      */
1652                     ahd_outb(ahd, SCSISEQ0, 0);
1653 
1654                     /*
1655                      * Determine what we were up to at the time of
1656                      * the busfree.
1657                      */
1658                     mode = AHD_MODE_SCSI;
1659                     busfreetime = ahd_inb(ahd, SSTAT2) & BUSFREETIME;
1660                     lqostat1 = ahd_inb(ahd, LQOSTAT1);
1661                     switch (busfreetime) {
1662                     case BUSFREE_DFF0:
1663                     case BUSFREE_DFF1:
1664                     {
1665                               u_int     scbid1;
1666                               struct    scb *scb1;
1667 
1668                               mode = busfreetime == BUSFREE_DFF0
1669                                    ? AHD_MODE_DFF0 : AHD_MODE_DFF1;
1670                               ahd_set_modes(ahd, mode, mode);
1671                               scbid1 = ahd_get_scbptr(ahd);
1672                               scb1 = ahd_lookup_scb(ahd, scbid1);
1673                               if (scb1 == NULL) {
1674                                         printf("%s: Invalid SCB %d in DFF%d "
1675                                                "during unexpected busfree\n",
1676                                                ahd_name(ahd), scbid1, mode);
1677                                         packetized = 0;
1678                               } else
1679                                         packetized =
1680                                             (scb1->flags & SCB_PACKETIZED) != 0;
1681                               clear_fifo = 1;
1682                               break;
1683                     }
1684                     case BUSFREE_LQO:
1685                               clear_fifo = 0;
1686                               packetized = 1;
1687                               break;
1688                     default:
1689                               clear_fifo = 0;
1690                               packetized =  (lqostat1 & LQOBUSFREE) != 0;
1691                               if (!packetized
1692                                && ahd_inb(ahd, LASTPHASE) == P_BUSFREE)
1693                                         packetized = 1;
1694                               break;
1695                     }
1696 
1697 #ifdef AHD_DEBUG
1698                     if ((ahd_debug & AHD_SHOW_MISC) != 0)
1699                               printf("Saw Busfree.  Busfreetime = 0x%x.\n",
1700                                      busfreetime);
1701 #endif
1702                     /*
1703                      * Busfrees that occur in non-packetized phases are
1704                      * handled by the nonpkt_busfree handler.
1705                      */
1706                     if (packetized && ahd_inb(ahd, LASTPHASE) == P_BUSFREE) {
1707                               restart = ahd_handle_pkt_busfree(ahd, busfreetime);
1708                     } else {
1709                               packetized = 0;
1710                               restart = ahd_handle_nonpkt_busfree(ahd);
1711                     }
1712                     /*
1713                      * Clear the busfree interrupt status.  The setting of
1714                      * the interrupt is a pulse, so in a perfect world, we
1715                      * would not need to muck with the ENBUSFREE logic.  This
1716                      * would ensure that if the bus moves on to another
1717                      * connection, busfree protection is still in force.  If
1718                      * BUSFREEREV is broken, however, we must manually clear
1719                      * the ENBUSFREE if the busfree occurred during a non-pack
1720                      * connection so that we don't get false positives during
1721                      * future, packetized, connections.
1722                      */
1723                     ahd_outb(ahd, CLRSINT1, CLRBUSFREE);
1724                     if (packetized == 0
1725                      && (ahd->bugs & AHD_BUSFREEREV_BUG) != 0)
1726                               ahd_outb(ahd, SIMODE1,
1727                                          ahd_inb(ahd, SIMODE1) & ~ENBUSFREE);
1728 
1729                     if (clear_fifo)
1730                               ahd_clear_fifo(ahd, mode);
1731 
1732                     ahd_clear_msg_state(ahd);
1733                     ahd_outb(ahd, CLRINT, CLRSCSIINT);
1734                     if (restart) {
1735                               ahd_restart(ahd);
1736                     } else {
1737                               ahd_unpause(ahd);
1738                     }
1739           } else {
1740                     printf("%s: Missing case in ahd_handle_scsiint. status = %x\n",
1741                            ahd_name(ahd), status);
1742                     ahd_dump_card_state(ahd);
1743                     ahd_clear_intstat(ahd);
1744                     ahd_unpause(ahd);
1745           }
1746 }
1747 
1748 static void
ahd_handle_transmission_error(struct ahd_softc * ahd)1749 ahd_handle_transmission_error(struct ahd_softc *ahd)
1750 {
1751           struct    scb *scb;
1752           u_int     scbid;
1753           u_int     lqistat1;
1754           u_int     msg_out;
1755           u_int     curphase;
1756           u_int     lastphase;
1757           u_int     perrdiag;
1758           u_int     cur_col;
1759           int       silent;
1760 
1761           scb = NULL;
1762           ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI);
1763           lqistat1 = ahd_inb(ahd, LQISTAT1) & ~(LQIPHASE_LQ|LQIPHASE_NLQ);
1764           (void)ahd_inb(ahd, LQISTAT2);
1765           if ((lqistat1 & (LQICRCI_NLQ|LQICRCI_LQ)) == 0
1766            && (ahd->bugs & AHD_NLQICRC_DELAYED_BUG) != 0) {
1767                     u_int lqistate;
1768 
1769                     ahd_set_modes(ahd, AHD_MODE_CFG, AHD_MODE_CFG);
1770                     lqistate = ahd_inb(ahd, LQISTATE);
1771                     if ((lqistate >= 0x1E && lqistate <= 0x24)
1772                      || (lqistate == 0x29)) {
1773 #ifdef AHD_DEBUG
1774                               if ((ahd_debug & AHD_SHOW_RECOVERY) != 0) {
1775                                         printf("%s: NLQCRC found via LQISTATE\n",
1776                                                ahd_name(ahd));
1777                               }
1778 #endif
1779                               lqistat1 |= LQICRCI_NLQ;
1780                     }
1781                     ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI);
1782           }
1783 
1784           ahd_outb(ahd, CLRLQIINT1, lqistat1);
1785           lastphase = ahd_inb(ahd, LASTPHASE);
1786           curphase = ahd_inb(ahd, SCSISIGI) & PHASE_MASK;
1787           perrdiag = ahd_inb(ahd, PERRDIAG);
1788           msg_out = MSG_INITIATOR_DET_ERR;
1789           ahd_outb(ahd, CLRSINT1, CLRSCSIPERR);
1790 
1791           /*
1792            * Try to find the SCB associated with this error.
1793            */
1794           silent = FALSE;
1795           if (lqistat1 == 0
1796            || (lqistat1 & LQICRCI_NLQ) != 0) {
1797                     if ((lqistat1 & (LQICRCI_NLQ|LQIOVERI_NLQ)) != 0)
1798                               ahd_set_active_fifo(ahd);
1799                     scbid = ahd_get_scbptr(ahd);
1800                     scb = ahd_lookup_scb(ahd, scbid);
1801                     if (scb != NULL && SCB_IS_SILENT(scb))
1802                               silent = TRUE;
1803           }
1804 
1805           cur_col = 0;
1806           if (silent == FALSE) {
1807                     printf("%s: Transmission error detected\n", ahd_name(ahd));
1808                     ahd_lqistat1_print(lqistat1, &cur_col, 50);
1809                     ahd_lastphase_print(lastphase, &cur_col, 50);
1810                     ahd_scsisigi_print(curphase, &cur_col, 50);
1811                     ahd_perrdiag_print(perrdiag, &cur_col, 50);
1812                     printf("\n");
1813                     ahd_dump_card_state(ahd);
1814           }
1815 
1816           if ((lqistat1 & (LQIOVERI_LQ|LQIOVERI_NLQ)) != 0) {
1817                     if (silent == FALSE) {
1818                               printf("%s: Gross protocol error during incoming "
1819                                      "packet.  lqistat1 == 0x%x.  Resetting bus.\n",
1820                                      ahd_name(ahd), lqistat1);
1821                     }
1822                     ahd_reset_channel(ahd, 'A', /*Initiate Reset*/TRUE);
1823                     return;
1824           } else if ((lqistat1 & LQICRCI_LQ) != 0) {
1825                     /*
1826                      * A CRC error has been detected on an incoming LQ.
1827                      * The bus is currently hung on the last ACK.
1828                      * Hit LQIRETRY to release the last ack, and
1829                      * wait for the sequencer to determine that ATNO
1830                      * is asserted while in message out to take us
1831                      * to our host message loop.  No NONPACKREQ or
1832                      * LQIPHASE type errors will occur in this
1833                      * scenario.  After this first LQIRETRY, the LQI
1834                      * manager will be in ISELO where it will
1835                      * happily sit until another packet phase begins.
1836                      * Unexpected bus free detection is enabled
1837                      * through any phases that occur after we release
1838                      * this last ack until the LQI manager sees a
1839                      * packet phase.  This implies we may have to
1840                      * ignore a perfectly valid "unexpected busfree"
1841                      * after our "initiator detected error" message is
1842                      * sent.  A busfree is the expected response after
1843                      * we tell the target that its L_Q was corrupted.
1844                      * (SPI4R09 10.7.3.3.3)
1845                      */
1846                     ahd_outb(ahd, LQCTL2, LQIRETRY);
1847                     printf("LQIRetry for LQICRCI_LQ to release ACK\n");
1848           } else if ((lqistat1 & LQICRCI_NLQ) != 0) {
1849                     /*
1850                      * We detected a CRC error in a NON-LQ packet.
1851                      * The hardware has varying behavior in this situation
1852                      * depending on whether this packet was part of a
1853                      * stream or not.
1854                      *
1855                      * PKT by PKT mode:
1856                      * The hardware has already acked the complete packet.
1857                      * If the target honors our outstanding ATN condition,
1858                      * we should be (or soon will be) in MSGOUT phase.
1859                      * This will trigger the LQIPHASE_LQ status bit as the
1860                      * hardware was expecting another LQ.  Unexpected
1861                      * busfree detection is enabled.  Once LQIPHASE_LQ is
1862                      * true (first entry into host message loop is much
1863                      * the same), we must clear LQIPHASE_LQ and hit
1864                      * LQIRETRY so the hardware is ready to handle
1865                      * a future LQ.  NONPACKREQ will not be asserted again
1866                      * once we hit LQIRETRY until another packet is
1867                      * processed.  The target may either go busfree
1868                      * or start another packet in response to our message.
1869                      *
1870                      * Read Streaming P0 asserted:
1871                      * If we raise ATN and the target completes the entire
1872                      * stream (P0 asserted during the last packet), the
1873                      * hardware will ack all data and return to the ISTART
1874                      * state.  When the target responds to our ATN condition,
1875                      * LQIPHASE_LQ will be asserted.  We should respond to
1876                      * this with an LQIRETRY to prepare for any future
1877                      * packets.  NONPACKREQ will not be asserted again
1878                      * once we hit LQIRETRY until another packet is
1879                      * processed.  The target may either go busfree or
1880                      * start another packet in response to our message.
1881                      * Busfree detection is enabled.
1882                      *
1883                      * Read Streaming P0 not asserted:
1884                      * If we raise ATN and the target transitions to
1885                      * MSGOUT in or after a packet where P0 is not
1886                      * asserted, the hardware will assert LQIPHASE_NLQ.
1887                      * We should respond to the LQIPHASE_NLQ with an
1888                      * LQIRETRY.  Should the target stay in a non-pkt
1889                      * phase after we send our message, the hardware
1890                      * will assert LQIPHASE_LQ.  Recovery is then just as
1891                      * listed above for the read streaming with P0 asserted.
1892                      * Busfree detection is enabled.
1893                      */
1894                     if (silent == FALSE)
1895                               printf("LQICRC_NLQ\n");
1896                     if (scb == NULL) {
1897                               printf("%s: No SCB valid for LQICRC_NLQ.  "
1898                                      "Resetting bus\n", ahd_name(ahd));
1899                               ahd_reset_channel(ahd, 'A', /*Initiate Reset*/TRUE);
1900                               return;
1901                     }
1902           } else if ((lqistat1 & LQIBADLQI) != 0) {
1903                     printf("Need to handle BADLQI!\n");
1904                     ahd_reset_channel(ahd, 'A', /*Initiate Reset*/TRUE);
1905                     return;
1906           } else if ((perrdiag & (PARITYERR|PREVPHASE)) == PARITYERR) {
1907                     if ((curphase & ~P_DATAIN_DT) != 0) {
1908                               /* Ack the byte.  So we can continue. */
1909                               if (silent == FALSE)
1910                                         printf("Acking %s to clear perror\n",
1911                                             ahd_lookup_phase_entry(curphase)->phasemsg);
1912                               ahd_inb(ahd, SCSIDAT);
1913                     }
1914 
1915                     if (curphase == P_MESGIN)
1916                               msg_out = MSG_PARITY_ERROR;
1917           }
1918 
1919           /*
1920            * We've set the hardware to assert ATN if we
1921            * get a parity error on "in" phases, so all we
1922            * need to do is stuff the message buffer with
1923            * the appropriate message.  "In" phases have set
1924            * mesg_out to something other than MSG_NOP.
1925            */
1926           ahd->send_msg_perror = msg_out;
1927           if (scb != NULL && msg_out == MSG_INITIATOR_DET_ERR)
1928                     scb->flags |= SCB_TRANSMISSION_ERROR;
1929           ahd_outb(ahd, MSG_OUT, HOST_MSG);
1930           ahd_outb(ahd, CLRINT, CLRSCSIINT);
1931           ahd_unpause(ahd);
1932 }
1933 
1934 static void
ahd_handle_lqiphase_error(struct ahd_softc * ahd,u_int lqistat1)1935 ahd_handle_lqiphase_error(struct ahd_softc *ahd, u_int lqistat1)
1936 {
1937           /*
1938            * Clear the sources of the interrupts.
1939            */
1940           ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI);
1941           ahd_outb(ahd, CLRLQIINT1, lqistat1);
1942 
1943           /*
1944            * If the "illegal" phase changes were in response
1945            * to our ATN to flag a CRC error, AND we ended up
1946            * on packet boundaries, clear the error, restart the
1947            * LQI manager as appropriate, and go on our merry
1948            * way toward sending the message.  Otherwise, reset
1949            * the bus to clear the error.
1950            */
1951           ahd_set_active_fifo(ahd);
1952           if ((ahd_inb(ahd, SCSISIGO) & ATNO) != 0
1953            && (ahd_inb(ahd, MDFFSTAT) & DLZERO) != 0) {
1954                     if ((lqistat1 & LQIPHASE_LQ) != 0) {
1955                               printf("LQIRETRY for LQIPHASE_LQ\n");
1956                               ahd_outb(ahd, LQCTL2, LQIRETRY);
1957                     } else if ((lqistat1 & LQIPHASE_NLQ) != 0) {
1958                               printf("LQIRETRY for LQIPHASE_NLQ\n");
1959                               ahd_outb(ahd, LQCTL2, LQIRETRY);
1960                     } else
1961                               panic("ahd_handle_lqiphase_error: No phase errors\n");
1962                     ahd_dump_card_state(ahd);
1963                     ahd_outb(ahd, CLRINT, CLRSCSIINT);
1964                     ahd_unpause(ahd);
1965           } else {
1966                     printf("Resetting Channel for LQI Phase error\n");
1967                     ahd_dump_card_state(ahd);
1968                     ahd_reset_channel(ahd, 'A', /*Initiate Reset*/TRUE);
1969           }
1970 }
1971 
1972 /*
1973  * Packetized unexpected or expected busfree.
1974  * Entered in mode based on busfreetime.
1975  */
1976 static int
ahd_handle_pkt_busfree(struct ahd_softc * ahd,u_int busfreetime)1977 ahd_handle_pkt_busfree(struct ahd_softc *ahd, u_int busfreetime)
1978 {
1979           u_int lqostat1;
1980 
1981           AHD_ASSERT_MODES(ahd, ~(AHD_MODE_UNKNOWN_MSK|AHD_MODE_CFG_MSK),
1982                                ~(AHD_MODE_UNKNOWN_MSK|AHD_MODE_CFG_MSK));
1983           lqostat1 = ahd_inb(ahd, LQOSTAT1);
1984           if ((lqostat1 & LQOBUSFREE) != 0) {
1985                     struct scb *scb;
1986                     u_int scbid;
1987                     u_int saved_scbptr;
1988                     u_int waiting_h;
1989                     u_int waiting_t;
1990                     u_int next;
1991 
1992                     if ((busfreetime & BUSFREE_LQO) == 0)
1993                               printf("%s: Warning, BUSFREE time is 0x%x.  "
1994                                      "Expected BUSFREE_LQO.\n",
1995                                      ahd_name(ahd), busfreetime);
1996                     /*
1997                      * The LQO manager detected an unexpected busfree
1998                      * either:
1999                      *
2000                      * 1) During an outgoing LQ.
2001                      * 2) After an outgoing LQ but before the first
2002                      *    REQ of the command packet.
2003                      * 3) During an outgoing command packet.
2004                      *
2005                      * In all cases, CURRSCB is pointing to the
2006                      * SCB that encountered the failure.  Clean
2007                      * up the queue, clear SELDO and LQOBUSFREE,
2008                      * and allow the sequencer to restart the select
2009                      * out at its lesure.
2010                      */
2011                     ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI);
2012                     scbid = ahd_inw(ahd, CURRSCB);
2013                     scb = ahd_lookup_scb(ahd, scbid);
2014                     if (scb == NULL)
2015                               panic("SCB not valid during LQOBUSFREE");
2016                     /*
2017                      * Clear the status.
2018                      */
2019                     ahd_outb(ahd, CLRLQOINT1, CLRLQOBUSFREE);
2020                     if ((ahd->bugs & AHD_CLRLQO_AUTOCLR_BUG) != 0)
2021                               ahd_outb(ahd, CLRLQOINT1, 0);
2022                     ahd_outb(ahd, SCSISEQ0, ahd_inb(ahd, SCSISEQ0) & ~ENSELO);
2023                     ahd_flush_device_writes(ahd);
2024                     ahd_outb(ahd, CLRSINT0, CLRSELDO);
2025 
2026                     /*
2027                      * Return the LQO manager to its idle loop.  It will
2028                      * not do this automatically if the busfree occurs
2029                      * after the first REQ of either the LQ or command
2030                      * packet or between the LQ and command packet.
2031                      */
2032                     ahd_outb(ahd, LQCTL2, ahd_inb(ahd, LQCTL2) | LQOTOIDLE);
2033 
2034                     /*
2035                      * Update the waiting for selection queue so
2036                      * we restart on the correct SCB.
2037                      */
2038                     waiting_h = ahd_inw(ahd, WAITING_TID_HEAD);
2039                     saved_scbptr = ahd_get_scbptr(ahd);
2040                     if (waiting_h != scbid) {
2041 
2042                               ahd_outw(ahd, WAITING_TID_HEAD, scbid);
2043                               waiting_t = ahd_inw(ahd, WAITING_TID_TAIL);
2044                               if (waiting_t == waiting_h) {
2045                                         ahd_outw(ahd, WAITING_TID_TAIL, scbid);
2046                                         next = SCB_LIST_NULL;
2047                               } else {
2048                                         ahd_set_scbptr(ahd, waiting_h);
2049                                         next = ahd_inw_scbram(ahd, SCB_NEXT2);
2050                               }
2051                               ahd_set_scbptr(ahd, scbid);
2052                               ahd_outw(ahd, SCB_NEXT2, next);
2053                     }
2054                     ahd_set_scbptr(ahd, saved_scbptr);
2055                     if (scb->crc_retry_count < AHD_MAX_LQ_CRC_ERRORS) {
2056                               if (SCB_IS_SILENT(scb) == FALSE) {
2057                                         ahd_print_path(ahd, scb);
2058                                         printf("Probable outgoing LQ CRC error.  "
2059                                                "Retrying command\n");
2060                               }
2061                               scb->crc_retry_count++;
2062                     } else {
2063                               ahd_set_transaction_status(scb, CAM_UNCOR_PARITY);
2064                               ahd_freeze_scb(scb);
2065                               ahd_freeze_devq(ahd, scb);
2066                     }
2067                     /* Return unpausing the sequencer. */
2068                     return (0);
2069           } else if ((ahd_inb(ahd, PERRDIAG) & PARITYERR) != 0) {
2070                     /*
2071                      * Ignore what are really parity errors that
2072                      * occur on the last REQ of a free running
2073                      * clock prior to going busfree.  Some drives
2074                      * do not properly active negate just before
2075                      * going busfree resulting in a parity glitch.
2076                      */
2077                     ahd_outb(ahd, CLRSINT1, CLRSCSIPERR|CLRBUSFREE);
2078 #ifdef AHD_DEBUG
2079                     if ((ahd_debug & AHD_SHOW_MASKED_ERRORS) != 0)
2080                               printf("%s: Parity on last REQ detected "
2081                                      "during busfree phase.\n",
2082                                      ahd_name(ahd));
2083 #endif
2084                     /* Return unpausing the sequencer. */
2085                     return (0);
2086           }
2087           if (ahd->src_mode != AHD_MODE_SCSI) {
2088                     u_int     scbid;
2089                     struct    scb *scb;
2090 
2091                     scbid = ahd_get_scbptr(ahd);
2092                     scb = ahd_lookup_scb(ahd, scbid);
2093                     ahd_print_path(ahd, scb);
2094                     printf("Unexpected PKT busfree condition\n");
2095                     ahd_dump_card_state(ahd);
2096                     ahd_abort_scbs(ahd, SCB_GET_TARGET(ahd, scb), 'A',
2097                                      SCB_GET_LUN(scb), SCB_GET_TAG(scb),
2098                                      ROLE_INITIATOR, CAM_UNEXP_BUSFREE);
2099 
2100                     /* Return restarting the sequencer. */
2101                     return (1);
2102           }
2103           printf("%s: Unexpected PKT busfree condition\n", ahd_name(ahd));
2104           ahd_dump_card_state(ahd);
2105           /* Restart the sequencer. */
2106           return (1);
2107 }
2108 
2109 /*
2110  * Non-packetized unexpected or expected busfree.
2111  */
2112 static int
ahd_handle_nonpkt_busfree(struct ahd_softc * ahd)2113 ahd_handle_nonpkt_busfree(struct ahd_softc *ahd)
2114 {
2115           struct    ahd_devinfo devinfo;
2116           struct    scb *scb;
2117           u_int     lastphase;
2118           u_int     saved_scsiid;
2119           u_int     saved_lun;
2120           u_int     target;
2121           u_int     initiator_role_id;
2122           u_int     scbid;
2123           u_int     ppr_busfree;
2124           int       printerror;
2125 
2126           /*
2127            * Look at what phase we were last in.  If its message out,
2128            * chances are pretty good that the busfree was in response
2129            * to one of our abort requests.
2130            */
2131           lastphase = ahd_inb(ahd, LASTPHASE);
2132           saved_scsiid = ahd_inb(ahd, SAVED_SCSIID);
2133           saved_lun = ahd_inb(ahd, SAVED_LUN);
2134           target = SCSIID_TARGET(ahd, saved_scsiid);
2135           initiator_role_id = SCSIID_OUR_ID(saved_scsiid);
2136           ahd_compile_devinfo(&devinfo, initiator_role_id,
2137                                   target, saved_lun, 'A', ROLE_INITIATOR);
2138           printerror = 1;
2139 
2140           scbid = ahd_get_scbptr(ahd);
2141           scb = ahd_lookup_scb(ahd, scbid);
2142           if (scb != NULL
2143            && (ahd_inb(ahd, SEQ_FLAGS) & NOT_IDENTIFIED) != 0)
2144                     scb = NULL;
2145 
2146           ppr_busfree = (ahd->msg_flags & MSG_FLAG_EXPECT_PPR_BUSFREE) != 0;
2147           if (lastphase == P_MESGOUT) {
2148                     u_int tag;
2149 
2150                     tag = SCB_LIST_NULL;
2151                     if (ahd_sent_msg(ahd, AHDMSG_1B, MSG_ABORT_TAG, TRUE)
2152                      || ahd_sent_msg(ahd, AHDMSG_1B, MSG_ABORT, TRUE)) {
2153                               int found;
2154                               int sent_msg;
2155 
2156                               if (scb == NULL) {
2157                                         ahd_print_devinfo(ahd, &devinfo);
2158                                         printf("Abort for unidentified "
2159                                                "connection completed.\n");
2160                                         /* restart the sequencer. */
2161                                         return (1);
2162                               }
2163                               sent_msg = ahd->msgout_buf[ahd->msgout_index - 1];
2164                               ahd_print_path(ahd, scb);
2165                               printf("SCB %d - Abort%s Completed.\n",
2166                                      SCB_GET_TAG(scb),
2167                                      sent_msg == MSG_ABORT_TAG ? "" : " Tag");
2168 
2169                               if (sent_msg == MSG_ABORT_TAG)
2170                                         tag = SCB_GET_TAG(scb);
2171 
2172                               if ((scb->flags & SCB_CMDPHASE_ABORT) != 0) {
2173                                         /*
2174                                          * This abort is in response to an
2175                                          * unexpected switch to command phase
2176                                          * for a packetized connection.  Since
2177                                          * the identify message was never sent,
2178                                          * "saved lun" is 0.  We really want to
2179                                          * abort only the SCB that encountered
2180                                          * this error, which could have a different
2181                                          * lun.  The SCB will be retried so the OS
2182                                          * will see the UA after renegotiating to
2183                                          * packetized.
2184                                          */
2185                                         tag = SCB_GET_TAG(scb);
2186                                         saved_lun = scb->hscb->lun;
2187                               }
2188                               found = ahd_abort_scbs(ahd, target, 'A', saved_lun,
2189                                                          tag, ROLE_INITIATOR,
2190                                                          CAM_REQ_ABORTED);
2191                               printf("found == 0x%x\n", found);
2192                               printerror = 0;
2193                     } else if (ahd_sent_msg(ahd, AHDMSG_1B,
2194                                                   MSG_BUS_DEV_RESET, TRUE)) {
2195 #ifdef __FreeBSD__
2196                               /*
2197                                * Don't mark the user's request for this BDR
2198                                * as completing with CAM_BDR_SENT.  CAM3
2199                                * specifies CAM_REQ_CMP.
2200                                */
2201                               if (scb != NULL
2202                                && scb->io_ctx->ccb_h.func_code== XPT_RESET_DEV
2203                                && ahd_match_scb(ahd, scb, target, 'A',
2204                                                     CAM_LUN_WILDCARD, SCB_LIST_NULL,
2205                                                     ROLE_INITIATOR))
2206                                         ahd_set_transaction_status(scb, CAM_REQ_CMP);
2207 #endif
2208                               ahd_handle_devreset(ahd, &devinfo, CAM_LUN_WILDCARD,
2209                                                       CAM_BDR_SENT, "Bus Device Reset",
2210                                                       /*verbose_level*/0);
2211                               printerror = 0;
2212                     } else if (ahd_sent_msg(ahd, AHDMSG_EXT, MSG_EXT_PPR, FALSE)
2213                               && ppr_busfree == 0) {
2214                               struct ahd_initiator_tinfo *tinfo;
2215                               struct ahd_tmode_tstate *tstate;
2216 
2217                               /*
2218                                * PPR Rejected.  Try non-ppr negotiation
2219                                * and retry command.
2220                                */
2221 #ifdef AHD_DEBUG
2222                               if ((ahd_debug & AHD_SHOW_MESSAGES) != 0)
2223                                         printf("PPR negotiation rejected busfree.\n");
2224 #endif
2225                               tinfo = ahd_fetch_transinfo(ahd, devinfo.channel,
2226                                                                 devinfo.our_scsiid,
2227                                                                 devinfo.target, &tstate);
2228                               tinfo->curr.transport_version = 2;
2229                               tinfo->goal.transport_version = 2;
2230                               tinfo->goal.ppr_options = 0;
2231                               ahd_qinfifo_requeue_tail(ahd, scb);
2232                               printerror = 0;
2233                     } else if (ahd_sent_msg(ahd, AHDMSG_EXT, MSG_EXT_WDTR, FALSE)
2234                               && ppr_busfree == 0) {
2235                               /*
2236                                * Negotiation Rejected.  Go-narrow and
2237                                * retry command.
2238                                */
2239 #ifdef AHD_DEBUG
2240                               if ((ahd_debug & AHD_SHOW_MESSAGES) != 0)
2241                                         printf("WDTR Negotiation rejected busfree.\n");
2242 #endif
2243                               ahd_set_width(ahd, &devinfo,
2244                                               MSG_EXT_WDTR_BUS_8_BIT,
2245                                               AHD_TRANS_CUR|AHD_TRANS_GOAL,
2246                                               /*paused*/TRUE);
2247                               ahd_qinfifo_requeue_tail(ahd, scb);
2248                               printerror = 0;
2249                     } else if (ahd_sent_msg(ahd, AHDMSG_EXT, MSG_EXT_SDTR, FALSE)
2250                               && ppr_busfree == 0) {
2251                               /*
2252                                * Negotiation Rejected.  Go-async and
2253                                * retry command.
2254                                */
2255 #ifdef AHD_DEBUG
2256                               if ((ahd_debug & AHD_SHOW_MESSAGES) != 0)
2257                                         printf("SDTR negotiation rejected busfree.\n");
2258 #endif
2259                               ahd_set_syncrate(ahd, &devinfo,
2260                                                   /*period*/0, /*offset*/0,
2261                                                   /*ppr_options*/0,
2262                                                   AHD_TRANS_CUR|AHD_TRANS_GOAL,
2263                                                   /*paused*/TRUE);
2264                               ahd_qinfifo_requeue_tail(ahd, scb);
2265                               printerror = 0;
2266                     } else if ((ahd->msg_flags & MSG_FLAG_EXPECT_IDE_BUSFREE) != 0
2267                               && ahd_sent_msg(ahd, AHDMSG_1B,
2268                                                    MSG_INITIATOR_DET_ERR, TRUE)) {
2269 
2270 #ifdef AHD_DEBUG
2271                               if ((ahd_debug & AHD_SHOW_MESSAGES) != 0)
2272                                         printf("Expected IDE Busfree\n");
2273 #endif
2274                               printerror = 0;
2275                     } else if ((ahd->msg_flags & MSG_FLAG_EXPECT_QASREJ_BUSFREE)
2276                               && ahd_sent_msg(ahd, AHDMSG_1B,
2277                                                   MSG_MESSAGE_REJECT, TRUE)) {
2278 
2279 #ifdef AHD_DEBUG
2280                               if ((ahd_debug & AHD_SHOW_MESSAGES) != 0)
2281                                         printf("Expected QAS Reject Busfree\n");
2282 #endif
2283                               printerror = 0;
2284                     }
2285           }
2286 
2287           /*
2288            * The busfree required flag is honored at the end of
2289            * the message phases.  We check it last in case we
2290            * had to send some other message that caused a busfree.
2291            */
2292           if (printerror != 0
2293            && (lastphase == P_MESGIN || lastphase == P_MESGOUT)
2294            && ((ahd->msg_flags & MSG_FLAG_EXPECT_PPR_BUSFREE) != 0)) {
2295 
2296                     ahd_freeze_devq(ahd, scb);
2297                     ahd_set_transaction_status(scb, CAM_REQUEUE_REQ);
2298                     ahd_freeze_scb(scb);
2299                     if ((ahd->msg_flags & MSG_FLAG_IU_REQ_CHANGED) != 0) {
2300                               ahd_abort_scbs(ahd, SCB_GET_TARGET(ahd, scb),
2301                                                SCB_GET_CHANNEL(ahd, scb),
2302                                                SCB_GET_LUN(scb), SCB_LIST_NULL,
2303                                                ROLE_INITIATOR, CAM_REQ_ABORTED);
2304                     } else {
2305 #ifdef AHD_DEBUG
2306                               if ((ahd_debug & AHD_SHOW_MESSAGES) != 0)
2307                                         printf("PPR Negotiation Busfree.\n");
2308 #endif
2309                               ahd_done(ahd, scb);
2310                     }
2311                     printerror = 0;
2312           }
2313           if (printerror != 0) {
2314                     int aborted;
2315 
2316                     aborted = 0;
2317                     if (scb != NULL) {
2318                               u_int tag;
2319 
2320                               if ((scb->hscb->control & TAG_ENB) != 0)
2321                                         tag = SCB_GET_TAG(scb);
2322                               else
2323                                         tag = SCB_LIST_NULL;
2324                               ahd_print_path(ahd, scb);
2325                               aborted = ahd_abort_scbs(ahd, target, 'A',
2326                                                SCB_GET_LUN(scb), tag,
2327                                                ROLE_INITIATOR,
2328                                                CAM_UNEXP_BUSFREE);
2329                     } else {
2330                               /*
2331                                * We had not fully identified this connection,
2332                                * so we cannot abort anything.
2333                                */
2334                               printf("%s: ", ahd_name(ahd));
2335                     }
2336                     if (lastphase != P_BUSFREE)
2337                               ahd_force_renegotiation(ahd, &devinfo);
2338                     printf("Unexpected busfree %s, %d SCBs aborted, "
2339                            "PRGMCNT == 0x%x\n",
2340                            ahd_lookup_phase_entry(lastphase)->phasemsg,
2341                            aborted,
2342                            ahd_inb(ahd, PRGMCNT)
2343                               | (ahd_inb(ahd, PRGMCNT+1) << 8));
2344                     ahd_dump_card_state(ahd);
2345           }
2346           /* Always restart the sequencer. */
2347           return (1);
2348 }
2349 
2350 static void
ahd_handle_proto_violation(struct ahd_softc * ahd)2351 ahd_handle_proto_violation(struct ahd_softc *ahd)
2352 {
2353           struct    ahd_devinfo devinfo;
2354           struct    scb *scb;
2355           u_int     scbid;
2356           u_int     seq_flags;
2357           u_int     curphase;
2358           u_int     lastphase;
2359           int       found;
2360 
2361           ahd_fetch_devinfo(ahd, &devinfo);
2362           scbid = ahd_get_scbptr(ahd);
2363           scb = ahd_lookup_scb(ahd, scbid);
2364           seq_flags = ahd_inb(ahd, SEQ_FLAGS);
2365           curphase = ahd_inb(ahd, SCSISIGI) & PHASE_MASK;
2366           lastphase = ahd_inb(ahd, LASTPHASE);
2367           if ((seq_flags & NOT_IDENTIFIED) != 0) {
2368 
2369                     /*
2370                      * The reconnecting target either did not send an
2371                      * identify message, or did, but we didn't find an SCB
2372                      * to match.
2373                      */
2374                     ahd_print_devinfo(ahd, &devinfo);
2375                     printf("Target did not send an IDENTIFY message. "
2376                            "LASTPHASE = 0x%x.\n", lastphase);
2377                     scb = NULL;
2378           } else if (scb == NULL) {
2379                     /*
2380                      * We don't seem to have an SCB active for this
2381                      * transaction.  Print an error and reset the bus.
2382                      */
2383                     ahd_print_devinfo(ahd, &devinfo);
2384                     printf("No SCB found during protocol violation\n");
2385                     goto proto_violation_reset;
2386           } else {
2387                     ahd_set_transaction_status(scb, CAM_SEQUENCE_FAIL);
2388                     if ((seq_flags & NO_CDB_SENT) != 0) {
2389                               ahd_print_path(ahd, scb);
2390                               printf("No or incomplete CDB sent to device.\n");
2391                     } else if ((ahd_inb_scbram(ahd, SCB_CONTROL)
2392                                 & STATUS_RCVD) == 0) {
2393                               /*
2394                                * The target never bothered to provide status to
2395                                * us prior to completing the command.  Since we don't
2396                                * know the disposition of this command, we must attempt
2397                                * to abort it.  Assert ATN and prepare to send an abort
2398                                * message.
2399                                */
2400                               ahd_print_path(ahd, scb);
2401                               printf("Completed command without status.\n");
2402                     } else {
2403                               ahd_print_path(ahd, scb);
2404                               printf("Unknown protocol violation.\n");
2405                               ahd_dump_card_state(ahd);
2406                     }
2407           }
2408           if ((lastphase & ~P_DATAIN_DT) == 0
2409            || lastphase == P_COMMAND) {
2410 proto_violation_reset:
2411                     /*
2412                      * Target either went directly to data
2413                      * phase or didn't respond to our ATN.
2414                      * The only safe thing to do is to blow
2415                      * it away with a bus reset.
2416                      */
2417                     found = ahd_reset_channel(ahd, 'A', TRUE);
2418                     printf("%s: Issued Channel %c Bus Reset. "
2419                            "%d SCBs aborted\n", ahd_name(ahd), 'A', found);
2420           } else {
2421                     /*
2422                      * Leave the selection hardware off in case
2423                      * this abort attempt will affect yet to
2424                      * be sent commands.
2425                      */
2426                     ahd_outb(ahd, SCSISEQ0,
2427                                ahd_inb(ahd, SCSISEQ0) & ~ENSELO);
2428                     ahd_assert_atn(ahd);
2429                     ahd_outb(ahd, MSG_OUT, HOST_MSG);
2430                     if (scb == NULL) {
2431                               ahd_print_devinfo(ahd, &devinfo);
2432                               ahd->msgout_buf[0] = MSG_ABORT_TASK;
2433                               ahd->msgout_len = 1;
2434                               ahd->msgout_index = 0;
2435                               ahd->msg_type = MSG_TYPE_INITIATOR_MSGOUT;
2436                     } else {
2437                               ahd_print_path(ahd, scb);
2438                               scb->flags |= SCB_ABORT;
2439                     }
2440                     printf("Protocol violation %s.  Attempting to abort.\n",
2441                            ahd_lookup_phase_entry(curphase)->phasemsg);
2442           }
2443 }
2444 
2445 /*
2446  * Force renegotiation to occur the next time we initiate
2447  * a command to the current device.
2448  */
2449 static void
ahd_force_renegotiation(struct ahd_softc * ahd,struct ahd_devinfo * devinfo)2450 ahd_force_renegotiation(struct ahd_softc *ahd, struct ahd_devinfo *devinfo)
2451 {
2452           struct    ahd_initiator_tinfo *targ_info;
2453           struct    ahd_tmode_tstate *tstate;
2454 
2455 #ifdef AHD_DEBUG
2456           if ((ahd_debug & AHD_SHOW_MESSAGES) != 0) {
2457                     ahd_print_devinfo(ahd, devinfo);
2458                     printf("Forcing renegotiation\n");
2459           }
2460 #endif
2461           targ_info = ahd_fetch_transinfo(ahd,
2462                                                   devinfo->channel,
2463                                                   devinfo->our_scsiid,
2464                                                   devinfo->target,
2465                                                   &tstate);
2466           ahd_update_neg_request(ahd, devinfo, tstate,
2467                                      targ_info, AHD_NEG_IF_NON_ASYNC);
2468 }
2469 
2470 #define AHD_MAX_STEPS 2000
2471 void
ahd_clear_critical_section(struct ahd_softc * ahd)2472 ahd_clear_critical_section(struct ahd_softc *ahd)
2473 {
2474           ahd_mode_state      saved_modes;
2475           int                 stepping;
2476           int                 steps;
2477           int                 first_instr;
2478           u_int               simode0;
2479           u_int               simode1;
2480           u_int               simode3;
2481           u_int               lqimode0;
2482           u_int               lqimode1;
2483           u_int               lqomode0;
2484           u_int               lqomode1;
2485 
2486           if (ahd->num_critical_sections == 0)
2487                     return;
2488 
2489           stepping = FALSE;
2490           steps = 0;
2491           first_instr = 0;
2492           simode0 = 0;
2493           simode1 = 0;
2494           simode3 = 0;
2495           lqimode0 = 0;
2496           lqimode1 = 0;
2497           lqomode0 = 0;
2498           lqomode1 = 0;
2499           saved_modes = ahd_save_modes(ahd);
2500           for (;;) {
2501                     struct    cs *cs;
2502                     u_int     seqaddr;
2503                     u_int     i;
2504 
2505                     ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI);
2506                     seqaddr = ahd_inb(ahd, CURADDR)
2507                               | (ahd_inb(ahd, CURADDR+1) << 8);
2508 
2509                     cs = ahd->critical_sections;
2510                     for (i = 0; i < ahd->num_critical_sections; i++, cs++) {
2511 
2512                               if (cs->begin < seqaddr && cs->end >= seqaddr)
2513                                         break;
2514                     }
2515 
2516                     if (i == ahd->num_critical_sections)
2517                               break;
2518 
2519                     if (steps > AHD_MAX_STEPS) {
2520                               printf("%s: Infinite loop in critical section\n"
2521                                      "%s: First Instruction 0x%x now 0x%x\n",
2522                                      ahd_name(ahd), ahd_name(ahd), first_instr,
2523                                      seqaddr);
2524                               ahd_dump_card_state(ahd);
2525                               panic("critical section loop");
2526                     }
2527 
2528                     steps++;
2529 #ifdef AHD_DEBUG
2530                     if ((ahd_debug & AHD_SHOW_MISC) != 0)
2531                               printf("%s: Single stepping at 0x%x\n", ahd_name(ahd),
2532                                      seqaddr);
2533 #endif
2534                     if (stepping == FALSE) {
2535 
2536                               first_instr = seqaddr;
2537                               ahd_set_modes(ahd, AHD_MODE_CFG, AHD_MODE_CFG);
2538                               simode0 = ahd_inb(ahd, SIMODE0);
2539                               simode3 = ahd_inb(ahd, SIMODE3);
2540                               lqimode0 = ahd_inb(ahd, LQIMODE0);
2541                               lqimode1 = ahd_inb(ahd, LQIMODE1);
2542                               lqomode0 = ahd_inb(ahd, LQOMODE0);
2543                               lqomode1 = ahd_inb(ahd, LQOMODE1);
2544                               ahd_outb(ahd, SIMODE0, 0);
2545                               ahd_outb(ahd, SIMODE3, 0);
2546                               ahd_outb(ahd, LQIMODE0, 0);
2547                               ahd_outb(ahd, LQIMODE1, 0);
2548                               ahd_outb(ahd, LQOMODE0, 0);
2549                               ahd_outb(ahd, LQOMODE1, 0);
2550                               ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI);
2551                               simode1 = ahd_inb(ahd, SIMODE1);
2552                               /*
2553                                * We don't clear ENBUSFREE.  Unfortunately
2554                                * we cannot re-enable busfree detection within
2555                                * the current connection, so we must leave it
2556                                * on while single stepping.
2557                                */
2558                               ahd_outb(ahd, SIMODE1, simode1 & ENBUSFREE);
2559                               ahd_outb(ahd, SEQCTL0, ahd_inb(ahd, SEQCTL0) | STEP);
2560                               stepping = TRUE;
2561                     }
2562                     ahd_outb(ahd, CLRSINT1, CLRBUSFREE);
2563                     ahd_outb(ahd, CLRINT, CLRSCSIINT);
2564                     ahd_set_modes(ahd, ahd->saved_src_mode, ahd->saved_dst_mode);
2565                     ahd_outb(ahd, HCNTRL, ahd->unpause);
2566                     while (!ahd_is_paused(ahd))
2567                               ahd_delay(200);
2568                     ahd_update_modes(ahd);
2569           }
2570           if (stepping) {
2571                     ahd_set_modes(ahd, AHD_MODE_CFG, AHD_MODE_CFG);
2572                     ahd_outb(ahd, SIMODE0, simode0);
2573                     ahd_outb(ahd, SIMODE3, simode3);
2574                     ahd_outb(ahd, LQIMODE0, lqimode0);
2575                     ahd_outb(ahd, LQIMODE1, lqimode1);
2576                     ahd_outb(ahd, LQOMODE0, lqomode0);
2577                     ahd_outb(ahd, LQOMODE1, lqomode1);
2578                     ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI);
2579                     ahd_outb(ahd, SEQCTL0, ahd_inb(ahd, SEQCTL0) & ~STEP);
2580                     ahd_outb(ahd, SIMODE1, simode1);
2581                     /*
2582                      * SCSIINT seems to glitch occasionally when
2583                      * the interrupt masks are restored.  Clear SCSIINT
2584                      * one more time so that only persistent errors
2585                      * are seen as a real interrupt.
2586                      */
2587                     ahd_outb(ahd, CLRINT, CLRSCSIINT);
2588           }
2589           ahd_restore_modes(ahd, saved_modes);
2590 }
2591 
2592 /*
2593  * Clear any pending interrupt status.
2594  */
2595 void
ahd_clear_intstat(struct ahd_softc * ahd)2596 ahd_clear_intstat(struct ahd_softc *ahd)
2597 {
2598           AHD_ASSERT_MODES(ahd, ~(AHD_MODE_UNKNOWN_MSK|AHD_MODE_CFG_MSK),
2599                                ~(AHD_MODE_UNKNOWN_MSK|AHD_MODE_CFG_MSK));
2600           /* Clear any interrupt conditions this may have caused */
2601           ahd_outb(ahd, CLRLQIINT0, CLRLQIATNQAS|CLRLQICRCT1|CLRLQICRCT2
2602                                          |CLRLQIBADLQT|CLRLQIATNLQ|CLRLQIATNCMD);
2603           ahd_outb(ahd, CLRLQIINT1, CLRLQIPHASE_LQ|CLRLQIPHASE_NLQ|CLRLIQABORT
2604                                          |CLRLQICRCI_LQ|CLRLQICRCI_NLQ|CLRLQIBADLQI
2605                                          |CLRLQIOVERI_LQ|CLRLQIOVERI_NLQ|CLRNONPACKREQ);
2606           ahd_outb(ahd, CLRLQOINT0, CLRLQOTARGSCBPERR|CLRLQOSTOPT2|CLRLQOATNLQ
2607                                          |CLRLQOATNPKT|CLRLQOTCRC);
2608           ahd_outb(ahd, CLRLQOINT1, CLRLQOINITSCBPERR|CLRLQOSTOPI2|CLRLQOBADQAS
2609                                          |CLRLQOBUSFREE|CLRLQOPHACHGINPKT);
2610           if ((ahd->bugs & AHD_CLRLQO_AUTOCLR_BUG) != 0) {
2611                     ahd_outb(ahd, CLRLQOINT0, 0);
2612                     ahd_outb(ahd, CLRLQOINT1, 0);
2613           }
2614           ahd_outb(ahd, CLRSINT3, CLRNTRAMPERR|CLROSRAMPERR);
2615           ahd_outb(ahd, CLRSINT1, CLRSELTIMEO|CLRATNO|CLRSCSIRSTI
2616                                         |CLRBUSFREE|CLRSCSIPERR|CLRREQINIT);
2617           ahd_outb(ahd, CLRSINT0, CLRSELDO|CLRSELDI|CLRSELINGO
2618                                       |CLRIOERR|CLROVERRUN);
2619           ahd_outb(ahd, CLRINT, CLRSCSIINT);
2620 }
2621 
2622 /**************************** Debugging Routines ******************************/
2623 #ifdef AHD_DEBUG
2624 uint32_t ahd_debug = AHD_DEBUG_OPTS;
2625 #endif
2626 void
ahd_print_scb(struct scb * scb)2627 ahd_print_scb(struct scb *scb)
2628 {
2629           struct hardware_scb *hscb;
2630           int i;
2631 
2632           hscb = scb->hscb;
2633           printf("scb:%p control:0x%x scsiid:0x%x lun:%d cdb_len:%d\n",
2634                  (void *)scb,
2635                  hscb->control,
2636                  hscb->scsiid,
2637                  hscb->lun,
2638                  hscb->cdb_len);
2639           printf("Shared Data: ");
2640           for (i = 0; i < sizeof(hscb->shared_data.idata.cdb); i++)
2641                     printf("%#02x", hscb->shared_data.idata.cdb[i]);
2642           printf("        dataptr:%#x%x datacnt:%#x sgptr:%#x tag:%#x\n",
2643                  (uint32_t)((ahd_le64toh(hscb->dataptr) >> 32) & 0xFFFFFFFF),
2644                  (uint32_t)(ahd_le64toh(hscb->dataptr) & 0xFFFFFFFF),
2645                  ahd_le32toh(hscb->datacnt),
2646                  ahd_le32toh(hscb->sgptr),
2647                  SCB_GET_TAG(scb));
2648           ahd_dump_sglist(scb);
2649 }
2650 
2651 void
ahd_dump_sglist(struct scb * scb)2652 ahd_dump_sglist(struct scb *scb)
2653 {
2654           int i;
2655 
2656           if (scb->sg_count > 0) {
2657                     if ((scb->ahd_softc->flags & AHD_64BIT_ADDRESSING) != 0) {
2658                               struct ahd_dma64_seg *sg_list;
2659 
2660                               sg_list = (struct ahd_dma64_seg*)scb->sg_list;
2661                               for (i = 0; i < scb->sg_count; i++) {
2662                                         uint64_t addr;
2663 
2664                                         addr = ahd_le64toh(sg_list[i].addr);
2665                                         printf("sg[%d] - Addr 0x%x%x : Length %d%s\n",
2666                                                i,
2667                                                (uint32_t)((addr >> 32) & 0xFFFFFFFF),
2668                                                (uint32_t)(addr & 0xFFFFFFFF),
2669                                                sg_list[i].len & AHD_SG_LEN_MASK,
2670                                                (sg_list[i].len & AHD_DMA_LAST_SEG)
2671                                              ? " Last" : "");
2672                               }
2673                     } else {
2674                               struct ahd_dma_seg *sg_list;
2675 
2676                               sg_list = (struct ahd_dma_seg*)scb->sg_list;
2677                               for (i = 0; i < scb->sg_count; i++) {
2678                                         uint32_t len;
2679 
2680                                         len = ahd_le32toh(sg_list[i].len);
2681                                         printf("sg[%d] - Addr 0x%x%x : Length %d%s\n",
2682                                                i,
2683                                                (len & AHD_SG_HIGH_ADDR_MASK) >> 24,
2684                                                ahd_le32toh(sg_list[i].addr),
2685                                                len & AHD_SG_LEN_MASK,
2686                                                len & AHD_DMA_LAST_SEG ? " Last" : "");
2687                               }
2688                     }
2689           }
2690 }
2691 
2692 /************************* Transfer Negotiation *******************************/
2693 /*
2694  * Allocate per target mode instance (ID we respond to as a target)
2695  * transfer negotiation data structures.
2696  */
2697 static struct ahd_tmode_tstate *
ahd_alloc_tstate(struct ahd_softc * ahd,u_int scsi_id,char channel)2698 ahd_alloc_tstate(struct ahd_softc *ahd, u_int scsi_id, char channel)
2699 {
2700           struct ahd_tmode_tstate *master_tstate;
2701           struct ahd_tmode_tstate *tstate;
2702           int i;
2703 
2704           master_tstate = ahd->enabled_targets[ahd->our_id];
2705           if (ahd->enabled_targets[scsi_id] != NULL
2706            && ahd->enabled_targets[scsi_id] != master_tstate)
2707                     panic("%s: ahd_alloc_tstate - Target already allocated",
2708                           ahd_name(ahd));
2709           tstate = malloc(sizeof(*tstate), M_DEVBUF, M_WAITOK | M_ZERO);
2710 
2711           /*
2712            * If we have allocated a master tstate, copy user settings from
2713            * the master tstate (taken from SRAM or the EEPROM) for this
2714            * channel, but reset our current and goal settings to async/narrow
2715            * until an initiator talks to us.
2716            */
2717           if (master_tstate != NULL) {
2718                     memcpy(tstate, master_tstate, sizeof(*tstate));
2719                     memset(tstate->enabled_luns, 0, sizeof(tstate->enabled_luns));
2720                     for (i = 0; i < 16; i++) {
2721                               memset(&tstate->transinfo[i].curr, 0,
2722                                     sizeof(tstate->transinfo[i].curr));
2723                               memset(&tstate->transinfo[i].goal, 0,
2724                                     sizeof(tstate->transinfo[i].goal));
2725                     }
2726           } else
2727                     memset(tstate, 0, sizeof(*tstate));
2728           ahd->enabled_targets[scsi_id] = tstate;
2729           return (tstate);
2730 }
2731 
2732 #ifdef AHD_TARGET_MODE
2733 /*
2734  * Free per target mode instance (ID we respond to as a target)
2735  * transfer negotiation data structures.
2736  */
2737 static void
ahd_free_tstate(struct ahd_softc * ahd,u_int scsi_id,char channel,int force)2738 ahd_free_tstate(struct ahd_softc *ahd, u_int scsi_id, char channel, int force)
2739 {
2740           struct ahd_tmode_tstate *tstate;
2741 
2742           /*
2743            * Don't clean up our "master" tstate.
2744            * It has our default user settings.
2745            */
2746           if (scsi_id == ahd->our_id
2747            && force == FALSE)
2748                     return;
2749 
2750           tstate = ahd->enabled_targets[scsi_id];
2751           if (tstate != NULL)
2752                     free(tstate, M_DEVBUF);
2753           ahd->enabled_targets[scsi_id] = NULL;
2754 }
2755 #endif
2756 
2757 /*
2758  * Called when we have an active connection to a target on the bus,
2759  * this function finds the nearest period to the input period limited
2760  * by the capabilities of the bus connectivity of and sync settings for
2761  * the target.
2762  */
2763 void
ahd_devlimited_syncrate(struct ahd_softc * ahd,struct ahd_initiator_tinfo * tinfo,u_int * period,u_int * ppr_options,role_t role)2764 ahd_devlimited_syncrate(struct ahd_softc *ahd,
2765                               struct ahd_initiator_tinfo *tinfo,
2766                               u_int *period, u_int *ppr_options, role_t role)
2767 {
2768           struct    ahd_transinfo *transinfo;
2769           u_int     maxsync;
2770 
2771           if ((ahd_inb(ahd, SBLKCTL) & ENAB40) != 0
2772            && (ahd_inb(ahd, SSTAT2) & EXP_ACTIVE) == 0) {
2773                     maxsync = AHD_SYNCRATE_PACED;
2774           } else {
2775                     maxsync = AHD_SYNCRATE_ULTRA;
2776                     /* Can't do DT related options on an SE bus */
2777                     *ppr_options &= MSG_EXT_PPR_QAS_REQ;
2778           }
2779           /*
2780            * Never allow a value higher than our current goal
2781            * period otherwise we may allow a target initiated
2782            * negotiation to go above the limit as set by the
2783            * user.  In the case of an initiator initiated
2784            * sync negotiation, we limit based on the user
2785            * setting.  This allows the system to still accept
2786            * incoming negotiations even if target initiated
2787            * negotiation is not performed.
2788            */
2789           if (role == ROLE_TARGET)
2790                     transinfo = &tinfo->user;
2791           else
2792                     transinfo = &tinfo->goal;
2793           *ppr_options &= (transinfo->ppr_options|MSG_EXT_PPR_PCOMP_EN);
2794           if (transinfo->width == MSG_EXT_WDTR_BUS_8_BIT) {
2795                     maxsync = MAX(maxsync, AHD_SYNCRATE_ULTRA2);
2796                     *ppr_options &= ~MSG_EXT_PPR_DT_REQ;
2797           }
2798           if (transinfo->period == 0) {
2799                     *period = 0;
2800                     *ppr_options = 0;
2801           } else {
2802                     *period = MAX(*period, transinfo->period);
2803                     ahd_find_syncrate(ahd, period, ppr_options, maxsync);
2804           }
2805 }
2806 
2807 /*
2808  * Look up the valid period to SCSIRATE conversion in our table.
2809  * Return the period and offset that should be sent to the target
2810  * if this was the beginning of an SDTR.
2811  */
2812 void
ahd_find_syncrate(struct ahd_softc * ahd,u_int * period,u_int * ppr_options,u_int maxsync)2813 ahd_find_syncrate(struct ahd_softc *ahd, u_int *period,
2814                       u_int *ppr_options, u_int maxsync)
2815 {
2816           if (*period < maxsync)
2817                     *period = maxsync;
2818 
2819           if ((*ppr_options & MSG_EXT_PPR_DT_REQ) != 0
2820            && *period > AHD_SYNCRATE_MIN_DT)
2821                     *ppr_options &= ~MSG_EXT_PPR_DT_REQ;
2822 
2823           if (*period > AHD_SYNCRATE_MIN)
2824                     *period = 0;
2825 
2826           /* Honor PPR option conformance rules. */
2827           if (*period > AHD_SYNCRATE_PACED)
2828                     *ppr_options &= ~MSG_EXT_PPR_RTI;
2829 
2830           if ((*ppr_options & MSG_EXT_PPR_IU_REQ) == 0)
2831                     *ppr_options &= (MSG_EXT_PPR_DT_REQ|MSG_EXT_PPR_QAS_REQ);
2832 
2833           if ((*ppr_options & MSG_EXT_PPR_DT_REQ) == 0)
2834                     *ppr_options &= MSG_EXT_PPR_QAS_REQ;
2835 
2836           /* Skip all PACED only entries if IU is not available */
2837           if ((*ppr_options & MSG_EXT_PPR_IU_REQ) == 0
2838            && *period < AHD_SYNCRATE_DT)
2839                     *period = AHD_SYNCRATE_DT;
2840 
2841           /* Skip all DT only entries if DT is not available */
2842           if ((*ppr_options & MSG_EXT_PPR_DT_REQ) == 0
2843            && *period < AHD_SYNCRATE_ULTRA2)
2844                     *period = AHD_SYNCRATE_ULTRA2;
2845 }
2846 
2847 /*
2848  * Truncate the given synchronous offset to a value the
2849  * current adapter type and syncrate are capable of.
2850  */
2851 void
ahd_validate_offset(struct ahd_softc * ahd,struct ahd_initiator_tinfo * tinfo,u_int period,u_int * offset,int wide,role_t role)2852 ahd_validate_offset(struct ahd_softc *ahd,
2853                         struct ahd_initiator_tinfo *tinfo,
2854                         u_int period, u_int *offset, int wide,
2855                         role_t role)
2856 {
2857           u_int maxoffset;
2858 
2859           /* Limit offset to what we can do */
2860           if (period == 0)
2861                     maxoffset = 0;
2862           else if (period <= AHD_SYNCRATE_PACED) {
2863                     if ((ahd->bugs & AHD_PACED_NEGTABLE_BUG) != 0)
2864                               maxoffset = MAX_OFFSET_PACED_BUG;
2865                     else
2866                               maxoffset = MAX_OFFSET_PACED;
2867           } else
2868                     maxoffset = MAX_OFFSET_NON_PACED;
2869           *offset = MIN(*offset, maxoffset);
2870           if (tinfo != NULL) {
2871                     if (role == ROLE_TARGET)
2872                               *offset = MIN(*offset, tinfo->user.offset);
2873                     else
2874                               *offset = MIN(*offset, tinfo->goal.offset);
2875           }
2876 }
2877 
2878 /*
2879  * Truncate the given transfer width parameter to a value the
2880  * current adapter type is capable of.
2881  */
2882 void
ahd_validate_width(struct ahd_softc * ahd,struct ahd_initiator_tinfo * tinfo,u_int * bus_width,role_t role)2883 ahd_validate_width(struct ahd_softc *ahd, struct ahd_initiator_tinfo *tinfo,
2884                        u_int *bus_width, role_t role)
2885 {
2886           switch (*bus_width) {
2887           default:
2888                     if (ahd->features & AHD_WIDE) {
2889                               /* Respond Wide */
2890                               *bus_width = MSG_EXT_WDTR_BUS_16_BIT;
2891                               break;
2892                     }
2893                     /* FALLTHROUGH */
2894           case MSG_EXT_WDTR_BUS_8_BIT:
2895                     *bus_width = MSG_EXT_WDTR_BUS_8_BIT;
2896                     break;
2897           }
2898           if (tinfo != NULL) {
2899                     if (role == ROLE_TARGET)
2900                               *bus_width = MIN(tinfo->user.width, *bus_width);
2901                     else
2902                               *bus_width = MIN(tinfo->goal.width, *bus_width);
2903           }
2904 }
2905 
2906 /*
2907  * Update the bitmask of targets for which the controller should
2908  * negotiate with at the next convenient opportunity.  This currently
2909  * means the next time we send the initial identify messages for
2910  * a new transaction.
2911  */
2912 int
ahd_update_neg_request(struct ahd_softc * ahd,struct ahd_devinfo * devinfo,struct ahd_tmode_tstate * tstate,struct ahd_initiator_tinfo * tinfo,ahd_neg_type neg_type)2913 ahd_update_neg_request(struct ahd_softc *ahd, struct ahd_devinfo *devinfo,
2914                            struct ahd_tmode_tstate *tstate,
2915                            struct ahd_initiator_tinfo *tinfo, ahd_neg_type neg_type)
2916 {
2917           u_int auto_negotiate_orig;
2918 
2919           auto_negotiate_orig = tstate->auto_negotiate;
2920           if (neg_type == AHD_NEG_ALWAYS) {
2921                     /*
2922                      * Force our "current" settings to be
2923                      * unknown so that unless a bus reset
2924                      * occurs the need to renegotiate is
2925                      * recorded persistently.
2926                      */
2927                     if ((ahd->features & AHD_WIDE) != 0)
2928                               tinfo->curr.width = AHD_WIDTH_UNKNOWN;
2929                     tinfo->curr.period = AHD_PERIOD_UNKNOWN;
2930                     tinfo->curr.offset = AHD_OFFSET_UNKNOWN;
2931           }
2932           if (tinfo->curr.period != tinfo->goal.period
2933            || tinfo->curr.width != tinfo->goal.width
2934            || tinfo->curr.offset != tinfo->goal.offset
2935            || tinfo->curr.ppr_options != tinfo->goal.ppr_options
2936            || (neg_type == AHD_NEG_IF_NON_ASYNC
2937             && (tinfo->goal.offset != 0
2938              || tinfo->goal.width != MSG_EXT_WDTR_BUS_8_BIT
2939              || tinfo->goal.ppr_options != 0)))
2940                     tstate->auto_negotiate |= devinfo->target_mask;
2941           else
2942                     tstate->auto_negotiate &= ~devinfo->target_mask;
2943 
2944           return (auto_negotiate_orig != tstate->auto_negotiate);
2945 }
2946 
2947 /*
2948  * Update the user/goal/curr tables of synchronous negotiation
2949  * parameters as well as, in the case of a current or active update,
2950  * any data structures on the host controller.  In the case of an
2951  * active update, the specified target is currently talking to us on
2952  * the bus, so the transfer parameter update must take effect
2953  * immediately.
2954  */
2955 void
ahd_set_syncrate(struct ahd_softc * ahd,struct ahd_devinfo * devinfo,u_int period,u_int offset,u_int ppr_options,u_int type,int paused)2956 ahd_set_syncrate(struct ahd_softc *ahd, struct ahd_devinfo *devinfo,
2957                      u_int period, u_int offset, u_int ppr_options,
2958                      u_int type, int paused)
2959 {
2960           struct    ahd_initiator_tinfo *tinfo;
2961           struct    ahd_tmode_tstate *tstate;
2962           u_int     old_period;
2963           u_int     old_offset;
2964           u_int     old_ppr;
2965           int       active;
2966           int       update_needed;
2967 
2968           active = (type & AHD_TRANS_ACTIVE) == AHD_TRANS_ACTIVE;
2969           update_needed = 0;
2970 
2971           if (period == 0 || offset == 0) {
2972                     period = 0;
2973                     offset = 0;
2974           }
2975 
2976           tinfo = ahd_fetch_transinfo(ahd, devinfo->channel, devinfo->our_scsiid,
2977                                             devinfo->target, &tstate);
2978 
2979           if ((type & AHD_TRANS_USER) != 0) {
2980                     tinfo->user.period = period;
2981                     tinfo->user.offset = offset;
2982                     tinfo->user.ppr_options = ppr_options;
2983           }
2984 
2985           if ((type & AHD_TRANS_GOAL) != 0) {
2986                     tinfo->goal.period = period;
2987                     tinfo->goal.offset = offset;
2988                     tinfo->goal.ppr_options = ppr_options;
2989           }
2990 
2991           old_period = tinfo->curr.period;
2992           old_offset = tinfo->curr.offset;
2993           old_ppr    = tinfo->curr.ppr_options;
2994 
2995           if ((type & AHD_TRANS_CUR) != 0
2996            && (old_period != period
2997             || old_offset != offset
2998             || old_ppr != ppr_options)) {
2999 
3000                     update_needed++;
3001 
3002                     tinfo->curr.period = period;
3003                     tinfo->curr.offset = offset;
3004                     tinfo->curr.ppr_options = ppr_options;
3005 
3006                     ahd_send_async(ahd, devinfo->channel, devinfo->target,
3007                                      CAM_LUN_WILDCARD, AC_TRANSFER_NEG, NULL);
3008 
3009                     if (bootverbose) {
3010                               if (offset != 0) {
3011                                         int options;
3012 
3013                                         printf("%s: target %d synchronous with "
3014                                                "period = 0x%x, offset = 0x%x",
3015                                                ahd_name(ahd), devinfo->target,
3016                                                period, offset);
3017                                         options = 0;
3018                                         if ((ppr_options & MSG_EXT_PPR_RD_STRM) != 0) {
3019                                                   printf("(RDSTRM");
3020                                                   options++;
3021                                         }
3022                                         if ((ppr_options & MSG_EXT_PPR_DT_REQ) != 0) {
3023                                                   printf("%s", options ? "|DT" : "(DT");
3024                                                   options++;
3025                                         }
3026                                         if ((ppr_options & MSG_EXT_PPR_IU_REQ) != 0) {
3027                                                   printf("%s", options ? "|IU" : "(IU");
3028                                                   options++;
3029                                         }
3030                                         if ((ppr_options & MSG_EXT_PPR_RTI) != 0) {
3031                                                   printf("%s", options ? "|RTI" : "(RTI");
3032                                                   options++;
3033                                         }
3034                                         if ((ppr_options & MSG_EXT_PPR_QAS_REQ) != 0) {
3035                                                   printf("%s", options ? "|QAS" : "(QAS");
3036                                                   options++;
3037                                         }
3038                                         if (options != 0)
3039                                                   printf(")\n");
3040                                         else
3041                                                   printf("\n");
3042                               } else {
3043                                         printf("%s: target %d using "
3044                                                "asynchronous transfers%s\n",
3045                                                ahd_name(ahd), devinfo->target,
3046                                                (ppr_options & MSG_EXT_PPR_QAS_REQ) != 0
3047                                              ?  "(QAS)" : "");
3048                               }
3049                     }
3050           }
3051           /*
3052            * Always refresh the neg-table to handle the case of the
3053            * sequencer setting the ENATNO bit for a MK_MESSAGE request.
3054            * We will always renegotiate in that case if this is a
3055            * packetized request.  Also manage the busfree expected flag
3056            * from this common routine so that we catch changes due to
3057            * WDTR or SDTR messages.
3058            */
3059           if ((type & AHD_TRANS_CUR) != 0) {
3060                     if (!paused)
3061                               ahd_pause(ahd);
3062                     ahd_update_neg_table(ahd, devinfo, &tinfo->curr);
3063                     if (!paused)
3064                               ahd_unpause(ahd);
3065                     if (ahd->msg_type != MSG_TYPE_NONE) {
3066                               if ((old_ppr & MSG_EXT_PPR_IU_REQ)
3067                                != (ppr_options & MSG_EXT_PPR_IU_REQ)) {
3068 #ifdef AHD_DEBUG
3069                                         if ((ahd_debug & AHD_SHOW_MESSAGES) != 0) {
3070                                                   ahd_print_devinfo(ahd, devinfo);
3071                                                   printf("Expecting IU Change busfree\n");
3072                                         }
3073 #endif
3074                                         ahd->msg_flags |= MSG_FLAG_EXPECT_PPR_BUSFREE
3075                                                          |  MSG_FLAG_IU_REQ_CHANGED;
3076                               }
3077                               if ((old_ppr & MSG_EXT_PPR_IU_REQ) != 0) {
3078 #ifdef AHD_DEBUG
3079                                         if ((ahd_debug & AHD_SHOW_MESSAGES) != 0)
3080                                                   printf("PPR with IU_REQ outstanding\n");
3081 #endif
3082                                         ahd->msg_flags |= MSG_FLAG_EXPECT_PPR_BUSFREE;
3083                               }
3084                     }
3085           }
3086 
3087           update_needed += ahd_update_neg_request(ahd, devinfo, tstate,
3088                                                             tinfo, AHD_NEG_TO_GOAL);
3089 
3090           if (update_needed && active)
3091                     ahd_update_pending_scbs(ahd);
3092 }
3093 
3094 /*
3095  * Update the user/goal/curr tables of wide negotiation
3096  * parameters as well as, in the case of a current or active update,
3097  * any data structures on the host controller.  In the case of an
3098  * active update, the specified target is currently talking to us on
3099  * the bus, so the transfer parameter update must take effect
3100  * immediately.
3101  */
3102 void
ahd_set_width(struct ahd_softc * ahd,struct ahd_devinfo * devinfo,u_int width,u_int type,int paused)3103 ahd_set_width(struct ahd_softc *ahd, struct ahd_devinfo *devinfo,
3104                 u_int width, u_int type, int paused)
3105 {
3106           struct    ahd_initiator_tinfo *tinfo;
3107           struct    ahd_tmode_tstate *tstate;
3108           u_int     oldwidth;
3109           int       active;
3110           int       update_needed;
3111 
3112           active = (type & AHD_TRANS_ACTIVE) == AHD_TRANS_ACTIVE;
3113           update_needed = 0;
3114           tinfo = ahd_fetch_transinfo(ahd, devinfo->channel, devinfo->our_scsiid,
3115                                             devinfo->target, &tstate);
3116 
3117           if ((type & AHD_TRANS_USER) != 0)
3118                     tinfo->user.width = width;
3119 
3120           if ((type & AHD_TRANS_GOAL) != 0)
3121                     tinfo->goal.width = width;
3122 
3123           oldwidth = tinfo->curr.width;
3124           if ((type & AHD_TRANS_CUR) != 0 && oldwidth != width) {
3125 
3126                     update_needed++;
3127 
3128                     tinfo->curr.width = width;
3129                     ahd_send_async(ahd, devinfo->channel, devinfo->target,
3130                                      CAM_LUN_WILDCARD, AC_TRANSFER_NEG, NULL);
3131 
3132                     if (bootverbose) {
3133                               printf("%s: target %d using %dbit transfers\n",
3134                                      ahd_name(ahd), devinfo->target,
3135                                      8 * (0x01 << width));
3136                     }
3137           }
3138 
3139           if ((type & AHD_TRANS_CUR) != 0) {
3140                     if (!paused)
3141                               ahd_pause(ahd);
3142                     ahd_update_neg_table(ahd, devinfo, &tinfo->curr);
3143                     if (!paused)
3144                               ahd_unpause(ahd);
3145           }
3146 
3147           update_needed += ahd_update_neg_request(ahd, devinfo, tstate,
3148                                                             tinfo, AHD_NEG_TO_GOAL);
3149           if (update_needed && active)
3150                     ahd_update_pending_scbs(ahd);
3151 
3152 }
3153 
3154 /*
3155  * Update the current state of tagged queuing for a given target.
3156  */
3157 void
ahd_set_tags(struct ahd_softc * ahd,struct ahd_devinfo * devinfo,ahd_queue_alg alg)3158 ahd_set_tags(struct ahd_softc *ahd, struct ahd_devinfo *devinfo,
3159              ahd_queue_alg alg)
3160 {
3161           ahd_platform_set_tags(ahd, devinfo, alg);
3162           ahd_send_async(ahd, devinfo->channel, devinfo->target,
3163                            devinfo->lun, AC_TRANSFER_NEG, &alg);
3164 }
3165 
3166 static void
ahd_update_neg_table(struct ahd_softc * ahd,struct ahd_devinfo * devinfo,struct ahd_transinfo * tinfo)3167 ahd_update_neg_table(struct ahd_softc *ahd, struct ahd_devinfo *devinfo,
3168                          struct ahd_transinfo *tinfo)
3169 {
3170           ahd_mode_state      saved_modes;
3171           u_int               period;
3172           u_int               ppr_opts;
3173           u_int               con_opts;
3174           u_int               offset;
3175           u_int               saved_negoaddr;
3176           uint8_t             iocell_opts[sizeof(ahd->iocell_opts)];
3177 
3178           saved_modes = ahd_save_modes(ahd);
3179           ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI);
3180 
3181           saved_negoaddr = ahd_inb(ahd, NEGOADDR);
3182           ahd_outb(ahd, NEGOADDR, devinfo->target);
3183           period = tinfo->period;
3184           offset = tinfo->offset;
3185           memcpy(iocell_opts, ahd->iocell_opts, sizeof(ahd->iocell_opts));
3186           ppr_opts = tinfo->ppr_options & (MSG_EXT_PPR_QAS_REQ|MSG_EXT_PPR_DT_REQ
3187                                                   |MSG_EXT_PPR_IU_REQ|MSG_EXT_PPR_RTI);
3188           con_opts = 0;
3189           if (period == 0)
3190                     period = AHD_SYNCRATE_ASYNC;
3191           if (period == AHD_SYNCRATE_160) {
3192 
3193                     if ((ahd->bugs & AHD_PACED_NEGTABLE_BUG) != 0) {
3194                               /*
3195                                * When the SPI4 spec was finalized, PACE transfers
3196                                * was not made a configurable option in the PPR
3197                                * message.  Instead it is assumed to be enabled for
3198                                * any syncrate faster than 80MHz.  Nevertheless,
3199                                * Harpoon2A4 allows this to be configurable.
3200                                *
3201                                * Harpoon2A4 also assumes at most 2 data bytes per
3202                                * negotiated REQ/ACK offset.  Paced transfers take
3203                                * 4, so we must adjust our offset.
3204                                */
3205                               ppr_opts |= PPROPT_PACE;
3206                               offset *= 2;
3207 
3208                               /*
3209                                * Harpoon2A assumed that there would be a
3210                                * fallback rate between 160 MHz and 80 MHz,
3211                                * so 7 is used as the period factor rather
3212                                * than 8 for 160MHz.
3213                                */
3214                               period = AHD_SYNCRATE_REVA_160;
3215                     }
3216                     if ((tinfo->ppr_options & MSG_EXT_PPR_PCOMP_EN) == 0)
3217                               iocell_opts[AHD_PRECOMP_SLEW_INDEX] &=
3218                                   ~AHD_PRECOMP_MASK;
3219           } else {
3220                     /*
3221                      * Precomp should be disabled for non-paced transfers.
3222                      */
3223                     iocell_opts[AHD_PRECOMP_SLEW_INDEX] &= ~AHD_PRECOMP_MASK;
3224 
3225                     if ((ahd->features & AHD_NEW_IOCELL_OPTS) != 0
3226                      && (ppr_opts & MSG_EXT_PPR_DT_REQ) != 0) {
3227                               /*
3228                                * Slow down our CRC interval to be
3229                                * compatible with devices that can't
3230                                * handle a CRC at full speed.
3231                                */
3232                               con_opts |= ENSLOWCRC;
3233                     }
3234           }
3235 
3236           ahd_outb(ahd, ANNEXCOL, AHD_ANNEXCOL_PRECOMP_SLEW);
3237           ahd_outb(ahd, ANNEXDAT, iocell_opts[AHD_PRECOMP_SLEW_INDEX]);
3238           ahd_outb(ahd, ANNEXCOL, AHD_ANNEXCOL_AMPLITUDE);
3239           ahd_outb(ahd, ANNEXDAT, iocell_opts[AHD_AMPLITUDE_INDEX]);
3240 
3241           ahd_outb(ahd, NEGPERIOD, period);
3242           ahd_outb(ahd, NEGPPROPTS, ppr_opts);
3243           ahd_outb(ahd, NEGOFFSET, offset);
3244 
3245           if (tinfo->width == MSG_EXT_WDTR_BUS_16_BIT)
3246                     con_opts |= WIDEXFER;
3247 
3248           /*
3249            * During packetized transfers, the target will
3250            * give us the opportunity to send command packets
3251            * without us asserting attention.
3252            */
3253           if ((tinfo->ppr_options & MSG_EXT_PPR_IU_REQ) == 0)
3254                     con_opts |= ENAUTOATNO;
3255           ahd_outb(ahd, NEGCONOPTS, con_opts);
3256           ahd_outb(ahd, NEGOADDR, saved_negoaddr);
3257           ahd_restore_modes(ahd, saved_modes);
3258 }
3259 
3260 /*
3261  * When the transfer settings for a connection change, setup for
3262  * negotiation in pending SCBs to effect the change as quickly as
3263  * possible.  We also cancel any negotiations that are scheduled
3264  * for inflight SCBs that have not been started yet.
3265  */
3266 static void
ahd_update_pending_scbs(struct ahd_softc * ahd)3267 ahd_update_pending_scbs(struct ahd_softc *ahd)
3268 {
3269           struct              scb *pending_scb;
3270           int                 pending_scb_count;
3271           u_int               scb_tag;
3272           int                 paused;
3273           u_int               saved_scbptr;
3274           ahd_mode_state      saved_modes;
3275 
3276           /*
3277            * Traverse the pending SCB list and ensure that all of the
3278            * SCBs there have the proper settings.  We can only safely
3279            * clear the negotiation required flag (setting requires the
3280            * execution queue to be modified) and this is only possible
3281            * if we are not already attempting to select out for this
3282            * SCB.  For this reason, all callers only call this routine
3283            * if we are changing the negotiation settings for the currently
3284            * active transaction on the bus.
3285            */
3286           pending_scb_count = 0;
3287           LIST_FOREACH(pending_scb, &ahd->pending_scbs, pending_links) {
3288                     struct ahd_devinfo devinfo;
3289                     struct hardware_scb *pending_hscb;
3290                     struct ahd_tmode_tstate *tstate;
3291 
3292                     ahd_scb_devinfo(ahd, &devinfo, pending_scb);
3293                     (void)ahd_fetch_transinfo(ahd, devinfo.channel,
3294                                                     devinfo.our_scsiid,
3295                                                     devinfo.target, &tstate);
3296                     pending_hscb = pending_scb->hscb;
3297                     if ((tstate->auto_negotiate & devinfo.target_mask) == 0
3298                      && (pending_scb->flags & SCB_AUTO_NEGOTIATE) != 0) {
3299                               pending_scb->flags &= ~SCB_AUTO_NEGOTIATE;
3300                               pending_hscb->control &= ~MK_MESSAGE;
3301                     }
3302                     ahd_sync_scb(ahd, pending_scb,
3303                                    BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
3304                     pending_scb_count++;
3305           }
3306 
3307           if (pending_scb_count == 0)
3308                     return;
3309 
3310           if (ahd_is_paused(ahd)) {
3311                     paused = 1;
3312           } else {
3313                     paused = 0;
3314                     ahd_pause(ahd);
3315           }
3316 
3317           /*
3318            * Force the sequencer to reinitialize the selection for
3319            * the command at the head of the execution queue if it
3320            * has already been setup.  The negotiation changes may
3321            * effect whether we select-out with ATN.
3322            */
3323           saved_modes = ahd_save_modes(ahd);
3324           ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI);
3325           ahd_outb(ahd, SCSISEQ0, ahd_inb(ahd, SCSISEQ0) & ~ENSELO);
3326           saved_scbptr = ahd_get_scbptr(ahd);
3327           /* Ensure that the hscbs down on the card match the new information */
3328           for (scb_tag = 0; scb_tag < ahd->scb_data.maxhscbs; scb_tag++) {
3329                     struct    hardware_scb *pending_hscb;
3330                     u_int     control;
3331 
3332                     pending_scb = ahd_lookup_scb(ahd, scb_tag);
3333                     if (pending_scb == NULL)
3334                               continue;
3335                     ahd_set_scbptr(ahd, scb_tag);
3336                     pending_hscb = pending_scb->hscb;
3337                     control = ahd_inb_scbram(ahd, SCB_CONTROL);
3338                     control &= ~MK_MESSAGE;
3339                     control |= pending_hscb->control & MK_MESSAGE;
3340                     ahd_outb(ahd, SCB_CONTROL, control);
3341           }
3342           ahd_set_scbptr(ahd, saved_scbptr);
3343           ahd_restore_modes(ahd, saved_modes);
3344 
3345           if (paused == 0)
3346                     ahd_unpause(ahd);
3347 }
3348 
3349 /**************************** Pathing Information *****************************/
3350 static void
ahd_fetch_devinfo(struct ahd_softc * ahd,struct ahd_devinfo * devinfo)3351 ahd_fetch_devinfo(struct ahd_softc *ahd, struct ahd_devinfo *devinfo)
3352 {
3353           ahd_mode_state      saved_modes;
3354           u_int               saved_scsiid;
3355           role_t              role;
3356           int                 our_id;
3357 
3358           saved_modes = ahd_save_modes(ahd);
3359           ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI);
3360 
3361           if (ahd_inb(ahd, SSTAT0) & TARGET)
3362                     role = ROLE_TARGET;
3363           else
3364                     role = ROLE_INITIATOR;
3365 
3366           if (role == ROLE_TARGET
3367            && (ahd_inb(ahd, SEQ_FLAGS) & CMDPHASE_PENDING) != 0) {
3368                     /* We were selected, so pull our id from TARGIDIN */
3369                     our_id = ahd_inb(ahd, TARGIDIN) & OID;
3370           } else if (role == ROLE_TARGET)
3371                     our_id = ahd_inb(ahd, TOWNID);
3372           else
3373                     our_id = ahd_inb(ahd, IOWNID);
3374 
3375           saved_scsiid = ahd_inb(ahd, SAVED_SCSIID);
3376           ahd_compile_devinfo(devinfo,
3377                                   our_id,
3378                                   SCSIID_TARGET(ahd, saved_scsiid),
3379                                   ahd_inb(ahd, SAVED_LUN),
3380                                   SCSIID_CHANNEL(ahd, saved_scsiid),
3381                                   role);
3382           ahd_restore_modes(ahd, saved_modes);
3383 }
3384 
3385 void
ahd_print_devinfo(struct ahd_softc * ahd,struct ahd_devinfo * devinfo)3386 ahd_print_devinfo(struct ahd_softc *ahd, struct ahd_devinfo *devinfo)
3387 {
3388           printf("%s:%c:%d:%d: (0x%x) ", ahd_name(ahd), 'A',
3389                  devinfo->target, devinfo->lun, ahd_get_scbptr(ahd));
3390 }
3391 
3392 struct ahd_phase_table_entry*
ahd_lookup_phase_entry(int phase)3393 ahd_lookup_phase_entry(int phase)
3394 {
3395           struct ahd_phase_table_entry *entry;
3396           struct ahd_phase_table_entry *last_entry;
3397 
3398           /*
3399            * num_phases doesn't include the default entry which
3400            * will be returned if the phase doesn't match.
3401            */
3402           last_entry = &ahd_phase_table[num_phases];
3403           for (entry = ahd_phase_table; entry < last_entry; entry++) {
3404                     if (phase == entry->phase)
3405                               break;
3406           }
3407           return (entry);
3408 }
3409 
3410 void
ahd_compile_devinfo(struct ahd_devinfo * devinfo,u_int our_id,u_int target,u_int lun,char channel,role_t role)3411 ahd_compile_devinfo(struct ahd_devinfo *devinfo, u_int our_id, u_int target,
3412                         u_int lun, char channel, role_t role)
3413 {
3414           devinfo->our_scsiid = our_id;
3415           devinfo->target = target;
3416           devinfo->lun = lun;
3417           devinfo->target_offset = target;
3418           devinfo->channel = channel;
3419           devinfo->role = role;
3420           if (channel == 'B')
3421                     devinfo->target_offset += 8;
3422           devinfo->target_mask = (0x01 << devinfo->target_offset);
3423 }
3424 
3425 static void
ahd_scb_devinfo(struct ahd_softc * ahd,struct ahd_devinfo * devinfo,struct scb * scb)3426 ahd_scb_devinfo(struct ahd_softc *ahd, struct ahd_devinfo *devinfo,
3427                     struct scb *scb)
3428 {
3429           role_t    role;
3430           int       our_id;
3431 
3432           our_id = SCSIID_OUR_ID(scb->hscb->scsiid);
3433           role = ROLE_INITIATOR;
3434           if ((scb->hscb->control & TARGET_SCB) != 0)
3435                     role = ROLE_TARGET;
3436           ahd_compile_devinfo(devinfo, our_id, SCB_GET_TARGET(ahd, scb),
3437                                   SCB_GET_LUN(scb), SCB_GET_CHANNEL(ahd, scb), role);
3438 }
3439 
3440 
3441 /************************ Message Phase Processing ****************************/
3442 /*
3443  * When an initiator transaction with the MK_MESSAGE flag either reconnects
3444  * or enters the initial message out phase, we are interrupted.  Fill our
3445  * outgoing message buffer with the appropriate message and begin handing
3446  * the message phase(s) manually.
3447  */
3448 static void
ahd_setup_initiator_msgout(struct ahd_softc * ahd,struct ahd_devinfo * devinfo,struct scb * scb)3449 ahd_setup_initiator_msgout(struct ahd_softc *ahd, struct ahd_devinfo *devinfo,
3450                                  struct scb *scb)
3451 {
3452           /*
3453            * To facilitate adding multiple messages together,
3454            * each routine should increment the index and len
3455            * variables instead of setting them explicitly.
3456            */
3457           ahd->msgout_index = 0;
3458           ahd->msgout_len = 0;
3459 
3460           if (ahd_currently_packetized(ahd))
3461                     ahd->msg_flags |= MSG_FLAG_PACKETIZED;
3462 
3463           if (ahd->send_msg_perror
3464            && ahd_inb(ahd, MSG_OUT) == HOST_MSG) {
3465                     ahd->msgout_buf[ahd->msgout_index++] = ahd->send_msg_perror;
3466                     ahd->msgout_len++;
3467                     ahd->msg_type = MSG_TYPE_INITIATOR_MSGOUT;
3468 #ifdef AHD_DEBUG
3469                     if ((ahd_debug & AHD_SHOW_MESSAGES) != 0)
3470                               printf("Setting up for Parity Error delivery\n");
3471 #endif
3472                     return;
3473           } else if (scb == NULL) {
3474                     printf("%s: WARNING. No pending message for "
3475                            "I_T msgin.  Issuing NO-OP\n", ahd_name(ahd));
3476                     ahd->msgout_buf[ahd->msgout_index++] = MSG_NOOP;
3477                     ahd->msgout_len++;
3478                     ahd->msg_type = MSG_TYPE_INITIATOR_MSGOUT;
3479                     return;
3480           }
3481 
3482           if ((scb->flags & SCB_DEVICE_RESET) == 0
3483            && (scb->flags & SCB_PACKETIZED) == 0
3484            && ahd_inb(ahd, MSG_OUT) == MSG_IDENTIFYFLAG) {
3485                     u_int identify_msg;
3486 
3487                     identify_msg = MSG_IDENTIFYFLAG | SCB_GET_LUN(scb);
3488                     if ((scb->hscb->control & DISCENB) != 0)
3489                               identify_msg |= MSG_IDENTIFY_DISCFLAG;
3490                     ahd->msgout_buf[ahd->msgout_index++] = identify_msg;
3491                     ahd->msgout_len++;
3492 
3493                     if ((scb->hscb->control & TAG_ENB) != 0) {
3494                               ahd->msgout_buf[ahd->msgout_index++] =
3495                                   scb->hscb->control & (TAG_ENB|SCB_TAG_TYPE);
3496                               ahd->msgout_buf[ahd->msgout_index++] = SCB_GET_TAG(scb);
3497                               ahd->msgout_len += 2;
3498                     }
3499           }
3500 
3501           if (scb->flags & SCB_DEVICE_RESET) {
3502                     ahd->msgout_buf[ahd->msgout_index++] = MSG_BUS_DEV_RESET;
3503                     ahd->msgout_len++;
3504                     ahd_print_path(ahd, scb);
3505                     printf("Bus Device Reset Message Sent\n");
3506                     /*
3507                      * Clear our selection hardware in advance of
3508                      * the busfree.  We may have an entry in the waiting
3509                      * Q for this target, and we don't want to go about
3510                      * selecting while we handle the busfree and blow it
3511                      * away.
3512                      */
3513                     ahd_outb(ahd, SCSISEQ0, 0);
3514           } else if ((scb->flags & SCB_ABORT) != 0) {
3515 
3516                     if ((scb->hscb->control & TAG_ENB) != 0) {
3517                               ahd->msgout_buf[ahd->msgout_index++] = MSG_ABORT_TAG;
3518                     } else {
3519                               ahd->msgout_buf[ahd->msgout_index++] = MSG_ABORT;
3520                     }
3521                     ahd->msgout_len++;
3522                     ahd_print_path(ahd, scb);
3523                     printf("Abort%s Message Sent\n",
3524                            (scb->hscb->control & TAG_ENB) != 0 ? " Tag" : "");
3525                     /*
3526                      * Clear our selection hardware in advance of
3527                      * the busfree.  We may have an entry in the waiting
3528                      * Q for this target, and we don't want to go about
3529                      * selecting while we handle the busfree and blow it
3530                      * away.
3531                      */
3532                     ahd_outb(ahd, SCSISEQ0, 0);
3533           } else if ((scb->flags & (SCB_AUTO_NEGOTIATE|SCB_NEGOTIATE)) != 0) {
3534                     ahd_build_transfer_msg(ahd, devinfo);
3535                     /*
3536                      * Clear our selection hardware in advance of potential
3537                      * PPR IU status change busfree.  We may have an entry in
3538                      * the waiting Q for this target, and we don't want to go
3539                      * about selecting while we handle the busfree and blow
3540                      * it away.
3541                      */
3542                     ahd_outb(ahd, SCSISEQ0, 0);
3543           } else {
3544                     printf("ahd_intr: AWAITING_MSG for an SCB that "
3545                            "does not have a waiting message\n");
3546                     printf("SCSIID = %x, target_mask = %x\n", scb->hscb->scsiid,
3547                            devinfo->target_mask);
3548                     panic("SCB = %d, SCB Control = %x:%x, MSG_OUT = %x "
3549                           "SCB flags = %x", SCB_GET_TAG(scb), scb->hscb->control,
3550                           ahd_inb_scbram(ahd, SCB_CONTROL), ahd_inb(ahd, MSG_OUT),
3551                           scb->flags);
3552           }
3553 
3554           /*
3555            * Clear the MK_MESSAGE flag from the SCB so we aren't
3556            * asked to send this message again.
3557            */
3558           ahd_outb(ahd, SCB_CONTROL,
3559                      ahd_inb_scbram(ahd, SCB_CONTROL) & ~MK_MESSAGE);
3560           scb->hscb->control &= ~MK_MESSAGE;
3561           ahd->msgout_index = 0;
3562           ahd->msg_type = MSG_TYPE_INITIATOR_MSGOUT;
3563 }
3564 
3565 /*
3566  * Build an appropriate transfer negotiation message for the
3567  * currently active target.
3568  */
3569 static void
ahd_build_transfer_msg(struct ahd_softc * ahd,struct ahd_devinfo * devinfo)3570 ahd_build_transfer_msg(struct ahd_softc *ahd, struct ahd_devinfo *devinfo)
3571 {
3572           /*
3573            * We need to initiate transfer negotiations.
3574            * If our current and goal settings are identical,
3575            * we want to renegotiate due to a check condition.
3576            */
3577           struct    ahd_initiator_tinfo *tinfo;
3578           struct    ahd_tmode_tstate *tstate;
3579           int       dowide;
3580           int       dosync;
3581           int       doppr;
3582           u_int     period;
3583           u_int     ppr_options;
3584           u_int     offset;
3585 
3586           tinfo = ahd_fetch_transinfo(ahd, devinfo->channel, devinfo->our_scsiid,
3587                                             devinfo->target, &tstate);
3588           /*
3589            * Filter our period based on the current connection.
3590            * If we can't perform DT transfers on this segment (not in LVD
3591            * mode for instance), then our decision to issue a PPR message
3592            * may change.
3593            */
3594           period = tinfo->goal.period;
3595           offset = tinfo->goal.offset;
3596           ppr_options = tinfo->goal.ppr_options;
3597           /* Target initiated PPR is not allowed in the SCSI spec */
3598           if (devinfo->role == ROLE_TARGET)
3599                     ppr_options = 0;
3600           ahd_devlimited_syncrate(ahd, tinfo, &period,
3601                                         &ppr_options, devinfo->role);
3602           dowide = tinfo->curr.width != tinfo->goal.width;
3603           dosync = tinfo->curr.offset != offset || tinfo->curr.period != period;
3604           /*
3605            * Only use PPR if we have options that need it, even if the device
3606            * claims to support it.  There might be an expander in the way
3607            * that doesn't.
3608            */
3609           doppr = ppr_options != 0;
3610 
3611           if (!dowide && !dosync && !doppr) {
3612                     dowide = tinfo->goal.width != MSG_EXT_WDTR_BUS_8_BIT;
3613                     dosync = tinfo->goal.offset != 0;
3614           }
3615 
3616           if (!dowide && !dosync && !doppr) {
3617                     /*
3618                      * Force async with a WDTR message if we have a wide bus,
3619                      * or just issue an SDTR with a 0 offset.
3620                      */
3621                     if ((ahd->features & AHD_WIDE) != 0)
3622                               dowide = 1;
3623                     else
3624                               dosync = 1;
3625 
3626                     if (bootverbose) {
3627                               ahd_print_devinfo(ahd, devinfo);
3628                               printf("Ensuring async\n");
3629                     }
3630           }
3631           /* Target initiated PPR is not allowed in the SCSI spec */
3632           if (devinfo->role == ROLE_TARGET)
3633                     doppr = 0;
3634 
3635           /*
3636            * Both the PPR message and SDTR message require the
3637            * goal syncrate to be limited to what the target device
3638            * is capable of handling (based on whether an LVD->SE
3639            * expander is on the bus), so combine these two cases.
3640            * Regardless, guarantee that if we are using WDTR and SDTR
3641            * messages that WDTR comes first.
3642            */
3643           if (doppr || (dosync && !dowide)) {
3644 
3645                     offset = tinfo->goal.offset;
3646                     ahd_validate_offset(ahd, tinfo, period, &offset,
3647                                             doppr ? tinfo->goal.width
3648                                                     : tinfo->curr.width,
3649                                             devinfo->role);
3650                     if (doppr) {
3651                               ahd_construct_ppr(ahd, devinfo, period, offset,
3652                                                     tinfo->goal.width, ppr_options);
3653                     } else {
3654                               ahd_construct_sdtr(ahd, devinfo, period, offset);
3655                     }
3656           } else {
3657                     ahd_construct_wdtr(ahd, devinfo, tinfo->goal.width);
3658           }
3659 }
3660 
3661 /*
3662  * Build a synchronous negotiation message in our message
3663  * buffer based on the input parameters.
3664  */
3665 static void
ahd_construct_sdtr(struct ahd_softc * ahd,struct ahd_devinfo * devinfo,u_int period,u_int offset)3666 ahd_construct_sdtr(struct ahd_softc *ahd, struct ahd_devinfo *devinfo,
3667                        u_int period, u_int offset)
3668 {
3669           if (offset == 0)
3670                     period = AHD_ASYNC_XFER_PERIOD;
3671           ahd->msgout_buf[ahd->msgout_index++] = MSG_EXTENDED;
3672           ahd->msgout_buf[ahd->msgout_index++] = MSG_EXT_SDTR_LEN;
3673           ahd->msgout_buf[ahd->msgout_index++] = MSG_EXT_SDTR;
3674           ahd->msgout_buf[ahd->msgout_index++] = period;
3675           ahd->msgout_buf[ahd->msgout_index++] = offset;
3676           ahd->msgout_len += 5;
3677           if (bootverbose) {
3678                     printf("(%s:%c:%d:%d): Sending SDTR period %x, offset %x\n",
3679                            ahd_name(ahd), devinfo->channel, devinfo->target,
3680                            devinfo->lun, period, offset);
3681           }
3682 }
3683 
3684 /*
3685  * Build a wide negotiation message in our message
3686  * buffer based on the input parameters.
3687  */
3688 static void
ahd_construct_wdtr(struct ahd_softc * ahd,struct ahd_devinfo * devinfo,u_int bus_width)3689 ahd_construct_wdtr(struct ahd_softc *ahd, struct ahd_devinfo *devinfo,
3690                        u_int bus_width)
3691 {
3692           ahd->msgout_buf[ahd->msgout_index++] = MSG_EXTENDED;
3693           ahd->msgout_buf[ahd->msgout_index++] = MSG_EXT_WDTR_LEN;
3694           ahd->msgout_buf[ahd->msgout_index++] = MSG_EXT_WDTR;
3695           ahd->msgout_buf[ahd->msgout_index++] = bus_width;
3696           ahd->msgout_len += 4;
3697           if (bootverbose) {
3698                     printf("(%s:%c:%d:%d): Sending WDTR %x\n",
3699                            ahd_name(ahd), devinfo->channel, devinfo->target,
3700                            devinfo->lun, bus_width);
3701           }
3702 }
3703 
3704 /*
3705  * Build a parallel protocol request message in our message
3706  * buffer based on the input parameters.
3707  */
3708 static void
ahd_construct_ppr(struct ahd_softc * ahd,struct ahd_devinfo * devinfo,u_int period,u_int offset,u_int bus_width,u_int ppr_options)3709 ahd_construct_ppr(struct ahd_softc *ahd, struct ahd_devinfo *devinfo,
3710                       u_int period, u_int offset, u_int bus_width,
3711                       u_int ppr_options)
3712 {
3713           /*
3714            * Always request precompensation from
3715            * the other target if we are running
3716            * at paced syncrates.
3717            */
3718           if (period <= AHD_SYNCRATE_PACED)
3719                     ppr_options |= MSG_EXT_PPR_PCOMP_EN;
3720           if (offset == 0)
3721                     period = AHD_ASYNC_XFER_PERIOD;
3722           ahd->msgout_buf[ahd->msgout_index++] = MSG_EXTENDED;
3723           ahd->msgout_buf[ahd->msgout_index++] = MSG_EXT_PPR_LEN;
3724           ahd->msgout_buf[ahd->msgout_index++] = MSG_EXT_PPR;
3725           ahd->msgout_buf[ahd->msgout_index++] = period;
3726           ahd->msgout_buf[ahd->msgout_index++] = 0;
3727           ahd->msgout_buf[ahd->msgout_index++] = offset;
3728           ahd->msgout_buf[ahd->msgout_index++] = bus_width;
3729           ahd->msgout_buf[ahd->msgout_index++] = ppr_options;
3730           ahd->msgout_len += 8;
3731           if (bootverbose) {
3732                     printf("(%s:%c:%d:%d): Sending PPR bus_width %x, period 0x%x, "
3733                            "offset 0x%x, ppr_options 0x%x\n", ahd_name(ahd),
3734                            devinfo->channel, devinfo->target, devinfo->lun,
3735                            bus_width, period, offset, ppr_options);
3736           }
3737 }
3738 
3739 /*
3740  * Clear any active message state.
3741  */
3742 static void
ahd_clear_msg_state(struct ahd_softc * ahd)3743 ahd_clear_msg_state(struct ahd_softc *ahd)
3744 {
3745           ahd_mode_state saved_modes;
3746 
3747           saved_modes = ahd_save_modes(ahd);
3748           ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI);
3749           ahd->send_msg_perror = 0;
3750           ahd->msg_flags = MSG_FLAG_NONE;
3751           ahd->msgout_len = 0;
3752           ahd->msgin_index = 0;
3753           ahd->msg_type = MSG_TYPE_NONE;
3754           if ((ahd_inb(ahd, SCSISIGO) & ATNO) != 0) {
3755                     /*
3756                      * The target didn't care to respond to our
3757                      * message request, so clear ATN.
3758                      */
3759                     ahd_outb(ahd, CLRSINT1, CLRATNO);
3760           }
3761           ahd_outb(ahd, MSG_OUT, MSG_NOOP);
3762           ahd_outb(ahd, SEQ_FLAGS2,
3763                      ahd_inb(ahd, SEQ_FLAGS2) & ~TARGET_MSG_PENDING);
3764           ahd_restore_modes(ahd, saved_modes);
3765 }
3766 
3767 /*
3768  * Manual message loop handler.
3769  */
3770 static void
ahd_handle_message_phase(struct ahd_softc * ahd)3771 ahd_handle_message_phase(struct ahd_softc *ahd)
3772 {
3773           struct    ahd_devinfo devinfo;
3774           u_int     bus_phase;
3775           int       end_session;
3776 
3777           ahd_fetch_devinfo(ahd, &devinfo);
3778           end_session = FALSE;
3779           bus_phase = ahd_inb(ahd, LASTPHASE);
3780 
3781           if ((ahd_inb(ahd, LQISTAT2) & LQIPHASE_OUTPKT) != 0) {
3782                     printf("LQIRETRY for LQIPHASE_OUTPKT\n");
3783                     ahd_outb(ahd, LQCTL2, LQIRETRY);
3784           }
3785 reswitch:
3786           switch (ahd->msg_type) {
3787           case MSG_TYPE_INITIATOR_MSGOUT:
3788           {
3789                     int lastbyte;
3790                     int phasemis;
3791                     int msgdone;
3792 
3793                     if (ahd->msgout_len == 0 && ahd->send_msg_perror == 0)
3794                               panic("HOST_MSG_LOOP interrupt with no active message");
3795 
3796 #ifdef AHD_DEBUG
3797                     if ((ahd_debug & AHD_SHOW_MESSAGES) != 0) {
3798                               ahd_print_devinfo(ahd, &devinfo);
3799                               printf("INITIATOR_MSG_OUT");
3800                     }
3801 #endif
3802                     phasemis = bus_phase != P_MESGOUT;
3803                     if (phasemis) {
3804 #ifdef AHD_DEBUG
3805                               if ((ahd_debug & AHD_SHOW_MESSAGES) != 0) {
3806                                         printf(" PHASEMIS %s\n",
3807                                                ahd_lookup_phase_entry(bus_phase)
3808                                                                            ->phasemsg);
3809                               }
3810 #endif
3811                               if (bus_phase == P_MESGIN) {
3812                                         /*
3813                                          * Change gears and see if
3814                                          * this messages is of interest to
3815                                          * us or should be passed back to
3816                                          * the sequencer.
3817                                          */
3818                                         ahd_outb(ahd, CLRSINT1, CLRATNO);
3819                                         ahd->send_msg_perror = 0;
3820                                         ahd->msg_type = MSG_TYPE_INITIATOR_MSGIN;
3821                                         ahd->msgin_index = 0;
3822                                         goto reswitch;
3823                               }
3824                               end_session = TRUE;
3825                               break;
3826                     }
3827 
3828                     if (ahd->send_msg_perror) {
3829                               ahd_outb(ahd, CLRSINT1, CLRATNO);
3830                               ahd_outb(ahd, CLRSINT1, CLRREQINIT);
3831 #ifdef AHD_DEBUG
3832                               if ((ahd_debug & AHD_SHOW_MESSAGES) != 0)
3833                                         printf(" byte 0x%x\n", ahd->send_msg_perror);
3834 #endif
3835                               /*
3836                                * If we are notifying the target of a CRC error
3837                                * during packetized operations, the target is
3838                                * within its rights to acknowledge our message
3839                                * with a busfree.
3840                                */
3841                               if ((ahd->msg_flags & MSG_FLAG_PACKETIZED) != 0
3842                                && ahd->send_msg_perror == MSG_INITIATOR_DET_ERR)
3843                                         ahd->msg_flags |= MSG_FLAG_EXPECT_IDE_BUSFREE;
3844 
3845                               ahd_outb(ahd, RETURN_2, ahd->send_msg_perror);
3846                               ahd_outb(ahd, RETURN_1, CONT_MSG_LOOP_WRITE);
3847                               break;
3848                     }
3849 
3850                     msgdone   = ahd->msgout_index == ahd->msgout_len;
3851                     if (msgdone) {
3852                               /*
3853                                * The target has requested a retry.
3854                                * Re-assert ATN, reset our message index to
3855                                * 0, and try again.
3856                                */
3857                               ahd->msgout_index = 0;
3858                               ahd_assert_atn(ahd);
3859                     }
3860 
3861                     lastbyte = ahd->msgout_index == (ahd->msgout_len - 1);
3862                     if (lastbyte) {
3863                               /* Last byte is signified by dropping ATN */
3864                               ahd_outb(ahd, CLRSINT1, CLRATNO);
3865                     }
3866 
3867                     /*
3868                      * Clear our interrupt status and present
3869                      * the next byte on the bus.
3870                      */
3871                     ahd_outb(ahd, CLRSINT1, CLRREQINIT);
3872 #ifdef AHD_DEBUG
3873                     if ((ahd_debug & AHD_SHOW_MESSAGES) != 0)
3874                               printf(" byte 0x%x\n",
3875                                      ahd->msgout_buf[ahd->msgout_index]);
3876 #endif
3877                     ahd_outb(ahd, RETURN_2, ahd->msgout_buf[ahd->msgout_index++]);
3878                     ahd_outb(ahd, RETURN_1, CONT_MSG_LOOP_WRITE);
3879                     break;
3880           }
3881           case MSG_TYPE_INITIATOR_MSGIN:
3882           {
3883                     int phasemis;
3884                     int message_done;
3885 
3886 #ifdef AHD_DEBUG
3887                     if ((ahd_debug & AHD_SHOW_MESSAGES) != 0) {
3888                               ahd_print_devinfo(ahd, &devinfo);
3889                               printf("INITIATOR_MSG_IN");
3890                     }
3891 #endif
3892                     phasemis = bus_phase != P_MESGIN;
3893                     if (phasemis) {
3894 #ifdef AHD_DEBUG
3895                               if ((ahd_debug & AHD_SHOW_MESSAGES) != 0) {
3896                                         printf(" PHASEMIS %s\n",
3897                                                ahd_lookup_phase_entry(bus_phase)
3898                                                                            ->phasemsg);
3899                               }
3900 #endif
3901                               ahd->msgin_index = 0;
3902                               if (bus_phase == P_MESGOUT
3903                                && (ahd->send_msg_perror != 0
3904                                 || (ahd->msgout_len != 0
3905                                  && ahd->msgout_index == 0))) {
3906                                         ahd->msg_type = MSG_TYPE_INITIATOR_MSGOUT;
3907                                         goto reswitch;
3908                               }
3909                               end_session = TRUE;
3910                               break;
3911                     }
3912 
3913                     /* Pull the byte in without acking it */
3914                     ahd->msgin_buf[ahd->msgin_index] = ahd_inb(ahd, SCSIBUS);
3915 #ifdef AHD_DEBUG
3916                     if ((ahd_debug & AHD_SHOW_MESSAGES) != 0)
3917                               printf(" byte 0x%x\n",
3918                                      ahd->msgin_buf[ahd->msgin_index]);
3919 #endif
3920 
3921                     message_done = ahd_parse_msg(ahd, &devinfo);
3922 
3923                     if (message_done) {
3924                               /*
3925                                * Clear our incoming message buffer in case there
3926                                * is another message following this one.
3927                                */
3928                               ahd->msgin_index = 0;
3929 
3930                               /*
3931                                * If this message illicited a response,
3932                                * assert ATN so the target takes us to the
3933                                * message out phase.
3934                                */
3935                               if (ahd->msgout_len != 0) {
3936 #ifdef AHD_DEBUG
3937                                         if ((ahd_debug & AHD_SHOW_MESSAGES) != 0) {
3938                                                   ahd_print_devinfo(ahd, &devinfo);
3939                                                   printf("Asserting ATN for response\n");
3940                                         }
3941 #endif
3942                                         ahd_assert_atn(ahd);
3943                               }
3944                     } else
3945                               ahd->msgin_index++;
3946 
3947                     if (message_done == MSGLOOP_TERMINATED) {
3948                               end_session = TRUE;
3949                     } else {
3950                               /* Ack the byte */
3951                               ahd_outb(ahd, CLRSINT1, CLRREQINIT);
3952                               ahd_outb(ahd, RETURN_1, CONT_MSG_LOOP_READ);
3953                     }
3954                     break;
3955           }
3956           case MSG_TYPE_TARGET_MSGIN:
3957           {
3958                     int msgdone;
3959                     int msgout_request;
3960 
3961                     /*
3962                      * By default, the message loop will continue.
3963                      */
3964                     ahd_outb(ahd, RETURN_1, CONT_MSG_LOOP_TARG);
3965 
3966                     if (ahd->msgout_len == 0)
3967                               panic("Target MSGIN with no active message");
3968 
3969                     /*
3970                      * If we interrupted a mesgout session, the initiator
3971                      * will not know this until our first REQ.  So, we
3972                      * only honor mesgout requests after we've sent our
3973                      * first byte.
3974                      */
3975                     if ((ahd_inb(ahd, SCSISIGI) & ATNI) != 0
3976                      && ahd->msgout_index > 0)
3977                               msgout_request = TRUE;
3978                     else
3979                               msgout_request = FALSE;
3980 
3981                     if (msgout_request) {
3982 
3983                               /*
3984                                * Change gears and see if
3985                                * this messages is of interest to
3986                                * us or should be passed back to
3987                                * the sequencer.
3988                                */
3989                               ahd->msg_type = MSG_TYPE_TARGET_MSGOUT;
3990                               ahd_outb(ahd, SCSISIGO, P_MESGOUT | BSYO);
3991                               ahd->msgin_index = 0;
3992                               /* Dummy read to REQ for first byte */
3993                               ahd_inb(ahd, SCSIDAT);
3994                               ahd_outb(ahd, SXFRCTL0,
3995                                          ahd_inb(ahd, SXFRCTL0) | SPIOEN);
3996                               break;
3997                     }
3998 
3999                     msgdone = ahd->msgout_index == ahd->msgout_len;
4000                     if (msgdone) {
4001                               ahd_outb(ahd, SXFRCTL0,
4002                                          ahd_inb(ahd, SXFRCTL0) & ~SPIOEN);
4003                               end_session = TRUE;
4004                               break;
4005                     }
4006 
4007                     /*
4008                      * Present the next byte on the bus.
4009                      */
4010                     ahd_outb(ahd, SXFRCTL0, ahd_inb(ahd, SXFRCTL0) | SPIOEN);
4011                     ahd_outb(ahd, SCSIDAT, ahd->msgout_buf[ahd->msgout_index++]);
4012                     break;
4013           }
4014           case MSG_TYPE_TARGET_MSGOUT:
4015           {
4016                     int lastbyte;
4017                     int msgdone;
4018 
4019                     /*
4020                      * By default, the message loop will continue.
4021                      */
4022                     ahd_outb(ahd, RETURN_1, CONT_MSG_LOOP_TARG);
4023 
4024                     /*
4025                      * The initiator signals that this is
4026                      * the last byte by dropping ATN.
4027                      */
4028                     lastbyte = (ahd_inb(ahd, SCSISIGI) & ATNI) == 0;
4029 
4030                     /*
4031                      * Read the latched byte, but turn off SPIOEN first
4032                      * so that we don't inadvertently cause a REQ for the
4033                      * next byte.
4034                      */
4035                     ahd_outb(ahd, SXFRCTL0, ahd_inb(ahd, SXFRCTL0) & ~SPIOEN);
4036                     ahd->msgin_buf[ahd->msgin_index] = ahd_inb(ahd, SCSIDAT);
4037                     msgdone = ahd_parse_msg(ahd, &devinfo);
4038                     if (msgdone == MSGLOOP_TERMINATED) {
4039                               /*
4040                                * The message is *really* done in that it caused
4041                                * us to go to bus free.  The sequencer has already
4042                                * been reset at this point, so pull the ejection
4043                                * handle.
4044                                */
4045                               return;
4046                     }
4047 
4048                     ahd->msgin_index++;
4049 
4050                     /*
4051                      * XXX Read spec about initiator dropping ATN too soon
4052                      *     and use msgdone to detect it.
4053                      */
4054                     if (msgdone == MSGLOOP_MSGCOMPLETE) {
4055                               ahd->msgin_index = 0;
4056 
4057                               /*
4058                                * If this message illicited a response, transition
4059                                * to the Message in phase and send it.
4060                                */
4061                               if (ahd->msgout_len != 0) {
4062                                         ahd_outb(ahd, SCSISIGO, P_MESGIN | BSYO);
4063                                         ahd_outb(ahd, SXFRCTL0,
4064                                                    ahd_inb(ahd, SXFRCTL0) | SPIOEN);
4065                                         ahd->msg_type = MSG_TYPE_TARGET_MSGIN;
4066                                         ahd->msgin_index = 0;
4067                                         break;
4068                               }
4069                     }
4070 
4071                     if (lastbyte)
4072                               end_session = TRUE;
4073                     else {
4074                               /* Ask for the next byte. */
4075                               ahd_outb(ahd, SXFRCTL0,
4076                                          ahd_inb(ahd, SXFRCTL0) | SPIOEN);
4077                     }
4078 
4079                     break;
4080           }
4081           default:
4082                     panic("Unknown REQINIT message type");
4083           }
4084 
4085           if (end_session) {
4086                     if ((ahd->msg_flags & MSG_FLAG_PACKETIZED) != 0) {
4087                               printf("%s: Returning to Idle Loop\n",
4088                                      ahd_name(ahd));
4089                               ahd_clear_msg_state(ahd);
4090 
4091                               /*
4092                                * Perform the equivalent of a clear_target_state.
4093                                */
4094                               ahd_outb(ahd, LASTPHASE, P_BUSFREE);
4095                               ahd_outb(ahd, SEQ_FLAGS, NOT_IDENTIFIED|NO_CDB_SENT);
4096                               ahd_outb(ahd, SEQCTL0, FASTMODE|SEQRESET);
4097                     } else {
4098                               ahd_clear_msg_state(ahd);
4099                               ahd_outb(ahd, RETURN_1, EXIT_MSG_LOOP);
4100                     }
4101           }
4102 }
4103 
4104 /*
4105  * See if we sent a particular extended message to the target.
4106  * If "full" is true, return true only if the target saw the full
4107  * message.  If "full" is false, return true if the target saw at
4108  * least the first byte of the message.
4109  */
4110 static int
ahd_sent_msg(struct ahd_softc * ahd,ahd_msgtype type,u_int msgval,int full)4111 ahd_sent_msg(struct ahd_softc *ahd, ahd_msgtype type, u_int msgval, int full)
4112 {
4113           int found;
4114           u_int index;
4115 
4116           found = FALSE;
4117           index = 0;
4118 
4119           while (index < ahd->msgout_len) {
4120                     if (ahd->msgout_buf[index] == MSG_EXTENDED) {
4121                               u_int end_index;
4122 
4123                               end_index = index + 1 + ahd->msgout_buf[index + 1];
4124                               if (ahd->msgout_buf[index+2] == msgval
4125                                && type == AHDMSG_EXT) {
4126 
4127                                         if (full) {
4128                                                   if (ahd->msgout_index > end_index)
4129                                                             found = TRUE;
4130                                         } else if (ahd->msgout_index > index)
4131                                                   found = TRUE;
4132                               }
4133                               index = end_index;
4134                     } else if (ahd->msgout_buf[index] >= MSG_SIMPLE_TASK
4135                               && ahd->msgout_buf[index] <= MSG_IGN_WIDE_RESIDUE) {
4136 
4137                               /* Skip tag type and tag id or residue param*/
4138                               index += 2;
4139                     } else {
4140                               /* Single byte message */
4141                               if (type == AHDMSG_1B
4142                                && ahd->msgout_index > index
4143                                && (ahd->msgout_buf[index] == msgval
4144                                 || ((ahd->msgout_buf[index] & MSG_IDENTIFYFLAG) != 0
4145                                  && msgval == MSG_IDENTIFYFLAG)))
4146                                         found = TRUE;
4147                               index++;
4148                     }
4149 
4150                     if (found)
4151                               break;
4152           }
4153           return (found);
4154 }
4155 
4156 /*
4157  * Wait for a complete incoming message, parse it, and respond accordingly.
4158  */
4159 static int
ahd_parse_msg(struct ahd_softc * ahd,struct ahd_devinfo * devinfo)4160 ahd_parse_msg(struct ahd_softc *ahd, struct ahd_devinfo *devinfo)
4161 {
4162           struct    ahd_initiator_tinfo *tinfo;
4163           struct    ahd_tmode_tstate *tstate;
4164           int       reject;
4165           int       done;
4166           int       response;
4167 
4168           done = MSGLOOP_IN_PROG;
4169           response = FALSE;
4170           reject = FALSE;
4171           tinfo = ahd_fetch_transinfo(ahd, devinfo->channel, devinfo->our_scsiid,
4172                                             devinfo->target, &tstate);
4173 
4174           /*
4175            * Parse as much of the message as is available,
4176            * rejecting it if we don't support it.  When
4177            * the entire message is available and has been
4178            * handled, return MSGLOOP_MSGCOMPLETE, indicating
4179            * that we have parsed an entire message.
4180            *
4181            * In the case of extended messages, we accept the length
4182            * byte outright and perform more checking once we know the
4183            * extended message type.
4184            */
4185           switch (ahd->msgin_buf[0]) {
4186           case MSG_DISCONNECT:
4187           case MSG_SAVEDATAPOINTER:
4188           case MSG_CMDCOMPLETE:
4189           case MSG_RESTOREPOINTERS:
4190           case MSG_IGN_WIDE_RESIDUE:
4191                     /*
4192                      * End our message loop as these are messages
4193                      * the sequencer handles on its own.
4194                      */
4195                     done = MSGLOOP_TERMINATED;
4196                     break;
4197           case MSG_MESSAGE_REJECT:
4198                     response = ahd_handle_msg_reject(ahd, devinfo);
4199                     /* FALLTHROUGH */
4200           case MSG_NOOP:
4201                     done = MSGLOOP_MSGCOMPLETE;
4202                     break;
4203           case MSG_EXTENDED:
4204           {
4205                     /* Wait for enough of the message to begin validation */
4206                     if (ahd->msgin_index < 2)
4207                               break;
4208                     switch (ahd->msgin_buf[2]) {
4209                     case MSG_EXT_SDTR:
4210                     {
4211                               u_int      period;
4212                               u_int      ppr_options;
4213                               u_int      offset;
4214                               u_int      saved_offset;
4215 
4216                               if (ahd->msgin_buf[1] != MSG_EXT_SDTR_LEN) {
4217                                         reject = TRUE;
4218                                         break;
4219                               }
4220 
4221                               /*
4222                                * Wait until we have both args before validating
4223                                * and acting on this message.
4224                                *
4225                                * Add one to MSG_EXT_SDTR_LEN to account for
4226                                * the extended message preamble.
4227                                */
4228                               if (ahd->msgin_index < (MSG_EXT_SDTR_LEN + 1))
4229                                         break;
4230 
4231                               period = ahd->msgin_buf[3];
4232                               ppr_options = 0;
4233                               saved_offset = offset = ahd->msgin_buf[4];
4234                               ahd_devlimited_syncrate(ahd, tinfo, &period,
4235                                                             &ppr_options, devinfo->role);
4236                               ahd_validate_offset(ahd, tinfo, period, &offset,
4237                                                       tinfo->curr.width, devinfo->role);
4238                               if (bootverbose) {
4239                                         printf("(%s:%c:%d:%d): Received "
4240                                                "SDTR period %x, offset %x\n\t"
4241                                                "Filtered to period %x, offset %x\n",
4242                                                ahd_name(ahd), devinfo->channel,
4243                                                devinfo->target, devinfo->lun,
4244                                                ahd->msgin_buf[3], saved_offset,
4245                                                period, offset);
4246                               }
4247                               ahd_set_syncrate(ahd, devinfo, period,
4248                                                    offset, ppr_options,
4249                                                    AHD_TRANS_ACTIVE|AHD_TRANS_GOAL,
4250                                                    /*paused*/TRUE);
4251 
4252                               /*
4253                                * See if we initiated Sync Negotiation
4254                                * and didn't have to fall down to async
4255                                * transfers.
4256                                */
4257                               if (ahd_sent_msg(ahd, AHDMSG_EXT, MSG_EXT_SDTR, TRUE)) {
4258                                         /* We started it */
4259                                         if (saved_offset != offset) {
4260                                                   /* Went too low - force async */
4261                                                   reject = TRUE;
4262                                         }
4263                               } else {
4264                                         /*
4265                                          * Send our own SDTR in reply
4266                                          */
4267                                         if (bootverbose
4268                                          && devinfo->role == ROLE_INITIATOR) {
4269                                                   printf("(%s:%c:%d:%d): Target "
4270                                                          "Initiated SDTR\n",
4271                                                          ahd_name(ahd), devinfo->channel,
4272                                                          devinfo->target, devinfo->lun);
4273                                         }
4274                                         ahd->msgout_index = 0;
4275                                         ahd->msgout_len = 0;
4276                                         ahd_construct_sdtr(ahd, devinfo,
4277                                                                period, offset);
4278                                         ahd->msgout_index = 0;
4279                                         response = TRUE;
4280                               }
4281                               done = MSGLOOP_MSGCOMPLETE;
4282                               break;
4283                     }
4284                     case MSG_EXT_WDTR:
4285                     {
4286                               u_int bus_width;
4287                               u_int saved_width;
4288                               u_int sending_reply;
4289 
4290                               sending_reply = FALSE;
4291                               if (ahd->msgin_buf[1] != MSG_EXT_WDTR_LEN) {
4292                                         reject = TRUE;
4293                                         break;
4294                               }
4295 
4296                               /*
4297                                * Wait until we have our arg before validating
4298                                * and acting on this message.
4299                                *
4300                                * Add one to MSG_EXT_WDTR_LEN to account for
4301                                * the extended message preamble.
4302                                */
4303                               if (ahd->msgin_index < (MSG_EXT_WDTR_LEN + 1))
4304                                         break;
4305 
4306                               bus_width = ahd->msgin_buf[3];
4307                               saved_width = bus_width;
4308                               ahd_validate_width(ahd, tinfo, &bus_width,
4309                                                      devinfo->role);
4310                               if (bootverbose) {
4311                                         printf("(%s:%c:%d:%d): Received WDTR "
4312                                                "%x filtered to %x\n",
4313                                                ahd_name(ahd), devinfo->channel,
4314                                                devinfo->target, devinfo->lun,
4315                                                saved_width, bus_width);
4316                               }
4317 
4318                               if (ahd_sent_msg(ahd, AHDMSG_EXT, MSG_EXT_WDTR, TRUE)) {
4319                                         /*
4320                                          * Don't send a WDTR back to the
4321                                          * target, since we asked first.
4322                                          * If the width went higher than our
4323                                          * request, reject it.
4324                                          */
4325                                         if (saved_width > bus_width) {
4326                                                   reject = TRUE;
4327                                                   printf("(%s:%c:%d:%d): requested %dBit "
4328                                                          "transfers.  Rejecting...\n",
4329                                                          ahd_name(ahd), devinfo->channel,
4330                                                          devinfo->target, devinfo->lun,
4331                                                          8 * (0x01 << bus_width));
4332                                                   bus_width = 0;
4333                                         }
4334                               } else {
4335                                         /*
4336                                          * Send our own WDTR in reply
4337                                          */
4338                                         if (bootverbose
4339                                          && devinfo->role == ROLE_INITIATOR) {
4340                                                   printf("(%s:%c:%d:%d): Target "
4341                                                          "Initiated WDTR\n",
4342                                                          ahd_name(ahd), devinfo->channel,
4343                                                          devinfo->target, devinfo->lun);
4344                                         }
4345                                         ahd->msgout_index = 0;
4346                                         ahd->msgout_len = 0;
4347                                         ahd_construct_wdtr(ahd, devinfo, bus_width);
4348                                         ahd->msgout_index = 0;
4349                                         response = TRUE;
4350                                         sending_reply = TRUE;
4351                               }
4352                               /*
4353                                * After a wide message, we are async, but
4354                                * some devices don't seem to honor this portion
4355                                * of the spec.  Force a renegotiation of the
4356                                * sync component of our transfer agreement even
4357                                * if our goal is async.  By updating our width
4358                                * after forcing the negotiation, we avoid
4359                                * renegotiating for width.
4360                                */
4361                               ahd_update_neg_request(ahd, devinfo, tstate,
4362                                                          tinfo, AHD_NEG_ALWAYS);
4363                               ahd_set_width(ahd, devinfo, bus_width,
4364                                               AHD_TRANS_ACTIVE|AHD_TRANS_GOAL,
4365                                               /*paused*/TRUE);
4366                               if (sending_reply == FALSE && reject == FALSE) {
4367 
4368                                         /*
4369                                          * We will always have an SDTR to send.
4370                                          */
4371                                         ahd->msgout_index = 0;
4372                                         ahd->msgout_len = 0;
4373                                         ahd_build_transfer_msg(ahd, devinfo);
4374                                         ahd->msgout_index = 0;
4375                                         response = TRUE;
4376                               }
4377                               done = MSGLOOP_MSGCOMPLETE;
4378                               break;
4379                     }
4380                     case MSG_EXT_PPR:
4381                     {
4382                               u_int     period;
4383                               u_int     offset;
4384                               u_int     bus_width;
4385                               u_int     ppr_options;
4386                               u_int     saved_width;
4387                               u_int     saved_offset;
4388                               u_int     saved_ppr_options;
4389 
4390                               if (ahd->msgin_buf[1] != MSG_EXT_PPR_LEN) {
4391                                         reject = TRUE;
4392                                         break;
4393                               }
4394 
4395                               /*
4396                                * Wait until we have all args before validating
4397                                * and acting on this message.
4398                                *
4399                                * Add one to MSG_EXT_PPR_LEN to account for
4400                                * the extended message preamble.
4401                                */
4402                               if (ahd->msgin_index < (MSG_EXT_PPR_LEN + 1))
4403                                         break;
4404 
4405                               period = ahd->msgin_buf[3];
4406                               offset = ahd->msgin_buf[5];
4407                               bus_width = ahd->msgin_buf[6];
4408                               saved_width = bus_width;
4409                               ppr_options = ahd->msgin_buf[7];
4410                               /*
4411                                * According to the spec, a DT only
4412                                * period factor with no DT option
4413                                * set implies async.
4414                                */
4415                               if ((ppr_options & MSG_EXT_PPR_DT_REQ) == 0
4416                                && period <= 9)
4417                                         offset = 0;
4418                               saved_ppr_options = ppr_options;
4419                               saved_offset = offset;
4420 
4421                               /*
4422                                * Transfer options are only available if we
4423                                * are negotiating wide.
4424                                */
4425                               if (bus_width == 0)
4426                                         ppr_options &= MSG_EXT_PPR_QAS_REQ;
4427 
4428                               ahd_validate_width(ahd, tinfo, &bus_width,
4429                                                      devinfo->role);
4430                               ahd_devlimited_syncrate(ahd, tinfo, &period,
4431                                                             &ppr_options, devinfo->role);
4432                               ahd_validate_offset(ahd, tinfo, period, &offset,
4433                                                       bus_width, devinfo->role);
4434 
4435                               if (ahd_sent_msg(ahd, AHDMSG_EXT, MSG_EXT_PPR, TRUE)) {
4436                                         /*
4437                                          * If we are unable to do any of the
4438                                          * requested options (we went too low),
4439                                          * then we'll have to reject the message.
4440                                          */
4441                                         if (saved_width > bus_width
4442                                          || saved_offset != offset
4443                                          || saved_ppr_options != ppr_options) {
4444                                                   reject = TRUE;
4445                                                   period = 0;
4446                                                   offset = 0;
4447                                                   bus_width = 0;
4448                                                   ppr_options = 0;
4449                                         }
4450                               } else {
4451                                         if (devinfo->role != ROLE_TARGET)
4452                                                   printf("(%s:%c:%d:%d): Target "
4453                                                          "Initiated PPR\n",
4454                                                          ahd_name(ahd), devinfo->channel,
4455                                                          devinfo->target, devinfo->lun);
4456                                         else
4457                                                   printf("(%s:%c:%d:%d): Initiator "
4458                                                          "Initiated PPR\n",
4459                                                          ahd_name(ahd), devinfo->channel,
4460                                                          devinfo->target, devinfo->lun);
4461                                         ahd->msgout_index = 0;
4462                                         ahd->msgout_len = 0;
4463                                         ahd_construct_ppr(ahd, devinfo, period, offset,
4464                                                               bus_width, ppr_options);
4465                                         ahd->msgout_index = 0;
4466                                         response = TRUE;
4467                               }
4468                               if (bootverbose) {
4469                                         printf("(%s:%c:%d:%d): Received PPR width %x, "
4470                                                "period %x, offset %x,options %x\n"
4471                                                "\tFiltered to width %x, period %x, "
4472                                                "offset %x, options %x\n",
4473                                                ahd_name(ahd), devinfo->channel,
4474                                                devinfo->target, devinfo->lun,
4475                                                saved_width, ahd->msgin_buf[3],
4476                                                saved_offset, saved_ppr_options,
4477                                                bus_width, period, offset, ppr_options);
4478                               }
4479                               ahd_set_width(ahd, devinfo, bus_width,
4480                                               AHD_TRANS_ACTIVE|AHD_TRANS_GOAL,
4481                                               /*paused*/TRUE);
4482                               ahd_set_syncrate(ahd, devinfo, period,
4483                                                    offset, ppr_options,
4484                                                    AHD_TRANS_ACTIVE|AHD_TRANS_GOAL,
4485                                                    /*paused*/TRUE);
4486 
4487                               done = MSGLOOP_MSGCOMPLETE;
4488                               break;
4489                     }
4490                     default:
4491                               /* Unknown extended message.  Reject it. */
4492                               reject = TRUE;
4493                               break;
4494                     }
4495                     break;
4496           }
4497 #ifdef AHD_TARGET_MODE
4498           case MSG_BUS_DEV_RESET:
4499                     ahd_handle_devreset(ahd, devinfo, CAM_LUN_WILDCARD,
4500                                             CAM_BDR_SENT,
4501                                             "Bus Device Reset Received",
4502                                             /*verbose_level*/0);
4503                     ahd_restart(ahd);
4504                     done = MSGLOOP_TERMINATED;
4505                     break;
4506           case MSG_ABORT_TAG:
4507           case MSG_ABORT:
4508           case MSG_CLEAR_QUEUE:
4509           {
4510                     int tag;
4511 
4512                     /* Target mode messages */
4513                     if (devinfo->role != ROLE_TARGET) {
4514                               reject = TRUE;
4515                               break;
4516                     }
4517                     tag = SCB_LIST_NULL;
4518                     if (ahd->msgin_buf[0] == MSG_ABORT_TAG)
4519                               tag = ahd_inb(ahd, INITIATOR_TAG);
4520                     ahd_abort_scbs(ahd, devinfo->target, devinfo->channel,
4521                                      devinfo->lun, tag, ROLE_TARGET,
4522                                      CAM_REQ_ABORTED);
4523 
4524                     tstate = ahd->enabled_targets[devinfo->our_scsiid];
4525                     if (tstate != NULL) {
4526                               struct ahd_tmode_lstate* lstate;
4527 
4528                               lstate = tstate->enabled_luns[devinfo->lun];
4529                               if (lstate != NULL) {
4530                                         ahd_queue_lstate_event(ahd, lstate,
4531                                                                    devinfo->our_scsiid,
4532                                                                    ahd->msgin_buf[0],
4533                                                                    /*arg*/tag);
4534                                         ahd_send_lstate_events(ahd, lstate);
4535                               }
4536                     }
4537                     ahd_restart(ahd);
4538                     done = MSGLOOP_TERMINATED;
4539                     break;
4540           }
4541 #endif
4542           case MSG_QAS_REQUEST:
4543 #ifdef AHD_DEBUG
4544                     if ((ahd_debug & AHD_SHOW_MESSAGES) != 0)
4545                               printf("%s: QAS request.  SCSISIGI == 0x%x\n",
4546                                      ahd_name(ahd), ahd_inb(ahd, SCSISIGI));
4547 #endif
4548                     ahd->msg_flags |= MSG_FLAG_EXPECT_QASREJ_BUSFREE;
4549                     /* FALLTHROUGH */
4550           case MSG_TERM_IO_PROC:
4551           default:
4552                     reject = TRUE;
4553                     break;
4554           }
4555 
4556           if (reject) {
4557                     /*
4558                      * Setup to reject the message.
4559                      */
4560                     ahd->msgout_index = 0;
4561                     ahd->msgout_len = 1;
4562                     ahd->msgout_buf[0] = MSG_MESSAGE_REJECT;
4563                     done = MSGLOOP_MSGCOMPLETE;
4564                     response = TRUE;
4565           }
4566 
4567           if (done != MSGLOOP_IN_PROG && !response)
4568                     /* Clear the outgoing message buffer */
4569                     ahd->msgout_len = 0;
4570 
4571           return (done);
4572 }
4573 
4574 /*
4575  * Process a message reject message.
4576  */
4577 static int
ahd_handle_msg_reject(struct ahd_softc * ahd,struct ahd_devinfo * devinfo)4578 ahd_handle_msg_reject(struct ahd_softc *ahd, struct ahd_devinfo *devinfo)
4579 {
4580           /*
4581            * What we care about here is if we had an
4582            * outstanding SDTR or WDTR message for this
4583            * target.  If we did, this is a signal that
4584            * the target is refusing negotiation.
4585            */
4586           struct scb *scb;
4587           struct ahd_initiator_tinfo *tinfo;
4588           struct ahd_tmode_tstate *tstate;
4589           u_int scb_index;
4590           u_int last_msg;
4591           int   response = 0;
4592 
4593           scb_index = ahd_get_scbptr(ahd);
4594           scb = ahd_lookup_scb(ahd, scb_index);
4595           tinfo = ahd_fetch_transinfo(ahd, devinfo->channel,
4596                                             devinfo->our_scsiid,
4597                                             devinfo->target, &tstate);
4598           /* Might be necessary */
4599           last_msg = ahd_inb(ahd, LAST_MSG);
4600 
4601           if (ahd_sent_msg(ahd, AHDMSG_EXT, MSG_EXT_PPR, /*full*/FALSE)) {
4602                     if (ahd_sent_msg(ahd, AHDMSG_EXT, MSG_EXT_PPR, /*full*/TRUE)
4603                      && tinfo->goal.period <= AHD_SYNCRATE_PACED) {
4604                               /*
4605                                * Target may not like our SPI-4 PPR Options.
4606                                * Attempt to negotiate 80MHz which will turn
4607                                * off these options.
4608                                */
4609                               if (bootverbose) {
4610                                         printf("(%s:%c:%d:%d): PPR Rejected. "
4611                                                "Trying simple U160 PPR\n",
4612                                                ahd_name(ahd), devinfo->channel,
4613                                                devinfo->target, devinfo->lun);
4614                               }
4615                               tinfo->goal.period = AHD_SYNCRATE_DT;
4616                               tinfo->goal.ppr_options &= MSG_EXT_PPR_IU_REQ
4617                                                             |  MSG_EXT_PPR_QAS_REQ
4618                                                             |  MSG_EXT_PPR_DT_REQ;
4619                     } else {
4620                               /*
4621                                * Target does not support the PPR message.
4622                                * Attempt to negotiate SPI-2 style.
4623                                */
4624                               if (bootverbose) {
4625                                         printf("(%s:%c:%d:%d): PPR Rejected. "
4626                                                "Trying WDTR/SDTR\n",
4627                                                ahd_name(ahd), devinfo->channel,
4628                                                devinfo->target, devinfo->lun);
4629                               }
4630                               tinfo->goal.ppr_options = 0;
4631                               tinfo->curr.transport_version = 2;
4632                               tinfo->goal.transport_version = 2;
4633                     }
4634                     ahd->msgout_index = 0;
4635                     ahd->msgout_len = 0;
4636                     ahd_build_transfer_msg(ahd, devinfo);
4637                     ahd->msgout_index = 0;
4638                     response = 1;
4639           } else if (ahd_sent_msg(ahd, AHDMSG_EXT, MSG_EXT_WDTR, /*full*/FALSE)) {
4640 
4641                     /* note 8bit xfers */
4642                     printf("(%s:%c:%d:%d): refuses WIDE negotiation.  Using "
4643                            "8bit transfers\n", ahd_name(ahd),
4644                            devinfo->channel, devinfo->target, devinfo->lun);
4645                     ahd_set_width(ahd, devinfo, MSG_EXT_WDTR_BUS_8_BIT,
4646                                     AHD_TRANS_ACTIVE|AHD_TRANS_GOAL,
4647                                     /*paused*/TRUE);
4648                     /*
4649                      * No need to clear the sync rate.  If the target
4650                      * did not accept the command, our syncrate is
4651                      * unaffected.  If the target started the negotiation,
4652                      * but rejected our response, we already cleared the
4653                      * sync rate before sending our WDTR.
4654                      */
4655                     if (tinfo->goal.offset != tinfo->curr.offset) {
4656 
4657                               /* Start the sync negotiation */
4658                               ahd->msgout_index = 0;
4659                               ahd->msgout_len = 0;
4660                               ahd_build_transfer_msg(ahd, devinfo);
4661                               ahd->msgout_index = 0;
4662                               response = 1;
4663                     }
4664           } else if (ahd_sent_msg(ahd, AHDMSG_EXT, MSG_EXT_SDTR, /*full*/FALSE)) {
4665                     /* note asynch xfers and clear flag */
4666                     ahd_set_syncrate(ahd, devinfo, /*period*/0,
4667                                          /*offset*/0, /*ppr_options*/0,
4668                                          AHD_TRANS_ACTIVE|AHD_TRANS_GOAL,
4669                                          /*paused*/TRUE);
4670                     printf("(%s:%c:%d:%d): refuses synchronous negotiation. "
4671                            "Using asynchronous transfers\n",
4672                            ahd_name(ahd), devinfo->channel,
4673                            devinfo->target, devinfo->lun);
4674           } else if ((scb->hscb->control & MSG_SIMPLE_TASK) != 0) {
4675                     int tag_type;
4676                     int mask;
4677 
4678                     tag_type = (scb->hscb->control & MSG_SIMPLE_TASK);
4679 
4680                     if (tag_type == MSG_SIMPLE_TASK) {
4681                               printf("(%s:%c:%d:%d): refuses tagged commands.  "
4682                                      "Performing non-tagged I/O\n", ahd_name(ahd),
4683                                      devinfo->channel, devinfo->target, devinfo->lun);
4684                               ahd_set_tags(ahd, devinfo, AHD_QUEUE_NONE);
4685                               mask = ~0x23;
4686                     } else {
4687                               printf("(%s:%c:%d:%d): refuses %s tagged commands.  "
4688                                      "Performing simple queue tagged I/O only\n",
4689                                      ahd_name(ahd), devinfo->channel, devinfo->target,
4690                                      devinfo->lun, tag_type == MSG_ORDERED_Q_TAG
4691                                      ? "ordered" : "head of queue");
4692                               ahd_set_tags(ahd, devinfo, AHD_QUEUE_BASIC);
4693                               mask = ~0x03;
4694                     }
4695 
4696                     /*
4697                      * Resend the identify for this CCB as the target
4698                      * may believe that the selection is invalid otherwise.
4699                      */
4700                     ahd_outb(ahd, SCB_CONTROL,
4701                                ahd_inb_scbram(ahd, SCB_CONTROL) & mask);
4702                     scb->hscb->control &= mask;
4703                     ahd_set_transaction_tag(scb, /*enabled*/FALSE,
4704                                                   /*type*/MSG_SIMPLE_TASK);
4705                     ahd_outb(ahd, MSG_OUT, MSG_IDENTIFYFLAG);
4706                     ahd_assert_atn(ahd);
4707                     ahd_busy_tcl(ahd, BUILD_TCL(scb->hscb->scsiid, devinfo->lun),
4708                                    SCB_GET_TAG(scb));
4709 
4710                     /*
4711                      * Requeue all tagged commands for this target
4712                      * currently in our possession so they can be
4713                      * converted to untagged commands.
4714                      */
4715                     ahd_search_qinfifo(ahd, SCB_GET_TARGET(ahd, scb),
4716                                            SCB_GET_CHANNEL(ahd, scb),
4717                                            SCB_GET_LUN(scb), /*tag*/SCB_LIST_NULL,
4718                                            ROLE_INITIATOR, CAM_REQUEUE_REQ,
4719                                            SEARCH_COMPLETE);
4720           } else if (ahd_sent_msg(ahd, AHDMSG_1B, MSG_IDENTIFYFLAG, TRUE)) {
4721                     /*
4722                      * Most likely the device believes that we had
4723                      * previously negotiated packetized.
4724                      */
4725                     ahd->msg_flags |= MSG_FLAG_EXPECT_PPR_BUSFREE
4726                                      |  MSG_FLAG_IU_REQ_CHANGED;
4727 
4728                     ahd_force_renegotiation(ahd, devinfo);
4729                     ahd->msgout_index = 0;
4730                     ahd->msgout_len = 0;
4731                     ahd_build_transfer_msg(ahd, devinfo);
4732                     ahd->msgout_index = 0;
4733                     response = 1;
4734           } else {
4735                     /*
4736                      * Otherwise, we ignore it.
4737                      */
4738                     printf("%s:%c:%d: Message reject for %x -- ignored\n",
4739                            ahd_name(ahd), devinfo->channel, devinfo->target,
4740                            last_msg);
4741           }
4742           return (response);
4743 }
4744 
4745 /*
4746  * Process an ignore wide residue message.
4747  */
4748 static void
ahd_handle_ign_wide_residue(struct ahd_softc * ahd,struct ahd_devinfo * devinfo)4749 ahd_handle_ign_wide_residue(struct ahd_softc *ahd,
4750     struct ahd_devinfo *devinfo)
4751 {
4752           u_int scb_index;
4753           struct scb *scb;
4754 
4755           printf("%s: ahd_handle_ign_wide_residue\n", ahd_name(ahd));
4756 
4757           scb_index = ahd_get_scbptr(ahd);
4758           scb = ahd_lookup_scb(ahd, scb_index);
4759           /*
4760            * XXX Actually check data direction in the sequencer?
4761            * Perhaps add datadir to some spare bits in the hscb?
4762            */
4763           if ((ahd_inb(ahd, SEQ_FLAGS) & DPHASE) == 0
4764            || ahd_get_transfer_dir(scb) != CAM_DIR_IN) {
4765                     /*
4766                      * Ignore the message if we haven't
4767                      * seen an appropriate data phase yet.
4768                      */
4769           } else {
4770                     /*
4771                      * If the residual occurred on the last
4772                      * transfer and the transfer request was
4773                      * expected to end on an odd count, do
4774                      * nothing.  Otherwise, subtract a byte
4775                      * and update the residual count accordingly.
4776                      */
4777                     uint32_t sgptr;
4778 
4779                     sgptr = ahd_inb_scbram(ahd, SCB_RESIDUAL_SGPTR);
4780                     if ((sgptr & SG_LIST_NULL) != 0
4781                      && (ahd_inb_scbram(ahd, SCB_TASK_ATTRIBUTE)
4782                          & SCB_XFERLEN_ODD) != 0) {
4783                               /*
4784                                * If the residual occurred on the last
4785                                * transfer and the transfer request was
4786                                * expected to end on an odd count, do
4787                                * nothing.
4788                                */
4789                     } else {
4790                               uint32_t data_cnt;
4791                               uint64_t data_addr;
4792                               uint32_t sglen;
4793 
4794                               /* Pull in the rest of the sgptr */
4795                               sgptr = ahd_inl_scbram(ahd, SCB_RESIDUAL_SGPTR);
4796                               data_cnt = ahd_inl_scbram(ahd, SCB_RESIDUAL_DATACNT);
4797                               if ((sgptr & SG_LIST_NULL) != 0) {
4798                                         /*
4799                                          * The residual data count is not updated
4800                                          * for the command run to completion case.
4801                                          * Explicitly zero the count.
4802                                          */
4803                                         data_cnt &= ~AHD_SG_LEN_MASK;
4804                               }
4805                               data_addr = ahd_inq(ahd, SHADDR);
4806                               data_cnt += 1;
4807                               data_addr -= 1;
4808                               sgptr &= SG_PTR_MASK;
4809                               if ((ahd->flags & AHD_64BIT_ADDRESSING) != 0) {
4810                                         struct ahd_dma64_seg *sg;
4811 
4812                                         sg = ahd_sg_bus_to_virt(ahd, scb, sgptr);
4813 
4814                                         /*
4815                                          * The residual sg ptr points to the next S/G
4816                                          * to load so we must go back one.
4817                                          */
4818                                         sg--;
4819                                         sglen = ahd_le32toh(sg->len) & AHD_SG_LEN_MASK;
4820                                         if (sg != scb->sg_list
4821                                          && sglen < (data_cnt & AHD_SG_LEN_MASK)) {
4822 
4823                                                   sg--;
4824                                                   sglen = ahd_le32toh(sg->len);
4825                                                   /*
4826                                                    * Preserve High Address and SG_LIST
4827                                                    * bits while setting the count to 1.
4828                                                    */
4829                                                   data_cnt = 1|(sglen&(~AHD_SG_LEN_MASK));
4830                                                   data_addr = ahd_le64toh(sg->addr)
4831                                                               + (sglen & AHD_SG_LEN_MASK)
4832                                                               - 1;
4833 
4834                                                   /*
4835                                                    * Increment sg so it points to the
4836                                                    * "next" sg.
4837                                                    */
4838                                                   sg++;
4839                                                   sgptr = ahd_sg_virt_to_bus(ahd, scb,
4840                                                                                    sg);
4841                                         }
4842                               } else {
4843                                         struct ahd_dma_seg *sg;
4844 
4845                                         sg = ahd_sg_bus_to_virt(ahd, scb, sgptr);
4846 
4847                                         /*
4848                                          * The residual sg ptr points to the next S/G
4849                                          * to load so we must go back one.
4850                                          */
4851                                         sg--;
4852                                         sglen = ahd_le32toh(sg->len) & AHD_SG_LEN_MASK;
4853                                         if (sg != scb->sg_list
4854                                          && sglen < (data_cnt & AHD_SG_LEN_MASK)) {
4855 
4856                                                   sg--;
4857                                                   sglen = ahd_le32toh(sg->len);
4858                                                   /*
4859                                                    * Preserve High Address and SG_LIST
4860                                                    * bits while setting the count to 1.
4861                                                    */
4862                                                   data_cnt = 1|(sglen&(~AHD_SG_LEN_MASK));
4863                                                   data_addr = ahd_le32toh(sg->addr)
4864                                                               + (sglen & AHD_SG_LEN_MASK)
4865                                                               - 1;
4866 
4867                                                   /*
4868                                                    * Increment sg so it points to the
4869                                                    * "next" sg.
4870                                                    */
4871                                                   sg++;
4872                                                   sgptr = ahd_sg_virt_to_bus(ahd, scb,
4873                                                                                    sg);
4874                                         }
4875                               }
4876                               /*
4877                                * Toggle the "oddness" of the transfer length
4878                                * to handle this mid-transfer ignore wide
4879                                * residue.  This ensures that the oddness is
4880                                * correct for subsequent data transfers.
4881                                */
4882                               ahd_outb(ahd, SCB_TASK_ATTRIBUTE,
4883                                   ahd_inb_scbram(ahd, SCB_TASK_ATTRIBUTE)
4884                                   ^ SCB_XFERLEN_ODD);
4885 
4886                               ahd_outl(ahd, SCB_RESIDUAL_SGPTR, sgptr);
4887                               ahd_outl(ahd, SCB_RESIDUAL_DATACNT, data_cnt);
4888                               /*
4889                                * The FIFO's pointers will be updated if/when the
4890                                * sequencer re-enters a data phase.
4891                                */
4892                     }
4893           }
4894 }
4895 
4896 
4897 /*
4898  * Reinitialize the data pointers for the active transfer
4899  * based on its current residual.
4900  */
4901 static void
ahd_reinitialize_dataptrs(struct ahd_softc * ahd)4902 ahd_reinitialize_dataptrs(struct ahd_softc *ahd)
4903 {
4904           struct               scb *scb;
4905           ahd_mode_state       saved_modes;
4906           u_int                scb_index;
4907           u_int                wait;
4908           uint32_t   sgptr;
4909           uint32_t   resid;
4910           uint64_t   dataptr;
4911 
4912           AHD_ASSERT_MODES(ahd, AHD_MODE_DFF0_MSK|AHD_MODE_DFF1_MSK,
4913                                AHD_MODE_DFF0_MSK|AHD_MODE_DFF1_MSK);
4914 
4915           scb_index = ahd_get_scbptr(ahd);
4916           scb = ahd_lookup_scb(ahd, scb_index);
4917 
4918           /*
4919            * Release and reacquire the FIFO so we
4920            * have a clean slate.
4921            */
4922           ahd_outb(ahd, DFFSXFRCTL, CLRCHN);
4923           wait = 1000;
4924           while (--wait && !(ahd_inb(ahd, MDFFSTAT) & FIFOFREE))
4925                     ahd_delay(100);
4926           if (wait == 0) {
4927                     ahd_print_path(ahd, scb);
4928                     printf("ahd_reinitialize_dataptrs: Forcing FIFO free.\n");
4929                     ahd_outb(ahd, DFFSXFRCTL, RSTCHN|CLRSHCNT);
4930           }
4931           saved_modes = ahd_save_modes(ahd);
4932           ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI);
4933           ahd_outb(ahd, DFFSTAT,
4934                      ahd_inb(ahd, DFFSTAT)
4935                     | (saved_modes == 0x11 ? CURRFIFO_1 : CURRFIFO_0));
4936 
4937           /*
4938            * Determine initial values for data_addr and data_cnt
4939            * for resuming the data phase.
4940            */
4941           sgptr = (ahd_inb_scbram(ahd, SCB_RESIDUAL_SGPTR + 3) << 24)
4942                 | (ahd_inb_scbram(ahd, SCB_RESIDUAL_SGPTR + 2) << 16)
4943                 | (ahd_inb_scbram(ahd, SCB_RESIDUAL_SGPTR + 1) << 8)
4944                 |   ahd_inb_scbram(ahd, SCB_RESIDUAL_SGPTR);
4945           sgptr &= SG_PTR_MASK;
4946 
4947           resid = (ahd_inb_scbram(ahd, SCB_RESIDUAL_DATACNT + 2) << 16)
4948                 | (ahd_inb_scbram(ahd, SCB_RESIDUAL_DATACNT + 1) << 8)
4949                 | ahd_inb_scbram(ahd, SCB_RESIDUAL_DATACNT);
4950 
4951           if ((ahd->flags & AHD_64BIT_ADDRESSING) != 0) {
4952                     struct ahd_dma64_seg *sg;
4953 
4954                     sg = ahd_sg_bus_to_virt(ahd, scb, sgptr);
4955 
4956                     /* The residual sg_ptr always points to the next sg */
4957                     sg--;
4958 
4959                     dataptr = ahd_le64toh(sg->addr)
4960                               + (ahd_le32toh(sg->len) & AHD_SG_LEN_MASK)
4961                               - resid;
4962                     ahd_outb(ahd, HADDR + 7, dataptr >> 56);
4963                     ahd_outb(ahd, HADDR + 6, dataptr >> 48);
4964                     ahd_outb(ahd, HADDR + 5, dataptr >> 40);
4965                     ahd_outb(ahd, HADDR + 4, dataptr >> 32);
4966           } else {
4967                     struct     ahd_dma_seg *sg;
4968 
4969                     sg = ahd_sg_bus_to_virt(ahd, scb, sgptr);
4970 
4971                     /* The residual sg_ptr always points to the next sg */
4972                     sg--;
4973 
4974                     dataptr = ahd_le32toh(sg->addr)
4975                               + (ahd_le32toh(sg->len) & AHD_SG_LEN_MASK)
4976                               - resid;
4977                     ahd_outb(ahd, HADDR + 4,
4978                                (ahd_le32toh(sg->len) & ~AHD_SG_LEN_MASK) >> 24);
4979           }
4980           ahd_outb(ahd, HADDR + 3, dataptr >> 24);
4981           ahd_outb(ahd, HADDR + 2, dataptr >> 16);
4982           ahd_outb(ahd, HADDR + 1, dataptr >> 8);
4983           ahd_outb(ahd, HADDR, dataptr);
4984           ahd_outb(ahd, HCNT + 2, resid >> 16);
4985           ahd_outb(ahd, HCNT + 1, resid >> 8);
4986           ahd_outb(ahd, HCNT, resid);
4987 }
4988 
4989 /*
4990  * Handle the effects of issuing a bus device reset message.
4991  */
4992 static void
ahd_handle_devreset(struct ahd_softc * ahd,struct ahd_devinfo * devinfo,u_int lun,cam_status status,const char * message,int verbose_level)4993 ahd_handle_devreset(struct ahd_softc *ahd, struct ahd_devinfo *devinfo,
4994                         u_int lun, cam_status status, const char *message,
4995                         int verbose_level)
4996 {
4997 #ifdef AHD_TARGET_MODE
4998           struct ahd_tmode_tstate* tstate;
4999 #endif
5000           int found;
5001 
5002           found = ahd_abort_scbs(ahd, devinfo->target, devinfo->channel,
5003                                      lun, SCB_LIST_NULL, devinfo->role,
5004                                      status);
5005 
5006 #ifdef AHD_TARGET_MODE
5007           /*
5008            * Send an immediate notify ccb to all target mord peripheral
5009            * drivers affected by this action.
5010            */
5011           tstate = ahd->enabled_targets[devinfo->our_scsiid];
5012           if (tstate != NULL) {
5013                     u_int cur_lun;
5014                     u_int max_lun;
5015 
5016                     if (lun != CAM_LUN_WILDCARD) {
5017                               cur_lun = 0;
5018                               max_lun = AHD_NUM_LUNS - 1;
5019                     } else {
5020                               cur_lun = lun;
5021                               max_lun = lun;
5022                     }
5023                     for (cur_lun <= max_lun; cur_lun++) {
5024                               struct ahd_tmode_lstate* lstate;
5025 
5026                               lstate = tstate->enabled_luns[cur_lun];
5027                               if (lstate == NULL)
5028                                         continue;
5029 
5030                               ahd_queue_lstate_event(ahd, lstate, devinfo->our_scsiid,
5031                                                          MSG_BUS_DEV_RESET, /*arg*/0);
5032                               ahd_send_lstate_events(ahd, lstate);
5033                     }
5034           }
5035 #endif
5036 
5037           /*
5038            * Go back to async/narrow transfers and renegotiate.
5039            */
5040           ahd_set_width(ahd, devinfo, MSG_EXT_WDTR_BUS_8_BIT,
5041                           AHD_TRANS_CUR, /*paused*/TRUE);
5042           ahd_set_syncrate(ahd, devinfo, /*period*/0, /*offset*/0,
5043                                /*ppr_options*/0, AHD_TRANS_CUR, /*paused*/TRUE);
5044 
5045           ahd_send_async(ahd, devinfo->channel, devinfo->target,
5046                            lun, AC_SENT_BDR, NULL);
5047 
5048           if (message != NULL
5049            && (verbose_level <= bootverbose))
5050                     printf("%s: %s on %c:%d. %d SCBs aborted\n", ahd_name(ahd),
5051                            message, devinfo->channel, devinfo->target, found);
5052 }
5053 
5054 #ifdef AHD_TARGET_MODE
5055 static void
ahd_setup_target_msgin(struct ahd_softc * ahd,struct ahd_devinfo * devinfo,struct scb * scb)5056 ahd_setup_target_msgin(struct ahd_softc *ahd, struct ahd_devinfo *devinfo,
5057                            struct scb *scb)
5058 {
5059 
5060           /*
5061            * To facilitate adding multiple messages together,
5062            * each routine should increment the index and len
5063            * variables instead of setting them explicitly.
5064            */
5065           ahd->msgout_index = 0;
5066           ahd->msgout_len = 0;
5067 
5068           if (scb != NULL && (scb->flags & SCB_AUTO_NEGOTIATE) != 0)
5069                     ahd_build_transfer_msg(ahd, devinfo);
5070           else
5071                     panic("ahd_intr: AWAITING target message with no message");
5072 
5073           ahd->msgout_index = 0;
5074           ahd->msg_type = MSG_TYPE_TARGET_MSGIN;
5075 }
5076 #endif
5077 /**************************** Initialization **********************************/
5078 static u_int
ahd_sglist_size(struct ahd_softc * ahd)5079 ahd_sglist_size(struct ahd_softc *ahd)
5080 {
5081           bus_size_t list_size;
5082 
5083           list_size = sizeof(struct ahd_dma_seg) * AHD_NSEG;
5084           if ((ahd->flags & AHD_64BIT_ADDRESSING) != 0)
5085                     list_size = sizeof(struct ahd_dma64_seg) * AHD_NSEG;
5086           return (list_size);
5087 }
5088 
5089 /*
5090  * Calculate the optimum S/G List allocation size.  S/G elements used
5091  * for a given transaction must be physically contiguous.  Assume the
5092  * OS will allocate full pages to us, so it doesn't make sense to request
5093  * less than a page.
5094  */
5095 static u_int
ahd_sglist_allocsize(struct ahd_softc * ahd)5096 ahd_sglist_allocsize(struct ahd_softc *ahd)
5097 {
5098           bus_size_t sg_list_increment;
5099           bus_size_t sg_list_size;
5100           bus_size_t max_list_size;
5101           bus_size_t best_list_size;
5102 
5103           /* Start out with the minimum required for AHD_NSEG. */
5104           sg_list_increment = ahd_sglist_size(ahd);
5105           sg_list_size = sg_list_increment;
5106 
5107           /* Get us as close as possible to a page in size. */
5108           while ((sg_list_size + sg_list_increment) <= PAGE_SIZE)
5109                     sg_list_size += sg_list_increment;
5110 
5111           /*
5112            * Try to reduce the amount of wastage by allocating
5113            * multiple pages.
5114            */
5115           best_list_size = sg_list_size;
5116           max_list_size = roundup(sg_list_increment, PAGE_SIZE);
5117           if (max_list_size < 4 * PAGE_SIZE)
5118                     max_list_size = 4 * PAGE_SIZE;
5119           if (max_list_size > (AHD_SCB_MAX_ALLOC * sg_list_increment))
5120                     max_list_size = (AHD_SCB_MAX_ALLOC * sg_list_increment);
5121           while ((sg_list_size + sg_list_increment) <= max_list_size
5122              &&  (sg_list_size % PAGE_SIZE) != 0) {
5123                     bus_size_t new_mod;
5124                     bus_size_t best_mod;
5125 
5126                     sg_list_size += sg_list_increment;
5127                     new_mod = sg_list_size % PAGE_SIZE;
5128                     best_mod = best_list_size % PAGE_SIZE;
5129                     if (new_mod > best_mod || new_mod == 0) {
5130                               best_list_size = sg_list_size;
5131                     }
5132           }
5133           return (best_list_size);
5134 }
5135 
5136 int
ahd_softc_init(struct ahd_softc * ahd)5137 ahd_softc_init(struct ahd_softc *ahd)
5138 {
5139 
5140           ahd->unpause = 0;
5141           ahd->pause = PAUSE;
5142           return (0);
5143 }
5144 
5145 void
ahd_set_unit(struct ahd_softc * ahd,int unit)5146 ahd_set_unit(struct ahd_softc *ahd, int unit)
5147 {
5148           ahd->unit = unit;
5149 }
5150 
5151 void
ahd_set_name(struct ahd_softc * ahd,const char * name)5152 ahd_set_name(struct ahd_softc *ahd, const char *name)
5153 {
5154           ahd->name = name;
5155 }
5156 
5157 void
ahd_free(struct ahd_softc * ahd)5158 ahd_free(struct ahd_softc *ahd)
5159 {
5160           int i;
5161 
5162           switch (ahd->init_level) {
5163           default:
5164           case 2:
5165                     ahd_shutdown(ahd);
5166                     TAILQ_REMOVE(&ahd_tailq, ahd, links);
5167                     /* FALLTHROUGH */
5168           case 1:
5169                     bus_dmamap_unload(ahd->parent_dmat,
5170                         ahd->shared_data_map.dmamap);
5171                     bus_dmamap_destroy(ahd->parent_dmat,
5172                         ahd->shared_data_map.dmamap);
5173                     bus_dmamem_unmap(ahd->parent_dmat, (void *)ahd->qoutfifo,
5174                         ahd->shared_data_size);
5175                     bus_dmamem_free(ahd->parent_dmat,
5176                         &ahd->shared_data_map.dmasegs, ahd->shared_data_map.nseg);
5177                     break;
5178           case 0:
5179                     break;
5180           }
5181 
5182           ahd_platform_free(ahd);
5183           ahd_fini_scbdata(ahd);
5184           for (i = 0; i < AHD_NUM_TARGETS; i++) {
5185                     struct ahd_tmode_tstate *tstate;
5186 
5187                     tstate = ahd->enabled_targets[i];
5188                     if (tstate != NULL) {
5189 #if AHD_TARGET_MODE
5190                               int j;
5191 
5192                               for (j = 0; j < AHD_NUM_LUNS; j++) {
5193                                         struct ahd_tmode_lstate *lstate;
5194 
5195                                         lstate = tstate->enabled_luns[j];
5196                                         if (lstate != NULL) {
5197                                                   xpt_free_path(lstate->path);
5198                                                   free(lstate, M_DEVBUF);
5199                                         }
5200                               }
5201 #endif
5202                               free(tstate, M_DEVBUF);
5203                     }
5204           }
5205 #if AHD_TARGET_MODE
5206           if (ahd->black_hole != NULL) {
5207                     xpt_free_path(ahd->black_hole->path);
5208                     free(ahd->black_hole, M_DEVBUF);
5209           }
5210 #endif
5211           if (ahd->seep_config != NULL)
5212                     free(ahd->seep_config, M_DEVBUF);
5213           if (ahd->saved_stack != NULL)
5214                     free(ahd->saved_stack, M_DEVBUF);
5215 #ifndef __FreeBSD__
5216           free(ahd, M_DEVBUF);
5217 #endif
5218           return;
5219 }
5220 
5221 void
ahd_shutdown(void * arg)5222 ahd_shutdown(void *arg)
5223 {
5224           struct    ahd_softc *ahd;
5225 
5226           ahd = arg;
5227 
5228 #ifdef AHD_DEBUG
5229           printf("%s: ahd_shutdown\n", ahd_name(ahd));
5230 #endif
5231           /*
5232            * Stop periodic timer callbacks.
5233            */
5234           ahd_timer_stop(&ahd->reset_timer);
5235           ahd_timer_stop(&ahd->stat_timer);
5236 
5237           /* This will reset most registers to 0, but not all */
5238           ahd_reset(ahd, /*reinit*/FALSE);
5239 }
5240 
5241 /*
5242  * Reset the controller and record some information about it
5243  * that is only available just after a reset.  If "reinit" is
5244  * non-zero, this reset occurred after initial configuration
5245  * and the caller requests that the chip be fully reinitialized
5246  * to a runnable state.  Chip interrupts are *not* enabled after
5247  * a reinitialization.  The caller must enable interrupts via
5248  * ahd_intr_enable().
5249  */
5250 int
ahd_reset(struct ahd_softc * ahd,int reinit)5251 ahd_reset(struct ahd_softc *ahd, int reinit)
5252 {
5253           u_int      sxfrctl1;
5254           int        wait;
5255           uint32_t cmd;
5256           struct ahd_pci_busdata        *bd = ahd->bus_data;
5257 
5258           /*
5259            * Preserve the value of the SXFRCTL1 register for all channels.
5260            * It contains settings that affect termination and we don't want
5261            * to disturb the integrity of the bus.
5262            */
5263           ahd_pause(ahd);
5264           ahd_update_modes(ahd);
5265           ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI);
5266           sxfrctl1 = ahd_inb(ahd, SXFRCTL1);
5267 
5268           cmd = pci_conf_read(bd->pc, bd->tag, PCI_COMMAND_STATUS_REG);
5269 
5270           if ((ahd->bugs & AHD_PCIX_CHIPRST_BUG) != 0) {
5271                     uint32_t mod_cmd;
5272 
5273                     /*
5274                      * A4 Razor #632
5275                      * During the assertion of CHIPRST, the chip
5276                      * does not disable its parity logic prior to
5277                      * the start of the reset.  This may cause a
5278                      * parity error to be detected and thus a
5279                      * spurious SERR or PERR assertion.  Disable
5280                      * PERR and SERR responses during the CHIPRST.
5281                      */
5282                     mod_cmd = cmd &
5283                         ~(PCI_COMMAND_PARITY_ENABLE|PCI_COMMAND_SERR_ENABLE);
5284                     pci_conf_write(bd->pc, bd->tag,
5285                         PCI_COMMAND_STATUS_REG, mod_cmd);
5286           }
5287           ahd_outb(ahd, HCNTRL, CHIPRST | ahd->pause);
5288 
5289           /*
5290            * Ensure that the reset has finished.  We delay 1000us
5291            * prior to reading the register to make sure the chip
5292            * has sufficiently completed its reset to handle register
5293            * accesses.
5294            */
5295           wait = 1000;
5296           do {
5297                     ahd_delay(1000);
5298           } while (--wait && !(ahd_inb(ahd, HCNTRL) & CHIPRSTACK));
5299 
5300           if (wait == 0) {
5301                     printf("%s: WARNING - Failed chip reset!  "
5302                            "Trying to initialize anyway.\n", ahd_name(ahd));
5303           }
5304           ahd_outb(ahd, HCNTRL, ahd->pause);
5305 
5306           if ((ahd->bugs & AHD_PCIX_CHIPRST_BUG) != 0) {
5307                     /*
5308                      * Clear any latched PCI error status and restore
5309                      * previous SERR and PERR response enables.
5310                      */
5311                     pci_conf_write(bd->pc, bd->tag, PCI_COMMAND_STATUS_REG, cmd |
5312                         (PCI_STATUS_PARITY_ERROR | PCI_STATUS_TARGET_TARGET_ABORT |
5313                          PCI_STATUS_MASTER_TARGET_ABORT | PCI_STATUS_MASTER_ABORT |
5314                          PCI_STATUS_SPECIAL_ERROR));
5315           }
5316 
5317           /*
5318            * Mode should be SCSI after a chip reset, but lets
5319            * set it just to be safe. We touch the MODE_PTR
5320            * register directly so as to bypass the lazy update
5321            * ode in ahd_set_modes().
5322            */
5323           ahd_known_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI);
5324           ahd_outb(ahd, MODE_PTR,
5325                      ahd_build_mode_state(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI));
5326 
5327           /*
5328            * Restore SXFRCTL1.
5329            *
5330            * We must always initialize STPWEN to 1 before we
5331            * restore the saved values.  STPWEN is initialized
5332            * to a tri-state condition which can only be cleared
5333            * by turning it on.
5334            */
5335           ahd_outb(ahd, SXFRCTL1, sxfrctl1|STPWEN);
5336           ahd_outb(ahd, SXFRCTL1, sxfrctl1);
5337 
5338           /* Determine chip configuration */
5339           ahd->features &= ~AHD_WIDE;
5340           if ((ahd_inb(ahd, SBLKCTL) & SELWIDE) != 0)
5341                     ahd->features |= AHD_WIDE;
5342 
5343           /*
5344            * If a recovery action has forced a chip reset,
5345            * re-initialize the chip to our liking.
5346            */
5347           if (reinit != 0)
5348                     ahd_chip_init(ahd);
5349 
5350           return (0);
5351 }
5352 
5353 /*
5354  * Determine the number of SCBs available on the controller
5355  */
5356 int
ahd_probe_scbs(struct ahd_softc * ahd)5357 ahd_probe_scbs(struct ahd_softc *ahd) {
5358           int i;
5359 
5360           AHD_ASSERT_MODES(ahd, ~(AHD_MODE_UNKNOWN_MSK|AHD_MODE_CFG_MSK),
5361                                ~(AHD_MODE_UNKNOWN_MSK|AHD_MODE_CFG_MSK));
5362           for (i = 0; i < AHD_SCB_MAX; i++) {
5363                     int j;
5364                     int ret;
5365 
5366                     ahd_set_scbptr(ahd, i);
5367                     ahd_outw(ahd, SCB_BASE, i);
5368                     for (j = 2; j < 64; j++)
5369                               ahd_outb(ahd, SCB_BASE+j, 0);
5370                     /* Start out life as unallocated (needing an abort) */
5371                     ahd_outb(ahd, SCB_CONTROL, MK_MESSAGE);
5372                     ret = ahd_inw_scbram(ahd, SCB_BASE);
5373                     if (ret != i) {
5374                               printf("%s: ahd_probe_scbs (!=%d): returned 0x%x\n",
5375                                   ahd_name(ahd), i, ret);
5376                               break;
5377                     }
5378                     ahd_set_scbptr(ahd, 0);
5379                     ret = ahd_inw_scbram(ahd, SCB_BASE);
5380                     if (ret != 0) {
5381                               printf("ahd_probe_scbs (non zero): returned 0x%x\n",
5382                                   ret);
5383                               break;
5384                     }
5385           }
5386           return (i);
5387 }
5388 
5389 static void
ahd_initialize_hscbs(struct ahd_softc * ahd)5390 ahd_initialize_hscbs(struct ahd_softc *ahd)
5391 {
5392           int i;
5393 
5394           for (i = 0; i < ahd->scb_data.maxhscbs; i++) {
5395                     ahd_set_scbptr(ahd, i);
5396 
5397                     /* Clear the control byte. */
5398                     ahd_outb(ahd, SCB_CONTROL, 0);
5399 
5400                     /* Set the next pointer */
5401                     ahd_outw(ahd, SCB_NEXT, SCB_LIST_NULL);
5402           }
5403 }
5404 
5405 static int
ahd_init_scbdata(struct ahd_softc * ahd)5406 ahd_init_scbdata(struct ahd_softc *ahd)
5407 {
5408           struct    scb_data *scb_data;
5409           int       i;
5410 
5411           scb_data = &ahd->scb_data;
5412           TAILQ_INIT(&scb_data->free_scbs);
5413           for (i = 0; i < AHD_NUM_TARGETS * AHD_NUM_LUNS_NONPKT; i++)
5414                     LIST_INIT(&scb_data->free_scb_lists[i]);
5415           LIST_INIT(&scb_data->any_dev_free_scb_list);
5416           SLIST_INIT(&scb_data->hscb_maps);
5417           SLIST_INIT(&scb_data->sg_maps);
5418           SLIST_INIT(&scb_data->sense_maps);
5419 
5420           /* Determine the number of hardware SCBs and initialize them */
5421           scb_data->maxhscbs = ahd_probe_scbs(ahd);
5422           if (scb_data->maxhscbs == 0) {
5423                     printf("%s: No SCB space found\n", ahd_name(ahd));
5424                     return (ENXIO);
5425           }
5426           ahd_initialize_hscbs(ahd);
5427 
5428           /*
5429            * Create our DMA tags.  These tags define the kinds of device
5430            * accessible memory allocations and memory mappings we will
5431            * need to perform during normal operation.
5432            *
5433            * Unless we need to further restrict the allocation, we rely
5434            * on the restrictions of the parent dmat, hence the common
5435            * use of MAXADDR and MAXSIZE.
5436            */
5437 
5438           /* Perform initial CCB allocation */
5439           ahd_alloc_scbs(ahd);
5440 
5441           if (scb_data->numscbs == 0) {
5442                     printf("%s: ahd_init_scbdata - "
5443                            "Unable to allocate initial scbs\n",
5444                            ahd_name(ahd));
5445                     goto error_exit;
5446           }
5447 
5448           /*
5449            * Note that we were successful
5450            */
5451           return (0);
5452 
5453 error_exit:
5454 
5455           return (ENOMEM);
5456 }
5457 
5458 static struct scb *
ahd_find_scb_by_tag(struct ahd_softc * ahd,u_int tag)5459 ahd_find_scb_by_tag(struct ahd_softc *ahd, u_int tag)
5460 {
5461           struct scb *scb;
5462 
5463           /*
5464            * Look on the pending list.
5465            */
5466           LIST_FOREACH(scb, &ahd->pending_scbs, pending_links) {
5467                     if (SCB_GET_TAG(scb) == tag)
5468                               return (scb);
5469           }
5470 
5471           /*
5472            * Then on all of the collision free lists.
5473            */
5474           TAILQ_FOREACH(scb, &ahd->scb_data.free_scbs, links.tqe) {
5475                     struct scb *list_scb;
5476 
5477                     list_scb = scb;
5478                     do {
5479                               if (SCB_GET_TAG(list_scb) == tag)
5480                                         return (list_scb);
5481                               list_scb = LIST_NEXT(list_scb, collision_links);
5482                     } while (list_scb);
5483           }
5484 
5485           /*
5486            * And finally on the generic free list.
5487            */
5488           LIST_FOREACH(scb, &ahd->scb_data.any_dev_free_scb_list, links.le) {
5489                     if (SCB_GET_TAG(scb) == tag)
5490                               return (scb);
5491           }
5492 
5493           return (NULL);
5494 }
5495 
5496 static void
ahd_fini_scbdata(struct ahd_softc * ahd)5497 ahd_fini_scbdata(struct ahd_softc *ahd)
5498 {
5499           struct scb_data *scb_data;
5500 
5501           scb_data = &ahd->scb_data;
5502           if (scb_data == NULL)
5503                     return;
5504 
5505           switch (scb_data->init_level) {
5506           default:
5507           case 3:
5508           {
5509                     struct map_node *sns_map;
5510 
5511                     while ((sns_map = SLIST_FIRST(&scb_data->sense_maps)) != NULL) {
5512                               SLIST_REMOVE_HEAD(&scb_data->sense_maps, links);
5513                               ahd_freedmamem(ahd->parent_dmat, PAGE_SIZE,
5514                                                sns_map->dmamap, (void *)sns_map->vaddr,
5515                                                &sns_map->dmasegs, sns_map->nseg);
5516                               free(sns_map, M_DEVBUF);
5517                     }
5518           }
5519           /* FALLTHROUGH */
5520           case 2:
5521           {
5522                     struct map_node *sg_map;
5523 
5524                     while ((sg_map = SLIST_FIRST(&scb_data->sg_maps)) != NULL) {
5525                               SLIST_REMOVE_HEAD(&scb_data->sg_maps, links);
5526                               ahd_freedmamem(ahd->parent_dmat,
5527                                                ahd_sglist_allocsize(ahd),
5528                                                sg_map->dmamap, (void *)sg_map->vaddr,
5529                                                &sg_map->dmasegs, sg_map->nseg);
5530                               free(sg_map, M_DEVBUF);
5531                     }
5532           }
5533           /* FALLTHROUGH */
5534           case 1:
5535           {
5536                     struct map_node *hscb_map;
5537 
5538                     while ((hscb_map = SLIST_FIRST(&scb_data->hscb_maps)) != NULL) {
5539                               SLIST_REMOVE_HEAD(&scb_data->hscb_maps, links);
5540                               ahd_freedmamem(ahd->parent_dmat, PAGE_SIZE,
5541                                                hscb_map->dmamap,
5542                                                (void *)hscb_map->vaddr,
5543                                                &hscb_map->dmasegs, hscb_map->nseg);
5544                               free(hscb_map, M_DEVBUF);
5545                     }
5546           }
5547           /* FALLTHROUGH */
5548           case 0:
5549                     break;
5550           }
5551 }
5552 
5553 /*
5554  * DSP filter Bypass must be enabled until the first selection
5555  * after a change in bus mode (Razor #491 and #493).
5556  */
5557 static void
ahd_setup_iocell_workaround(struct ahd_softc * ahd)5558 ahd_setup_iocell_workaround(struct ahd_softc *ahd)
5559 {
5560           ahd_mode_state saved_modes;
5561 
5562           saved_modes = ahd_save_modes(ahd);
5563           ahd_set_modes(ahd, AHD_MODE_CFG, AHD_MODE_CFG);
5564           ahd_outb(ahd, DSPDATACTL, ahd_inb(ahd, DSPDATACTL)
5565                  | BYPASSENAB | RCVROFFSTDIS | XMITOFFSTDIS);
5566           ahd_outb(ahd, SIMODE0, ahd_inb(ahd, SIMODE0) | (ENSELDO|ENSELDI));
5567 #ifdef AHD_DEBUG
5568           if ((ahd_debug & AHD_SHOW_MISC) != 0)
5569                     printf("%s: Setting up iocell workaround\n", ahd_name(ahd));
5570 #endif
5571           ahd_restore_modes(ahd, saved_modes);
5572           ahd->flags &= ~AHD_HAD_FIRST_SEL;
5573 }
5574 
5575 static void
ahd_iocell_first_selection(struct ahd_softc * ahd)5576 ahd_iocell_first_selection(struct ahd_softc *ahd)
5577 {
5578           ahd_mode_state      saved_modes;
5579           u_int               sblkctl;
5580 
5581           if ((ahd->flags & AHD_HAD_FIRST_SEL) != 0)
5582                     return;
5583           saved_modes = ahd_save_modes(ahd);
5584           ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI);
5585           sblkctl = ahd_inb(ahd, SBLKCTL);
5586           ahd_set_modes(ahd, AHD_MODE_CFG, AHD_MODE_CFG);
5587 #ifdef AHD_DEBUG
5588           if ((ahd_debug & AHD_SHOW_MISC) != 0)
5589                     printf("%s: iocell first selection\n", ahd_name(ahd));
5590 #endif
5591           if ((sblkctl & ENAB40) != 0) {
5592                     ahd_outb(ahd, DSPDATACTL,
5593                                ahd_inb(ahd, DSPDATACTL) & ~BYPASSENAB);
5594 #ifdef AHD_DEBUG
5595                     if ((ahd_debug & AHD_SHOW_MISC) != 0)
5596                               printf("%s: BYPASS now disabled\n", ahd_name(ahd));
5597 #endif
5598           }
5599           ahd_outb(ahd, SIMODE0, ahd_inb(ahd, SIMODE0) & ~(ENSELDO|ENSELDI));
5600           ahd_outb(ahd, CLRINT, CLRSCSIINT);
5601           ahd_restore_modes(ahd, saved_modes);
5602           ahd->flags |= AHD_HAD_FIRST_SEL;
5603 }
5604 
5605 /*************************** SCB Management ***********************************/
5606 static void
ahd_add_col_list(struct ahd_softc * ahd,struct scb * scb,u_int col_idx)5607 ahd_add_col_list(struct ahd_softc *ahd, struct scb *scb, u_int col_idx)
5608 {
5609           struct    scb_list *free_list;
5610           struct    scb_tailq *free_tailq;
5611           struct    scb *first_scb;
5612 
5613           scb->flags |= SCB_ON_COL_LIST;
5614           AHD_SET_SCB_COL_IDX(scb, col_idx);
5615           free_list = &ahd->scb_data.free_scb_lists[col_idx];
5616           free_tailq = &ahd->scb_data.free_scbs;
5617           first_scb = LIST_FIRST(free_list);
5618           if (first_scb != NULL) {
5619                     LIST_INSERT_AFTER(first_scb, scb, collision_links);
5620           } else {
5621                     LIST_INSERT_HEAD(free_list, scb, collision_links);
5622                     TAILQ_INSERT_TAIL(free_tailq, scb, links.tqe);
5623           }
5624 }
5625 
5626 static void
ahd_rem_col_list(struct ahd_softc * ahd,struct scb * scb)5627 ahd_rem_col_list(struct ahd_softc *ahd, struct scb *scb)
5628 {
5629           struct    scb_list *free_list;
5630           struct    scb_tailq *free_tailq;
5631           struct    scb *first_scb;
5632           u_int     col_idx;
5633 
5634           scb->flags &= ~SCB_ON_COL_LIST;
5635           col_idx = AHD_GET_SCB_COL_IDX(ahd, scb);
5636           free_list = &ahd->scb_data.free_scb_lists[col_idx];
5637           free_tailq = &ahd->scb_data.free_scbs;
5638           first_scb = LIST_FIRST(free_list);
5639           if (first_scb == scb) {
5640                     struct scb *next_scb;
5641 
5642                     /*
5643                      * Maintain order in the collision free
5644                      * lists for fairness if this device has
5645                      * other colliding tags active.
5646                      */
5647                     next_scb = LIST_NEXT(scb, collision_links);
5648                     if (next_scb != NULL) {
5649                               TAILQ_INSERT_AFTER(free_tailq, scb,
5650                                                      next_scb, links.tqe);
5651                     }
5652                     TAILQ_REMOVE(free_tailq, scb, links.tqe);
5653           }
5654           LIST_REMOVE(scb, collision_links);
5655 }
5656 
5657 /*
5658  * Get a free scb. If there are none, see if we can allocate a new SCB.
5659  */
5660 struct scb *
ahd_get_scb(struct ahd_softc * ahd,u_int col_idx)5661 ahd_get_scb(struct ahd_softc *ahd, u_int col_idx)
5662 {
5663           struct scb *scb;
5664           TAILQ_FOREACH(scb, &ahd->scb_data.free_scbs, links.tqe) {
5665                     if (AHD_GET_SCB_COL_IDX(ahd, scb) != col_idx) {
5666                               ahd_rem_col_list(ahd, scb);
5667                               goto found;
5668                     }
5669           }
5670           if ((scb = LIST_FIRST(&ahd->scb_data.any_dev_free_scb_list)) == NULL)
5671                     return (NULL);
5672           LIST_REMOVE(scb, links.le);
5673           if (col_idx != AHD_NEVER_COL_IDX
5674            && (scb->col_scb != NULL)
5675            && (scb->col_scb->flags & SCB_ACTIVE) == 0) {
5676                     LIST_REMOVE(scb->col_scb, links.le);
5677                     ahd_add_col_list(ahd, scb->col_scb, col_idx);
5678           }
5679 found:
5680           scb->flags |= SCB_ACTIVE;
5681           return (scb);
5682 }
5683 
5684 /*
5685  * Return an SCB resource to the free list.
5686  */
5687 void
ahd_free_scb(struct ahd_softc * ahd,struct scb * scb)5688 ahd_free_scb(struct ahd_softc *ahd, struct scb *scb)
5689 {
5690 
5691           /* Clean up for the next user */
5692           scb->flags = SCB_FLAG_NONE;
5693           scb->hscb->control = 0;
5694           ahd->scb_data.scbindex[SCB_GET_TAG(scb)] = NULL;
5695 
5696           if (scb->col_scb == NULL) {
5697 
5698                     /*
5699                      * No collision possible.  Just free normally.
5700                      */
5701                     LIST_INSERT_HEAD(&ahd->scb_data.any_dev_free_scb_list,
5702                                          scb, links.le);
5703           } else if ((scb->col_scb->flags & SCB_ON_COL_LIST) != 0) {
5704 
5705                     /*
5706                      * The SCB we might have collided with is on
5707                      * a free collision list.  Put both SCBs on
5708                      * the generic list.
5709                      */
5710                     ahd_rem_col_list(ahd, scb->col_scb);
5711                     LIST_INSERT_HEAD(&ahd->scb_data.any_dev_free_scb_list,
5712                                          scb, links.le);
5713                     LIST_INSERT_HEAD(&ahd->scb_data.any_dev_free_scb_list,
5714                                          scb->col_scb, links.le);
5715           } else if ((scb->col_scb->flags
5716                       & (SCB_PACKETIZED|SCB_ACTIVE)) == SCB_ACTIVE
5717                     && (scb->col_scb->hscb->control & TAG_ENB) != 0) {
5718 
5719                     /*
5720                      * The SCB we might collide with on the next allocation
5721                      * is still active in a non-packetized, tagged, context.
5722                      * Put us on the SCB collision list.
5723                      */
5724                     ahd_add_col_list(ahd, scb,
5725                                          AHD_GET_SCB_COL_IDX(ahd, scb->col_scb));
5726           } else {
5727                     /*
5728                      * The SCB we might collide with on the next allocation
5729                      * is either active in a packetized context, or free.
5730                      * Since we can't collide, put this SCB on the generic
5731                      * free list.
5732                      */
5733                     LIST_INSERT_HEAD(&ahd->scb_data.any_dev_free_scb_list,
5734                                          scb, links.le);
5735           }
5736 
5737           ahd_platform_scb_free(ahd, scb);
5738 }
5739 
5740 int
ahd_alloc_scbs(struct ahd_softc * ahd)5741 ahd_alloc_scbs(struct ahd_softc *ahd)
5742 {
5743           struct scb_data *scb_data;
5744           struct scb          *next_scb;
5745           struct hardware_scb *hscb;
5746           struct map_node *hscb_map;
5747           struct map_node *sg_map;
5748           struct map_node *sense_map;
5749           uint8_t             *segs;
5750           uint8_t             *sense_data;
5751           bus_addr_t           hscb_busaddr;
5752           bus_addr_t           sg_busaddr;
5753           bus_addr_t           sense_busaddr;
5754           int                  newcount;
5755           int                  i;
5756 
5757           scb_data = &ahd->scb_data;
5758           if (scb_data->numscbs >= AHD_SCB_MAX_ALLOC)
5759                     /* Can't allocate any more */
5760                     return (0);
5761 
5762           KASSERT(scb_data->scbs_left >= 0);
5763           if (scb_data->scbs_left != 0) {
5764                     int offset;
5765 
5766                     offset = (PAGE_SIZE / sizeof(*hscb)) - scb_data->scbs_left;
5767                     hscb_map = SLIST_FIRST(&scb_data->hscb_maps);
5768                     hscb = &((struct hardware_scb *)hscb_map->vaddr)[offset];
5769                     hscb_busaddr = hscb_map->physaddr + (offset * sizeof(*hscb));
5770           } else {
5771                     hscb_map = malloc(sizeof(*hscb_map), M_DEVBUF, M_WAITOK);
5772 
5773                     if (hscb_map == NULL)
5774                               return (0);
5775 
5776                     memset(hscb_map, 0, sizeof(*hscb_map));
5777 
5778                     /* Allocate the next batch of hardware SCBs */
5779                     if (ahd_createdmamem(ahd->parent_dmat, PAGE_SIZE,
5780                                              ahd->sc_dmaflags,
5781                                              &hscb_map->dmamap,
5782                                              (void **)&hscb_map->vaddr,
5783                                              &hscb_map->physaddr, &hscb_map->dmasegs,
5784                                              &hscb_map->nseg, ahd_name(ahd),
5785                                              "hardware SCB structures") < 0) {
5786                               free(hscb_map, M_DEVBUF);
5787                               return (0);
5788                     }
5789 
5790                     SLIST_INSERT_HEAD(&scb_data->hscb_maps, hscb_map, links);
5791 
5792                     hscb = (struct hardware_scb *)hscb_map->vaddr;
5793                     hscb_busaddr = hscb_map->physaddr;
5794                     scb_data->scbs_left = PAGE_SIZE / sizeof(*hscb);
5795           }
5796 
5797           scb_data->init_level++;
5798 
5799           if (scb_data->sgs_left != 0) {
5800                     int offset;
5801 
5802                     offset = ((ahd_sglist_allocsize(ahd) / ahd_sglist_size(ahd))
5803                            - scb_data->sgs_left) * ahd_sglist_size(ahd);
5804                     sg_map = SLIST_FIRST(&scb_data->sg_maps);
5805                     segs = sg_map->vaddr + offset;
5806                     sg_busaddr = sg_map->physaddr + offset;
5807           } else {
5808                     sg_map = malloc(sizeof(*sg_map), M_DEVBUF, M_WAITOK);
5809 
5810                     if (sg_map == NULL)
5811                               return (0);
5812 
5813                     memset(sg_map, 0, sizeof(*sg_map));
5814 
5815                     /* Allocate the next batch of S/G lists */
5816                     if (ahd_createdmamem(ahd->parent_dmat,
5817                                              ahd_sglist_allocsize(ahd),
5818                                              ahd->sc_dmaflags,
5819                                              &sg_map->dmamap, (void **)&sg_map->vaddr,
5820                                              &sg_map->physaddr, &sg_map->dmasegs,
5821                                              &sg_map->nseg, ahd_name(ahd),
5822                                              "SG data structures") < 0) {
5823                               free(sg_map, M_DEVBUF);
5824                               return (0);
5825                     }
5826 
5827                     SLIST_INSERT_HEAD(&scb_data->sg_maps, sg_map, links);
5828 
5829                     segs = sg_map->vaddr;
5830                     sg_busaddr = sg_map->physaddr;
5831                     scb_data->sgs_left =
5832                         ahd_sglist_allocsize(ahd) / ahd_sglist_size(ahd);
5833 #ifdef AHD_DEBUG
5834                     if (ahd_debug & AHD_SHOW_MEMORY)
5835                               printf("%s: ahd_alloc_scbs - Mapped SG data\n",
5836                                   ahd_name(ahd));
5837 #endif
5838           }
5839 
5840           scb_data->init_level++;
5841 
5842 
5843           if (scb_data->sense_left != 0) {
5844                     int offset;
5845 
5846                     offset = PAGE_SIZE - (AHD_SENSE_BUFSIZE * scb_data->sense_left);
5847                     sense_map = SLIST_FIRST(&scb_data->sense_maps);
5848                     sense_data = sense_map->vaddr + offset;
5849                     sense_busaddr = sense_map->physaddr + offset;
5850           } else {
5851                     sense_map = malloc(sizeof(*sense_map), M_DEVBUF, M_WAITOK);
5852 
5853                     if (sense_map == NULL)
5854                               return (0);
5855 
5856                     memset(sense_map, 0, sizeof(*sense_map));
5857 
5858                     /* Allocate the next batch of sense buffers */
5859                     if (ahd_createdmamem(ahd->parent_dmat, PAGE_SIZE,
5860                                              ahd->sc_dmaflags,
5861                                              &sense_map->dmamap,
5862                                              (void **)&sense_map->vaddr,
5863                                              &sense_map->physaddr, &sense_map->dmasegs,
5864                                              &sense_map->nseg, ahd_name(ahd),
5865                                              "Sense Data structures") < 0) {
5866                               free(sense_map, M_DEVBUF);
5867                               return (0);
5868                     }
5869 
5870                     SLIST_INSERT_HEAD(&scb_data->sense_maps, sense_map, links);
5871 
5872                     sense_data = sense_map->vaddr;
5873                     sense_busaddr = sense_map->physaddr;
5874                     scb_data->sense_left = PAGE_SIZE / AHD_SENSE_BUFSIZE;
5875 #ifdef AHD_DEBUG
5876                     if (ahd_debug & AHD_SHOW_MEMORY)
5877                               printf("%s: ahd_alloc_scbs - Mapped sense data\n",
5878                                   ahd_name(ahd));
5879 #endif
5880           }
5881 
5882           scb_data->init_level++;
5883 
5884           newcount = MIN(scb_data->sense_left, scb_data->scbs_left);
5885           newcount = MIN(newcount, scb_data->sgs_left);
5886           newcount = MIN(newcount, (AHD_SCB_MAX_ALLOC - scb_data->numscbs));
5887           scb_data->sense_left -= newcount;
5888           scb_data->scbs_left -= newcount;
5889           scb_data->sgs_left -= newcount;
5890 
5891           for (i = 0; i < newcount; i++) {
5892                     u_int col_tag;
5893 
5894                     struct scb_platform_data *pdata;
5895 #ifndef __linux__
5896                     int error;
5897 #endif
5898                     next_scb = malloc(sizeof(*next_scb), M_DEVBUF, M_WAITOK);
5899                     if (next_scb == NULL)
5900                               break;
5901 
5902                     pdata = malloc(sizeof(*pdata), M_DEVBUF, M_WAITOK);
5903                     if (pdata == NULL) {
5904                               free(next_scb, M_DEVBUF);
5905                               break;
5906                     }
5907                     next_scb->platform_data = pdata;
5908                     next_scb->hscb_map = hscb_map;
5909                     next_scb->sg_map = sg_map;
5910                     next_scb->sense_map = sense_map;
5911                     next_scb->sg_list = segs;
5912                     next_scb->sense_data = sense_data;
5913                     next_scb->sense_busaddr = sense_busaddr;
5914                     memset(hscb, 0, sizeof(*hscb));
5915                     next_scb->hscb = hscb;
5916                     hscb->hscb_busaddr = ahd_htole32(hscb_busaddr);
5917                     KASSERT((vaddr_t)hscb >= (vaddr_t)hscb_map->vaddr &&
5918                               (vaddr_t)hscb < (vaddr_t)hscb_map->vaddr + PAGE_SIZE);
5919 
5920                     /*
5921                      * The sequencer always starts with the second entry.
5922                      * The first entry is embedded in the scb.
5923                      */
5924                     next_scb->sg_list_busaddr = sg_busaddr;
5925                     if ((ahd->flags & AHD_64BIT_ADDRESSING) != 0)
5926                               next_scb->sg_list_busaddr
5927                                   += sizeof(struct ahd_dma64_seg);
5928                     else
5929                               next_scb->sg_list_busaddr += sizeof(struct ahd_dma_seg);
5930                     next_scb->ahd_softc = ahd;
5931                     next_scb->flags = SCB_FLAG_NONE;
5932 
5933                     error = bus_dmamap_create(ahd->parent_dmat,
5934                                                     AHD_MAXTRANSFER_SIZE, AHD_NSEG,
5935                                                     MAXBSIZE, 0,
5936                                                     BUS_DMA_WAITOK|BUS_DMA_ALLOCNOW|
5937                                                     ahd->sc_dmaflags,
5938                                                     &next_scb->dmamap);
5939                     if (error != 0) {
5940                               free(next_scb, M_DEVBUF);
5941                               free(pdata, M_DEVBUF);
5942                               break;
5943                     }
5944                     next_scb->hscb->tag = ahd_htole16(scb_data->numscbs);
5945                     col_tag = scb_data->numscbs ^ 0x100;
5946                     next_scb->col_scb = ahd_find_scb_by_tag(ahd, col_tag);
5947                     if (next_scb->col_scb != NULL)
5948                               next_scb->col_scb->col_scb = next_scb;
5949                     ahd_free_scb(ahd, next_scb);
5950                     hscb++;
5951                     hscb_busaddr += sizeof(*hscb);
5952                     segs += ahd_sglist_size(ahd);
5953                     sg_busaddr += ahd_sglist_size(ahd);
5954                     sense_data += AHD_SENSE_BUFSIZE;
5955                     sense_busaddr += AHD_SENSE_BUFSIZE;
5956                     scb_data->numscbs++;
5957           }
5958           return (i);
5959 }
5960 
5961 void
ahd_controller_info(struct ahd_softc * ahd,char * tbuf,size_t l)5962 ahd_controller_info(struct ahd_softc *ahd, char *tbuf, size_t l)
5963 {
5964           const char *speed;
5965           const char *type;
5966           size_t len;
5967 
5968           len = snprintf(tbuf, l, "%s: ",
5969               ahd_chip_names[ahd->chip & AHD_CHIPID_MASK]);
5970           if (len > l)
5971                     return;
5972           speed = "Ultra320 ";
5973           if ((ahd->features & AHD_WIDE) != 0) {
5974                     type = "Wide ";
5975           } else {
5976                     type = "Single ";
5977           }
5978           len += snprintf(tbuf + len, l  - len, "%s%sChannel %c, SCSI Id=%d, ",
5979                           speed, type, ahd->channel, ahd->our_id);
5980           if (len > l)
5981                     return;
5982           snprintf(tbuf + len, l - len, "%s, %d SCBs", ahd->bus_description,
5983                     ahd->scb_data.maxhscbs);
5984 }
5985 
5986 static const char * const channel_strings[] = {
5987           "Primary Low",
5988           "Primary High",
5989           "Secondary Low",
5990           "Secondary High"
5991 };
5992 
5993 static const char * const termstat_strings[] = {
5994           "Terminated Correctly",
5995           "Over Terminated",
5996           "Under Terminated",
5997           "Not Configured"
5998 };
5999 
6000 /*
6001  * Start the board, ready for normal operation
6002  */
6003 int
ahd_init(struct ahd_softc * ahd)6004 ahd_init(struct ahd_softc *ahd)
6005 {
6006           uint8_t             *next_vaddr;
6007           bus_addr_t           next_baddr;
6008           size_t               driver_data_size;
6009           int                  i;
6010           int                  error;
6011           u_int                warn_user;
6012           uint8_t              current_sensing;
6013           uint8_t              fstat;
6014 
6015           AHD_ASSERT_MODES(ahd, AHD_MODE_SCSI_MSK, AHD_MODE_SCSI_MSK);
6016 
6017           ahd->stack_size = ahd_probe_stack_size(ahd);
6018           ahd->saved_stack = malloc(ahd->stack_size * sizeof(uint16_t),
6019                                           M_DEVBUF, M_WAITOK | M_ZERO);
6020 
6021           /*
6022            * Verify that the compiler hasn't over-aggressively
6023            * padded important structures.
6024            */
6025           if (sizeof(struct hardware_scb) != 64)
6026                     panic("Hardware SCB size is incorrect");
6027 
6028 #ifdef AHD_DEBUG
6029           if ((ahd_debug & AHD_DEBUG_SEQUENCER) != 0)
6030                     ahd->flags |= AHD_SEQUENCER_DEBUG;
6031 #endif
6032 
6033           /*
6034            * Default to allowing initiator operations.
6035            */
6036           ahd->flags |= AHD_INITIATORROLE;
6037 
6038           /*
6039            * Only allow target mode features if this unit has them enabled.
6040            */
6041           if ((AHD_TMODE_ENABLE & (0x1 << ahd->unit)) == 0)
6042                     ahd->features &= ~AHD_TARGETMODE;
6043 
6044           /*
6045            * DMA tag for our command fifos and other data in system memory
6046            * the card's sequencer must be able to access.  For initiator
6047            * roles, we need to allocate space for the qoutfifo.  When providing
6048            * for the target mode role, we must additionally provide space for
6049            * the incoming target command fifo.
6050            */
6051           driver_data_size = AHD_SCB_MAX * sizeof(uint16_t)
6052                                + sizeof(struct hardware_scb);
6053           if ((ahd->features & AHD_TARGETMODE) != 0)
6054                     driver_data_size += AHD_TMODE_CMDS * sizeof(struct target_cmd);
6055           if ((ahd->bugs & AHD_PKT_BITBUCKET_BUG) != 0)
6056                     driver_data_size += PKT_OVERRUN_BUFSIZE;
6057           ahd->shared_data_size = driver_data_size;
6058 
6059           memset(&ahd->shared_data_map, 0, sizeof(ahd->shared_data_map));
6060           ahd->sc_dmaflags = BUS_DMA_NOWAIT;
6061 
6062           if (ahd_createdmamem(ahd->parent_dmat, ahd->shared_data_size,
6063                                    ahd->sc_dmaflags,
6064                                    &ahd->shared_data_map.dmamap,
6065                                    (void **)&ahd->shared_data_map.vaddr,
6066                                    &ahd->shared_data_map.physaddr,
6067                                    &ahd->shared_data_map.dmasegs,
6068                                    &ahd->shared_data_map.nseg, ahd_name(ahd),
6069                                    "shared data") < 0)
6070                     return (ENOMEM);
6071           ahd->qoutfifo = (void *) ahd->shared_data_map.vaddr;
6072 
6073           ahd->init_level++;
6074 
6075           next_vaddr = (uint8_t *)&ahd->qoutfifo[AHD_QOUT_SIZE];
6076           next_baddr = ahd->shared_data_map.physaddr +
6077               AHD_QOUT_SIZE * sizeof(uint16_t);
6078           if ((ahd->features & AHD_TARGETMODE) != 0) {
6079                     ahd->targetcmds = (struct target_cmd *)next_vaddr;
6080                     next_vaddr += AHD_TMODE_CMDS * sizeof(struct target_cmd);
6081                     next_baddr += AHD_TMODE_CMDS * sizeof(struct target_cmd);
6082           }
6083 
6084           if ((ahd->bugs & AHD_PKT_BITBUCKET_BUG) != 0) {
6085                     ahd->overrun_buf = next_vaddr;
6086                     next_vaddr += PKT_OVERRUN_BUFSIZE;
6087                     next_baddr += PKT_OVERRUN_BUFSIZE;
6088           }
6089 
6090           /*
6091            * We need one SCB to serve as the "next SCB".  Since the
6092            * tag identifier in this SCB will never be used, there is
6093            * no point in using a valid HSCB tag from an SCB pulled from
6094            * the standard free pool.  So, we allocate this "sentinel"
6095            * specially from the DMA safe memory chunk used for the QOUTFIFO.
6096            */
6097           ahd->next_queued_hscb = (struct hardware_scb *)next_vaddr;
6098           ahd->next_queued_hscb_map = &ahd->shared_data_map;
6099           ahd->next_queued_hscb->hscb_busaddr = ahd_htole32(next_baddr);
6100 
6101           memset(&ahd->scb_data, 0, sizeof(struct scb_data));
6102 
6103           /* Allocate SCB data now that parent_dmat is initialized */
6104           if (ahd_init_scbdata(ahd) != 0)
6105                     return (ENOMEM);
6106 
6107           if ((ahd->flags & AHD_INITIATORROLE) == 0)
6108                     ahd->flags &= ~AHD_RESET_BUS_A;
6109 
6110           /*
6111            * Before committing these settings to the chip, give
6112            * the OSM one last chance to modify our configuration.
6113            */
6114           ahd_platform_init(ahd);
6115 
6116           /* Bring up the chip. */
6117           ahd_chip_init(ahd);
6118 
6119           AHD_ASSERT_MODES(ahd, AHD_MODE_SCSI_MSK, AHD_MODE_SCSI_MSK);
6120 
6121           if ((ahd->flags & AHD_CURRENT_SENSING) == 0)
6122                     goto init_done;
6123 
6124           /*
6125            * Verify termination based on current draw and
6126            * warn user if the bus is over/under terminated.
6127            */
6128           error = ahd_write_flexport(ahd, FLXADDR_ROMSTAT_CURSENSECTL,
6129                                            CURSENSE_ENB);
6130           if (error != 0) {
6131                     printf("%s: current sensing timeout 1\n", ahd_name(ahd));
6132                     goto init_done;
6133           }
6134           for (i = 20, fstat = FLX_FSTAT_BUSY;
6135                (fstat & FLX_FSTAT_BUSY) != 0 && i; i--) {
6136                     error = ahd_read_flexport(ahd, FLXADDR_FLEXSTAT, &fstat);
6137                     if (error != 0) {
6138                               printf("%s: current sensing timeout 2\n",
6139                                      ahd_name(ahd));
6140                               goto init_done;
6141                     }
6142           }
6143           if (i == 0) {
6144                     printf("%s: Timedout during current-sensing test\n",
6145                            ahd_name(ahd));
6146                     goto init_done;
6147           }
6148 
6149           /* Latch Current Sensing status. */
6150           error = ahd_read_flexport(ahd, FLXADDR_CURRENT_STAT, &current_sensing);
6151           if (error != 0) {
6152                     printf("%s: current sensing timeout 3\n", ahd_name(ahd));
6153                     goto init_done;
6154           }
6155 
6156           /* Disable current sensing. */
6157           ahd_write_flexport(ahd, FLXADDR_ROMSTAT_CURSENSECTL, 0);
6158 
6159 #ifdef AHD_DEBUG
6160           if ((ahd_debug & AHD_SHOW_TERMCTL) != 0) {
6161                     printf("%s: current_sensing == 0x%x\n",
6162                            ahd_name(ahd), current_sensing);
6163           }
6164 #endif
6165           warn_user = 0;
6166           for (i = 0; i < 4; i++, current_sensing >>= FLX_CSTAT_SHIFT) {
6167                     u_int term_stat;
6168 
6169                     term_stat = (current_sensing & FLX_CSTAT_MASK);
6170                     switch (term_stat) {
6171                     case FLX_CSTAT_OVER:
6172                     case FLX_CSTAT_UNDER:
6173                               warn_user++;
6174                               /* FALLTHROUGH */
6175                     case FLX_CSTAT_INVALID:
6176                     case FLX_CSTAT_OKAY:
6177                               if (warn_user == 0 && bootverbose == 0)
6178                                         break;
6179                               printf("%s: %s Channel %s\n", ahd_name(ahd),
6180                                      channel_strings[i], termstat_strings[term_stat]);
6181                               break;
6182                     }
6183           }
6184           if (warn_user) {
6185                     printf("%s: WARNING. Termination is not configured correctly.\n"
6186                            "%s: WARNING. SCSI bus operations may FAIL.\n",
6187                            ahd_name(ahd), ahd_name(ahd));
6188           }
6189 init_done:
6190           ahd_reset_current_bus(ahd);
6191           ahd_restart(ahd);
6192           ahd_timer_reset(&ahd->stat_timer, AHD_STAT_UPDATE_US,
6193                               ahd_stat_timer, ahd);
6194 
6195           return (0);
6196 }
6197 
6198 /*
6199  * (Re)initialize chip state after a chip reset.
6200  */
6201 static void
ahd_chip_init(struct ahd_softc * ahd)6202 ahd_chip_init(struct ahd_softc *ahd)
6203 {
6204           uint32_t busaddr;
6205           u_int      sxfrctl1;
6206           u_int      scsiseq_template;
6207           u_int      wait;
6208           u_int      i;
6209           u_int      target;
6210 
6211           ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI);
6212           /*
6213            * Take the LED out of diagnostic mode
6214            */
6215           ahd_outb(ahd, SBLKCTL, ahd_inb(ahd, SBLKCTL) & ~(DIAGLEDEN|DIAGLEDON));
6216 
6217           /*
6218            * Return HS_MAILBOX to its default value.
6219            */
6220           ahd->hs_mailbox = 0;
6221           ahd_outb(ahd, HS_MAILBOX, 0);
6222 
6223           /* Set the SCSI Id, SXFRCTL0, SXFRCTL1, and SIMODE1. */
6224           ahd_outb(ahd, IOWNID, ahd->our_id);
6225           ahd_outb(ahd, TOWNID, ahd->our_id);
6226           sxfrctl1 = (ahd->flags & AHD_TERM_ENB_A) != 0 ? STPWEN : 0;
6227           sxfrctl1 |= (ahd->flags & AHD_SPCHK_ENB_A) != 0 ? ENSPCHK : 0;
6228           if ((ahd->bugs & AHD_LONG_SETIMO_BUG)
6229            && (ahd->seltime != STIMESEL_MIN)) {
6230                     /*
6231                      * The selection timer duration is twice as long
6232                      * as it should be.  Halve it by adding "1" to
6233                      * the user specified setting.
6234                      */
6235                     sxfrctl1 |= ahd->seltime + STIMESEL_BUG_ADJ;
6236           } else {
6237                     sxfrctl1 |= ahd->seltime;
6238           }
6239 
6240           ahd_outb(ahd, SXFRCTL0, DFON);
6241           ahd_outb(ahd, SXFRCTL1, sxfrctl1|ahd->seltime|ENSTIMER|ACTNEGEN);
6242           ahd_outb(ahd, SIMODE1, ENSELTIMO|ENSCSIRST|ENSCSIPERR);
6243 
6244           /*
6245            * Now that termination is set, wait for up
6246            * to 500ms for our transceivers to settle.  If
6247            * the adapter does not have a cable attached,
6248            * the transceivers may never settle, so don't
6249            * complain if we fail here.
6250            */
6251           for (wait = 10000;
6252                (ahd_inb(ahd, SBLKCTL) & (ENAB40|ENAB20)) == 0 && wait;
6253                wait--)
6254                     ahd_delay(100);
6255 
6256           /* Clear any false bus resets due to the transceivers settling */
6257           ahd_outb(ahd, CLRSINT1, CLRSCSIRSTI);
6258           ahd_outb(ahd, CLRINT, CLRSCSIINT);
6259 
6260           /* Initialize mode specific S/G state. */
6261           for (i = 0; i < 2; i++) {
6262                     ahd_set_modes(ahd, AHD_MODE_DFF0 + i, AHD_MODE_DFF0 + i);
6263                     ahd_outb(ahd, LONGJMP_ADDR + 1, INVALID_ADDR);
6264                     ahd_outb(ahd, SG_STATE, 0);
6265                     ahd_outb(ahd, CLRSEQINTSRC, 0xFF);
6266                     ahd_outb(ahd, SEQIMODE,
6267                                ENSAVEPTRS|ENCFG4DATA|ENCFG4ISTAT
6268                               |ENCFG4TSTAT|ENCFG4ICMD|ENCFG4TCMD);
6269           }
6270 
6271           ahd_set_modes(ahd, AHD_MODE_CFG, AHD_MODE_CFG);
6272           ahd_outb(ahd, DSCOMMAND0, ahd_inb(ahd, DSCOMMAND0)|MPARCKEN|CACHETHEN);
6273           ahd_outb(ahd, DFF_THRSH, RD_DFTHRSH_75|WR_DFTHRSH_75);
6274           ahd_outb(ahd, SIMODE0, ENIOERR|ENOVERRUN);
6275           ahd_outb(ahd, SIMODE3, ENNTRAMPERR|ENOSRAMPERR);
6276           if ((ahd->bugs & AHD_BUSFREEREV_BUG) != 0) {
6277                     ahd_outb(ahd, OPTIONMODE, AUTOACKEN|AUTO_MSGOUT_DE);
6278           } else {
6279                     ahd_outb(ahd, OPTIONMODE, AUTOACKEN|BUSFREEREV|AUTO_MSGOUT_DE);
6280           }
6281           ahd_outb(ahd, SCSCHKN, CURRFIFODEF|WIDERESEN|SHVALIDSTDIS);
6282           if ((ahd->chip & AHD_BUS_MASK) == AHD_PCIX)
6283                     /*
6284                      * Do not issue a target abort when a split completion
6285                      * error occurs.  Let our PCIX interrupt handler deal
6286                      * with it instead. H2A4 Razor #625
6287                      */
6288                     ahd_outb(ahd, PCIXCTL, ahd_inb(ahd, PCIXCTL) | SPLTSTADIS);
6289 
6290           if ((ahd->bugs & AHD_LQOOVERRUN_BUG) != 0)
6291                     ahd_outb(ahd, LQOSCSCTL, LQONOCHKOVER);
6292 
6293           /*
6294            * Tweak IOCELL settings.
6295            */
6296           if ((ahd->flags & AHD_HP_BOARD) != 0) {
6297                     for (i = 0; i < NUMDSPS; i++) {
6298                               ahd_outb(ahd, DSPSELECT, i);
6299                               ahd_outb(ahd, WRTBIASCTL, WRTBIASCTL_HP_DEFAULT);
6300                     }
6301 #ifdef AHD_DEBUG
6302                     if ((ahd_debug & AHD_SHOW_MISC) != 0)
6303                               printf("%s: WRTBIASCTL now 0x%x\n", ahd_name(ahd),
6304                                      WRTBIASCTL_HP_DEFAULT);
6305 #endif
6306           }
6307           ahd_setup_iocell_workaround(ahd);
6308 
6309           /*
6310            * Enable LQI Manager interrupts.
6311            */
6312           ahd_outb(ahd, LQIMODE1, ENLQIPHASE_LQ|ENLQIPHASE_NLQ|ENLIQABORT
6313                                     | ENLQICRCI_LQ|ENLQICRCI_NLQ|ENLQIBADLQI
6314                                     | ENLQIOVERI_LQ|ENLQIOVERI_NLQ);
6315           ahd_outb(ahd, LQOMODE0, ENLQOATNLQ|ENLQOATNPKT|ENLQOTCRC);
6316           /*
6317            * An interrupt from LQOBUSFREE is made redundant by the
6318            * BUSFREE interrupt.  We choose to have the sequencer catch
6319            * LQOPHCHGINPKT errors manually for the command phase at the
6320            * start of a packetized selection case.
6321                     ahd_outb(ahd, LQOMODE1, ENLQOBUSFREE|ENLQOPHACHGINPKT);
6322            */
6323           ahd_outb(ahd, LQOMODE1, 0);
6324 
6325           /*
6326            * Setup sequencer interrupt handlers.
6327            */
6328           ahd_outw(ahd, INTVEC1_ADDR, ahd_resolve_seqaddr(ahd, LABEL_seq_isr));
6329           ahd_outw(ahd, INTVEC2_ADDR, ahd_resolve_seqaddr(ahd, LABEL_timer_isr));
6330 
6331           /*
6332            * Setup SCB Offset registers.
6333            */
6334           if ((ahd->bugs & AHD_PKT_LUN_BUG) != 0) {
6335                     ahd_outb(ahd, LUNPTR, offsetof(struct hardware_scb,
6336                                pkt_long_lun));
6337           } else {
6338                     ahd_outb(ahd, LUNPTR, offsetof(struct hardware_scb, lun));
6339           }
6340           ahd_outb(ahd, CMDLENPTR, offsetof(struct hardware_scb, cdb_len));
6341           ahd_outb(ahd, ATTRPTR, offsetof(struct hardware_scb, task_attribute));
6342           ahd_outb(ahd, FLAGPTR, offsetof(struct hardware_scb, task_management));
6343           ahd_outb(ahd, CMDPTR, offsetof(struct hardware_scb,
6344                                                shared_data.idata.cdb));
6345           ahd_outb(ahd, QNEXTPTR,
6346                      offsetof(struct hardware_scb, next_hscb_busaddr));
6347           ahd_outb(ahd, ABRTBITPTR, MK_MESSAGE_BIT_OFFSET);
6348           ahd_outb(ahd, ABRTBYTEPTR, offsetof(struct hardware_scb, control));
6349           if ((ahd->bugs & AHD_PKT_LUN_BUG) != 0) {
6350                     ahd_outb(ahd, LUNLEN,
6351                                sizeof(ahd->next_queued_hscb->pkt_long_lun) - 1);
6352           } else {
6353                     ahd_outb(ahd, LUNLEN, LUNLEN_SINGLE_LEVEL_LUN);
6354           }
6355           ahd_outb(ahd, CDBLIMIT, SCB_CDB_LEN_PTR - 1);
6356           ahd_outb(ahd, MAXCMD, 0xFF);
6357           ahd_outb(ahd, SCBAUTOPTR,
6358                      AUSCBPTR_EN | offsetof(struct hardware_scb, tag));
6359 
6360           /* We haven't been enabled for target mode yet. */
6361           ahd_outb(ahd, MULTARGID, 0);
6362           ahd_outb(ahd, MULTARGID + 1, 0);
6363 
6364           ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI);
6365           /* Initialize the negotiation table. */
6366           if ((ahd->features & AHD_NEW_IOCELL_OPTS) == 0) {
6367                     /*
6368                      * Clear the spare bytes in the neg table to avoid
6369                      * spurious parity errors.
6370                      */
6371                     for (target = 0; target < AHD_NUM_TARGETS; target++) {
6372                               ahd_outb(ahd, NEGOADDR, target);
6373                               ahd_outb(ahd, ANNEXCOL, AHD_ANNEXCOL_PER_DEV0);
6374                               for (i = 0; i < AHD_NUM_PER_DEV_ANNEXCOLS; i++)
6375                                         ahd_outb(ahd, ANNEXDAT, 0);
6376                     }
6377           }
6378 
6379           for (target = 0; target < AHD_NUM_TARGETS; target++) {
6380                     struct     ahd_devinfo devinfo;
6381                     struct     ahd_initiator_tinfo *tinfo;
6382                     struct     ahd_tmode_tstate *tstate;
6383 
6384                     tinfo = ahd_fetch_transinfo(ahd, 'A', ahd->our_id,
6385                                                       target, &tstate);
6386                     ahd_compile_devinfo(&devinfo, ahd->our_id,
6387                                             target, CAM_LUN_WILDCARD,
6388                                             'A', ROLE_INITIATOR);
6389                     ahd_update_neg_table(ahd, &devinfo, &tinfo->curr);
6390           }
6391 
6392           ahd_outb(ahd, CLRSINT3, NTRAMPERR|OSRAMPERR);
6393           ahd_outb(ahd, CLRINT, CLRSCSIINT);
6394 
6395 #if NEEDS_MORE_TESTING
6396           /*
6397            * Always enable abort on incoming L_Qs if this feature is
6398            * supported.  We use this to catch invalid SCB references.
6399            */
6400           if ((ahd->bugs & AHD_ABORT_LQI_BUG) == 0)
6401                     ahd_outb(ahd, LQCTL1, ABORTPENDING);
6402           else
6403 #endif
6404                     ahd_outb(ahd, LQCTL1, 0);
6405 
6406           /* All of our queues are empty */
6407           ahd->qoutfifonext = 0;
6408           ahd->qoutfifonext_valid_tag = QOUTFIFO_ENTRY_VALID_LE;
6409           ahd_outb(ahd, QOUTFIFO_ENTRY_VALID_TAG, QOUTFIFO_ENTRY_VALID >> 8);
6410           for (i = 0; i < AHD_QOUT_SIZE; i++)
6411                     ahd->qoutfifo[i] = 0;
6412           ahd_sync_qoutfifo(ahd, BUS_DMASYNC_PREREAD);
6413 
6414           ahd->qinfifonext = 0;
6415           for (i = 0; i < AHD_QIN_SIZE; i++)
6416                     ahd->qinfifo[i] = SCB_LIST_NULL;
6417 
6418           if ((ahd->features & AHD_TARGETMODE) != 0) {
6419                     /* All target command blocks start out invalid. */
6420                     for (i = 0; i < AHD_TMODE_CMDS; i++)
6421                               ahd->targetcmds[i].cmd_valid = 0;
6422                     ahd_sync_tqinfifo(ahd, BUS_DMASYNC_PREREAD);
6423                     ahd->tqinfifonext = 1;
6424                     ahd_outb(ahd, KERNEL_TQINPOS, ahd->tqinfifonext - 1);
6425                     ahd_outb(ahd, TQINPOS, ahd->tqinfifonext);
6426           }
6427 
6428           /* Initialize Scratch Ram. */
6429           ahd_outb(ahd, SEQ_FLAGS, 0);
6430           ahd_outb(ahd, SEQ_FLAGS2, 0);
6431 
6432           /* We don't have any waiting selections */
6433           ahd_outw(ahd, WAITING_TID_HEAD, SCB_LIST_NULL);
6434           ahd_outw(ahd, WAITING_TID_TAIL, SCB_LIST_NULL);
6435           for (i = 0; i < AHD_NUM_TARGETS; i++) {
6436                     ahd_outw(ahd, WAITING_SCB_TAILS + (2 * i), SCB_LIST_NULL);
6437           }
6438 
6439           /*
6440            * Nobody is waiting to be DMAed into the QOUTFIFO.
6441            */
6442           ahd_outw(ahd, COMPLETE_SCB_HEAD, SCB_LIST_NULL);
6443           ahd_outw(ahd, COMPLETE_SCB_DMAINPROG_HEAD, SCB_LIST_NULL);
6444           ahd_outw(ahd, COMPLETE_DMA_SCB_HEAD, SCB_LIST_NULL);
6445 
6446           /*
6447            * The Freeze Count is 0.
6448            */
6449           ahd_outw(ahd, QFREEZE_COUNT, 0);
6450 
6451           /*
6452            * Tell the sequencer where it can find our arrays in memory.
6453            */
6454           busaddr = ahd->shared_data_map.physaddr;
6455           ahd_outb(ahd, SHARED_DATA_ADDR, busaddr & 0xFF);
6456           ahd_outb(ahd, SHARED_DATA_ADDR + 1, (busaddr >> 8) & 0xFF);
6457           ahd_outb(ahd, SHARED_DATA_ADDR + 2, (busaddr >> 16) & 0xFF);
6458           ahd_outb(ahd, SHARED_DATA_ADDR + 3, (busaddr >> 24) & 0xFF);
6459           ahd_outb(ahd, QOUTFIFO_NEXT_ADDR, busaddr & 0xFF);
6460           ahd_outb(ahd, QOUTFIFO_NEXT_ADDR + 1, (busaddr >> 8) & 0xFF);
6461           ahd_outb(ahd, QOUTFIFO_NEXT_ADDR + 2, (busaddr >> 16) & 0xFF);
6462           ahd_outb(ahd, QOUTFIFO_NEXT_ADDR + 3, (busaddr >> 24) & 0xFF);
6463           /*
6464            * Setup the allowed SCSI Sequences based on operational mode.
6465            * If we are a target, we'll enable select in operations once
6466            * we've had a lun enabled.
6467            */
6468           scsiseq_template = ENAUTOATNP;
6469           if ((ahd->flags & AHD_INITIATORROLE) != 0)
6470                     scsiseq_template |= ENRSELI;
6471           ahd_outb(ahd, SCSISEQ_TEMPLATE, scsiseq_template);
6472 
6473           /* There are no busy SCBs yet. */
6474           for (target = 0; target < AHD_NUM_TARGETS; target++) {
6475                     int lun;
6476 
6477                     for (lun = 0; lun < AHD_NUM_LUNS_NONPKT; lun++)
6478                               ahd_unbusy_tcl(ahd, BUILD_TCL_RAW(target, 'A', lun));
6479           }
6480 
6481           /*
6482            * Initialize the group code to command length table.
6483            * Vendor Unique codes are set to 0 so we only capture
6484            * the first byte of the cdb.  These can be overridden
6485            * when target mode is enabled.
6486            */
6487           ahd_outb(ahd, CMDSIZE_TABLE, 5);
6488           ahd_outb(ahd, CMDSIZE_TABLE + 1, 9);
6489           ahd_outb(ahd, CMDSIZE_TABLE + 2, 9);
6490           ahd_outb(ahd, CMDSIZE_TABLE + 3, 0);
6491           ahd_outb(ahd, CMDSIZE_TABLE + 4, 15);
6492           ahd_outb(ahd, CMDSIZE_TABLE + 5, 11);
6493           ahd_outb(ahd, CMDSIZE_TABLE + 6, 0);
6494           ahd_outb(ahd, CMDSIZE_TABLE + 7, 0);
6495 
6496           /* Tell the sequencer of our initial queue positions */
6497           ahd_set_modes(ahd, AHD_MODE_CCHAN, AHD_MODE_CCHAN);
6498           ahd_outb(ahd, QOFF_CTLSTA, SCB_QSIZE_512);
6499           ahd->qinfifonext = 0;
6500           ahd_set_hnscb_qoff(ahd, ahd->qinfifonext);
6501           ahd_set_hescb_qoff(ahd, 0);
6502           ahd_set_snscb_qoff(ahd, 0);
6503           ahd_set_sescb_qoff(ahd, 0);
6504           ahd_set_sdscb_qoff(ahd, 0);
6505 
6506           /*
6507            * Tell the sequencer which SCB will be the next one it receives.
6508            */
6509           busaddr = ahd_le32toh(ahd->next_queued_hscb->hscb_busaddr);
6510           ahd_outb(ahd, NEXT_QUEUED_SCB_ADDR + 0, busaddr & 0xFF);
6511           ahd_outb(ahd, NEXT_QUEUED_SCB_ADDR + 1, (busaddr >> 8) & 0xFF);
6512           ahd_outb(ahd, NEXT_QUEUED_SCB_ADDR + 2, (busaddr >> 16) & 0xFF);
6513           ahd_outb(ahd, NEXT_QUEUED_SCB_ADDR + 3, (busaddr >> 24) & 0xFF);
6514 
6515           /*
6516            * Default to coalescing disabled.
6517            */
6518           ahd_outw(ahd, INT_COALESCING_CMDCOUNT, 0);
6519           ahd_outw(ahd, CMDS_PENDING, 0);
6520           ahd_update_coalescing_values(ahd, ahd->int_coalescing_timer,
6521                                              ahd->int_coalescing_maxcmds,
6522                                              ahd->int_coalescing_mincmds);
6523           ahd_enable_coalescing(ahd, FALSE);
6524 
6525           ahd_loadseq(ahd);
6526           ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI);
6527 }
6528 
6529 /*
6530  * Setup default device and controller settings.
6531  * This should only be called if our probe has
6532  * determined that no configuration data is available.
6533  */
6534 int
ahd_default_config(struct ahd_softc * ahd)6535 ahd_default_config(struct ahd_softc *ahd)
6536 {
6537           int       targ;
6538 
6539           ahd->our_id = 7;
6540 
6541           /*
6542            * Allocate a tstate to house information for our
6543            * initiator presence on the bus as well as the user
6544            * data for any target mode initiator.
6545            */
6546           if (ahd_alloc_tstate(ahd, ahd->our_id, 'A') == NULL) {
6547                     printf("%s: unable to allocate ahd_tmode_tstate.  "
6548                            "Failing attach\n", ahd_name(ahd));
6549                     return (ENOMEM);
6550           }
6551 
6552           for (targ = 0; targ < AHD_NUM_TARGETS; targ++) {
6553                     struct     ahd_devinfo devinfo;
6554                     struct     ahd_initiator_tinfo *tinfo;
6555                     struct     ahd_tmode_tstate *tstate;
6556                     uint16_t target_mask;
6557 
6558                     tinfo = ahd_fetch_transinfo(ahd, 'A', ahd->our_id,
6559                                                       targ, &tstate);
6560                     /*
6561                      * We support SPC2 and SPI4.
6562                      */
6563                     tinfo->user.protocol_version = 4;
6564                     tinfo->user.transport_version = 4;
6565 
6566                     target_mask = 0x01 << targ;
6567                     ahd->user_discenable |= target_mask;
6568                     tstate->discenable |= target_mask;
6569                     ahd->user_tagenable |= target_mask;
6570 #ifdef AHD_FORCE_160
6571                     tinfo->user.period = AHD_SYNCRATE_DT;
6572 #else
6573                     tinfo->user.period = AHD_SYNCRATE_160;
6574 #endif
6575                     tinfo->user.offset= MAX_OFFSET;
6576                     tinfo->user.ppr_options = MSG_EXT_PPR_RDSTRM
6577                                                   | MSG_EXT_PPR_WRFLOW
6578                                                   | MSG_EXT_PPR_HOLDMCS
6579                                                   | MSG_EXT_PPR_IU_REQ
6580                                                   | MSG_EXT_PPR_QAS_REQ
6581                                                   | MSG_EXT_PPR_DT_REQ;
6582                     if ((ahd->features & AHD_RTI) != 0)
6583                               tinfo->user.ppr_options |= MSG_EXT_PPR_RTI;
6584 
6585                     tinfo->user.width = MSG_EXT_WDTR_BUS_16_BIT;
6586 
6587                     /*
6588                      * Start out Async/Narrow/Untagged and with
6589                      * conservative protocol support.
6590                      */
6591                     tinfo->goal.protocol_version = 2;
6592                     tinfo->goal.transport_version = 2;
6593                     tinfo->curr.protocol_version = 2;
6594                     tinfo->curr.transport_version = 2;
6595                     ahd_compile_devinfo(&devinfo, ahd->our_id,
6596                                             targ, CAM_LUN_WILDCARD,
6597                                             'A', ROLE_INITIATOR);
6598                     tstate->tagenable &= ~target_mask;
6599                     ahd_set_width(ahd, &devinfo, MSG_EXT_WDTR_BUS_8_BIT,
6600                                     AHD_TRANS_CUR|AHD_TRANS_GOAL, /*paused*/TRUE);
6601                     ahd_set_syncrate(ahd, &devinfo, /*period*/0, /*offset*/0,
6602                                          /*ppr_options*/0, AHD_TRANS_CUR|AHD_TRANS_GOAL,
6603                                          /*paused*/TRUE);
6604           }
6605           return (0);
6606 }
6607 
6608 /*
6609  * Parse device configuration information.
6610  */
6611 int
ahd_parse_cfgdata(struct ahd_softc * ahd,struct seeprom_config * sc)6612 ahd_parse_cfgdata(struct ahd_softc *ahd, struct seeprom_config *sc)
6613 {
6614           int targ;
6615           int max_targ;
6616 
6617           max_targ = sc->max_targets & CFMAXTARG;
6618           ahd->our_id = sc->brtime_id & CFSCSIID;
6619 
6620           /*
6621            * Allocate a tstate to house information for our
6622            * initiator presence on the bus as well as the user
6623            * data for any target mode initiator.
6624            */
6625           if (ahd_alloc_tstate(ahd, ahd->our_id, 'A') == NULL) {
6626                     printf("%s: unable to allocate ahd_tmode_tstate.  "
6627                            "Failing attach\n", ahd_name(ahd));
6628                     return (ENOMEM);
6629           }
6630 
6631           for (targ = 0; targ < max_targ; targ++) {
6632                     struct     ahd_devinfo devinfo;
6633                     struct     ahd_initiator_tinfo *tinfo;
6634                     struct     ahd_transinfo *user_tinfo;
6635                     struct     ahd_tmode_tstate *tstate;
6636                     uint16_t target_mask;
6637 
6638                     tinfo = ahd_fetch_transinfo(ahd, 'A', ahd->our_id,
6639                                                       targ, &tstate);
6640                     user_tinfo = &tinfo->user;
6641 
6642                     /*
6643                      * We support SPC2 and SPI4.
6644                      */
6645                     tinfo->user.protocol_version = 4;
6646                     tinfo->user.transport_version = 4;
6647 
6648                     target_mask = 0x01 << targ;
6649                     ahd->user_discenable &= ~target_mask;
6650                     tstate->discenable &= ~target_mask;
6651                     ahd->user_tagenable &= ~target_mask;
6652                     if (sc->device_flags[targ] & CFDISC) {
6653                               tstate->discenable |= target_mask;
6654                               ahd->user_discenable |= target_mask;
6655                               ahd->user_tagenable |= target_mask;
6656                     } else {
6657                               /*
6658                                * Cannot be packetized without disconnection.
6659                                */
6660                               sc->device_flags[targ] &= ~CFPACKETIZED;
6661                     }
6662 
6663                     user_tinfo->ppr_options = 0;
6664                     user_tinfo->period = (sc->device_flags[targ] & CFXFER);
6665                     if (user_tinfo->period < CFXFER_ASYNC) {
6666                               if (user_tinfo->period <= AHD_PERIOD_10MHz)
6667                                         user_tinfo->ppr_options |= MSG_EXT_PPR_DT_REQ;
6668                               user_tinfo->offset = MAX_OFFSET;
6669                     } else  {
6670                               user_tinfo->offset = 0;
6671                               user_tinfo->period = AHD_ASYNC_XFER_PERIOD;
6672                     }
6673 #ifdef AHD_FORCE_160
6674                     if (user_tinfo->period <= AHD_SYNCRATE_160)
6675                               user_tinfo->period = AHD_SYNCRATE_DT;
6676 #endif
6677 
6678                     if ((sc->device_flags[targ] & CFPACKETIZED) != 0) {
6679                               user_tinfo->ppr_options |= MSG_EXT_PPR_RDSTRM
6680                                                             |  MSG_EXT_PPR_WRFLOW
6681                                                             |  MSG_EXT_PPR_HOLDMCS
6682                                                             |  MSG_EXT_PPR_IU_REQ;
6683                               if ((ahd->features & AHD_RTI) != 0)
6684                                         user_tinfo->ppr_options |= MSG_EXT_PPR_RTI;
6685                     }
6686 
6687                     if ((sc->device_flags[targ] & CFQAS) != 0)
6688                               user_tinfo->ppr_options |= MSG_EXT_PPR_QAS_REQ;
6689 
6690                     if ((sc->device_flags[targ] & CFWIDEB) != 0)
6691                               user_tinfo->width = MSG_EXT_WDTR_BUS_16_BIT;
6692                     else
6693                               user_tinfo->width = MSG_EXT_WDTR_BUS_8_BIT;
6694 #ifdef AHD_DEBUG
6695                     if ((ahd_debug & AHD_SHOW_MISC) != 0)
6696                               printf("(%d): %x:%x:%x:%x\n", targ, user_tinfo->width,
6697                                      user_tinfo->period, user_tinfo->offset,
6698                                      user_tinfo->ppr_options);
6699 #endif
6700                     /*
6701                      * Start out Async/Narrow/Untagged and with
6702                      * conservative protocol support.
6703                      */
6704                     tstate->tagenable &= ~target_mask;
6705                     tinfo->goal.protocol_version = 2;
6706                     tinfo->goal.transport_version = 2;
6707                     tinfo->curr.protocol_version = 2;
6708                     tinfo->curr.transport_version = 2;
6709                     ahd_compile_devinfo(&devinfo, ahd->our_id,
6710                                             targ, CAM_LUN_WILDCARD,
6711                                             'A', ROLE_INITIATOR);
6712                     ahd_set_width(ahd, &devinfo, MSG_EXT_WDTR_BUS_8_BIT,
6713                                     AHD_TRANS_CUR|AHD_TRANS_GOAL, /*paused*/TRUE);
6714                     ahd_set_syncrate(ahd, &devinfo, /*period*/0, /*offset*/0,
6715                                          /*ppr_options*/0, AHD_TRANS_CUR|AHD_TRANS_GOAL,
6716                                          /*paused*/TRUE);
6717           }
6718 
6719           ahd->flags &= ~AHD_SPCHK_ENB_A;
6720           if (sc->bios_control & CFSPARITY)
6721                     ahd->flags |= AHD_SPCHK_ENB_A;
6722 
6723           ahd->flags &= ~AHD_RESET_BUS_A;
6724           if (sc->bios_control & CFRESETB)
6725                     ahd->flags |= AHD_RESET_BUS_A;
6726 
6727           ahd->flags &= ~AHD_EXTENDED_TRANS_A;
6728           if (sc->bios_control & CFEXTEND)
6729                     ahd->flags |= AHD_EXTENDED_TRANS_A;
6730 
6731           ahd->flags &= ~AHD_BIOS_ENABLED;
6732           if ((sc->bios_control & CFBIOSSTATE) == CFBS_ENABLED)
6733                     ahd->flags |= AHD_BIOS_ENABLED;
6734 
6735           ahd->flags &= ~AHD_STPWLEVEL_A;
6736           if ((sc->adapter_control & CFSTPWLEVEL) != 0)
6737                     ahd->flags |= AHD_STPWLEVEL_A;
6738 
6739           return (0);
6740 }
6741 
6742 /*
6743  * Parse device configuration information.
6744  */
6745 int
ahd_parse_vpddata(struct ahd_softc * ahd,struct vpd_config * vpd)6746 ahd_parse_vpddata(struct ahd_softc *ahd, struct vpd_config *vpd)
6747 {
6748           int error;
6749 
6750           error = ahd_verify_vpd_cksum(vpd);
6751           if (error == 0)
6752                     return (EINVAL);
6753           if ((vpd->bios_flags & VPDBOOTHOST) != 0)
6754                     ahd->flags |= AHD_BOOT_CHANNEL;
6755           return (0);
6756 }
6757 
6758 void
ahd_intr_enable(struct ahd_softc * ahd,int enable)6759 ahd_intr_enable(struct ahd_softc *ahd, int enable)
6760 {
6761           u_int hcntrl;
6762 
6763           hcntrl = ahd_inb(ahd, HCNTRL);
6764           hcntrl &= ~INTEN;
6765           ahd->pause &= ~INTEN;
6766           ahd->unpause &= ~INTEN;
6767           if (enable) {
6768                     hcntrl |= INTEN;
6769                     ahd->pause |= INTEN;
6770                     ahd->unpause |= INTEN;
6771           }
6772           ahd_outb(ahd, HCNTRL, hcntrl);
6773 }
6774 
6775 void
ahd_update_coalescing_values(struct ahd_softc * ahd,u_int timer,u_int maxcmds,u_int mincmds)6776 ahd_update_coalescing_values(struct ahd_softc *ahd, u_int timer, u_int maxcmds,
6777                                    u_int mincmds)
6778 {
6779           if (timer > AHD_TIMER_MAX_US)
6780                     timer = AHD_TIMER_MAX_US;
6781           ahd->int_coalescing_timer = timer;
6782 
6783           if (maxcmds > AHD_INT_COALESCING_MAXCMDS_MAX)
6784                     maxcmds = AHD_INT_COALESCING_MAXCMDS_MAX;
6785           if (mincmds > AHD_INT_COALESCING_MINCMDS_MAX)
6786                     mincmds = AHD_INT_COALESCING_MINCMDS_MAX;
6787           ahd->int_coalescing_maxcmds = maxcmds;
6788           ahd_outw(ahd, INT_COALESCING_TIMER, timer / AHD_TIMER_US_PER_TICK);
6789           ahd_outb(ahd, INT_COALESCING_MAXCMDS, -maxcmds);
6790           ahd_outb(ahd, INT_COALESCING_MINCMDS, -mincmds);
6791 }
6792 
6793 void
ahd_enable_coalescing(struct ahd_softc * ahd,int enable)6794 ahd_enable_coalescing(struct ahd_softc *ahd, int enable)
6795 {
6796 
6797           ahd->hs_mailbox &= ~ENINT_COALESCE;
6798           if (enable)
6799                     ahd->hs_mailbox |= ENINT_COALESCE;
6800           ahd_outb(ahd, HS_MAILBOX, ahd->hs_mailbox);
6801           ahd_flush_device_writes(ahd);
6802           ahd_run_qoutfifo(ahd);
6803 }
6804 
6805 /*
6806  * Ensure that the card is paused in a location
6807  * outside of all critical sections and that all
6808  * pending work is completed prior to returning.
6809  * This routine should only be called from outside
6810  * an interrupt context.
6811  */
6812 void
ahd_pause_and_flushwork(struct ahd_softc * ahd)6813 ahd_pause_and_flushwork(struct ahd_softc *ahd)
6814 {
6815           u_int intstat;
6816           u_int maxloops;
6817           u_int qfreeze_cnt;
6818 
6819           maxloops = 1000;
6820           ahd->flags |= AHD_ALL_INTERRUPTS;
6821           ahd_pause(ahd);
6822           /*
6823            * Increment the QFreeze Count so that the sequencer
6824            * will not start new selections.  We do this only
6825            * until we are safely paused without further selections
6826            * pending.
6827            */
6828           ahd_outw(ahd, QFREEZE_COUNT, ahd_inw(ahd, QFREEZE_COUNT) + 1);
6829           ahd_outb(ahd, SEQ_FLAGS2, ahd_inb(ahd, SEQ_FLAGS2) | SELECTOUT_QFROZEN);
6830           do {
6831                     struct scb *waiting_scb;
6832 
6833                     ahd_unpause(ahd);
6834                     ahd_intr(ahd);
6835                     ahd_pause(ahd);
6836                     ahd_clear_critical_section(ahd);
6837                     intstat = ahd_inb(ahd, INTSTAT);
6838                     ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI);
6839                     if ((ahd_inb(ahd, SSTAT0) & (SELDO|SELINGO)) == 0)
6840                               ahd_outb(ahd, SCSISEQ0,
6841                                          ahd_inb(ahd, SCSISEQ0) & ~ENSELO);
6842                     /*
6843                      * In the non-packetized case, the sequencer (for Rev A),
6844                      * relies on ENSELO remaining set after SELDO.  The hardware
6845                      * auto-clears ENSELO in the packetized case.
6846                      */
6847                     waiting_scb = ahd_lookup_scb(ahd,
6848                                                        ahd_inw(ahd, WAITING_TID_HEAD));
6849                     if (waiting_scb != NULL
6850                      && (waiting_scb->flags & SCB_PACKETIZED) == 0
6851                      && (ahd_inb(ahd, SSTAT0) & (SELDO|SELINGO)) != 0)
6852                               ahd_outb(ahd, SCSISEQ0,
6853                                          ahd_inb(ahd, SCSISEQ0) | ENSELO);
6854           } while (--maxloops
6855                      && (intstat != 0xFF || (ahd->features & AHD_REMOVABLE) == 0)
6856                      && ((intstat & INT_PEND) != 0
6857                       || (ahd_inb(ahd, SCSISEQ0) & ENSELO) != 0
6858                       || (ahd_inb(ahd, SSTAT0) & (SELDO|SELINGO)) != 0));
6859           if (maxloops == 0) {
6860                     printf("Infinite interrupt loop, INTSTAT = %x",
6861                           ahd_inb(ahd, INTSTAT));
6862           }
6863           qfreeze_cnt = ahd_inw(ahd, QFREEZE_COUNT);
6864           if (qfreeze_cnt == 0) {
6865                     printf("%s: ahd_pause_and_flushwork with 0 qfreeze count!\n",
6866                            ahd_name(ahd));
6867           } else {
6868                     qfreeze_cnt--;
6869           }
6870           ahd_outw(ahd, QFREEZE_COUNT, qfreeze_cnt);
6871           if (qfreeze_cnt == 0)
6872                     ahd_outb(ahd, SEQ_FLAGS2,
6873                                ahd_inb(ahd, SEQ_FLAGS2) & ~SELECTOUT_QFROZEN);
6874 
6875           ahd_flush_qoutfifo(ahd);
6876 
6877           ahd_platform_flushwork(ahd);
6878           ahd->flags &= ~AHD_ALL_INTERRUPTS;
6879 }
6880 
6881 int
ahd_suspend(struct ahd_softc * ahd)6882 ahd_suspend(struct ahd_softc *ahd)
6883 {
6884 
6885           ahd_pause_and_flushwork(ahd);
6886 
6887           if (LIST_FIRST(&ahd->pending_scbs) != NULL) {
6888                     ahd_unpause(ahd);
6889                     return (EBUSY);
6890           }
6891           ahd_shutdown(ahd);
6892           return (0);
6893 }
6894 
6895 int
ahd_resume(struct ahd_softc * ahd)6896 ahd_resume(struct ahd_softc *ahd)
6897 {
6898 
6899           ahd_reset(ahd, /*reinit*/TRUE);
6900           ahd_intr_enable(ahd, TRUE);
6901           ahd_restart(ahd);
6902           return (0);
6903 }
6904 
6905 /************************** Busy Target Table *********************************/
6906 /*
6907  * Set SCBPTR to the SCB that contains the busy
6908  * table entry for TCL.  Return the offset into
6909  * the SCB that contains the entry for TCL.
6910  * saved_scbid is dereferenced and set to the
6911  * scbid that should be restored once manipulation
6912  * of the TCL entry is complete.
6913  */
6914 static inline u_int
ahd_index_busy_tcl(struct ahd_softc * ahd,u_int * saved_scbid,u_int tcl)6915 ahd_index_busy_tcl(struct ahd_softc *ahd, u_int *saved_scbid, u_int tcl)
6916 {
6917           /*
6918            * Index to the SCB that contains the busy entry.
6919            */
6920           AHD_ASSERT_MODES(ahd, AHD_MODE_SCSI_MSK, AHD_MODE_SCSI_MSK);
6921           *saved_scbid = ahd_get_scbptr(ahd);
6922           ahd_set_scbptr(ahd, TCL_LUN(tcl)
6923                          | ((TCL_TARGET_OFFSET(tcl) & 0xC) << 4));
6924 
6925           /*
6926            * And now calculate the SCB offset to the entry.
6927            * Each entry is 2 bytes wide, hence the
6928            * multiplication by 2.
6929            */
6930           return (((TCL_TARGET_OFFSET(tcl) & 0x3) << 1) + SCB_DISCONNECTED_LISTS);
6931 }
6932 
6933 /*
6934  * Return the untagged transaction id for a given target/channel lun.
6935  */
6936 u_int
ahd_find_busy_tcl(struct ahd_softc * ahd,u_int tcl)6937 ahd_find_busy_tcl(struct ahd_softc *ahd, u_int tcl)
6938 {
6939           u_int scbid;
6940           u_int scb_offset;
6941           u_int saved_scbptr;
6942 
6943           scb_offset = ahd_index_busy_tcl(ahd, &saved_scbptr, tcl);
6944           scbid = ahd_inw_scbram(ahd, scb_offset);
6945           ahd_set_scbptr(ahd, saved_scbptr);
6946           return (scbid);
6947 }
6948 
6949 void
ahd_busy_tcl(struct ahd_softc * ahd,u_int tcl,u_int scbid)6950 ahd_busy_tcl(struct ahd_softc *ahd, u_int tcl, u_int scbid)
6951 {
6952           u_int scb_offset;
6953           u_int saved_scbptr;
6954 
6955           scb_offset = ahd_index_busy_tcl(ahd, &saved_scbptr, tcl);
6956           ahd_outw(ahd, scb_offset, scbid);
6957           ahd_set_scbptr(ahd, saved_scbptr);
6958 }
6959 
6960 /************************** SCB and SCB queue management **********************/
6961 int
ahd_match_scb(struct ahd_softc * ahd,struct scb * scb,int target,char channel,int lun,u_int tag,role_t role)6962 ahd_match_scb(struct ahd_softc *ahd, struct scb *scb, int target,
6963                 char channel, int lun, u_int tag, role_t role)
6964 {
6965           int targ = SCB_GET_TARGET(ahd, scb);
6966           char chan = SCB_GET_CHANNEL(ahd, scb);
6967           int slun = SCB_GET_LUN(scb);
6968           int match;
6969 
6970           match = ((chan == channel) || (channel == ALL_CHANNELS));
6971           if (match != 0)
6972                     match = ((targ == target) || (target == CAM_TARGET_WILDCARD));
6973           if (match != 0)
6974                     match = ((lun == slun) || (lun == CAM_LUN_WILDCARD));
6975           if (match != 0) {
6976 #if AHD_TARGET_MODE
6977                     int group;
6978 
6979                     group = XPT_FC_GROUP(scb->io_ctx->ccb_h.func_code);
6980                     if (role == ROLE_INITIATOR) {
6981                               match = (group != XPT_FC_GROUP_TMODE)
6982                                     && ((tag == SCB_GET_TAG(scb))
6983                                      || (tag == SCB_LIST_NULL));
6984                     } else if (role == ROLE_TARGET) {
6985                               match = (group == XPT_FC_GROUP_TMODE)
6986                                     && ((tag == scb->io_ctx->csio.tag_id)
6987                                      || (tag == SCB_LIST_NULL));
6988                     }
6989 #else /* !AHD_TARGET_MODE */
6990                     match = ((tag == SCB_GET_TAG(scb)) || (tag == SCB_LIST_NULL));
6991 #endif /* AHD_TARGET_MODE */
6992           }
6993 
6994           return match;
6995 }
6996 
6997 void
ahd_freeze_devq(struct ahd_softc * ahd,struct scb * scb)6998 ahd_freeze_devq(struct ahd_softc *ahd, struct scb *scb)
6999 {
7000           int       target;
7001           char      channel;
7002           int       lun;
7003 
7004           target = SCB_GET_TARGET(ahd, scb);
7005           lun = SCB_GET_LUN(scb);
7006           channel = SCB_GET_CHANNEL(ahd, scb);
7007 
7008           ahd_search_qinfifo(ahd, target, channel, lun,
7009                                  /*tag*/SCB_LIST_NULL, ROLE_UNKNOWN,
7010                                  CAM_REQUEUE_REQ, SEARCH_COMPLETE);
7011 
7012           ahd_platform_freeze_devq(ahd, scb);
7013 }
7014 
7015 void
ahd_qinfifo_requeue_tail(struct ahd_softc * ahd,struct scb * scb)7016 ahd_qinfifo_requeue_tail(struct ahd_softc *ahd, struct scb *scb)
7017 {
7018           struct scb          *prev_scb;
7019           ahd_mode_state       saved_modes;
7020 
7021           saved_modes = ahd_save_modes(ahd);
7022           ahd_set_modes(ahd, AHD_MODE_CCHAN, AHD_MODE_CCHAN);
7023           prev_scb = NULL;
7024           if (ahd_qinfifo_count(ahd) != 0) {
7025                     u_int prev_tag;
7026                     u_int prev_pos;
7027 
7028                     prev_pos = AHD_QIN_WRAP(ahd->qinfifonext - 1);
7029                     prev_tag = ahd->qinfifo[prev_pos];
7030                     prev_scb = ahd_lookup_scb(ahd, prev_tag);
7031           }
7032           ahd_qinfifo_requeue(ahd, prev_scb, scb);
7033           ahd_set_hnscb_qoff(ahd, ahd->qinfifonext);
7034           ahd_restore_modes(ahd, saved_modes);
7035 }
7036 
7037 static void
ahd_qinfifo_requeue(struct ahd_softc * ahd,struct scb * prev_scb,struct scb * scb)7038 ahd_qinfifo_requeue(struct ahd_softc *ahd, struct scb *prev_scb,
7039                         struct scb *scb)
7040 {
7041           if (prev_scb == NULL) {
7042                     uint32_t busaddr;
7043 
7044                     busaddr = ahd_le32toh(scb->hscb->hscb_busaddr);
7045                     ahd_outb(ahd, NEXT_QUEUED_SCB_ADDR + 0, busaddr & 0xFF);
7046                     ahd_outb(ahd, NEXT_QUEUED_SCB_ADDR + 1, (busaddr >> 8) & 0xFF);
7047                     ahd_outb(ahd, NEXT_QUEUED_SCB_ADDR + 2, (busaddr >> 16) & 0xFF);
7048                     ahd_outb(ahd, NEXT_QUEUED_SCB_ADDR + 3, (busaddr >> 24) & 0xFF);
7049           } else {
7050                     prev_scb->hscb->next_hscb_busaddr = scb->hscb->hscb_busaddr;
7051                     ahd_sync_scb(ahd, prev_scb,
7052                                    BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
7053           }
7054           ahd->qinfifo[AHD_QIN_WRAP(ahd->qinfifonext)] = SCB_GET_TAG(scb);
7055           ahd->qinfifonext++;
7056           scb->hscb->next_hscb_busaddr = ahd->next_queued_hscb->hscb_busaddr;
7057           ahd_sync_scb(ahd, scb, BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
7058 }
7059 
7060 static int
ahd_qinfifo_count(struct ahd_softc * ahd)7061 ahd_qinfifo_count(struct ahd_softc *ahd)
7062 {
7063           u_int qinpos;
7064           u_int wrap_qinpos;
7065           u_int wrap_qinfifonext;
7066 
7067           AHD_ASSERT_MODES(ahd, AHD_MODE_CCHAN_MSK, AHD_MODE_CCHAN_MSK);
7068           qinpos = ahd_get_snscb_qoff(ahd);
7069           wrap_qinpos = AHD_QIN_WRAP(qinpos);
7070           wrap_qinfifonext = AHD_QIN_WRAP(ahd->qinfifonext);
7071           if (wrap_qinfifonext >= wrap_qinpos)
7072                     return (wrap_qinfifonext - wrap_qinpos);
7073           else
7074                     return (wrap_qinfifonext
7075                           + NUM_ELEMENTS(ahd->qinfifo) - wrap_qinpos);
7076 }
7077 
7078 void
ahd_reset_cmds_pending(struct ahd_softc * ahd)7079 ahd_reset_cmds_pending(struct ahd_softc *ahd)
7080 {
7081           struct              scb *scb;
7082           ahd_mode_state      saved_modes;
7083           u_int               pending_cmds;
7084 
7085           saved_modes = ahd_save_modes(ahd);
7086           ahd_set_modes(ahd, AHD_MODE_CCHAN, AHD_MODE_CCHAN);
7087 
7088           /*
7089            * Don't count any commands as outstanding that the
7090            * sequencer has already marked for completion.
7091            */
7092           ahd_flush_qoutfifo(ahd);
7093 
7094           pending_cmds = 0;
7095           LIST_FOREACH(scb, &ahd->pending_scbs, pending_links) {
7096                     pending_cmds++;
7097           }
7098           ahd_outw(ahd, CMDS_PENDING, pending_cmds - ahd_qinfifo_count(ahd));
7099           ahd_restore_modes(ahd, saved_modes);
7100           ahd->flags &= ~AHD_UPDATE_PEND_CMDS;
7101 }
7102 
7103 int
ahd_search_qinfifo(struct ahd_softc * ahd,int target,char channel,int lun,u_int tag,role_t role,uint32_t status,ahd_search_action action)7104 ahd_search_qinfifo(struct ahd_softc *ahd, int target, char channel,
7105                        int lun, u_int tag, role_t role, uint32_t status,
7106                        ahd_search_action action)
7107 {
7108           struct scb          *scb;
7109           struct scb          *prev_scb;
7110           ahd_mode_state       saved_modes;
7111           u_int                qinstart;
7112           u_int                qinpos;
7113           u_int                qintail;
7114           u_int                tid_next;
7115           u_int                tid_prev;
7116           u_int                scbid;
7117           u_int                savedscbptr;
7118           uint32_t   busaddr;
7119           int                  found;
7120           int                  targets;
7121           int                  pending_cmds;
7122 
7123           /* Must be in CCHAN mode */
7124           saved_modes = ahd_save_modes(ahd);
7125           ahd_set_modes(ahd, AHD_MODE_CCHAN, AHD_MODE_CCHAN);
7126 
7127           /*
7128            * Halt any pending SCB DMA.  The sequencer will reinitiate
7129            * this DMA if the qinfifo is not empty once we unpause.
7130            */
7131           if ((ahd_inb(ahd, CCSCBCTL) & (CCARREN|CCSCBEN|CCSCBDIR))
7132               == (CCARREN|CCSCBEN|CCSCBDIR)) {
7133                     ahd_outb(ahd, CCSCBCTL,
7134                                ahd_inb(ahd, CCSCBCTL) & ~(CCARREN|CCSCBEN));
7135                     while ((ahd_inb(ahd, CCSCBCTL) & (CCARREN|CCSCBEN)) != 0)
7136                               ;
7137           }
7138           /* Determine sequencer's position in the qinfifo. */
7139           qintail = AHD_QIN_WRAP(ahd->qinfifonext);
7140           qinstart = ahd_get_snscb_qoff(ahd);
7141           qinpos = AHD_QIN_WRAP(qinstart);
7142           found = 0;
7143           prev_scb = NULL;
7144 
7145           pending_cmds = 0;
7146           LIST_FOREACH(scb, &ahd->pending_scbs, pending_links) {
7147                     pending_cmds++;
7148           }
7149           (void)ahd_qinfifo_count(ahd);
7150 
7151           if (action == SEARCH_PRINT) {
7152                     printf("qinstart = 0x%x qinfifonext = 0x%x\n",
7153                            qinstart, ahd->qinfifonext);
7154           }
7155 
7156           /*
7157            * Start with an empty queue.  Entries that are not chosen
7158            * for removal will be re-added to the queue as we go.
7159            */
7160           ahd->qinfifonext = qinstart;
7161           busaddr = ahd_le32toh(ahd->next_queued_hscb->hscb_busaddr);
7162           ahd_outb(ahd, NEXT_QUEUED_SCB_ADDR + 0, busaddr & 0xFF);
7163           ahd_outb(ahd, NEXT_QUEUED_SCB_ADDR + 1, (busaddr >> 8) & 0xFF);
7164           ahd_outb(ahd, NEXT_QUEUED_SCB_ADDR + 2, (busaddr >> 16) & 0xFF);
7165           ahd_outb(ahd, NEXT_QUEUED_SCB_ADDR + 3, (busaddr >> 24) & 0xFF);
7166 
7167           while (qinpos != qintail) {
7168                     scb = ahd_lookup_scb(ahd, ahd->qinfifo[qinpos]);
7169                     if (scb == NULL) {
7170                               panic("Loop 1\n");
7171                     }
7172 
7173                     if (ahd_match_scb(ahd, scb, target, channel, lun, tag, role)) {
7174                               /*
7175                                * We found an scb that needs to be acted on.
7176                                */
7177                               found++;
7178                               switch (action) {
7179                               case SEARCH_COMPLETE:
7180                               {
7181                                         cam_status ostat;
7182                                         cam_status cstat;
7183 
7184                                         ostat = ahd_get_scsi_status(scb);
7185                                         if (ostat == CAM_REQ_INPROG)
7186                                                   ahd_set_scsi_status(scb, status);
7187                                         cstat = ahd_get_transaction_status(scb);
7188                                         if (cstat != CAM_REQ_CMP)
7189                                                   ahd_freeze_scb(scb);
7190                                         if ((scb->flags & SCB_ACTIVE) == 0)
7191                                                   printf("Inactive SCB in qinfifo\n");
7192                                         if ((cam_status)scb->xs->error != CAM_REQ_CMP)
7193                                                   printf("SEARCH_COMPLETE(0x%x):"
7194                                                          " ostat 0x%x, cstat 0x%x, "
7195                                                          "xs_error 0x%x\n",
7196                                                          SCB_GET_TAG(scb), ostat, cstat,
7197                                                          scb->xs->error);
7198                                         ahd_done(ahd, scb);
7199 
7200                                         /* FALLTHROUGH */
7201                               }
7202                               case SEARCH_REMOVE:
7203                                         break;
7204                               case SEARCH_PRINT:
7205                                         printf(" 0x%x", ahd->qinfifo[qinpos]);
7206                                         /* FALLTHROUGH */
7207                               case SEARCH_COUNT:
7208                                         ahd_qinfifo_requeue(ahd, prev_scb, scb);
7209                                         prev_scb = scb;
7210                                         break;
7211                               }
7212                     } else {
7213                               ahd_qinfifo_requeue(ahd, prev_scb, scb);
7214                               prev_scb = scb;
7215                     }
7216                     qinpos = AHD_QIN_WRAP(qinpos+1);
7217           }
7218 
7219           ahd_set_hnscb_qoff(ahd, ahd->qinfifonext);
7220 
7221           if (action == SEARCH_PRINT)
7222                     printf("\nWAITING_TID_QUEUES:\n");
7223 
7224           /*
7225            * Search waiting for selection lists.  We traverse the
7226            * list of "their ids" waiting for selection and, if
7227            * appropriate, traverse the SCBs of each "their id"
7228            * looking for matches.
7229            */
7230           savedscbptr = ahd_get_scbptr(ahd);
7231           tid_next = ahd_inw(ahd, WAITING_TID_HEAD);
7232           tid_prev = SCB_LIST_NULL;
7233           targets = 0;
7234           for (scbid = tid_next; !SCBID_IS_NULL(scbid); scbid = tid_next) {
7235                     u_int tid_head;
7236 
7237                     /*
7238                      * We limit based on the number of SCBs since
7239                      * MK_MESSAGE SCBs are not in the per-tid lists.
7240                      */
7241                     targets++;
7242                     if (targets > AHD_SCB_MAX) {
7243                               panic("TID LIST LOOP");
7244                     }
7245                     if (scbid >= ahd->scb_data.numscbs) {
7246                               printf("%s: Waiting TID List inconsistency. "
7247                                      "SCB index == 0x%x, yet numscbs == 0x%x.",
7248                                      ahd_name(ahd), scbid, ahd->scb_data.numscbs);
7249                               ahd_dump_card_state(ahd);
7250                               panic("for safety");
7251                     }
7252                     scb = ahd_lookup_scb(ahd, scbid);
7253                     if (scb == NULL) {
7254                               printf("%s: SCB = 0x%x Not Active!\n",
7255                                      ahd_name(ahd), scbid);
7256                               panic("Waiting TID List traversal\n");
7257                               break;
7258                     }
7259                     ahd_set_scbptr(ahd, scbid);
7260                     tid_next = ahd_inw_scbram(ahd, SCB_NEXT2);
7261                     if (ahd_match_scb(ahd, scb, target, channel, CAM_LUN_WILDCARD,
7262                                           SCB_LIST_NULL, ROLE_UNKNOWN) == 0) {
7263                               tid_prev = scbid;
7264                               continue;
7265                     }
7266 
7267                     /*
7268                      * We found a list of scbs that needs to be searched.
7269                      */
7270                     if (action == SEARCH_PRINT)
7271                               printf("       %d ( ", SCB_GET_TARGET(ahd, scb));
7272                     tid_head = scbid;
7273                     found += ahd_search_scb_list(ahd, target, channel,
7274                                                        lun, tag, role, status,
7275                                                        action, &tid_head,
7276                                                        SCB_GET_TARGET(ahd, scb));
7277                     if (tid_head != scbid)
7278                               ahd_stitch_tid_list(ahd, tid_prev, tid_head, tid_next);
7279                     if (!SCBID_IS_NULL(tid_head))
7280                               tid_prev = tid_head;
7281                     if (action == SEARCH_PRINT)
7282                               printf(")\n");
7283           }
7284           ahd_set_scbptr(ahd, savedscbptr);
7285           ahd_restore_modes(ahd, saved_modes);
7286           return (found);
7287 }
7288 
7289 static int
ahd_search_scb_list(struct ahd_softc * ahd,int target,char channel,int lun,u_int tag,role_t role,uint32_t status,ahd_search_action action,u_int * list_head,u_int tid)7290 ahd_search_scb_list(struct ahd_softc *ahd, int target, char channel,
7291                         int lun, u_int tag, role_t role, uint32_t status,
7292                         ahd_search_action action, u_int *list_head, u_int tid)
7293 {
7294           struct    scb *scb;
7295           u_int     scbid;
7296           u_int     next;
7297           u_int     prev;
7298           int       found;
7299 
7300           AHD_ASSERT_MODES(ahd, AHD_MODE_CCHAN_MSK, AHD_MODE_CCHAN_MSK);
7301           found = 0;
7302           prev = SCB_LIST_NULL;
7303           next = *list_head;
7304           for (scbid = next; !SCBID_IS_NULL(scbid); scbid = next) {
7305                     if (scbid >= ahd->scb_data.numscbs) {
7306                               printf("%s:SCB List inconsistency. "
7307                                      "SCB == 0x%x, yet numscbs == 0x%x.",
7308                                      ahd_name(ahd), scbid, ahd->scb_data.numscbs);
7309                               ahd_dump_card_state(ahd);
7310                               panic("for safety");
7311                     }
7312                     scb = ahd_lookup_scb(ahd, scbid);
7313                     if (scb == NULL) {
7314                               printf("%s: SCB = %d Not Active!\n",
7315                                      ahd_name(ahd), scbid);
7316                               panic("Waiting List traversal\n");
7317                     }
7318                     ahd_set_scbptr(ahd, scbid);
7319                     next = ahd_inw_scbram(ahd, SCB_NEXT);
7320                     if (ahd_match_scb(ahd, scb, target, channel,
7321                                           lun, SCB_LIST_NULL, role) == 0) {
7322                               prev = scbid;
7323                               continue;
7324                     }
7325                     found++;
7326                     switch (action) {
7327                     case SEARCH_COMPLETE:
7328                     {
7329                               cam_status ostat;
7330                               cam_status cstat;
7331 
7332                               ostat = ahd_get_scsi_status(scb);
7333                               if (ostat == CAM_REQ_INPROG)
7334                                         ahd_set_scsi_status(scb, status);
7335                               cstat = ahd_get_transaction_status(scb);
7336                               if (cstat != CAM_REQ_CMP)
7337                                         ahd_freeze_scb(scb);
7338                               if ((scb->flags & SCB_ACTIVE) == 0)
7339                                         printf("Inactive SCB in Waiting List\n");
7340                               ahd_done(ahd, scb);
7341                     }
7342                     /* FALLTHROUGH */
7343                     case SEARCH_REMOVE:
7344                               ahd_rem_wscb(ahd, scbid, prev, next, tid);
7345                               if (prev == SCB_LIST_NULL)
7346                                         *list_head = next;
7347                               break;
7348                     case SEARCH_PRINT:
7349                               printf("0x%x ", scbid);
7350                               /* FALLTHROUGH */
7351                     case SEARCH_COUNT:
7352                               prev = scbid;
7353                               break;
7354                     }
7355                     if (found > AHD_SCB_MAX)
7356                               panic("SCB LIST LOOP");
7357           }
7358           if (action == SEARCH_COMPLETE
7359            || action == SEARCH_REMOVE)
7360                     ahd_outw(ahd, CMDS_PENDING, ahd_inw(ahd, CMDS_PENDING) - found);
7361           return (found);
7362 }
7363 
7364 static void
ahd_stitch_tid_list(struct ahd_softc * ahd,u_int tid_prev,u_int tid_cur,u_int tid_next)7365 ahd_stitch_tid_list(struct ahd_softc *ahd, u_int tid_prev,
7366                         u_int tid_cur, u_int tid_next)
7367 {
7368           AHD_ASSERT_MODES(ahd, AHD_MODE_CCHAN_MSK, AHD_MODE_CCHAN_MSK);
7369 
7370           if (SCBID_IS_NULL(tid_cur)) {
7371 
7372                     /* Bypass current TID list */
7373                     if (SCBID_IS_NULL(tid_prev)) {
7374                               ahd_outw(ahd, WAITING_TID_HEAD, tid_next);
7375                     } else {
7376                               ahd_set_scbptr(ahd, tid_prev);
7377                               ahd_outw(ahd, SCB_NEXT2, tid_next);
7378                     }
7379                     if (SCBID_IS_NULL(tid_next))
7380                               ahd_outw(ahd, WAITING_TID_TAIL, tid_prev);
7381           } else {
7382 
7383                     /* Stitch through tid_cur */
7384                     if (SCBID_IS_NULL(tid_prev)) {
7385                               ahd_outw(ahd, WAITING_TID_HEAD, tid_cur);
7386                     } else {
7387                               ahd_set_scbptr(ahd, tid_prev);
7388                               ahd_outw(ahd, SCB_NEXT2, tid_cur);
7389                     }
7390                     ahd_set_scbptr(ahd, tid_cur);
7391                     ahd_outw(ahd, SCB_NEXT2, tid_next);
7392 
7393                     if (SCBID_IS_NULL(tid_next))
7394                               ahd_outw(ahd, WAITING_TID_TAIL, tid_cur);
7395           }
7396 }
7397 
7398 /*
7399  * Manipulate the waiting for selection list and return the
7400  * scb that follows the one that we remove.
7401  */
7402 static u_int
ahd_rem_wscb(struct ahd_softc * ahd,u_int scbid,u_int prev,u_int next,u_int tid)7403 ahd_rem_wscb(struct ahd_softc *ahd, u_int scbid,
7404                u_int prev, u_int next, u_int tid)
7405 {
7406           u_int tail_offset;
7407 
7408           AHD_ASSERT_MODES(ahd, AHD_MODE_CCHAN_MSK, AHD_MODE_CCHAN_MSK);
7409           if (!SCBID_IS_NULL(prev)) {
7410                     ahd_set_scbptr(ahd, prev);
7411                     ahd_outw(ahd, SCB_NEXT, next);
7412           }
7413 
7414           /*
7415            * SCBs that had MK_MESSAGE set in them will not
7416            * be queued to the per-target lists, so don't
7417            * blindly clear the tail pointer.
7418            */
7419           tail_offset = WAITING_SCB_TAILS + (2 * tid);
7420           if (SCBID_IS_NULL(next)
7421            && ahd_inw(ahd, tail_offset) == scbid)
7422                     ahd_outw(ahd, tail_offset, prev);
7423           ahd_add_scb_to_free_list(ahd, scbid);
7424           return (next);
7425 }
7426 
7427 /*
7428  * Add the SCB as selected by SCBPTR onto the on chip list of
7429  * free hardware SCBs.  This list is empty/unused if we are not
7430  * performing SCB paging.
7431  */
7432 static void
ahd_add_scb_to_free_list(struct ahd_softc * ahd,u_int scbid)7433 ahd_add_scb_to_free_list(struct ahd_softc *ahd, u_int scbid)
7434 {
7435 #ifdef notdef
7436 /* XXX Need some other mechanism to designate "free". */
7437           /*
7438            * Invalidate the tag so that our abort
7439            * routines don't think it's active.
7440            */
7441           ahd_outb(ahd, SCB_TAG, SCB_LIST_NULL);
7442 #endif
7443 }
7444 
7445 /******************************** Error Handling ******************************/
7446 /*
7447  * Abort all SCBs that match the given description (target/channel/lun/tag),
7448  * setting their status to the passed in status if the status has not already
7449  * been modified from CAM_REQ_INPROG.  This routine assumes that the sequencer
7450  * is paused before it is called.
7451  */
7452 int
ahd_abort_scbs(struct ahd_softc * ahd,int target,char channel,int lun,u_int tag,role_t role,uint32_t status)7453 ahd_abort_scbs(struct ahd_softc *ahd, int target, char channel,
7454                  int lun, u_int tag, role_t role, uint32_t status)
7455 {
7456           struct              scb *scbp;
7457           struct              scb *scbp_next;
7458           u_int               i, j;
7459           u_int               maxtarget;
7460           u_int               minlun;
7461           u_int               maxlun;
7462           int                 found;
7463           ahd_mode_state      saved_modes;
7464 
7465           /* restore this when we're done */
7466           saved_modes = ahd_save_modes(ahd);
7467           ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI);
7468 
7469           found = ahd_search_qinfifo(ahd, target, channel, lun, SCB_LIST_NULL,
7470                                            role, CAM_REQUEUE_REQ, SEARCH_COMPLETE);
7471 
7472           /*
7473            * Clean out the busy target table for any untagged commands.
7474            */
7475           i = 0;
7476           maxtarget = 16;
7477           if (target != CAM_TARGET_WILDCARD) {
7478                     i = target;
7479                     if (channel == 'B')
7480                               i += 8;
7481                     maxtarget = i + 1;
7482           }
7483 
7484           if (lun == CAM_LUN_WILDCARD) {
7485                     minlun = 0;
7486                     maxlun = AHD_NUM_LUNS_NONPKT;
7487           } else if (lun >= AHD_NUM_LUNS_NONPKT) {
7488                     minlun = maxlun = 0;
7489           } else {
7490                     minlun = lun;
7491                     maxlun = lun + 1;
7492           }
7493 
7494           if (role != ROLE_TARGET) {
7495                     for (;i < maxtarget; i++) {
7496                               for (j = minlun;j < maxlun; j++) {
7497                                         u_int scbid;
7498                                         u_int tcl;
7499 
7500                                         tcl = BUILD_TCL_RAW(i, 'A', j);
7501                                         scbid = ahd_find_busy_tcl(ahd, tcl);
7502                                         scbp = ahd_lookup_scb(ahd, scbid);
7503                                         if (scbp == NULL
7504                                          || ahd_match_scb(ahd, scbp, target, channel,
7505                                                               lun, tag, role) == 0)
7506                                                   continue;
7507                                         ahd_unbusy_tcl(ahd, BUILD_TCL_RAW(i, 'A', j));
7508                               }
7509                     }
7510           }
7511 
7512           /*
7513            * Don't abort commands that have already completed,
7514            * but haven't quite made it up to the host yet.
7515            */
7516           ahd_flush_qoutfifo(ahd);
7517 
7518           /*
7519            * Go through the pending CCB list and look for
7520            * commands for this target that are still active.
7521            * These are other tagged commands that were
7522            * disconnected when the reset occurred.
7523            */
7524           scbp_next = LIST_FIRST(&ahd->pending_scbs);
7525           while (scbp_next != NULL) {
7526                     scbp = scbp_next;
7527                     scbp_next = LIST_NEXT(scbp, pending_links);
7528                     if (ahd_match_scb(ahd, scbp, target, channel, lun, tag, role)) {
7529                               cam_status ostat;
7530 
7531                               ostat = ahd_get_scsi_status(scbp);
7532                               if (ostat == CAM_REQ_INPROG)
7533                                         ahd_set_scsi_status(scbp, status);
7534                               if (ahd_get_transaction_status(scbp) != CAM_REQ_CMP)
7535                                         ahd_freeze_scb(scbp);
7536                               if ((scbp->flags & SCB_ACTIVE) == 0)
7537                                         printf("Inactive SCB on pending list\n");
7538                               ahd_done(ahd, scbp);
7539                               found++;
7540                     }
7541           }
7542           ahd_restore_modes(ahd, saved_modes);
7543           ahd_platform_abort_scbs(ahd, target, channel, lun, tag, role, status);
7544           ahd->flags |= AHD_UPDATE_PEND_CMDS;
7545           return found;
7546 }
7547 
7548 static void
ahd_reset_current_bus(struct ahd_softc * ahd)7549 ahd_reset_current_bus(struct ahd_softc *ahd)
7550 {
7551           uint8_t scsiseq;
7552 
7553           AHD_ASSERT_MODES(ahd, AHD_MODE_SCSI_MSK, AHD_MODE_SCSI_MSK);
7554           ahd_outb(ahd, SIMODE1, ahd_inb(ahd, SIMODE1) & ~ENSCSIRST);
7555           scsiseq = ahd_inb(ahd, SCSISEQ0) & ~(ENSELO|ENARBO|SCSIRSTO);
7556           ahd_outb(ahd, SCSISEQ0, scsiseq | SCSIRSTO);
7557           ahd_flush_device_writes(ahd);
7558           ahd_delay(AHD_BUSRESET_DELAY);
7559           /* Turn off the bus reset */
7560           ahd_outb(ahd, SCSISEQ0, scsiseq);
7561           ahd_flush_device_writes(ahd);
7562           ahd_delay(AHD_BUSRESET_DELAY);
7563           if ((ahd->bugs & AHD_SCSIRST_BUG) != 0) {
7564                     /*
7565                      * 2A Razor #474
7566                      * Certain chip state is not cleared for
7567                      * SCSI bus resets that we initiate, so
7568                      * we must reset the chip.
7569                      */
7570                     ahd_reset(ahd, /*reinit*/TRUE);
7571                     ahd_intr_enable(ahd, /*enable*/TRUE);
7572                     AHD_ASSERT_MODES(ahd, AHD_MODE_SCSI_MSK, AHD_MODE_SCSI_MSK);
7573           }
7574 
7575           ahd_clear_intstat(ahd);
7576 }
7577 
7578 int
ahd_reset_channel(struct ahd_softc * ahd,char channel,int initiate_reset)7579 ahd_reset_channel(struct ahd_softc *ahd, char channel, int initiate_reset)
7580 {
7581           struct    ahd_devinfo devinfo;
7582           u_int     initiator;
7583           u_int     target;
7584           u_int     max_scsiid;
7585           int       found;
7586           u_int     fifo;
7587           u_int     next_fifo;
7588 
7589 
7590           ahd->pending_device = NULL;
7591 
7592           ahd_compile_devinfo(&devinfo,
7593                                   CAM_TARGET_WILDCARD,
7594                                   CAM_TARGET_WILDCARD,
7595                                   CAM_LUN_WILDCARD,
7596                                   channel, ROLE_UNKNOWN);
7597           ahd_pause(ahd);
7598 
7599           /* Make sure the sequencer is in a safe location. */
7600           ahd_clear_critical_section(ahd);
7601 
7602 #if AHD_TARGET_MODE
7603           if ((ahd->flags & AHD_TARGETROLE) != 0) {
7604                     ahd_run_tqinfifo(ahd, /*paused*/TRUE);
7605           }
7606 #endif
7607           ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI);
7608 
7609           /*
7610            * Disable selections so no automatic hardware
7611            * functions will modify chip state.
7612            */
7613           ahd_outb(ahd, SCSISEQ0, 0);
7614           ahd_outb(ahd, SCSISEQ1, 0);
7615 
7616           /*
7617            * Safely shut down our DMA engines.  Always start with
7618            * the FIFO that is not currently active (if any are
7619            * actively connected).
7620            */
7621           next_fifo = fifo = ahd_inb(ahd, DFFSTAT) & CURRFIFO;
7622           if (next_fifo > CURRFIFO_1)
7623                     /* If disconnected, arbitrarily start with FIFO1. */
7624                     next_fifo = fifo = 0;
7625           do {
7626                     next_fifo ^= CURRFIFO_1;
7627                     ahd_set_modes(ahd, next_fifo, next_fifo);
7628                     ahd_outb(ahd, DFCNTRL,
7629                                ahd_inb(ahd, DFCNTRL) & ~(SCSIEN|HDMAEN));
7630                     while ((ahd_inb(ahd, DFCNTRL) & HDMAENACK) != 0)
7631                               ahd_delay(10);
7632                     /*
7633                      * Set CURRFIFO to the now inactive channel.
7634                      */
7635                     ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI);
7636                     ahd_outb(ahd, DFFSTAT, next_fifo);
7637           } while (next_fifo != fifo);
7638 
7639           /*
7640            * Reset the bus if we are initiating this reset
7641            */
7642           ahd_clear_msg_state(ahd);
7643           ahd_outb(ahd, SIMODE1,
7644                      ahd_inb(ahd, SIMODE1) & ~(ENBUSFREE|ENSCSIRST|ENBUSFREE));
7645 
7646           if (initiate_reset)
7647                     ahd_reset_current_bus(ahd);
7648 
7649           ahd_clear_intstat(ahd);
7650 
7651           /*
7652            * Clean up all the state information for the
7653            * pending transactions on this bus.
7654            */
7655           found = ahd_abort_scbs(ahd, CAM_TARGET_WILDCARD, channel,
7656                                      CAM_LUN_WILDCARD, SCB_LIST_NULL,
7657                                      ROLE_UNKNOWN, CAM_SCSI_BUS_RESET);
7658 
7659           /*
7660            * Cleanup anything left in the FIFOs.
7661            */
7662           ahd_clear_fifo(ahd, 0);
7663           ahd_clear_fifo(ahd, 1);
7664 
7665           /*
7666            * Revert to async/narrow transfers until we renegotiate.
7667            */
7668           max_scsiid = (ahd->features & AHD_WIDE) ? 15 : 7;
7669           for (target = 0; target <= max_scsiid; target++) {
7670 
7671                     if (ahd->enabled_targets[target] == NULL)
7672                               continue;
7673                     for (initiator = 0; initiator <= max_scsiid; initiator++) {
7674                               struct ahd_devinfo dinfo;
7675 
7676                               ahd_compile_devinfo(&dinfo, target, initiator,
7677                                                       CAM_LUN_WILDCARD,
7678                                                       'A', ROLE_UNKNOWN);
7679                               ahd_set_width(ahd, &dinfo, MSG_EXT_WDTR_BUS_8_BIT,
7680                                               AHD_TRANS_CUR, /*paused*/TRUE);
7681                               ahd_set_syncrate(ahd, &dinfo, /*period*/0,
7682                                                    /*offset*/0, /*ppr_options*/0,
7683                                                    AHD_TRANS_CUR, /*paused*/TRUE);
7684                     }
7685           }
7686 
7687 #ifdef AHD_TARGET_MODE
7688           max_scsiid = (ahd->features & AHD_WIDE) ? 15 : 7;
7689 
7690           /*
7691            * Send an immediate notify ccb to all target more peripheral
7692            * drivers affected by this action.
7693            */
7694           for (target = 0; target <= max_scsiid; target++) {
7695                     struct ahd_tmode_tstate* tstate;
7696                     u_int lun;
7697 
7698                     tstate = ahd->enabled_targets[target];
7699                     if (tstate == NULL)
7700                               continue;
7701                     for (lun = 0; lun < AHD_NUM_LUNS; lun++) {
7702                               struct ahd_tmode_lstate* lstate;
7703 
7704                               lstate = tstate->enabled_luns[lun];
7705                               if (lstate == NULL)
7706                                         continue;
7707 
7708                               ahd_queue_lstate_event(ahd, lstate, CAM_TARGET_WILDCARD,
7709                                                          EVENT_TYPE_BUS_RESET, /*arg*/0);
7710                               ahd_send_lstate_events(ahd, lstate);
7711                     }
7712           }
7713 #endif
7714 
7715           /* Notify the XPT that a bus reset occurred */
7716           ahd_send_async(ahd, devinfo.channel, CAM_TARGET_WILDCARD,
7717                            CAM_LUN_WILDCARD, AC_BUS_RESET, NULL);
7718           ahd_restart(ahd);
7719 
7720           /*
7721            * Freeze the SIMQ until our poller can determine that
7722            * the bus reset has really gone away.  We set the initial
7723            * timer to 0 to have the check performed as soon as possible
7724            * from the timer context.
7725            */
7726           if ((ahd->flags & AHD_RESET_POLL_ACTIVE) == 0) {
7727                     ahd->flags |= AHD_RESET_POLL_ACTIVE;
7728                     ahd_freeze_simq(ahd);
7729                     ahd_timer_reset(&ahd->reset_timer, 0, ahd_reset_poll, ahd);
7730           }
7731           return (found);
7732 }
7733 
7734 
7735 #define AHD_RESET_POLL_US 1000
7736 static void
ahd_reset_poll(void * arg)7737 ahd_reset_poll(void *arg)
7738 {
7739           struct    ahd_softc *ahd;
7740           u_int     scsiseq1;
7741           u_long    l;
7742           int       s;
7743 
7744           ahd_list_lock(&l);
7745           ahd = arg;
7746           if (ahd == NULL) {
7747                     printf("ahd_reset_poll: Instance %p no longer exists\n", arg);
7748                     ahd_list_unlock(&l);
7749                     return;
7750           }
7751           ahd_lock(ahd, &s);
7752           ahd_pause(ahd);
7753           ahd_update_modes(ahd);
7754           ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI);
7755           ahd_outb(ahd, CLRSINT1, CLRSCSIRSTI);
7756           if ((ahd_inb(ahd, SSTAT1) & SCSIRSTI) != 0) {
7757                     ahd_timer_reset(&ahd->reset_timer, AHD_RESET_POLL_US,
7758                                         ahd_reset_poll, ahd);
7759                     ahd_unpause(ahd);
7760                     ahd_unlock(ahd, &s);
7761                     ahd_list_unlock(&l);
7762                     return;
7763           }
7764 
7765           /* Reset is now low.  Complete chip reinitialization. */
7766           ahd_outb(ahd, SIMODE1, ahd_inb(ahd, SIMODE1) | ENSCSIRST);
7767           scsiseq1 = ahd_inb(ahd, SCSISEQ_TEMPLATE);
7768           ahd_outb(ahd, SCSISEQ1, scsiseq1 & (ENSELI|ENRSELI|ENAUTOATNP));
7769           ahd_unpause(ahd);
7770           ahd->flags &= ~AHD_RESET_POLL_ACTIVE;
7771           ahd_unlock(ahd, &s);
7772           ahd_release_simq(ahd);
7773           ahd_list_unlock(&l);
7774 }
7775 
7776 /**************************** Statistics Processing ***************************/
7777 static void
ahd_stat_timer(void * arg)7778 ahd_stat_timer(void *arg)
7779 {
7780           struct    ahd_softc *ahd;
7781           u_long    l;
7782           int       s;
7783           int       enint_coal;
7784 
7785           ahd_list_lock(&l);
7786           ahd = arg;
7787           if (ahd == NULL) {
7788                     printf("ahd_stat_timer: Instance %p no longer exists\n", arg);
7789                     ahd_list_unlock(&l);
7790                     return;
7791           }
7792           ahd_lock(ahd, &s);
7793 
7794           enint_coal = ahd->hs_mailbox & ENINT_COALESCE;
7795           if (ahd->cmdcmplt_total > ahd->int_coalescing_threshold)
7796                     enint_coal |= ENINT_COALESCE;
7797           else if (ahd->cmdcmplt_total < ahd->int_coalescing_stop_threshold)
7798                     enint_coal &= ~ENINT_COALESCE;
7799 
7800           if (enint_coal != (ahd->hs_mailbox & ENINT_COALESCE)) {
7801                     ahd_enable_coalescing(ahd, enint_coal);
7802 #ifdef AHD_DEBUG
7803                     if ((ahd_debug & AHD_SHOW_INT_COALESCING) != 0)
7804                               printf("%s: Interrupt coalescing "
7805                                      "now %sabled. Cmds %d\n",
7806                                      ahd_name(ahd),
7807                                      (enint_coal & ENINT_COALESCE) ? "en" : "dis",
7808                                      ahd->cmdcmplt_total);
7809 #endif
7810           }
7811 
7812           ahd->cmdcmplt_bucket = (ahd->cmdcmplt_bucket+1) & (AHD_STAT_BUCKETS-1);
7813           ahd->cmdcmplt_total -= ahd->cmdcmplt_counts[ahd->cmdcmplt_bucket];
7814           ahd->cmdcmplt_counts[ahd->cmdcmplt_bucket] = 0;
7815           ahd_timer_reset(&ahd->stat_timer, AHD_STAT_UPDATE_US,
7816                               ahd_stat_timer, ahd);
7817           ahd_unlock(ahd, &s);
7818           ahd_list_unlock(&l);
7819 }
7820 
7821 /****************************** Status Processing *****************************/
7822 void
ahd_handle_scb_status(struct ahd_softc * ahd,struct scb * scb)7823 ahd_handle_scb_status(struct ahd_softc *ahd, struct scb *scb)
7824 {
7825           if (scb->hscb->shared_data.istatus.scsi_status != 0) {
7826                     ahd_handle_scsi_status(ahd, scb);
7827           } else {
7828                     ahd_calc_residual(ahd, scb);
7829                     ahd_done(ahd, scb);
7830           }
7831 }
7832 
7833 void
ahd_handle_scsi_status(struct ahd_softc * ahd,struct scb * scb)7834 ahd_handle_scsi_status(struct ahd_softc *ahd, struct scb *scb)
7835 {
7836           struct hardware_scb *hscb;
7837           u_int  qfreeze_cnt;
7838 
7839           /*
7840            * The sequencer freezes its select-out queue
7841            * anytime a SCSI status error occurs.  We must
7842            * handle the error and decrement the QFREEZE count
7843            * to allow the sequencer to continue.
7844            */
7845           hscb = scb->hscb;
7846 
7847           /* Freeze the queue until the client sees the error. */
7848           ahd_freeze_devq(ahd, scb);
7849           ahd_freeze_scb(scb);
7850           qfreeze_cnt = ahd_inw(ahd, QFREEZE_COUNT);
7851           if (qfreeze_cnt == 0) {
7852                     printf("%s: Bad status with 0 qfreeze count!\n", ahd_name(ahd));
7853           } else {
7854                     qfreeze_cnt--;
7855                     ahd_outw(ahd, QFREEZE_COUNT, qfreeze_cnt);
7856           }
7857           if (qfreeze_cnt == 0)
7858                     ahd_outb(ahd, SEQ_FLAGS2,
7859                                ahd_inb(ahd, SEQ_FLAGS2) & ~SELECTOUT_QFROZEN);
7860 
7861           /* Don't want to clobber the original sense code */
7862           if ((scb->flags & SCB_SENSE) != 0) {
7863                     /*
7864                      * Clear the SCB_SENSE Flag and perform
7865                      * a normal command completion.
7866                      */
7867                     scb->flags &= ~SCB_SENSE;
7868                     ahd_set_transaction_status(scb, CAM_AUTOSENSE_FAIL);
7869                     ahd_done(ahd, scb);
7870                     return;
7871           }
7872           ahd_set_scsi_status(scb, hscb->shared_data.istatus.scsi_status);
7873           ahd_set_xfer_status(scb, hscb->shared_data.istatus.scsi_status);
7874           switch (hscb->shared_data.istatus.scsi_status) {
7875           case STATUS_PKT_SENSE:
7876           {
7877                     struct scsi_status_iu_header *siu;
7878 
7879                     ahd_sync_sense(ahd, scb, BUS_DMASYNC_POSTREAD);
7880                     siu = (struct scsi_status_iu_header *)scb->sense_data;
7881                     ahd_set_scsi_status(scb, siu->status);
7882 #ifdef AHD_DEBUG
7883                     if ((ahd_debug & AHD_SHOW_SENSE) != 0) {
7884                               ahd_print_path(ahd, scb);
7885                               printf("SCB 0x%x Received PKT Status of 0x%x\n",
7886                                      SCB_GET_TAG(scb), siu->status);
7887                     }
7888 #endif
7889                     if ((siu->flags & SIU_RSPVALID) != 0) {
7890                               scsipi_printaddr(scb->xs->xs_periph);
7891                               if (scsi_4btoul(siu->pkt_failures_length) < 4) {
7892                                         printf("Unable to parse pkt_failures\n");
7893                               } else {
7894 
7895                                         switch (SIU_PKTFAIL_CODE(siu)) {
7896                                         case SIU_PFC_NONE:
7897                                                   printf("No packet failure found\n");
7898                                                   break;
7899                                         case SIU_PFC_CIU_FIELDS_INVALID:
7900                                                   printf("Invalid Command IU Field\n");
7901                                                   break;
7902                                         case SIU_PFC_TMF_NOT_SUPPORTED:
7903                                                   printf("TMF not supported\n");
7904                                                   break;
7905                                         case SIU_PFC_TMF_FAILED:
7906                                                   printf("TMF failed\n");
7907                                                   break;
7908                                         case SIU_PFC_INVALID_TYPE_CODE:
7909                                                   printf("Invalid L_Q Type code\n");
7910                                                   break;
7911                                         case SIU_PFC_ILLEGAL_REQUEST:
7912                                                   printf("Illegal request\n");
7913                                         default:
7914                                                   break;
7915                                         }
7916                               }
7917                               if (siu->status == SCSI_STATUS_OK)
7918                                         ahd_set_transaction_status(scb,
7919                                             CAM_REQ_CMP_ERR);
7920                     }
7921                     if ((siu->flags & SIU_SNSVALID) != 0) {
7922                               scb->flags |= SCB_PKT_SENSE;
7923 #ifdef AHD_DEBUG
7924                               if ((ahd_debug & AHD_SHOW_SENSE) != 0) {
7925                                         printf("Sense data available (%d)\n",
7926                                                siu->sense_length[0]);
7927                                         printf("SK 0x%x ASC 0x%x ASCQ 0x%x\n",
7928                                                ((uint8_t)scb->sense_data[
7929                                                 SIU_SENSE_OFFSET(siu)+2]) & 0x0F,
7930                                                ((uint8_t)scb->sense_data[
7931                                                 SIU_SENSE_OFFSET(siu)+12]),
7932                                                ((uint8_t)scb->sense_data[
7933                                                 SIU_SENSE_OFFSET(siu)+13]));
7934                               }
7935 #endif
7936                     }
7937                     ahd_done(ahd, scb);
7938                     break;
7939           }
7940           case SCSI_STATUS_CMD_TERMINATED:
7941           case SCSI_STATUS_CHECK_COND:
7942           {
7943                     struct ahd_devinfo devinfo;
7944                     struct ahd_dma_seg *sg;
7945                     struct scsi_request_sense *sc;
7946                     struct ahd_initiator_tinfo *targ_info;
7947                     struct ahd_tmode_tstate *tstate;
7948 #ifdef AHD_DEBUG
7949                     if (ahd_debug & AHD_SHOW_SENSE) {
7950                               ahd_print_path(ahd, scb);
7951                               printf("SCB %d: requests Check Status\n",
7952                                      SCB_GET_TAG(scb));
7953                     }
7954 #endif
7955 
7956                     if (ahd_perform_autosense(scb) == 0)
7957                               break;
7958 
7959                     ahd_compile_devinfo(&devinfo, SCB_GET_OUR_ID(scb),
7960                                             SCB_GET_TARGET(ahd, scb),
7961                                             SCB_GET_LUN(scb),
7962                                             SCB_GET_CHANNEL(ahd, scb),
7963                                             ROLE_INITIATOR);
7964                     targ_info = ahd_fetch_transinfo(ahd,
7965                                                             devinfo.channel,
7966                                                             devinfo.our_scsiid,
7967                                                             devinfo.target,
7968                                                             &tstate);
7969                     sg = scb->sg_list;
7970                     sc = (struct scsi_request_sense *)hscb->shared_data.idata.cdb;
7971                     /*
7972                      * Save off the residual if there is one.
7973                      */
7974                     ahd_update_residual(ahd, scb);
7975 #ifdef AHD_DEBUG
7976                     if (ahd_debug & AHD_SHOW_SENSE) {
7977                               ahd_print_path(ahd, scb);
7978                               printf("Sending Sense\n");
7979                     }
7980 #endif
7981                     scb->sg_count = 0;
7982                     sg = ahd_sg_setup(ahd, scb, sg, ahd_get_sense_bufaddr(ahd, scb),
7983                                           ahd_get_sense_bufsize(ahd, scb),
7984                                           /*last*/TRUE);
7985                     memset(sc, 0, sizeof(*sc));
7986                     sc->opcode = SCSI_REQUEST_SENSE;
7987                     sc->length = ahd_get_sense_bufsize(ahd, scb);
7988 
7989                     /*
7990                      * We can't allow the target to disconnect.
7991                      * This will be an untagged transaction and
7992                      * having the target disconnect will make this
7993                      * transaction indistinguishable from outstanding
7994                      * tagged transactions.
7995                      */
7996                     hscb->control = 0;
7997 
7998                     /*
7999                      * This request sense could be because the
8000                      * the device lost power or in some other
8001                      * way has lost our transfer negotiations.
8002                      * Renegotiate if appropriate.  Unit attention
8003                      * errors will be reported before any data
8004                      * phases occur.
8005                      */
8006                     if (ahd_get_residual(scb) == ahd_get_transfer_length(scb)) {
8007                               ahd_update_neg_request(ahd, &devinfo,
8008                                                          tstate, targ_info,
8009                                                          AHD_NEG_IF_NON_ASYNC);
8010                     }
8011                     if (tstate->auto_negotiate & devinfo.target_mask) {
8012                               hscb->control |= MK_MESSAGE;
8013                               scb->flags &=
8014                                   ~(SCB_NEGOTIATE|SCB_ABORT|SCB_DEVICE_RESET);
8015                               scb->flags |= SCB_AUTO_NEGOTIATE;
8016                     }
8017                     hscb->cdb_len = sizeof(*sc);
8018                     ahd_setup_data_scb(ahd, scb);
8019                     scb->flags |= SCB_SENSE;
8020                     ahd_queue_scb(ahd, scb);
8021                     /*
8022                      * Ensure we have enough time to actually
8023                      * retrieve the sense.
8024                      */
8025                     ahd_scb_timer_reset(scb, 5 * 1000000);
8026                     break;
8027           }
8028           case SCSI_STATUS_OK:
8029                     printf("%s: Interrupted for status of 0? (SCB 0x%x)\n",
8030                            ahd_name(ahd), SCB_GET_TAG(scb));
8031                     /* FALLTHROUGH */
8032           default:
8033                     ahd_done(ahd, scb);
8034                     break;
8035           }
8036 }
8037 
8038 /*
8039  * Calculate the residual for a just completed SCB.
8040  */
8041 void
ahd_calc_residual(struct ahd_softc * ahd,struct scb * scb)8042 ahd_calc_residual(struct ahd_softc *ahd, struct scb *scb)
8043 {
8044           struct hardware_scb *hscb;
8045           struct initiator_status *spkt;
8046           uint32_t sgptr;
8047           uint32_t resid_sgptr;
8048           uint32_t resid;
8049 
8050           /*
8051            * 5 cases.
8052            * 1) No residual.
8053            *    SG_STATUS_VALID clear in sgptr.
8054            * 2) Transferless command
8055            * 3) Never performed any transfers.
8056            *    sgptr has SG_FULL_RESID set.
8057            * 4) No residual but target did not
8058            *    save data pointers after the
8059            *    last transfer, so sgptr was
8060            *    never updated.
8061            * 5) We have a partial residual.
8062            *    Use residual_sgptr to determine
8063            *    where we are.
8064            */
8065 
8066           hscb = scb->hscb;
8067           sgptr = ahd_le32toh(hscb->sgptr);
8068           if ((sgptr & SG_STATUS_VALID) == 0)
8069                     /* Case 1 */
8070                     return;
8071           sgptr &= ~SG_STATUS_VALID;
8072 
8073           if ((sgptr & SG_LIST_NULL) != 0)
8074                     /* Case 2 */
8075                     return;
8076 
8077           /*
8078            * Residual fields are the same in both
8079            * target and initiator status packets,
8080            * so we can always use the initiator fields
8081            * regardless of the role for this SCB.
8082            */
8083           spkt = &hscb->shared_data.istatus;
8084           resid_sgptr = ahd_le32toh(spkt->residual_sgptr);
8085           if ((sgptr & SG_FULL_RESID) != 0) {
8086                     /* Case 3 */
8087                     resid = ahd_get_transfer_length(scb);
8088           } else if ((resid_sgptr & SG_LIST_NULL) != 0) {
8089                     /* Case 4 */
8090                     return;
8091           } else if ((resid_sgptr & SG_OVERRUN_RESID) != 0) {
8092                     ahd_print_path(ahd, scb);
8093                     printf("data overrun detected Tag == 0x%x.\n",
8094                            SCB_GET_TAG(scb));
8095                     ahd_freeze_devq(ahd, scb);
8096                     ahd_set_transaction_status(scb, CAM_DATA_RUN_ERR);
8097                     ahd_freeze_scb(scb);
8098                     return;
8099           } else if ((resid_sgptr & ~SG_PTR_MASK) != 0) {
8100                     panic("Bogus resid sgptr value 0x%x\n", resid_sgptr);
8101                     /* NOTREACHED */
8102           } else {
8103                     struct ahd_dma_seg *sg;
8104 
8105                     /*
8106                      * Remainder of the SG where the transfer
8107                      * stopped.
8108                      */
8109                     resid = ahd_le32toh(spkt->residual_datacnt) & AHD_SG_LEN_MASK;
8110                     sg = ahd_sg_bus_to_virt(ahd, scb, resid_sgptr & SG_PTR_MASK);
8111 
8112                     /* The residual sg_ptr always points to the next sg */
8113                     sg--;
8114 
8115                     /*
8116                      * Add up the contents of all residual
8117                      * SG segments that are after the SG where
8118                      * the transfer stopped.
8119                      */
8120                     while ((ahd_le32toh(sg->len) & AHD_DMA_LAST_SEG) == 0) {
8121                               sg++;
8122                               resid += ahd_le32toh(sg->len) & AHD_SG_LEN_MASK;
8123                     }
8124           }
8125 
8126           if ((scb->flags & SCB_SENSE) == 0)
8127                     ahd_set_residual(scb, resid);
8128                     /*else
8129                       ahd_set_sense_residual(scb, resid);*/
8130 
8131 #ifdef AHD_DEBUG
8132           if ((ahd_debug & AHD_SHOW_MISC) != 0) {
8133                     ahd_print_path(ahd, scb);
8134                     printf("Handled %sResidual of %d bytes\n",
8135                            (scb->flags & SCB_SENSE) ? "Sense " : "", resid);
8136           }
8137 #endif
8138 }
8139 
8140 /******************************* Target Mode **********************************/
8141 #ifdef AHD_TARGET_MODE
8142 /*
8143  * Add a target mode event to this lun's queue
8144  */
8145 static void
ahd_queue_lstate_event(struct ahd_softc * ahd,struct ahd_tmode_lstate * lstate,u_int initiator_id,u_int event_type,u_int event_arg)8146 ahd_queue_lstate_event(struct ahd_softc *ahd, struct ahd_tmode_lstate *lstate,
8147                            u_int initiator_id, u_int event_type, u_int event_arg)
8148 {
8149           struct ahd_tmode_event *event;
8150           int pending;
8151 
8152           xpt_freeze_devq(lstate->path, /*count*/1);
8153           if (lstate->event_w_idx >= lstate->event_r_idx)
8154                     pending = lstate->event_w_idx - lstate->event_r_idx;
8155           else
8156                     pending = AHD_TMODE_EVENT_BUFFER_SIZE + 1
8157                               - (lstate->event_r_idx - lstate->event_w_idx);
8158 
8159           if (event_type == EVENT_TYPE_BUS_RESET
8160            || event_type == MSG_BUS_DEV_RESET) {
8161                     /*
8162                      * Any earlier events are irrelevant, so reset our buffer.
8163                      * This has the effect of allowing us to deal with reset
8164                      * floods (an external device holding down the reset line)
8165                      * without losing the event that is really interesting.
8166                      */
8167                     lstate->event_r_idx = 0;
8168                     lstate->event_w_idx = 0;
8169                     xpt_release_devq(lstate->path, pending, /*runqueue*/FALSE);
8170           }
8171 
8172           if (pending == AHD_TMODE_EVENT_BUFFER_SIZE) {
8173                     xpt_print_path(lstate->path);
8174                     printf("immediate event %x:%x lost\n",
8175                            lstate->event_buffer[lstate->event_r_idx].event_type,
8176                            lstate->event_buffer[lstate->event_r_idx].event_arg);
8177                     lstate->event_r_idx++;
8178                     if (lstate->event_r_idx == AHD_TMODE_EVENT_BUFFER_SIZE)
8179                               lstate->event_r_idx = 0;
8180                     xpt_release_devq(lstate->path, /*count*/1, /*runqueue*/FALSE);
8181           }
8182 
8183           event = &lstate->event_buffer[lstate->event_w_idx];
8184           event->initiator_id = initiator_id;
8185           event->event_type = event_type;
8186           event->event_arg = event_arg;
8187           lstate->event_w_idx++;
8188           if (lstate->event_w_idx == AHD_TMODE_EVENT_BUFFER_SIZE)
8189                     lstate->event_w_idx = 0;
8190 }
8191 
8192 /*
8193  * Send any target mode events queued up waiting
8194  * for immediate notify resources.
8195  */
8196 void
ahd_send_lstate_events(struct ahd_softc * ahd,struct ahd_tmode_lstate * lstate)8197 ahd_send_lstate_events(struct ahd_softc *ahd, struct ahd_tmode_lstate *lstate)
8198 {
8199           struct ccb_hdr *ccbh;
8200           struct ccb_immed_notify *inot;
8201 
8202           while (lstate->event_r_idx != lstate->event_w_idx
8203               && (ccbh = SLIST_FIRST(&lstate->immed_notifies)) != NULL) {
8204                     struct ahd_tmode_event *event;
8205 
8206                     event = &lstate->event_buffer[lstate->event_r_idx];
8207                     SLIST_REMOVE_HEAD(&lstate->immed_notifies, sim_links.sle);
8208                     inot = (struct ccb_immed_notify *)ccbh;
8209                     switch (event->event_type) {
8210                     case EVENT_TYPE_BUS_RESET:
8211                               ccbh->status = CAM_SCSI_BUS_RESET|CAM_DEV_QFRZN;
8212                               break;
8213                     default:
8214                               ccbh->status = CAM_MESSAGE_RECV|CAM_DEV_QFRZN;
8215                               inot->message_args[0] = event->event_type;
8216                               inot->message_args[1] = event->event_arg;
8217                               break;
8218                     }
8219                     inot->initiator_id = event->initiator_id;
8220                     inot->sense_len = 0;
8221                     xpt_done((union ccb *)inot);
8222                     lstate->event_r_idx++;
8223                     if (lstate->event_r_idx == AHD_TMODE_EVENT_BUFFER_SIZE)
8224                               lstate->event_r_idx = 0;
8225           }
8226 }
8227 #endif
8228 
8229 /******************** Sequencer Program Patching/Download *********************/
8230 
8231 #ifdef AHD_DUMP_SEQ
8232 void
ahd_dumpseq(struct ahd_softc * ahd)8233 ahd_dumpseq(struct ahd_softc* ahd)
8234 {
8235           int i;
8236           int max_prog;
8237 
8238           max_prog = 2048;
8239 
8240           ahd_outb(ahd, SEQCTL0, PERRORDIS|FAILDIS|FASTMODE|LOADRAM);
8241           ahd_outb(ahd, PRGMCNT, 0);
8242           ahd_outb(ahd, PRGMCNT+1, 0);
8243           for (i = 0; i < max_prog; i++) {
8244                     uint8_t ins_bytes[4];
8245 
8246                     ahd_insb(ahd, SEQRAM, ins_bytes, 4);
8247                     printf("0x%08x\n", ins_bytes[0] << 24
8248                                          | ins_bytes[1] << 16
8249                                          | ins_bytes[2] << 8
8250                                          | ins_bytes[3]);
8251           }
8252 }
8253 #endif
8254 
8255 static void __noinline
ahd_loadseq(struct ahd_softc * ahd)8256 ahd_loadseq(struct ahd_softc *ahd)
8257 {
8258           struct    cs cs_table[NUM_CRITICAL_SECTIONS];
8259           u_int     begin_set[NUM_CRITICAL_SECTIONS];
8260           u_int     end_set[NUM_CRITICAL_SECTIONS];
8261           const struct patch *cur_patch;
8262           u_int     cs_count;
8263           u_int     cur_cs;
8264           u_int     i;
8265           int       downloaded;
8266           u_int     skip_addr;
8267           u_int     sg_prefetch_cnt;
8268           u_int     sg_prefetch_cnt_limit;
8269           u_int     sg_prefetch_align;
8270           u_int     sg_size;
8271           uint8_t   download_consts[DOWNLOAD_CONST_COUNT];
8272 
8273           if (bootverbose)
8274                     printf("%s: Downloading Sequencer Program...",
8275                            ahd_name(ahd));
8276 
8277 #if DOWNLOAD_CONST_COUNT != 7
8278 #error "Download Const Mismatch"
8279 #endif
8280           /*
8281            * Start out with 0 critical sections
8282            * that apply to this firmware load.
8283            */
8284           cs_count = 0;
8285           cur_cs = 0;
8286           memset(begin_set, 0, sizeof(begin_set));
8287           memset(end_set, 0, sizeof(end_set));
8288 
8289           /*
8290            * Setup downloadable constant table.
8291            *
8292            * The computation for the S/G prefetch variables is
8293            * a bit complicated.  We would like to always fetch
8294            * in terms of cachelined sized increments.  However,
8295            * if the cacheline is not an even multiple of the
8296            * SG element size or is larger than our SG RAM, using
8297            * just the cache size might leave us with only a portion
8298            * of an SG element at the tail of a prefetch.  If the
8299            * cacheline is larger than our S/G prefetch buffer less
8300            * the size of an SG element, we may round down to a cacheline
8301            * that doesn't contain any or all of the S/G of interest
8302            * within the bounds of our S/G ram.  Provide variables to
8303            * the sequencer that will allow it to handle these edge
8304            * cases.
8305            */
8306           /* Start by aligning to the nearest cacheline. */
8307           sg_prefetch_align = ahd->pci_cachesize;
8308           if (sg_prefetch_align == 0)
8309                     sg_prefetch_align = 8;
8310           /* Round down to the nearest power of 2. */
8311           while (powerof2(sg_prefetch_align) == 0)
8312                     sg_prefetch_align--;
8313           /*
8314            * If the cacheline boundary is greater than half our prefetch RAM
8315            * we risk not being able to fetch even a single complete S/G
8316            * segment if we align to that boundary.
8317            */
8318           if (sg_prefetch_align > CCSGADDR_MAX/2)
8319                     sg_prefetch_align = CCSGADDR_MAX/2;
8320           /* Start by fetching a single cacheline. */
8321           sg_prefetch_cnt = sg_prefetch_align;
8322           /*
8323            * Increment the prefetch count by cachelines until
8324            * at least one S/G element will fit.
8325            */
8326           sg_size = sizeof(struct ahd_dma_seg);
8327           if ((ahd->flags & AHD_64BIT_ADDRESSING) != 0)
8328                     sg_size = sizeof(struct ahd_dma64_seg);
8329           while (sg_prefetch_cnt < sg_size)
8330                     sg_prefetch_cnt += sg_prefetch_align;
8331           /*
8332            * If the cacheline is not an even multiple of
8333            * the S/G size, we may only get a partial S/G when
8334            * we align. Add a cacheline if this is the case.
8335            */
8336           if ((sg_prefetch_align % sg_size) != 0
8337            && (sg_prefetch_cnt < CCSGADDR_MAX))
8338                     sg_prefetch_cnt += sg_prefetch_align;
8339           /*
8340            * Lastly, compute a value that the sequencer can use
8341            * to determine if the remainder of the CCSGRAM buffer
8342            * has a full S/G element in it.
8343            */
8344           sg_prefetch_cnt_limit = -(sg_prefetch_cnt - sg_size + 1);
8345           download_consts[SG_PREFETCH_CNT] = sg_prefetch_cnt;
8346           download_consts[SG_PREFETCH_CNT_LIMIT] = sg_prefetch_cnt_limit;
8347           download_consts[SG_PREFETCH_ALIGN_MASK] = ~(sg_prefetch_align - 1);
8348           download_consts[SG_PREFETCH_ADDR_MASK] = (sg_prefetch_align - 1);
8349           download_consts[SG_SIZEOF] = sg_size;
8350           download_consts[PKT_OVERRUN_BUFOFFSET] =
8351                     (ahd->overrun_buf - (uint8_t *)ahd->qoutfifo) / 256;
8352           download_consts[SCB_TRANSFER_SIZE] = SCB_TRANSFER_SIZE_1BYTE_LUN;
8353           cur_patch = patches;
8354           downloaded = 0;
8355           skip_addr = 0;
8356           ahd_outb(ahd, SEQCTL0, PERRORDIS|FAILDIS|FASTMODE|LOADRAM);
8357           ahd_outb(ahd, PRGMCNT, 0);
8358           ahd_outb(ahd, PRGMCNT+1, 0);
8359 
8360           for (i = 0; i < sizeof(seqprog)/4; i++) {
8361                     if (ahd_check_patch(ahd, &cur_patch, i, &skip_addr) == 0) {
8362                               /*
8363                                * Don't download this instruction as it
8364                                * is in a patch that was removed.
8365                                */
8366                               continue;
8367                     }
8368                     /*
8369                      * Move through the CS table until we find a CS
8370                      * that might apply to this instruction.
8371                      */
8372                     for (; cur_cs < num_critical_sections; cur_cs++) {
8373                               if (critical_sections[cur_cs].end <= i) {
8374                                         if (begin_set[cs_count] == TRUE
8375                                          && end_set[cs_count] == FALSE) {
8376                                                   cs_table[cs_count].end = downloaded;
8377                                                   end_set[cs_count] = TRUE;
8378                                                   cs_count++;
8379                                         }
8380                                         continue;
8381                               }
8382                               if (critical_sections[cur_cs].begin <= i
8383                                && begin_set[cs_count] == FALSE) {
8384                                         cs_table[cs_count].begin = downloaded;
8385                                         begin_set[cs_count] = TRUE;
8386                               }
8387                               break;
8388                     }
8389                     ahd_download_instr(ahd, i, download_consts);
8390                     downloaded++;
8391           }
8392 
8393           ahd->num_critical_sections = cs_count;
8394           if (cs_count != 0) {
8395 
8396                     cs_count *= sizeof(struct cs);
8397                     ahd->critical_sections = malloc(cs_count, M_DEVBUF, M_NOWAIT);
8398                     if (ahd->critical_sections == NULL)
8399                               panic("ahd_loadseq: Could not malloc");
8400                     memcpy(ahd->critical_sections, cs_table, cs_count);
8401           }
8402           ahd_outb(ahd, SEQCTL0, PERRORDIS|FAILDIS|FASTMODE);
8403 
8404           if (bootverbose) {
8405                     printf(" %d instructions downloaded\n", downloaded);
8406                     printf("%s: Features 0x%x, Bugs 0x%x, Flags 0x%x\n",
8407                            ahd_name(ahd), ahd->features, ahd->bugs, ahd->flags);
8408           }
8409 }
8410 
8411 static int
ahd_check_patch(struct ahd_softc * ahd,const struct patch ** start_patch,u_int start_instr,u_int * skip_addr)8412 ahd_check_patch(struct ahd_softc *ahd, const struct patch **start_patch,
8413                     u_int start_instr, u_int *skip_addr)
8414 {
8415           const struct        patch *cur_patch;
8416           const struct        patch *last_patch;
8417           u_int               num_patches;
8418 
8419           num_patches = sizeof(patches)/sizeof(struct patch);
8420           last_patch = &patches[num_patches];
8421           cur_patch = *start_patch;
8422 
8423           while (cur_patch < last_patch && start_instr == cur_patch->begin) {
8424 
8425                     if (cur_patch->patch_func(ahd) == 0) {
8426 
8427                               /* Start rejecting code */
8428                               *skip_addr = start_instr + cur_patch->skip_instr;
8429                               cur_patch += cur_patch->skip_patch;
8430                     } else {
8431                               /* Accepted this patch.  Advance to the next
8432                                * one and wait for our instruction pointer to
8433                                * hit this point.
8434                                */
8435                               cur_patch++;
8436                     }
8437           }
8438 
8439           *start_patch = cur_patch;
8440           if (start_instr < *skip_addr)
8441                     /* Still skipping */
8442                     return (0);
8443 
8444           return (1);
8445 }
8446 
8447 static u_int
ahd_resolve_seqaddr(struct ahd_softc * ahd,u_int address)8448 ahd_resolve_seqaddr(struct ahd_softc *ahd, u_int address)
8449 {
8450           const struct patch *cur_patch;
8451           int address_offset;
8452           u_int skip_addr;
8453           u_int i;
8454 
8455           address_offset = 0;
8456           cur_patch = patches;
8457           skip_addr = 0;
8458 
8459           for (i = 0; i < address;) {
8460 
8461                     ahd_check_patch(ahd, &cur_patch, i, &skip_addr);
8462 
8463                     if (skip_addr > i) {
8464                               int end_addr;
8465 
8466                               end_addr = MIN(address, skip_addr);
8467                               address_offset += end_addr - i;
8468                               i = skip_addr;
8469                     } else {
8470                               i++;
8471                     }
8472           }
8473           return (address - address_offset);
8474 }
8475 
8476 static void
ahd_download_instr(struct ahd_softc * ahd,u_int instrptr,uint8_t * dconsts)8477 ahd_download_instr(struct ahd_softc *ahd, u_int instrptr, uint8_t *dconsts)
8478 {
8479           union     ins_formats instr;
8480           struct    ins_format1 *fmt1_ins;
8481           struct    ins_format3 *fmt3_ins;
8482           u_int     opcode;
8483 
8484           /*
8485            * The firmware is always compiled into a little endian format.
8486            */
8487           instr.integer = ahd_le32toh(*(const uint32_t*)&seqprog[instrptr * 4]);
8488 
8489           fmt1_ins = &instr.format1;
8490           fmt3_ins = NULL;
8491 
8492           /* Pull the opcode */
8493           opcode = instr.format1.opcode;
8494           switch (opcode) {
8495           case AIC_OP_JMP:
8496           case AIC_OP_JC:
8497           case AIC_OP_JNC:
8498           case AIC_OP_CALL:
8499           case AIC_OP_JNE:
8500           case AIC_OP_JNZ:
8501           case AIC_OP_JE:
8502           case AIC_OP_JZ:
8503           {
8504                     fmt3_ins = &instr.format3;
8505                     fmt3_ins->address = ahd_resolve_seqaddr(ahd, fmt3_ins->address);
8506           }
8507           /* FALLTHROUGH */
8508           case AIC_OP_OR:
8509           case AIC_OP_AND:
8510           case AIC_OP_XOR:
8511           case AIC_OP_ADD:
8512           case AIC_OP_ADC:
8513           case AIC_OP_BMOV:
8514                     if (fmt1_ins->parity != 0) {
8515                               fmt1_ins->immediate = dconsts[fmt1_ins->immediate];
8516                     }
8517                     fmt1_ins->parity = 0;
8518                     /* FALLTHROUGH */
8519           case AIC_OP_ROL:
8520           {
8521                     int i, count;
8522 
8523                     /* Calculate odd parity for the instruction */
8524                     for (i = 0, count = 0; i < 31; i++) {
8525                               uint32_t mask;
8526 
8527                               mask = 0x01 << i;
8528                               if ((instr.integer & mask) != 0)
8529                                         count++;
8530                     }
8531                     if ((count & 0x01) == 0)
8532                               instr.format1.parity = 1;
8533 
8534                     /* The sequencer is a little endian CPU */
8535                     instr.integer = ahd_htole32(instr.integer);
8536                     ahd_outsb(ahd, SEQRAM, instr.bytes, 4);
8537                     break;
8538           }
8539           default:
8540                     panic("Unknown opcode encountered in seq program");
8541                     break;
8542           }
8543 }
8544 
8545 static int
ahd_probe_stack_size(struct ahd_softc * ahd)8546 ahd_probe_stack_size(struct ahd_softc *ahd)
8547 {
8548           int last_probe;
8549 
8550           last_probe = 0;
8551           while (1) {
8552                     int i;
8553 
8554                     /*
8555                      * We avoid using 0 as a pattern to avoid
8556                      * confusion if the stack implementation
8557                      * "back-fills" with zeros when "poping'
8558                      * entries.
8559                      */
8560                     for (i = 1; i <= last_probe+1; i++) {
8561                               ahd_outb(ahd, STACK, i & 0xFF);
8562                               ahd_outb(ahd, STACK, (i >> 8) & 0xFF);
8563                     }
8564 
8565                     /* Verify */
8566                     for (i = last_probe+1; i > 0; i--) {
8567                               u_int stack_entry;
8568 
8569                               stack_entry = ahd_inb(ahd, STACK)
8570                                             |(ahd_inb(ahd, STACK) << 8);
8571                               if (stack_entry != i)
8572                                         goto sized;
8573                     }
8574                     last_probe++;
8575           }
8576 sized:
8577           return (last_probe);
8578 }
8579 
8580 void
ahd_dump_all_cards_state(void)8581 ahd_dump_all_cards_state(void)
8582 {
8583           struct ahd_softc *list_ahd;
8584 
8585           TAILQ_FOREACH(list_ahd, &ahd_tailq, links) {
8586                     ahd_dump_card_state(list_ahd);
8587           }
8588 }
8589 
8590 int
ahd_print_register(ahd_reg_parse_entry_t * table,u_int num_entries,const char * name,u_int address,u_int value,u_int * cur_column,u_int wrap_point)8591 ahd_print_register(ahd_reg_parse_entry_t *table, u_int num_entries,
8592                        const char *name, u_int address, u_int value,
8593                        u_int *cur_column, u_int wrap_point)
8594 {
8595           size_t    printed;
8596           u_int     printed_mask;
8597           char    line[1024];
8598 
8599           line[0] = 0;
8600 
8601           if (cur_column != NULL && *cur_column >= wrap_point) {
8602                     printf("\n");
8603                     *cur_column = 0;
8604           }
8605           printed = snprintf(line, sizeof(line), "%s[0x%x]", name, value);
8606                     printed = sizeof(line);
8607           if (table == NULL) {
8608                     if (printed < sizeof(line))
8609                         printed += snprintf(&line[printed],
8610                               (sizeof line) - printed, " ");
8611                     printf("%s", line);
8612                     if (cur_column != NULL)
8613                               *cur_column += printed;
8614                     return (printed);
8615           }
8616           printed_mask = 0;
8617           while (printed_mask != 0xFF) {
8618                     int entry;
8619 
8620                     for (entry = 0; entry < num_entries; entry++) {
8621                               if (((value & table[entry].mask)
8622                                 != table[entry].value)
8623                                || ((printed_mask & table[entry].mask)
8624                                 == table[entry].mask))
8625                                         continue;
8626                               if (printed < sizeof(line))
8627                                   printed += snprintf(&line[printed],
8628                                         (sizeof line) - printed, "%s%s",
8629                                             printed_mask == 0 ? ":(" : "|",
8630                                             table[entry].name);
8631                               printed_mask |= table[entry].mask;
8632 
8633                               break;
8634                     }
8635                     if (entry >= num_entries)
8636                               break;
8637           }
8638           if (printed < sizeof(line)) {
8639                     if (printed_mask != 0)
8640                               printed += snprintf(&line[printed],
8641                                   (sizeof line) - printed, ") ");
8642                     else
8643                               printed += snprintf(&line[printed],
8644                                   (sizeof line) - printed, " ");
8645           }
8646           if (cur_column != NULL)
8647                     *cur_column += printed;
8648           printf("%s", line);
8649 
8650           return (printed);
8651 }
8652 
8653 void
ahd_dump_card_state(struct ahd_softc * ahd)8654 ahd_dump_card_state(struct ahd_softc *ahd)
8655 {
8656           struct scb          *scb;
8657           ahd_mode_state       saved_modes;
8658           u_int                dffstat;
8659           int                  paused;
8660           u_int                scb_index;
8661           u_int                saved_scb_index;
8662           u_int                cur_col;
8663           int                  i;
8664 
8665           if (ahd_is_paused(ahd)) {
8666                     paused = 1;
8667           } else {
8668                     paused = 0;
8669                     ahd_pause(ahd);
8670           }
8671           saved_modes = ahd_save_modes(ahd);
8672           ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI);
8673           printf(">>>>>>>>>>>>>>>>>> Dump Card State Begins <<<<<<<<<<<<<<<<<\n"
8674                  "%s: Dumping Card State at program address 0x%x Mode 0x%x\n",
8675                  ahd_name(ahd),
8676                  ahd_inb(ahd, CURADDR) | (ahd_inb(ahd, CURADDR+1) << 8),
8677                  ahd_build_mode_state(ahd, ahd->saved_src_mode,
8678                                             ahd->saved_dst_mode));
8679           if (paused)
8680                     printf("Card was paused\n");
8681 
8682           if (ahd_check_cmdcmpltqueues(ahd))
8683                     printf("Completions are pending\n");
8684           /*
8685            * Mode independent registers.
8686            */
8687           cur_col = 0;
8688           ahd_hs_mailbox_print(ahd_inb(ahd, LOCAL_HS_MAILBOX), &cur_col, 50);
8689           ahd_intctl_print(ahd_inb(ahd, INTCTL), &cur_col, 50);
8690           ahd_seqintstat_print(ahd_inb(ahd, SEQINTSTAT), &cur_col, 50);
8691           ahd_saved_mode_print(ahd_inb(ahd, SAVED_MODE), &cur_col, 50);
8692           ahd_dffstat_print(ahd_inb(ahd, DFFSTAT), &cur_col, 50);
8693           ahd_scsisigi_print(ahd_inb(ahd, SCSISIGI), &cur_col, 50);
8694           ahd_scsiphase_print(ahd_inb(ahd, SCSIPHASE), &cur_col, 50);
8695           ahd_scsibus_print(ahd_inb(ahd, SCSIBUS), &cur_col, 50);
8696           ahd_lastphase_print(ahd_inb(ahd, LASTPHASE), &cur_col, 50);
8697           ahd_scsiseq0_print(ahd_inb(ahd, SCSISEQ0), &cur_col, 50);
8698           ahd_scsiseq1_print(ahd_inb(ahd, SCSISEQ1), &cur_col, 50);
8699           ahd_seqctl0_print(ahd_inb(ahd, SEQCTL0), &cur_col, 50);
8700           ahd_seqintctl_print(ahd_inb(ahd, SEQINTCTL), &cur_col, 50);
8701           ahd_seq_flags_print(ahd_inb(ahd, SEQ_FLAGS), &cur_col, 50);
8702           ahd_seq_flags2_print(ahd_inb(ahd, SEQ_FLAGS2), &cur_col, 50);
8703           ahd_sstat0_print(ahd_inb(ahd, SSTAT0), &cur_col, 50);
8704           ahd_sstat1_print(ahd_inb(ahd, SSTAT1), &cur_col, 50);
8705           ahd_sstat2_print(ahd_inb(ahd, SSTAT2), &cur_col, 50);
8706           ahd_sstat3_print(ahd_inb(ahd, SSTAT3), &cur_col, 50);
8707           ahd_perrdiag_print(ahd_inb(ahd, PERRDIAG), &cur_col, 50);
8708           ahd_simode1_print(ahd_inb(ahd, SIMODE1), &cur_col, 50);
8709           ahd_lqistat0_print(ahd_inb(ahd, LQISTAT0), &cur_col, 50);
8710           ahd_lqistat1_print(ahd_inb(ahd, LQISTAT1), &cur_col, 50);
8711           ahd_lqistat2_print(ahd_inb(ahd, LQISTAT2), &cur_col, 50);
8712           ahd_lqostat0_print(ahd_inb(ahd, LQOSTAT0), &cur_col, 50);
8713           ahd_lqostat1_print(ahd_inb(ahd, LQOSTAT1), &cur_col, 50);
8714           ahd_lqostat2_print(ahd_inb(ahd, LQOSTAT2), &cur_col, 50);
8715           printf("\n");
8716           printf("\nSCB Count = %d CMDS_PENDING = %d LASTSCB 0x%x "
8717                  "CURRSCB 0x%x NEXTSCB 0x%x\n",
8718                  ahd->scb_data.numscbs, ahd_inw(ahd, CMDS_PENDING),
8719                  ahd_inw(ahd, LASTSCB), ahd_inw(ahd, CURRSCB),
8720                  ahd_inw(ahd, NEXTSCB));
8721           cur_col = 0;
8722           /* QINFIFO */
8723           ahd_search_qinfifo(ahd, CAM_TARGET_WILDCARD, ALL_CHANNELS,
8724                                  CAM_LUN_WILDCARD, SCB_LIST_NULL,
8725                                  ROLE_UNKNOWN, /*status*/0, SEARCH_PRINT);
8726           saved_scb_index = ahd_get_scbptr(ahd);
8727           printf("Pending list:");
8728           i = 0;
8729           LIST_FOREACH(scb, &ahd->pending_scbs, pending_links) {
8730                     if (i++ > AHD_SCB_MAX)
8731                               break;
8732                     /*cur_col =*/ printf("\n%3d FIFO_USE[0x%x] ", SCB_GET_TAG(scb),
8733                                              ahd_inb_scbram(ahd, SCB_FIFO_USE_COUNT));
8734                     ahd_set_scbptr(ahd, SCB_GET_TAG(scb));
8735                     ahd_scb_control_print(ahd_inb_scbram(ahd, SCB_CONTROL),
8736                                               &cur_col, 60);
8737                     ahd_scb_scsiid_print(ahd_inb_scbram(ahd, SCB_SCSIID),
8738                                              &cur_col, 60);
8739           }
8740           printf("\nTotal %d\n", i);
8741 
8742           printf("Kernel Free SCB list: ");
8743           i = 0;
8744           TAILQ_FOREACH(scb, &ahd->scb_data.free_scbs, links.tqe) {
8745                     struct scb *list_scb;
8746 
8747                     list_scb = scb;
8748                     do {
8749                               printf("%d ", SCB_GET_TAG(list_scb));
8750                               list_scb = LIST_NEXT(list_scb, collision_links);
8751                     } while (list_scb && i++ < AHD_SCB_MAX);
8752           }
8753 
8754           LIST_FOREACH(scb, &ahd->scb_data.any_dev_free_scb_list, links.le) {
8755                     if (i++ > AHD_SCB_MAX)
8756                               break;
8757                     printf("%d ", SCB_GET_TAG(scb));
8758           }
8759           printf("\n");
8760 
8761           printf("Sequencer Complete DMA-inprog list: ");
8762           scb_index = ahd_inw(ahd, COMPLETE_SCB_DMAINPROG_HEAD);
8763           i = 0;
8764           while (!SCBID_IS_NULL(scb_index) && i++ < AHD_SCB_MAX) {
8765                     ahd_set_scbptr(ahd, scb_index);
8766                     printf("%d ", scb_index);
8767                     scb_index = ahd_inw_scbram(ahd, SCB_NEXT_COMPLETE);
8768           }
8769           printf("\n");
8770 
8771           printf("Sequencer Complete list: ");
8772           scb_index = ahd_inw(ahd, COMPLETE_SCB_HEAD);
8773           i = 0;
8774           while (!SCBID_IS_NULL(scb_index) && i++ < AHD_SCB_MAX) {
8775                     ahd_set_scbptr(ahd, scb_index);
8776                     printf("%d ", scb_index);
8777                     scb_index = ahd_inw_scbram(ahd, SCB_NEXT_COMPLETE);
8778           }
8779           printf("\n");
8780 
8781 
8782           printf("Sequencer DMA-Up and Complete list: ");
8783           scb_index = ahd_inw(ahd, COMPLETE_DMA_SCB_HEAD);
8784           i = 0;
8785           while (!SCBID_IS_NULL(scb_index) && i++ < AHD_SCB_MAX) {
8786                     ahd_set_scbptr(ahd, scb_index);
8787                     printf("%d ", scb_index);
8788                     scb_index = ahd_inw_scbram(ahd, SCB_NEXT_COMPLETE);
8789           }
8790           printf("\n");
8791           ahd_set_scbptr(ahd, saved_scb_index);
8792           dffstat = ahd_inb(ahd, DFFSTAT);
8793           for (i = 0; i < 2; i++) {
8794 #ifdef AHD_DEBUG
8795                     struct scb *fifo_scb;
8796 #endif
8797                     u_int         fifo_scbptr;
8798 
8799                     ahd_set_modes(ahd, AHD_MODE_DFF0 + i, AHD_MODE_DFF0 + i);
8800                     fifo_scbptr = ahd_get_scbptr(ahd);
8801                     printf("\n%s: FIFO%d %s, LONGJMP == 0x%x, SCB 0x%x\n",
8802                            ahd_name(ahd), i,
8803                            (dffstat & (FIFO0FREE << i)) ? "Free" : "Active",
8804                            ahd_inw(ahd, LONGJMP_ADDR), fifo_scbptr);
8805                     cur_col = 0;
8806                     ahd_seqimode_print(ahd_inb(ahd, SEQIMODE), &cur_col, 50);
8807                     ahd_seqintsrc_print(ahd_inb(ahd, SEQINTSRC), &cur_col, 50);
8808                     ahd_dfcntrl_print(ahd_inb(ahd, DFCNTRL), &cur_col, 50);
8809                     ahd_dfstatus_print(ahd_inb(ahd, DFSTATUS), &cur_col, 50);
8810                     ahd_sg_cache_shadow_print(ahd_inb(ahd, SG_CACHE_SHADOW),
8811                                                     &cur_col, 50);
8812                     ahd_sg_state_print(ahd_inb(ahd, SG_STATE), &cur_col, 50);
8813                     ahd_dffsxfrctl_print(ahd_inb(ahd, DFFSXFRCTL), &cur_col, 50);
8814                     ahd_soffcnt_print(ahd_inb(ahd, SOFFCNT), &cur_col, 50);
8815                     ahd_mdffstat_print(ahd_inb(ahd, MDFFSTAT), &cur_col, 50);
8816                     if (cur_col > 50) {
8817                               printf("\n");
8818                               cur_col = 0;
8819                     }
8820                     printf("\nSHADDR = 0x%x%x, SHCNT = 0x%x ",
8821                                           ahd_inl(ahd, SHADDR+4),
8822                                           ahd_inl(ahd, SHADDR),
8823                                           (ahd_inb(ahd, SHCNT)
8824                                         | (ahd_inb(ahd, SHCNT + 1) << 8)
8825                                         | (ahd_inb(ahd, SHCNT + 2) << 16)));
8826                     printf("HADDR = 0x%x%x, HCNT = 0x%x \n",
8827                                           ahd_inl(ahd, HADDR+4),
8828                                           ahd_inl(ahd, HADDR),
8829                                           (ahd_inb(ahd, HCNT)
8830                                         | (ahd_inb(ahd, HCNT + 1) << 8)
8831                                         | (ahd_inb(ahd, HCNT + 2) << 16)));
8832                     ahd_ccsgctl_print(ahd_inb(ahd, CCSGCTL), &cur_col, 50);
8833 #ifdef AHD_DEBUG
8834                     if ((ahd_debug & AHD_SHOW_SG) != 0) {
8835                               fifo_scb = ahd_lookup_scb(ahd, fifo_scbptr);
8836                               if (fifo_scb != NULL)
8837                                         ahd_dump_sglist(fifo_scb);
8838                     }
8839 #endif
8840           }
8841           printf("\nLQIN: ");
8842           for (i = 0; i < 20; i++)
8843                     printf("0x%x ", ahd_inb(ahd, LQIN + i));
8844           printf("\n");
8845           ahd_set_modes(ahd, AHD_MODE_CFG, AHD_MODE_CFG);
8846           printf("%s: LQISTATE = 0x%x, LQOSTATE = 0x%x, OPTIONMODE = 0x%x\n",
8847                  ahd_name(ahd), ahd_inb(ahd, LQISTATE), ahd_inb(ahd, LQOSTATE),
8848                  ahd_inb(ahd, OPTIONMODE));
8849           printf("%s: OS_SPACE_CNT = 0x%x MAXCMDCNT = 0x%x\n",
8850                  ahd_name(ahd), ahd_inb(ahd, OS_SPACE_CNT),
8851                  ahd_inb(ahd, MAXCMDCNT));
8852           ahd_simode0_print(ahd_inb(ahd, SIMODE0), &cur_col, 50);
8853           printf("\n");
8854           ahd_set_modes(ahd, AHD_MODE_CCHAN, AHD_MODE_CCHAN);
8855           cur_col = 0;
8856           ahd_set_modes(ahd, ahd->saved_src_mode, ahd->saved_dst_mode);
8857           printf("%s: REG0 == 0x%x, SINDEX = 0x%x, DINDEX = 0x%x\n",
8858                  ahd_name(ahd), ahd_inw(ahd, REG0), ahd_inw(ahd, SINDEX),
8859                  ahd_inw(ahd, DINDEX));
8860           printf("%s: SCBPTR == 0x%x, SCB_NEXT == 0x%x, SCB_NEXT2 == 0x%x\n",
8861                  ahd_name(ahd), ahd_get_scbptr(ahd),
8862                  ahd_inw_scbram(ahd, SCB_NEXT),
8863                  ahd_inw_scbram(ahd, SCB_NEXT2));
8864           printf("CDB %x %x %x %x %x %x\n",
8865                  ahd_inb_scbram(ahd, SCB_CDB_STORE),
8866                  ahd_inb_scbram(ahd, SCB_CDB_STORE+1),
8867                  ahd_inb_scbram(ahd, SCB_CDB_STORE+2),
8868                  ahd_inb_scbram(ahd, SCB_CDB_STORE+3),
8869                  ahd_inb_scbram(ahd, SCB_CDB_STORE+4),
8870                  ahd_inb_scbram(ahd, SCB_CDB_STORE+5));
8871           printf("STACK:");
8872           for (i = 0; i < ahd->stack_size; i++) {
8873                     ahd->saved_stack[i] =
8874                         ahd_inb(ahd, STACK)|(ahd_inb(ahd, STACK) << 8);
8875                     printf(" 0x%x", ahd->saved_stack[i]);
8876           }
8877           for (i = ahd->stack_size-1; i >= 0; i--) {
8878                     ahd_outb(ahd, STACK, ahd->saved_stack[i] & 0xFF);
8879                     ahd_outb(ahd, STACK, (ahd->saved_stack[i] >> 8) & 0xFF);
8880           }
8881           printf("\n<<<<<<<<<<<<<<<<< Dump Card State Ends >>>>>>>>>>>>>>>>>>\n");
8882           ahd_platform_dump_card_state(ahd);
8883           ahd_restore_modes(ahd, saved_modes);
8884           if (paused == 0)
8885                     ahd_unpause(ahd);
8886 }
8887 
8888 void
ahd_dump_scbs(struct ahd_softc * ahd)8889 ahd_dump_scbs(struct ahd_softc *ahd)
8890 {
8891           ahd_mode_state saved_modes;
8892           u_int            saved_scb_index;
8893           int              i;
8894 
8895           saved_modes = ahd_save_modes(ahd);
8896           ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI);
8897           saved_scb_index = ahd_get_scbptr(ahd);
8898           for (i = 0; i < AHD_SCB_MAX; i++) {
8899                     ahd_set_scbptr(ahd, i);
8900                     printf("%3d", i);
8901                     printf("(CTRL 0x%x ID 0x%x N 0x%x N2 0x%x SG 0x%x, RSG 0x%x)\n",
8902                            ahd_inb_scbram(ahd, SCB_CONTROL),
8903                            ahd_inb_scbram(ahd, SCB_SCSIID),
8904                            ahd_inw_scbram(ahd, SCB_NEXT),
8905                            ahd_inw_scbram(ahd, SCB_NEXT2),
8906                            ahd_inl_scbram(ahd, SCB_SGPTR),
8907                            ahd_inl_scbram(ahd, SCB_RESIDUAL_SGPTR));
8908           }
8909           printf("\n");
8910           ahd_set_scbptr(ahd, saved_scb_index);
8911           ahd_restore_modes(ahd, saved_modes);
8912 }
8913 
8914 /**************************** Flexport Logic **********************************/
8915 /*
8916  * Read count 16bit words from 16bit word address start_addr from the
8917  * SEEPROM attached to the controller, into tbuf, using the controller's
8918  * SEEPROM reading state machine.  Optionally treat the data as a byte
8919  * stream in terms of byte order.
8920  */
8921 int
ahd_read_seeprom(struct ahd_softc * ahd,uint16_t * tbuf,u_int start_addr,u_int count,int bytestream)8922 ahd_read_seeprom(struct ahd_softc *ahd, uint16_t *tbuf,
8923                      u_int start_addr, u_int count, int bytestream)
8924 {
8925           u_int cur_addr;
8926           u_int end_addr;
8927           int   error;
8928 
8929           /*
8930            * If we never make it through the loop even once,
8931            * we were passed invalid arguments.
8932            */
8933           error = EINVAL;
8934           AHD_ASSERT_MODES(ahd, AHD_MODE_SCSI_MSK, AHD_MODE_SCSI_MSK);
8935           end_addr = start_addr + count;
8936           for (cur_addr = start_addr; cur_addr < end_addr; cur_addr++) {
8937 
8938                     ahd_outb(ahd, SEEADR, cur_addr);
8939                     ahd_outb(ahd, SEECTL, SEEOP_READ | SEESTART);
8940 
8941                     error = ahd_wait_seeprom(ahd);
8942                     if (error) {
8943                               printf("%s: ahd_wait_seeprom timed out\n",
8944                                   ahd_name(ahd));
8945                               break;
8946                     }
8947                     if (bytestream != 0) {
8948                               uint8_t *bytestream_ptr;
8949 
8950                               bytestream_ptr = (uint8_t *)tbuf;
8951                               *bytestream_ptr++ = ahd_inb(ahd, SEEDAT);
8952                               *bytestream_ptr = ahd_inb(ahd, SEEDAT+1);
8953                     } else {
8954                               /*
8955                                * ahd_inw() already handles machine byte order.
8956                                */
8957                               *tbuf = ahd_inw(ahd, SEEDAT);
8958                     }
8959                     tbuf++;
8960           }
8961           return (error);
8962 }
8963 
8964 /*
8965  * Write count 16bit words from tbuf, into SEEPROM attached to the
8966  * controller starting at 16bit word address start_addr, using the
8967  * controller's SEEPROM writing state machine.
8968  */
8969 int
ahd_write_seeprom(struct ahd_softc * ahd,uint16_t * tbuf,u_int start_addr,u_int count)8970 ahd_write_seeprom(struct ahd_softc *ahd, uint16_t *tbuf,
8971                       u_int start_addr, u_int count)
8972 {
8973           u_int cur_addr;
8974           u_int end_addr;
8975           int   error;
8976           int   retval;
8977 
8978           AHD_ASSERT_MODES(ahd, AHD_MODE_SCSI_MSK, AHD_MODE_SCSI_MSK);
8979           error = ENOENT;
8980 
8981           /* Place the chip into write-enable mode */
8982           ahd_outb(ahd, SEEADR, SEEOP_EWEN_ADDR);
8983           ahd_outb(ahd, SEECTL, SEEOP_EWEN | SEESTART);
8984           error = ahd_wait_seeprom(ahd);
8985           if (error)
8986                     return (error);
8987 
8988           /*
8989            * Write the data.  If we don't get through the loop at
8990            * least once, the arguments were invalid.
8991            */
8992           retval = EINVAL;
8993           end_addr = start_addr + count;
8994           for (cur_addr = start_addr; cur_addr < end_addr; cur_addr++) {
8995                     ahd_outw(ahd, SEEDAT, *tbuf++);
8996                     ahd_outb(ahd, SEEADR, cur_addr);
8997                     ahd_outb(ahd, SEECTL, SEEOP_WRITE | SEESTART);
8998 
8999                     retval = ahd_wait_seeprom(ahd);
9000                     if (retval)
9001                               break;
9002           }
9003 
9004           /*
9005            * Disable writes.
9006            */
9007           ahd_outb(ahd, SEEADR, SEEOP_EWDS_ADDR);
9008           ahd_outb(ahd, SEECTL, SEEOP_EWDS | SEESTART);
9009           error = ahd_wait_seeprom(ahd);
9010           if (error)
9011                     return (error);
9012           return (retval);
9013 }
9014 
9015 /*
9016  * Wait ~100us for the serial eeprom to satisfy our request.
9017  */
9018 int
ahd_wait_seeprom(struct ahd_softc * ahd)9019 ahd_wait_seeprom(struct ahd_softc *ahd)
9020 {
9021           int cnt;
9022 
9023           cnt = 2000;
9024           while ((ahd_inb(ahd, SEESTAT) & (SEEARBACK|SEEBUSY)) != 0 && --cnt)
9025                     ahd_delay(5);
9026 
9027           if (cnt == 0)
9028                     return (ETIMEDOUT);
9029           return (0);
9030 }
9031 
9032 /*
9033  * Validate the two checksums in the per_channel
9034  * vital product data struct.
9035  */
9036 int
ahd_verify_vpd_cksum(struct vpd_config * vpd)9037 ahd_verify_vpd_cksum(struct vpd_config *vpd)
9038 {
9039           int i;
9040           int maxaddr;
9041           uint32_t checksum;
9042           uint8_t *vpdarray;
9043 
9044           vpdarray = (uint8_t *)vpd;
9045           maxaddr = offsetof(struct vpd_config, vpd_checksum);
9046           checksum = 0;
9047           for (i = offsetof(struct vpd_config, resource_type); i < maxaddr; i++)
9048                     checksum = checksum + vpdarray[i];
9049           if (checksum == 0
9050            || (-checksum & 0xFF) != vpd->vpd_checksum)
9051                     return (0);
9052 
9053           checksum = 0;
9054           maxaddr = offsetof(struct vpd_config, checksum);
9055           for (i = offsetof(struct vpd_config, default_target_flags);
9056                i < maxaddr; i++)
9057                     checksum = checksum + vpdarray[i];
9058           if (checksum == 0
9059            || (-checksum & 0xFF) != vpd->checksum)
9060                     return (0);
9061           return (1);
9062 }
9063 
9064 int
ahd_verify_cksum(struct seeprom_config * sc)9065 ahd_verify_cksum(struct seeprom_config *sc)
9066 {
9067           int i;
9068           int maxaddr;
9069           uint32_t checksum;
9070           uint16_t *scarray;
9071 
9072           maxaddr = (sizeof(*sc)/2) - 1;
9073           checksum = 0;
9074           scarray = (uint16_t *)sc;
9075 
9076           for (i = 0; i < maxaddr; i++)
9077                     checksum = checksum + scarray[i];
9078           if (checksum == 0
9079            || (checksum & 0xFFFF) != sc->checksum) {
9080                     return (0);
9081           } else {
9082                     return (1);
9083           }
9084 }
9085 
9086 int
ahd_acquire_seeprom(struct ahd_softc * ahd)9087 ahd_acquire_seeprom(struct ahd_softc *ahd)
9088 {
9089           /*
9090            * We should be able to determine the SEEPROM type
9091            * from the flexport logic, but unfortunately not
9092            * all implementations have this logic and there is
9093            * no programmatic method for determining if the logic
9094            * is present.
9095            */
9096 
9097           return (1);
9098 #if 0
9099           uint8_t   seetype;
9100           int       error;
9101 
9102           error = ahd_read_flexport(ahd, FLXADDR_ROMSTAT_CURSENSECTL, &seetype);
9103           if (error != 0
9104            || ((seetype & FLX_ROMSTAT_SEECFG) == FLX_ROMSTAT_SEE_NONE))
9105                     return (0);
9106           return (1);
9107 #endif
9108 }
9109 
9110 void
ahd_release_seeprom(struct ahd_softc * ahd)9111 ahd_release_seeprom(struct ahd_softc *ahd)
9112 {
9113           /* Currently a no-op */
9114 }
9115 
9116 int
ahd_write_flexport(struct ahd_softc * ahd,u_int addr,u_int value)9117 ahd_write_flexport(struct ahd_softc *ahd, u_int addr, u_int value)
9118 {
9119           int error;
9120 
9121           AHD_ASSERT_MODES(ahd, AHD_MODE_SCSI_MSK, AHD_MODE_SCSI_MSK);
9122           if (addr > 7)
9123                     panic("ahd_write_flexport: address out of range");
9124           ahd_outb(ahd, BRDCTL, BRDEN|(addr << 3));
9125           error = ahd_wait_flexport(ahd);
9126           if (error != 0)
9127                     return (error);
9128           ahd_outb(ahd, BRDDAT, value);
9129           ahd_flush_device_writes(ahd);
9130           ahd_outb(ahd, BRDCTL, BRDSTB|BRDEN|(addr << 3));
9131           ahd_flush_device_writes(ahd);
9132           ahd_outb(ahd, BRDCTL, BRDEN|(addr << 3));
9133           ahd_flush_device_writes(ahd);
9134           ahd_outb(ahd, BRDCTL, 0);
9135           ahd_flush_device_writes(ahd);
9136           return (0);
9137 }
9138 
9139 int
ahd_read_flexport(struct ahd_softc * ahd,u_int addr,uint8_t * value)9140 ahd_read_flexport(struct ahd_softc *ahd, u_int addr, uint8_t *value)
9141 {
9142           int       error;
9143 
9144           AHD_ASSERT_MODES(ahd, AHD_MODE_SCSI_MSK, AHD_MODE_SCSI_MSK);
9145           if (addr > 7)
9146                     panic("ahd_read_flexport: address out of range");
9147           ahd_outb(ahd, BRDCTL, BRDRW|BRDEN|(addr << 3));
9148           error = ahd_wait_flexport(ahd);
9149           if (error != 0)
9150                     return (error);
9151           *value = ahd_inb(ahd, BRDDAT);
9152           ahd_outb(ahd, BRDCTL, 0);
9153           ahd_flush_device_writes(ahd);
9154           return (0);
9155 }
9156 
9157 /*
9158  * Wait at most 2 seconds for flexport arbitration to succeed.
9159  */
9160 int
ahd_wait_flexport(struct ahd_softc * ahd)9161 ahd_wait_flexport(struct ahd_softc *ahd)
9162 {
9163           int cnt;
9164 
9165           AHD_ASSERT_MODES(ahd, AHD_MODE_SCSI_MSK, AHD_MODE_SCSI_MSK);
9166           cnt = 1000000 * 2 / 5;
9167           while ((ahd_inb(ahd, BRDCTL) & FLXARBACK) == 0 && --cnt)
9168                     ahd_delay(5);
9169 
9170           if (cnt == 0)
9171                     return (ETIMEDOUT);
9172           return (0);
9173 }
9174 
9175 /************************* Target Mode ****************************************/
9176 #ifdef AHD_TARGET_MODE
9177 cam_status
ahd_find_tmode_devs(struct ahd_softc * ahd,struct cam_sim * sim,union ccb * ccb,struct ahd_tmode_tstate ** tstate,struct ahd_tmode_lstate ** lstate,int notfound_failure)9178 ahd_find_tmode_devs(struct ahd_softc *ahd, struct cam_sim *sim, union ccb *ccb,
9179                         struct ahd_tmode_tstate **tstate,
9180                         struct ahd_tmode_lstate **lstate,
9181                         int notfound_failure)
9182 {
9183 
9184           if ((ahd->features & AHD_TARGETMODE) == 0)
9185                     return (CAM_REQ_INVALID);
9186 
9187           /*
9188            * Handle the 'black hole' device that sucks up
9189            * requests to unattached luns on enabled targets.
9190            */
9191           if (ccb->ccb_h.target_id == CAM_TARGET_WILDCARD
9192            && ccb->ccb_h.target_lun == CAM_LUN_WILDCARD) {
9193                     *tstate = NULL;
9194                     *lstate = ahd->black_hole;
9195           } else {
9196                     u_int max_id;
9197 
9198                     max_id = (ahd->features & AHD_WIDE) ? 15 : 7;
9199                     if (ccb->ccb_h.target_id > max_id)
9200                               return (CAM_TID_INVALID);
9201 
9202                     if (ccb->ccb_h.target_lun >= AHD_NUM_LUNS)
9203                               return (CAM_LUN_INVALID);
9204 
9205                     *tstate = ahd->enabled_targets[ccb->ccb_h.target_id];
9206                     *lstate = NULL;
9207                     if (*tstate != NULL)
9208                               *lstate =
9209                                   (*tstate)->enabled_luns[ccb->ccb_h.target_lun];
9210           }
9211 
9212           if (notfound_failure != 0 && *lstate == NULL)
9213                     return (CAM_PATH_INVALID);
9214 
9215           return (CAM_REQ_CMP);
9216 }
9217 
9218 void
ahd_handle_en_lun(struct ahd_softc * ahd,struct cam_sim * sim,union ccb * ccb)9219 ahd_handle_en_lun(struct ahd_softc *ahd, struct cam_sim *sim, union ccb *ccb)
9220 {
9221 #if NOT_YET
9222           struct       ahd_tmode_tstate *tstate;
9223           struct       ahd_tmode_lstate *lstate;
9224           struct       ccb_en_lun *cel;
9225           cam_status status;
9226           u_int        target;
9227           u_int        lun;
9228           u_int        target_mask;
9229           u_long       s;
9230           char         channel;
9231 
9232           status = ahd_find_tmode_devs(ahd, sim, ccb, &tstate, &lstate,
9233                                              /*notfound_failure*/FALSE);
9234 
9235           if (status != CAM_REQ_CMP) {
9236                     ccb->ccb_h.status = status;
9237                     return;
9238           }
9239 
9240           if ((ahd->features & AHD_MULTIROLE) != 0) {
9241                     u_int        our_id;
9242 
9243                     our_id = ahd->our_id;
9244                     if (ccb->ccb_h.target_id != our_id) {
9245                               if ((ahd->features & AHD_MULTI_TID) != 0
9246                                && (ahd->flags & AHD_INITIATORROLE) != 0) {
9247                                         /*
9248                                          * Only allow additional targets if
9249                                          * the initiator role is disabled.
9250                                          * The hardware cannot handle a re-select-in
9251                                          * on the initiator id during a re-select-out
9252                                          * on a different target id.
9253                                          */
9254                                         status = CAM_TID_INVALID;
9255                               } else if ((ahd->flags & AHD_INITIATORROLE) != 0
9256                                         || ahd->enabled_luns > 0) {
9257                                         /*
9258                                          * Only allow our target id to change
9259                                          * if the initiator role is not configured
9260                                          * and there are no enabled luns which
9261                                          * are attached to the currently registered
9262                                          * scsi id.
9263                                          */
9264                                         status = CAM_TID_INVALID;
9265                               }
9266                     }
9267           }
9268 
9269           if (status != CAM_REQ_CMP) {
9270                     ccb->ccb_h.status = status;
9271                     return;
9272           }
9273 
9274           /*
9275            * We now have an id that is valid.
9276            * If we aren't in target mode, switch modes.
9277            */
9278           if ((ahd->flags & AHD_TARGETROLE) == 0
9279            && ccb->ccb_h.target_id != CAM_TARGET_WILDCARD) {
9280                     u_long    s;
9281 
9282                     printf("Configuring Target Mode\n");
9283                     ahd_lock(ahd, &s);
9284                     if (LIST_FIRST(&ahd->pending_scbs) != NULL) {
9285                               ccb->ccb_h.status = CAM_BUSY;
9286                               ahd_unlock(ahd, &s);
9287                               return;
9288                     }
9289                     ahd->flags |= AHD_TARGETROLE;
9290                     if ((ahd->features & AHD_MULTIROLE) == 0)
9291                               ahd->flags &= ~AHD_INITIATORROLE;
9292                     ahd_pause(ahd);
9293                     ahd_loadseq(ahd);
9294                     ahd_restart(ahd);
9295                     ahd_unlock(ahd, &s);
9296           }
9297           cel = &ccb->cel;
9298           target = ccb->ccb_h.target_id;
9299           lun = ccb->ccb_h.target_lun;
9300           channel = SIM_CHANNEL(ahd, sim);
9301           target_mask = 0x01 << target;
9302           if (channel == 'B')
9303                     target_mask <<= 8;
9304 
9305           if (cel->enable != 0) {
9306                     u_int scsiseq1;
9307 
9308                     /* Are we already enabled?? */
9309                     if (lstate != NULL) {
9310                               xpt_print_path(ccb->ccb_h.path);
9311                               printf("Lun already enabled\n");
9312                               ccb->ccb_h.status = CAM_LUN_ALRDY_ENA;
9313                               return;
9314                     }
9315 
9316                     if (cel->grp6_len != 0
9317                      || cel->grp7_len != 0) {
9318                               /*
9319                                * Don't (yet?) support vendor
9320                                * specific commands.
9321                                */
9322                               ccb->ccb_h.status = CAM_REQ_INVALID;
9323                               printf("Non-zero Group Codes\n");
9324                               return;
9325                     }
9326 
9327                     /*
9328                      * Seems to be okay.
9329                      * Setup our data structures.
9330                      */
9331                     if (target != CAM_TARGET_WILDCARD && tstate == NULL) {
9332                               tstate = ahd_alloc_tstate(ahd, target, channel);
9333                               if (tstate == NULL) {
9334                                         xpt_print_path(ccb->ccb_h.path);
9335                                         printf("Couldn't allocate tstate\n");
9336                                         ccb->ccb_h.status = CAM_RESRC_UNAVAIL;
9337                                         return;
9338                               }
9339                     }
9340                     lstate = malloc(sizeof(*lstate), M_DEVBUF, M_NOWAIT);
9341                     if (lstate == NULL) {
9342                               xpt_print_path(ccb->ccb_h.path);
9343                               printf("Couldn't allocate lstate\n");
9344                               ccb->ccb_h.status = CAM_RESRC_UNAVAIL;
9345                               return;
9346                     }
9347                     memset(lstate, 0, sizeof(*lstate));
9348                     status = xpt_create_path(&lstate->path, /*periph*/NULL,
9349                                                    xpt_path_path_id(ccb->ccb_h.path),
9350                                                    xpt_path_target_id(ccb->ccb_h.path),
9351                                                    xpt_path_lun_id(ccb->ccb_h.path));
9352                     if (status != CAM_REQ_CMP) {
9353                               free(lstate, M_DEVBUF);
9354                               xpt_print_path(ccb->ccb_h.path);
9355                               printf("Couldn't allocate path\n");
9356                               ccb->ccb_h.status = CAM_RESRC_UNAVAIL;
9357                               return;
9358                     }
9359                     SLIST_INIT(&lstate->accept_tios);
9360                     SLIST_INIT(&lstate->immed_notifies);
9361                     ahd_lock(ahd, &s);
9362                     ahd_pause(ahd);
9363                     if (target != CAM_TARGET_WILDCARD) {
9364                               tstate->enabled_luns[lun] = lstate;
9365                               ahd->enabled_luns++;
9366 
9367                               if ((ahd->features & AHD_MULTI_TID) != 0) {
9368                                         u_int targid_mask;
9369 
9370                                         targid_mask = ahd_inb(ahd, TARGID)
9371                                                       | (ahd_inb(ahd, TARGID + 1) << 8);
9372 
9373                                         targid_mask |= target_mask;
9374                                         ahd_outb(ahd, TARGID, targid_mask);
9375                                         ahd_outb(ahd, TARGID+1, (targid_mask >> 8));
9376 
9377                                         ahd_update_scsiid(ahd, targid_mask);
9378                               } else {
9379                                         u_int our_id;
9380                                         char  channel;
9381 
9382                                         channel = SIM_CHANNEL(ahd, sim);
9383                                         our_id = SIM_SCSI_ID(ahd, sim);
9384 
9385                                         /*
9386                                          * This can only happen if selections
9387                                          * are not enabled
9388                                          */
9389                                         if (target != our_id) {
9390                                                   u_int sblkctl;
9391                                                   char  cur_channel;
9392                                                   int   swap;
9393 
9394                                                   sblkctl = ahd_inb(ahd, SBLKCTL);
9395                                                   cur_channel = (sblkctl & SELBUSB)
9396                                                                 ? 'B' : 'A';
9397                                                   if ((ahd->features & AHD_TWIN) == 0)
9398                                                             cur_channel = 'A';
9399                                                   swap = cur_channel != channel;
9400                                                   ahd->our_id = target;
9401 
9402                                                   if (swap)
9403                                                             ahd_outb(ahd, SBLKCTL,
9404                                                                        sblkctl ^ SELBUSB);
9405 
9406                                                   ahd_outb(ahd, SCSIID, target);
9407 
9408                                                   if (swap)
9409                                                             ahd_outb(ahd, SBLKCTL, sblkctl);
9410                                         }
9411                               }
9412                     } else
9413                               ahd->black_hole = lstate;
9414                     /* Allow select-in operations */
9415                     if (ahd->black_hole != NULL && ahd->enabled_luns > 0) {
9416                               scsiseq1 = ahd_inb(ahd, SCSISEQ_TEMPLATE);
9417                               scsiseq1 |= ENSELI;
9418                               ahd_outb(ahd, SCSISEQ_TEMPLATE, scsiseq1);
9419                               scsiseq1 = ahd_inb(ahd, SCSISEQ1);
9420                               scsiseq1 |= ENSELI;
9421                               ahd_outb(ahd, SCSISEQ1, scsiseq1);
9422                     }
9423                     ahd_unpause(ahd);
9424                     ahd_unlock(ahd, &s);
9425                     ccb->ccb_h.status = CAM_REQ_CMP;
9426                     xpt_print_path(ccb->ccb_h.path);
9427                     printf("Lun now enabled for target mode\n");
9428           } else {
9429                     struct scb *scb;
9430                     int i, empty;
9431 
9432                     if (lstate == NULL) {
9433                               ccb->ccb_h.status = CAM_LUN_INVALID;
9434                               return;
9435                     }
9436 
9437                     ahd_lock(ahd, &s);
9438 
9439                     ccb->ccb_h.status = CAM_REQ_CMP;
9440                     LIST_FOREACH(scb, &ahd->pending_scbs, pending_links) {
9441                               struct ccb_hdr *ccbh;
9442 
9443                               ccbh = &scb->io_ctx->ccb_h;
9444                               if (ccbh->func_code == XPT_CONT_TARGET_IO
9445                                && !xpt_path_comp(ccbh->path, ccb->ccb_h.path)){
9446                                         printf("CTIO pending\n");
9447                                         ccb->ccb_h.status = CAM_REQ_INVALID;
9448                                         ahd_unlock(ahd, &s);
9449                                         return;
9450                               }
9451                     }
9452 
9453                     if (SLIST_FIRST(&lstate->accept_tios) != NULL) {
9454                               printf("ATIOs pending\n");
9455                               ccb->ccb_h.status = CAM_REQ_INVALID;
9456                     }
9457 
9458                     if (SLIST_FIRST(&lstate->immed_notifies) != NULL) {
9459                               printf("INOTs pending\n");
9460                               ccb->ccb_h.status = CAM_REQ_INVALID;
9461                     }
9462 
9463                     if (ccb->ccb_h.status != CAM_REQ_CMP) {
9464                               ahd_unlock(ahd, &s);
9465                               return;
9466                     }
9467 
9468                     xpt_print_path(ccb->ccb_h.path);
9469                     printf("Target mode disabled\n");
9470                     xpt_free_path(lstate->path);
9471                     free(lstate, M_DEVBUF);
9472 
9473                     ahd_pause(ahd);
9474                     /* Can we clean up the target too? */
9475                     if (target != CAM_TARGET_WILDCARD) {
9476                               tstate->enabled_luns[lun] = NULL;
9477                               ahd->enabled_luns--;
9478                               for (empty = 1, i = 0; i < 8; i++)
9479                                         if (tstate->enabled_luns[i] != NULL) {
9480                                                   empty = 0;
9481                                                   break;
9482                                         }
9483 
9484                               if (empty) {
9485                                         ahd_free_tstate(ahd, target, channel,
9486                                                             /*force*/FALSE);
9487                                         if (ahd->features & AHD_MULTI_TID) {
9488                                                   u_int targid_mask;
9489 
9490                                                   targid_mask = ahd_inb(ahd, TARGID)
9491                                                                 | (ahd_inb(ahd, TARGID + 1)
9492                                                                    << 8);
9493 
9494                                                   targid_mask &= ~target_mask;
9495                                                   ahd_outb(ahd, TARGID, targid_mask);
9496                                                   ahd_outb(ahd, TARGID+1,
9497                                                              (targid_mask >> 8));
9498                                                   ahd_update_scsiid(ahd, targid_mask);
9499                                         }
9500                               }
9501                     } else {
9502 
9503                               ahd->black_hole = NULL;
9504 
9505                               /*
9506                                * We can't allow selections without
9507                                * our black hole device.
9508                                */
9509                               empty = TRUE;
9510                     }
9511                     if (ahd->enabled_luns == 0) {
9512                               /* Disallow select-in */
9513                               u_int scsiseq1;
9514 
9515                               scsiseq1 = ahd_inb(ahd, SCSISEQ_TEMPLATE);
9516                               scsiseq1 &= ~ENSELI;
9517                               ahd_outb(ahd, SCSISEQ_TEMPLATE, scsiseq1);
9518                               scsiseq1 = ahd_inb(ahd, SCSISEQ1);
9519                               scsiseq1 &= ~ENSELI;
9520                               ahd_outb(ahd, SCSISEQ1, scsiseq1);
9521 
9522                               if ((ahd->features & AHD_MULTIROLE) == 0) {
9523                                         printf("Configuring Initiator Mode\n");
9524                                         ahd->flags &= ~AHD_TARGETROLE;
9525                                         ahd->flags |= AHD_INITIATORROLE;
9526                                         ahd_pause(ahd);
9527                                         ahd_loadseq(ahd);
9528                                         ahd_restart(ahd);
9529                                         /*
9530                                          * Unpaused.  The extra unpause
9531                                          * that follows is harmless.
9532                                          */
9533                               }
9534                     }
9535                     ahd_unpause(ahd);
9536                     ahd_unlock(ahd, &s);
9537           }
9538 #endif
9539 }
9540 
9541 static void
ahd_update_scsiid(struct ahd_softc * ahd,u_int targid_mask)9542 ahd_update_scsiid(struct ahd_softc *ahd, u_int targid_mask)
9543 {
9544 #if NOT_YET
9545           u_int scsiid_mask;
9546           u_int scsiid;
9547 
9548           if ((ahd->features & AHD_MULTI_TID) == 0)
9549                     panic("ahd_update_scsiid called on non-multitid unit\n");
9550 
9551           /*
9552            * Since we will rely on the TARGID mask
9553            * for selection enables, ensure that OID
9554            * in SCSIID is not set to some other ID
9555            * that we don't want to allow selections on.
9556            */
9557           if ((ahd->features & AHD_ULTRA2) != 0)
9558                     scsiid = ahd_inb(ahd, SCSIID_ULTRA2);
9559           else
9560                     scsiid = ahd_inb(ahd, SCSIID);
9561           scsiid_mask = 0x1 << (scsiid & OID);
9562           if ((targid_mask & scsiid_mask) == 0) {
9563                     u_int our_id;
9564 
9565                     /* ffs counts from 1 */
9566                     our_id = ffs(targid_mask);
9567                     if (our_id == 0)
9568                               our_id = ahd->our_id;
9569                     else
9570                               our_id--;
9571                     scsiid &= TID;
9572                     scsiid |= our_id;
9573           }
9574           if ((ahd->features & AHD_ULTRA2) != 0)
9575                     ahd_outb(ahd, SCSIID_ULTRA2, scsiid);
9576           else
9577                     ahd_outb(ahd, SCSIID, scsiid);
9578 #endif
9579 }
9580 
9581 #ifdef AHD_TARGET_MODE
9582 void
ahd_run_tqinfifo(struct ahd_softc * ahd,int paused)9583 ahd_run_tqinfifo(struct ahd_softc *ahd, int paused)
9584 {
9585           struct target_cmd *cmd;
9586 
9587           ahd_sync_tqinfifo(ahd, BUS_DMASYNC_POSTREAD);
9588           while ((cmd = &ahd->targetcmds[ahd->tqinfifonext])->cmd_valid != 0) {
9589 
9590                     /*
9591                      * Only advance through the queue if we
9592                      * have the resources to process the command.
9593                      */
9594                     if (ahd_handle_target_cmd(ahd, cmd) != 0)
9595                               break;
9596 
9597                     cmd->cmd_valid = 0;
9598                     ahd_dmamap_sync(ahd, ahd->parent_dmat /*shared_data_dmat*/,
9599                                         ahd->shared_data_map.dmamap,
9600                                         ahd_targetcmd_offset(ahd, ahd->tqinfifonext),
9601                                         sizeof(struct target_cmd),
9602                                         BUS_DMASYNC_PREREAD);
9603                     ahd->tqinfifonext++;
9604 
9605                     /*
9606                      * Lazily update our position in the target mode incoming
9607                      * command queue as seen by the sequencer.
9608                      */
9609                     if ((ahd->tqinfifonext & (HOST_TQINPOS - 1)) == 1) {
9610                               u_int hs_mailbox;
9611 
9612                               hs_mailbox = ahd_inb(ahd, HS_MAILBOX);
9613                               hs_mailbox &= ~HOST_TQINPOS;
9614                               hs_mailbox |= ahd->tqinfifonext & HOST_TQINPOS;
9615                               ahd_outb(ahd, HS_MAILBOX, hs_mailbox);
9616                     }
9617           }
9618 }
9619 #endif
9620 
9621 static int
ahd_handle_target_cmd(struct ahd_softc * ahd,struct target_cmd * cmd)9622 ahd_handle_target_cmd(struct ahd_softc *ahd, struct target_cmd *cmd)
9623 {
9624           struct      ahd_tmode_tstate *tstate;
9625           struct      ahd_tmode_lstate *lstate;
9626           struct      ccb_accept_tio *atio;
9627           uint8_t *byte;
9628           int         initiator;
9629           int         target;
9630           int         lun;
9631 
9632           initiator = SCSIID_TARGET(ahd, cmd->scsiid);
9633           target = SCSIID_OUR_ID(cmd->scsiid);
9634           lun    = (cmd->identify & MSG_IDENTIFY_LUNMASK);
9635 
9636           byte = cmd->bytes;
9637           tstate = ahd->enabled_targets[target];
9638           lstate = NULL;
9639           if (tstate != NULL)
9640                     lstate = tstate->enabled_luns[lun];
9641 
9642           /*
9643            * Commands for disabled luns go to the black hole driver.
9644            */
9645           if (lstate == NULL)
9646                     lstate = ahd->black_hole;
9647 
9648           atio = (struct ccb_accept_tio*)SLIST_FIRST(&lstate->accept_tios);
9649           if (atio == NULL) {
9650                     ahd->flags |= AHD_TQINFIFO_BLOCKED;
9651                     /*
9652                      * Wait for more ATIOs from the peripheral driver for this lun.
9653                      */
9654                     return (1);
9655           } else
9656                     ahd->flags &= ~AHD_TQINFIFO_BLOCKED;
9657 #ifdef AHD_DEBUG
9658           if ((ahd_debug & AHD_SHOW_TQIN) != 0)
9659             printf("%s: incoming command from %d for %d:%d%s\n",
9660                      ahd_name(ahd),
9661                      initiator, target, lun,
9662                      lstate == ahd->black_hole ? "(Black Holed)" : "");
9663 #endif
9664           SLIST_REMOVE_HEAD(&lstate->accept_tios, sim_links.sle);
9665 
9666           if (lstate == ahd->black_hole) {
9667                     /* Fill in the wildcards */
9668                     atio->ccb_h.target_id = target;
9669                     atio->ccb_h.target_lun = lun;
9670           }
9671 
9672           /*
9673            * Package it up and send it off to
9674            * whomever has this lun enabled.
9675            */
9676           atio->sense_len = 0;
9677           atio->init_id = initiator;
9678           if (byte[0] != 0xFF) {
9679                     /* Tag was included */
9680                     atio->tag_action = *byte++;
9681                     atio->tag_id = *byte++;
9682                     atio->ccb_h.flags = CAM_TAG_ACTION_VALID;
9683           } else {
9684                     atio->ccb_h.flags = 0;
9685           }
9686           byte++;
9687 
9688           /* Okay.  Now determine the cdb size based on the command code */
9689           switch (*byte >> CMD_GROUP_CODE_SHIFT) {
9690           case 0:
9691                     atio->cdb_len = 6;
9692                     break;
9693           case 1:
9694           case 2:
9695                     atio->cdb_len = 10;
9696                     break;
9697           case 4:
9698                     atio->cdb_len = 16;
9699                     break;
9700           case 5:
9701                     atio->cdb_len = 12;
9702                     break;
9703           case 3:
9704           default:
9705                     /* Only copy the opcode. */
9706                     atio->cdb_len = 1;
9707                     printf("Reserved or VU command code type encountered\n");
9708                     break;
9709           }
9710 
9711           memcpy(atio->cdb_io.cdb_bytes, byte, atio->cdb_len);
9712 
9713           atio->ccb_h.status |= CAM_CDB_RECVD;
9714 
9715           if ((cmd->identify & MSG_IDENTIFY_DISCFLAG) == 0) {
9716                     /*
9717                      * We weren't allowed to disconnect.
9718                      * We're hanging on the bus until a
9719                      * continue target I/O comes in response
9720                      * to this accept tio.
9721                      */
9722 #ifdef AHD_DEBUG
9723                     if ((ahd_debug & AHD_SHOW_TQIN) != 0)
9724                               printf("Received Immediate Command %d:%d:%d - %p\n",
9725                                      initiator, target, lun, ahd->pending_device);
9726 #endif
9727                     ahd->pending_device = lstate;
9728                     ahd_freeze_ccb((union ccb *)atio);
9729                     atio->ccb_h.flags |= CAM_DIS_DISCONNECT;
9730           }
9731           xpt_done((union ccb*)atio);
9732           return (0);
9733 }
9734 
9735 #endif
9736 
9737 static int
ahd_createdmamem(bus_dma_tag_t tag,int size,int flags,bus_dmamap_t * mapp,void ** vaddr,bus_addr_t * baddr,bus_dma_segment_t * seg,int * nseg,const char * myname,const char * what)9738 ahd_createdmamem(bus_dma_tag_t tag, int size, int flags, bus_dmamap_t *mapp,
9739     void **vaddr, bus_addr_t *baddr, bus_dma_segment_t *seg, int *nseg,
9740     const char *myname, const char *what)
9741 {
9742           int error, level = 0;
9743 
9744           if ((error = bus_dmamem_alloc(tag, size, PAGE_SIZE, 0,
9745                                               seg, 1, nseg, BUS_DMA_WAITOK)) != 0) {
9746                     printf("%s: failed to allocate DMA mem for %s, error = %d\n",
9747                               myname, what, error);
9748                     goto out;
9749           }
9750           level++;
9751 
9752           if ((error = bus_dmamem_map(tag, seg, *nseg, size, vaddr,
9753                                             BUS_DMA_WAITOK|BUS_DMA_COHERENT)) != 0) {
9754                     printf("%s: failed to map DMA mem for %s, error = %d\n",
9755                               myname, what, error);
9756                     goto out;
9757           }
9758           level++;
9759 
9760           if ((error = bus_dmamap_create(tag, size, 1, size, 0,
9761                                                BUS_DMA_WAITOK | flags, mapp)) != 0) {
9762                     printf("%s: failed to create DMA map for %s, error = %d\n",
9763                               myname, what, error);
9764                     goto out;
9765           }
9766           level++;
9767 
9768 
9769           if ((error = bus_dmamap_load(tag, *mapp, *vaddr, size, NULL,
9770                                              BUS_DMA_WAITOK)) != 0) {
9771                     printf("%s: failed to load DMA map for %s, error = %d\n",
9772                               myname, what, error);
9773                     goto out;
9774           }
9775 
9776           *baddr = (*mapp)->dm_segs[0].ds_addr;
9777 
9778           return 0;
9779 out:
9780           printf("ahd_createdmamem error (%d)\n", level);
9781           switch (level) {
9782           case 3:
9783                     bus_dmamap_destroy(tag, *mapp);
9784                     /* FALLTHROUGH */
9785           case 2:
9786                     bus_dmamem_unmap(tag, *vaddr, size);
9787                     /* FALLTHROUGH */
9788           case 1:
9789                     bus_dmamem_free(tag, seg, *nseg);
9790                     break;
9791           default:
9792                     break;
9793           }
9794 
9795           return error;
9796 }
9797 
9798 static void
ahd_freedmamem(bus_dma_tag_t tag,int size,bus_dmamap_t map,void * vaddr,bus_dma_segment_t * seg,int nseg)9799 ahd_freedmamem(bus_dma_tag_t tag, int size, bus_dmamap_t map, void *vaddr,
9800     bus_dma_segment_t *seg, int nseg)
9801 {
9802 
9803           bus_dmamap_unload(tag, map);
9804           bus_dmamap_destroy(tag, map);
9805           bus_dmamem_unmap(tag, vaddr, size);
9806           bus_dmamem_free(tag, seg, nseg);
9807 }
9808