Convert to use cam_calc_geometry().
[dragonfly.git] / sys / dev / disk / aic7xxx / aic79xx_osm.c
1 /*
2  * Bus independent FreeBSD shim for the aic7xxx based adaptec SCSI controllers
3  *
4  * Copyright (c) 1994-2002 Justin T. Gibbs.
5  * Copyright (c) 2001-2002 Adaptec Inc.
6  * All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  * 1. Redistributions of source code must retain the above copyright
12  *    notice, this list of conditions, and the following disclaimer,
13  *    without modification.
14  * 2. The name of the author may not be used to endorse or promote products
15  *    derived from this software without specific prior written permission.
16  *
17  * Alternatively, this software may be distributed under the terms of the
18  * GNU Public License ("GPL").
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
21  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23  * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
24  * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30  * SUCH DAMAGE.
31  *
32  * $Id: //depot/aic7xxx/freebsd/dev/aic7xxx/aic79xx_osm.c#27 $
33  *
34  * $FreeBSD: src/sys/dev/aic7xxx/aic79xx_osm.c,v 1.14 2003/06/14 22:17:39 njl Exp $
35  * $DragonFly: src/sys/dev/disk/aic7xxx/aic79xx_osm.c,v 1.14 2007/07/03 20:55:42 pavalos Exp $
36  */
37
38 #include "aic79xx_osm.h"
39 #include "aic79xx_inline.h"
40
41 #include "opt_ddb.h"
42 #ifdef DDB
43 #include <ddb/ddb.h>
44 #endif
45
46 #ifndef AHD_TMODE_ENABLE
47 #define AHD_TMODE_ENABLE 0
48 #endif
49
50 #define ccb_scb_ptr spriv_ptr0
51
52 #if UNUSED
53 static void     ahd_dump_targcmd(struct target_cmd *cmd);
54 #endif
55 static int      ahd_modevent(module_t mod, int type, void *data);
56 static void     ahd_action(struct cam_sim *sim, union ccb *ccb);
57 static void     ahd_set_tran_settings(struct ahd_softc *ahd,
58                                       int our_id, char channel,
59                                       struct ccb_trans_settings *cts);
60 static void     ahd_get_tran_settings(struct ahd_softc *ahd,
61                                       int our_id, char channel,
62                                       struct ccb_trans_settings *cts);
63 static void     ahd_async(void *callback_arg, uint32_t code,
64                           struct cam_path *path, void *arg);
65 static void     ahd_execute_scb(void *arg, bus_dma_segment_t *dm_segs,
66                                 int nsegments, int error);
67 static void     ahd_poll(struct cam_sim *sim);
68 static void     ahd_setup_data(struct ahd_softc *ahd, struct cam_sim *sim,
69                                struct ccb_scsiio *csio, struct scb *scb);
70 static void     ahd_abort_ccb(struct ahd_softc *ahd, struct cam_sim *sim,
71                               union ccb *ccb);
72 static int      ahd_create_path(struct ahd_softc *ahd,
73                                 char channel, u_int target, u_int lun,
74                                 struct cam_path **path);
75
76 #if NOT_YET
77 static void     ahd_set_recoveryscb(struct ahd_softc *ahd, struct scb *scb);
78 #endif
79
80 static int
81 ahd_create_path(struct ahd_softc *ahd, char channel, u_int target,
82                 u_int lun, struct cam_path **path)
83 {
84         path_id_t path_id;
85
86         if (channel == 'B')
87                 path_id = cam_sim_path(ahd->platform_data->sim_b);
88         else 
89                 path_id = cam_sim_path(ahd->platform_data->sim);
90
91         return (xpt_create_path(path, /*periph*/NULL,
92                                 path_id, target, lun));
93 }
94
95 int
96 ahd_map_int(struct ahd_softc *ahd)
97 {
98         int error;
99
100         /* Hook up our interrupt handler */
101         error = bus_setup_intr(ahd->dev_softc, ahd->platform_data->irq,
102                                0, ahd_platform_intr, ahd,
103                                &ahd->platform_data->ih, NULL);
104         if (error != 0)
105                 device_printf(ahd->dev_softc, "bus_setup_intr() failed: %d\n",
106                               error);
107         return (error);
108 }
109
110 /*
111  * Attach all the sub-devices we can find
112  */
113 int
114 ahd_attach(struct ahd_softc *ahd)
115 {
116         char   ahd_info[256];
117         struct ccb_setasync csa;
118         struct cam_sim *sim;
119         struct cam_path *path;
120         int count;
121
122         count = 0;
123         sim = NULL;
124
125         ahd_controller_info(ahd, ahd_info);
126         kprintf("%s\n", ahd_info);
127         ahd_lock();
128
129         /*
130          * Construct our SIM entry
131          */
132         sim = cam_sim_alloc(ahd_action, ahd_poll, "ahd", ahd,
133                             device_get_unit(ahd->dev_softc),
134                             1, AHD_MAX_QUEUE, NULL);
135         if (sim == NULL)
136                 goto fail;
137
138         if (xpt_bus_register(sim, /*bus_id*/0) != CAM_SUCCESS) {
139                 cam_sim_free(sim);
140                 sim = NULL;
141                 goto fail;
142         }
143         
144         if (xpt_create_path(&path, /*periph*/NULL,
145                             cam_sim_path(sim), CAM_TARGET_WILDCARD,
146                             CAM_LUN_WILDCARD) != CAM_REQ_CMP) {
147                 xpt_bus_deregister(cam_sim_path(sim));
148                 cam_sim_free(sim);
149                 sim = NULL;
150                 goto fail;
151         }
152                 
153         xpt_setup_ccb(&csa.ccb_h, path, /*priority*/5);
154         csa.ccb_h.func_code = XPT_SASYNC_CB;
155         csa.event_enable = AC_LOST_DEVICE;
156         csa.callback = ahd_async;
157         csa.callback_arg = sim;
158         xpt_action((union ccb *)&csa);
159         count++;
160
161 fail:
162         ahd->platform_data->sim = sim;
163         ahd->platform_data->path = path;
164         if (count != 0) {
165                 /* We have to wait until after any system dumps... */
166                 ahd->platform_data->eh =
167                     EVENTHANDLER_REGISTER(shutdown_post_sync, ahd_shutdown,
168                                           ahd, SHUTDOWN_PRI_DEFAULT);
169                 ahd_intr_enable(ahd, TRUE);
170         }
171
172         ahd_unlock();
173
174         return (count);
175 }
176
177 /*
178  * Catch an interrupt from the adapter
179  */
180 void
181 ahd_platform_intr(void *arg)
182 {
183         struct  ahd_softc *ahd;
184
185         ahd = (struct ahd_softc *)arg; 
186         ahd_intr(ahd);
187 }
188
189 /*
190  * We have an scb which has been processed by the
191  * adaptor, now we look to see how the operation
192  * went.
193  */
194 void
195 ahd_done(struct ahd_softc *ahd, struct scb *scb)
196 {
197         union ccb *ccb;
198
199         CAM_DEBUG(scb->io_ctx->ccb_h.path, CAM_DEBUG_TRACE,
200                   ("ahd_done - scb %d\n", SCB_GET_TAG(scb)));
201
202         ccb = scb->io_ctx;
203         LIST_REMOVE(scb, pending_links);
204
205         callout_stop(&ccb->ccb_h.timeout_ch);
206
207         if ((ccb->ccb_h.flags & CAM_DIR_MASK) != CAM_DIR_NONE) {
208                 bus_dmasync_op_t op;
209
210                 if ((ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_IN)
211                         op = BUS_DMASYNC_POSTREAD;
212                 else
213                         op = BUS_DMASYNC_POSTWRITE;
214                 bus_dmamap_sync(ahd->buffer_dmat, scb->dmamap, op);
215                 bus_dmamap_unload(ahd->buffer_dmat, scb->dmamap);
216         }
217
218 #ifdef AHD_TARGET_MODE
219         if (ccb->ccb_h.func_code == XPT_CONT_TARGET_IO) {
220                 struct cam_path *ccb_path;
221
222                 /*
223                  * If we have finally disconnected, clean up our
224                  * pending device state.
225                  * XXX - There may be error states that cause where
226                  *       we will remain connected.
227                  */
228                 ccb_path = ccb->ccb_h.path;
229                 if (ahd->pending_device != NULL
230                  && xpt_path_comp(ahd->pending_device->path, ccb_path) == 0) {
231
232                         if ((ccb->ccb_h.flags & CAM_SEND_STATUS) != 0) {
233                                 ahd->pending_device = NULL;
234                         } else {
235                                 xpt_print_path(ccb->ccb_h.path);
236                                 kprintf("Still disconnected\n");
237                                 ahd_freeze_ccb(ccb);
238                         }
239                 }
240
241                 if (ahd_get_transaction_status(scb) == CAM_REQ_INPROG)
242                         ccb->ccb_h.status |= CAM_REQ_CMP;
243                 ccb->ccb_h.status &= ~CAM_SIM_QUEUED;
244                 ahd_free_scb(ahd, scb);
245                 xpt_done(ccb);
246                 return;
247         }
248 #endif
249
250         /*
251          * If the recovery SCB completes, we have to be
252          * out of our timeout.
253          */
254         if ((scb->flags & SCB_RECOVERY_SCB) != 0) {
255                 struct  scb *list_scb;
256
257                 /*
258                  * We were able to complete the command successfully,
259                  * so reinstate the timeouts for all other pending
260                  * commands.
261                  */
262                 LIST_FOREACH(list_scb, &ahd->pending_scbs, pending_links) {
263                         union ccb *ccb;
264                         uint64_t time;
265
266                         ccb = list_scb->io_ctx;
267                         if (ccb->ccb_h.timeout == CAM_TIME_INFINITY)
268                                 continue;
269
270                         time = ccb->ccb_h.timeout;
271                         time *= hz;
272                         time /= 1000;
273                         callout_reset(&ccb->ccb_h.timeout_ch, time,
274                             ahd_timeout, list_scb);
275                 }
276
277                 if (ahd_get_transaction_status(scb) == CAM_BDR_SENT
278                  || ahd_get_transaction_status(scb) == CAM_REQ_ABORTED)
279                         ahd_set_transaction_status(scb, CAM_CMD_TIMEOUT);
280                 ahd_print_path(ahd, scb);
281                 kprintf("no longer in timeout, status = %x\n",
282                        ccb->ccb_h.status);
283         }
284
285         /* Don't clobber any existing error state */
286         if (ahd_get_transaction_status(scb) == CAM_REQ_INPROG) {
287                 ccb->ccb_h.status |= CAM_REQ_CMP;
288         } else if ((scb->flags & SCB_SENSE) != 0) {
289                 /*
290                  * We performed autosense retrieval.
291                  *
292                  * Zero any sense not transferred by the
293                  * device.  The SCSI spec mandates that any
294                  * untransfered data should be assumed to be
295                  * zero.  Complete the 'bounce' of sense information
296                  * through buffers accessible via bus-space by
297                  * copying it into the clients csio.
298                  */
299                 memset(&ccb->csio.sense_data, 0, sizeof(ccb->csio.sense_data));
300                 memcpy(&ccb->csio.sense_data,
301                        ahd_get_sense_buf(ahd, scb),
302 /* XXX What size do we want to use??? */
303                         sizeof(ccb->csio.sense_data)
304                        - ccb->csio.sense_resid);
305                 scb->io_ctx->ccb_h.status |= CAM_AUTOSNS_VALID;
306         } else if ((scb->flags & SCB_PKT_SENSE) != 0) {
307                 struct scsi_status_iu_header *siu;
308                 u_int sense_len;
309                 int i;
310
311                 /*
312                  * Copy only the sense data into the provided buffer.
313                  */
314                 siu = (struct scsi_status_iu_header *)scb->sense_data;
315                 sense_len = MIN(scsi_4btoul(siu->sense_length),
316                                 sizeof(ccb->csio.sense_data));
317                 memset(&ccb->csio.sense_data, 0, sizeof(ccb->csio.sense_data));
318                 memcpy(&ccb->csio.sense_data,
319                        ahd_get_sense_buf(ahd, scb) + SIU_SENSE_OFFSET(siu),
320                        sense_len);
321                 kprintf("Copied %d bytes of sense data offset %d:", sense_len,
322                        SIU_SENSE_OFFSET(siu));
323                 for (i = 0; i < sense_len; i++)
324                         kprintf(" 0x%x", ((uint8_t *)&ccb->csio.sense_data)[i]);
325                 kprintf("\n");
326                 scb->io_ctx->ccb_h.status |= CAM_AUTOSNS_VALID;
327         }
328         ccb->ccb_h.status &= ~CAM_SIM_QUEUED;
329         ahd_free_scb(ahd, scb);
330         xpt_done(ccb);
331 }
332
333 static void
334 ahd_action(struct cam_sim *sim, union ccb *ccb)
335 {
336         struct  ahd_softc *ahd;
337 #ifdef AHD_TARGET_MODE
338         struct  ahd_tmode_lstate *lstate;
339 #endif
340         u_int   target_id;
341         u_int   our_id;
342
343         CAM_DEBUG(ccb->ccb_h.path, CAM_DEBUG_TRACE, ("ahd_action\n"));
344         
345         ahd = (struct ahd_softc *)cam_sim_softc(sim);
346
347         target_id = ccb->ccb_h.target_id;
348         our_id = SIM_SCSI_ID(ahd, sim);
349         
350         switch (ccb->ccb_h.func_code) {
351         /* Common cases first */
352 #ifdef AHD_TARGET_MODE
353         case XPT_ACCEPT_TARGET_IO:      /* Accept Host Target Mode CDB */
354         case XPT_CONT_TARGET_IO:/* Continue Host Target I/O Connection*/
355         {
356                 struct     ahd_tmode_tstate *tstate;
357                 cam_status status;
358
359                 status = ahd_find_tmode_devs(ahd, sim, ccb, &tstate,
360                                              &lstate, TRUE);
361
362                 if (status != CAM_REQ_CMP) {
363                         if (ccb->ccb_h.func_code == XPT_CONT_TARGET_IO) {
364                                 /* Response from the black hole device */
365                                 tstate = NULL;
366                                 lstate = ahd->black_hole;
367                         } else {
368                                 ccb->ccb_h.status = status;
369                                 xpt_done(ccb);
370                                 break;
371                         }
372                 }
373                 if (ccb->ccb_h.func_code == XPT_ACCEPT_TARGET_IO) {
374
375                         ahd_lock();
376                         SLIST_INSERT_HEAD(&lstate->accept_tios, &ccb->ccb_h,
377                                           sim_links.sle);
378                         ccb->ccb_h.status = CAM_REQ_INPROG;
379                         if ((ahd->flags & AHD_TQINFIFO_BLOCKED) != 0)
380                                 ahd_run_tqinfifo(ahd, /*paused*/FALSE);
381                         ahd_unlock();
382                         break;
383                 }
384
385                 /*
386                  * The target_id represents the target we attempt to
387                  * select.  In target mode, this is the initiator of
388                  * the original command.
389                  */
390                 our_id = target_id;
391                 target_id = ccb->csio.init_id;
392                 /* FALLTHROUGH */
393         }
394 #endif
395         case XPT_SCSI_IO:       /* Execute the requested I/O operation */
396         case XPT_RESET_DEV:     /* Bus Device Reset the specified SCSI device */
397         {
398                 struct  scb *scb;
399                 struct  hardware_scb *hscb;     
400                 struct  ahd_initiator_tinfo *tinfo;
401                 struct  ahd_tmode_tstate *tstate;
402                 u_int   col_idx;
403
404                 if ((ahd->flags & AHD_INITIATORROLE) == 0
405                  && (ccb->ccb_h.func_code == XPT_SCSI_IO
406                   || ccb->ccb_h.func_code == XPT_RESET_DEV)) {
407                         ccb->ccb_h.status = CAM_PROVIDE_FAIL;
408                         xpt_done(ccb);
409                         return;
410                 }
411
412                 /*
413                  * get an scb to use.
414                  */
415                 ahd_lock();
416                 tinfo = ahd_fetch_transinfo(ahd, 'A', our_id,
417                                             target_id, &tstate);
418                 if ((ccb->ccb_h.flags & CAM_TAG_ACTION_VALID) == 0
419                  || (tinfo->curr.ppr_options & MSG_EXT_PPR_IU_REQ) != 0
420                  || ccb->ccb_h.func_code == XPT_CONT_TARGET_IO) {
421                         col_idx = AHD_NEVER_COL_IDX;
422                 } else {
423                         col_idx = AHD_BUILD_COL_IDX(target_id,
424                                                     ccb->ccb_h.target_lun);
425                 }
426                 if ((scb = ahd_get_scb(ahd, col_idx)) == NULL) {
427         
428                         xpt_freeze_simq(sim, /*count*/1);
429                         ahd->flags |= AHD_RESOURCE_SHORTAGE;
430                         ahd_unlock();
431                         ccb->ccb_h.status = CAM_REQUEUE_REQ;
432                         xpt_done(ccb);
433                         return;
434                 }
435                 ahd_unlock();
436                 
437                 hscb = scb->hscb;
438                 
439                 CAM_DEBUG(ccb->ccb_h.path, CAM_DEBUG_SUBTRACE,
440                           ("start scb(%p)\n", scb));
441                 scb->io_ctx = ccb;
442                 /*
443                  * So we can find the SCB when an abort is requested
444                  */
445                 ccb->ccb_h.ccb_scb_ptr = scb;
446
447                 /*
448                  * Put all the arguments for the xfer in the scb
449                  */
450                 hscb->control = 0;
451                 hscb->scsiid = BUILD_SCSIID(ahd, sim, target_id, our_id);
452                 hscb->lun = ccb->ccb_h.target_lun;
453                 if (ccb->ccb_h.func_code == XPT_RESET_DEV) {
454                         hscb->cdb_len = 0;
455                         scb->flags |= SCB_DEVICE_RESET;
456                         hscb->control |= MK_MESSAGE;
457                         hscb->task_management = SIU_TASKMGMT_LUN_RESET;
458                         ahd_execute_scb(scb, NULL, 0, 0);
459                 } else {
460 #ifdef AHD_TARGET_MODE
461                         if (ccb->ccb_h.func_code == XPT_CONT_TARGET_IO) {
462                                 struct target_data *tdata;
463
464                                 tdata = &hscb->shared_data.tdata;
465                                 if (ahd->pending_device == lstate)
466                                         scb->flags |= SCB_TARGET_IMMEDIATE;
467                                 hscb->control |= TARGET_SCB;
468                                 tdata->target_phases = 0;
469                                 if ((ccb->ccb_h.flags & CAM_SEND_STATUS) != 0) {
470                                         tdata->target_phases |= SPHASE_PENDING;
471                                         tdata->scsi_status =
472                                             ccb->csio.scsi_status;
473                                 }
474                                 if (ccb->ccb_h.flags & CAM_DIS_DISCONNECT)
475                                         tdata->target_phases |= NO_DISCONNECT;
476
477                                 tdata->initiator_tag =
478                                     ahd_htole16(ccb->csio.tag_id);
479                         }
480 #endif
481                         hscb->task_management = 0;
482                         if (ccb->ccb_h.flags & CAM_TAG_ACTION_VALID)
483                                 hscb->control |= ccb->csio.tag_action;
484                         
485                         ahd_setup_data(ahd, sim, &ccb->csio, scb);
486                 }
487                 break;
488         }
489 #ifdef AHD_TARGET_MODE
490         case XPT_NOTIFY_ACK:
491         case XPT_IMMED_NOTIFY:
492         {
493                 struct     ahd_tmode_tstate *tstate;
494                 struct     ahd_tmode_lstate *lstate;
495                 cam_status status;
496
497                 status = ahd_find_tmode_devs(ahd, sim, ccb, &tstate,
498                                              &lstate, TRUE);
499
500                 if (status != CAM_REQ_CMP) {
501                         ccb->ccb_h.status = status;
502                         xpt_done(ccb);
503                         break;
504                 }
505                 SLIST_INSERT_HEAD(&lstate->immed_notifies, &ccb->ccb_h,
506                                   sim_links.sle);
507                 ccb->ccb_h.status = CAM_REQ_INPROG;
508                 ahd_send_lstate_events(ahd, lstate);
509                 break;
510         }
511         case XPT_EN_LUN:                /* Enable LUN as a target */
512                 ahd_handle_en_lun(ahd, sim, ccb);
513                 xpt_done(ccb);
514                 break;
515 #endif
516         case XPT_ABORT:                 /* Abort the specified CCB */
517         {
518                 ahd_abort_ccb(ahd, sim, ccb);
519                 break;
520         }
521         case XPT_SET_TRAN_SETTINGS:
522         {
523                 ahd_lock();
524                 ahd_set_tran_settings(ahd, SIM_SCSI_ID(ahd, sim),
525                                       SIM_CHANNEL(ahd, sim), &ccb->cts);
526                 ahd_unlock();
527                 xpt_done(ccb);
528                 break;
529         }
530         case XPT_GET_TRAN_SETTINGS:
531         /* Get default/user set transfer settings for the target */
532         {
533                 ahd_lock();
534                 ahd_get_tran_settings(ahd, SIM_SCSI_ID(ahd, sim),
535                                       SIM_CHANNEL(ahd, sim), &ccb->cts);
536                 ahd_unlock();
537                 xpt_done(ccb);
538                 break;
539         }
540         case XPT_CALC_GEOMETRY:
541         {
542                 int       extended;
543
544                 extended = ahd->flags & AHD_EXTENDED_TRANS_A;
545                 cam_calc_geometry(&ccb->ccg, extended);
546                 xpt_done(ccb);
547                 break;
548         }
549         case XPT_RESET_BUS:             /* Reset the specified SCSI bus */
550         {
551                 int  found;
552                 
553                 ahd_lock();
554                 found = ahd_reset_channel(ahd, SIM_CHANNEL(ahd, sim),
555                                           /*initiate reset*/TRUE);
556                 ahd_unlock();
557                 if (bootverbose) {
558                         xpt_print_path(SIM_PATH(ahd, sim));
559                         kprintf("SCSI bus reset delivered. "
560                                "%d SCBs aborted.\n", found);
561                 }
562                 ccb->ccb_h.status = CAM_REQ_CMP;
563                 xpt_done(ccb);
564                 break;
565         }
566         case XPT_TERM_IO:               /* Terminate the I/O process */
567                 /* XXX Implement */
568                 ccb->ccb_h.status = CAM_REQ_INVALID;
569                 xpt_done(ccb);
570                 break;
571         case XPT_PATH_INQ:              /* Path routing inquiry */
572         {
573                 struct ccb_pathinq *cpi = &ccb->cpi;
574                 
575                 cpi->version_num = 1; /* XXX??? */
576                 cpi->hba_inquiry = PI_SDTR_ABLE|PI_TAG_ABLE;
577                 if ((ahd->features & AHD_WIDE) != 0)
578                         cpi->hba_inquiry |= PI_WIDE_16;
579                 if ((ahd->features & AHD_TARGETMODE) != 0) {
580                         cpi->target_sprt = PIT_PROCESSOR
581                                          | PIT_DISCONNECT
582                                          | PIT_TERM_IO;
583                 } else {
584                         cpi->target_sprt = 0;
585                 }
586                 cpi->hba_misc = 0;
587                 cpi->hba_eng_cnt = 0;
588                 cpi->max_target = (ahd->features & AHD_WIDE) ? 15 : 7;
589                 cpi->max_lun = AHD_NUM_LUNS - 1;
590                 cpi->initiator_id = ahd->our_id;
591                 if ((ahd->flags & AHD_RESET_BUS_A) == 0) {
592                         cpi->hba_misc |= PIM_NOBUSRESET;
593                 }
594                 cpi->bus_id = cam_sim_bus(sim);
595                 cpi->base_transfer_speed = 3300;
596                 strncpy(cpi->sim_vid, "FreeBSD", SIM_IDLEN);
597                 strncpy(cpi->hba_vid, "Adaptec", HBA_IDLEN);
598                 strncpy(cpi->dev_name, cam_sim_name(sim), DEV_IDLEN);
599                 cpi->unit_number = cam_sim_unit(sim);
600 #ifdef AHD_NEW_TRAN_SETTINGS
601                 cpi->protocol = PROTO_SCSI;
602                 cpi->protocol_version = SCSI_REV_2;
603                 cpi->transport = XPORT_SPI;
604                 cpi->transport_version = 2;
605                 cpi->xport_specific.spi.ppr_options = SID_SPI_CLOCK_ST;
606                 cpi->transport_version = 4;
607                 cpi->xport_specific.spi.ppr_options = SID_SPI_CLOCK_DT_ST;
608 #endif
609                 cpi->ccb_h.status = CAM_REQ_CMP;
610                 xpt_done(ccb);
611                 break;
612         }
613         default:
614                 ccb->ccb_h.status = CAM_PROVIDE_FAIL;
615                 xpt_done(ccb);
616                 break;
617         }
618 }
619
620
621 static void
622 ahd_set_tran_settings(struct ahd_softc *ahd, int our_id, char channel,
623                       struct ccb_trans_settings *cts)
624 {
625 #ifdef AHD_NEW_TRAN_SETTINGS
626         struct    ahd_devinfo devinfo;
627         struct    ccb_trans_settings_scsi *scsi;
628         struct    ccb_trans_settings_spi *spi;
629         struct    ahd_initiator_tinfo *tinfo;
630         struct    ahd_tmode_tstate *tstate;
631         uint16_t *discenable;
632         uint16_t *tagenable;
633         u_int     update_type;
634
635         scsi = &cts->proto_specific.scsi;
636         spi = &cts->xport_specific.spi;
637         ahd_compile_devinfo(&devinfo, SIM_SCSI_ID(ahd, sim),
638                             cts->ccb_h.target_id,
639                             cts->ccb_h.target_lun,
640                             SIM_CHANNEL(ahd, sim),
641                             ROLE_UNKNOWN);
642         tinfo = ahd_fetch_transinfo(ahd, devinfo.channel,
643                                     devinfo.our_scsiid,
644                                     devinfo.target, &tstate);
645         update_type = 0;
646         if (cts->type == CTS_TYPE_CURRENT_SETTINGS) {
647                 update_type |= AHD_TRANS_GOAL;
648                 discenable = &tstate->discenable;
649                 tagenable = &tstate->tagenable;
650                 tinfo->curr.protocol_version = cts->protocol_version;
651                 tinfo->curr.transport_version = cts->transport_version;
652                 tinfo->goal.protocol_version = cts->protocol_version;
653                 tinfo->goal.transport_version = cts->transport_version;
654         } else if (cts->type == CTS_TYPE_USER_SETTINGS) {
655                 update_type |= AHD_TRANS_USER;
656                 discenable = &ahd->user_discenable;
657                 tagenable = &ahd->user_tagenable;
658                 tinfo->user.protocol_version = cts->protocol_version;
659                 tinfo->user.transport_version = cts->transport_version;
660         } else {
661                 cts->ccb_h.status = CAM_REQ_INVALID;
662                 return;
663         }
664         
665         if ((spi->valid & CTS_SPI_VALID_DISC) != 0) {
666                 if ((spi->flags & CTS_SPI_FLAGS_DISC_ENB) != 0)
667                         *discenable |= devinfo.target_mask;
668                 else
669                         *discenable &= ~devinfo.target_mask;
670         }
671         
672         if ((scsi->valid & CTS_SCSI_VALID_TQ) != 0) {
673                 if ((scsi->flags & CTS_SCSI_FLAGS_TAG_ENB) != 0)
674                         *tagenable |= devinfo.target_mask;
675                 else
676                         *tagenable &= ~devinfo.target_mask;
677         }       
678
679         if ((spi->valid & CTS_SPI_VALID_BUS_WIDTH) != 0) {
680                 ahd_validate_width(ahd, /*tinfo limit*/NULL,
681                                    &spi->bus_width, ROLE_UNKNOWN);
682                 ahd_set_width(ahd, &devinfo, spi->bus_width,
683                               update_type, /*paused*/FALSE);
684         }
685
686         if ((spi->valid & CTS_SPI_VALID_PPR_OPTIONS) == 0) {
687                 if (update_type == AHD_TRANS_USER)
688                         spi->ppr_options = tinfo->user.ppr_options;
689                 else
690                         spi->ppr_options = tinfo->goal.ppr_options;
691         }
692
693         if ((spi->valid & CTS_SPI_VALID_SYNC_OFFSET) == 0) {
694                 if (update_type == AHD_TRANS_USER)
695                         spi->sync_offset = tinfo->user.offset;
696                 else
697                         spi->sync_offset = tinfo->goal.offset;
698         }
699
700         if ((spi->valid & CTS_SPI_VALID_SYNC_RATE) == 0) {
701                 if (update_type == AHD_TRANS_USER)
702                         spi->sync_period = tinfo->user.period;
703                 else
704                         spi->sync_period = tinfo->goal.period;
705         }
706
707         if (((spi->valid & CTS_SPI_VALID_SYNC_RATE) != 0)
708          || ((spi->valid & CTS_SPI_VALID_SYNC_OFFSET) != 0)) {
709                 u_int   maxsync;
710
711                 maxsync = AHD_SYNCRATE_MAX;
712
713                 if (spi->bus_width != MSG_EXT_WDTR_BUS_16_BIT)
714                         spi->ppr_options &= ~MSG_EXT_PPR_DT_REQ;
715
716                 if ((*discenable & devinfo.target_mask) == 0)
717                         spi->ppr_options &= ~MSG_EXT_PPR_IU_REQ;
718
719                 ahd_find_syncrate(ahd, &spi->sync_period,
720                                   &spi->ppr_options, maxsync);
721                 ahd_validate_offset(ahd, /*tinfo limit*/NULL,
722                                     spi->sync_period, &spi->sync_offset,
723                                     spi->bus_width, ROLE_UNKNOWN);
724
725                 /* We use a period of 0 to represent async */
726                 if (spi->sync_offset == 0) {
727                         spi->sync_period = 0;
728                         spi->ppr_options = 0;
729                 }
730
731                 ahd_set_syncrate(ahd, &devinfo, spi->sync_period,
732                                  spi->sync_offset, spi->ppr_options,
733                                  update_type, /*paused*/FALSE);
734         }
735         cts->ccb_h.status = CAM_REQ_CMP;
736 #else
737         struct    ahd_devinfo devinfo;
738         struct    ahd_initiator_tinfo *tinfo;
739         struct    ahd_tmode_tstate *tstate;
740         uint16_t *discenable;
741         uint16_t *tagenable;
742         u_int     update_type;
743
744         ahd_compile_devinfo(&devinfo, SIM_SCSI_ID(ahd, sim),
745                             cts->ccb_h.target_id,
746                             cts->ccb_h.target_lun,
747                             SIM_CHANNEL(ahd, sim),
748                             ROLE_UNKNOWN);
749         tinfo = ahd_fetch_transinfo(ahd, devinfo.channel,
750                                     devinfo.our_scsiid,
751                                     devinfo.target, &tstate);
752         update_type = 0;
753         if ((cts->flags & CCB_TRANS_CURRENT_SETTINGS) != 0) {
754                 update_type |= AHD_TRANS_GOAL;
755                 discenable = &tstate->discenable;
756                 tagenable = &tstate->tagenable;
757         } else if ((cts->flags & CCB_TRANS_USER_SETTINGS) != 0) {
758                 update_type |= AHD_TRANS_USER;
759                 discenable = &ahd->user_discenable;
760                 tagenable = &ahd->user_tagenable;
761         } else {
762                 cts->ccb_h.status = CAM_REQ_INVALID;
763                 return;
764         }
765         
766         if ((cts->valid & CCB_TRANS_DISC_VALID) != 0) {
767                 if ((cts->flags & CCB_TRANS_DISC_ENB) != 0)
768                         *discenable |= devinfo.target_mask;
769                 else
770                         *discenable &= ~devinfo.target_mask;
771         }
772         
773         if ((cts->valid & CCB_TRANS_TQ_VALID) != 0) {
774                 if ((cts->flags & CCB_TRANS_TAG_ENB) != 0)
775                         *tagenable |= devinfo.target_mask;
776                 else
777                         *tagenable &= ~devinfo.target_mask;
778         }       
779
780         if ((cts->valid & CCB_TRANS_BUS_WIDTH_VALID) != 0) {
781                 ahd_validate_width(ahd, /*tinfo limit*/NULL,
782                                    &cts->bus_width, ROLE_UNKNOWN);
783                 ahd_set_width(ahd, &devinfo, cts->bus_width,
784                               update_type, /*paused*/FALSE);
785         }
786
787         if ((cts->valid & CCB_TRANS_SYNC_OFFSET_VALID) == 0) {
788                 if (update_type == AHD_TRANS_USER)
789                         cts->sync_offset = tinfo->user.offset;
790                 else
791                         cts->sync_offset = tinfo->goal.offset;
792         }
793
794         if ((cts->valid & CCB_TRANS_SYNC_RATE_VALID) == 0) {
795                 if (update_type == AHD_TRANS_USER)
796                         cts->sync_period = tinfo->user.period;
797                 else
798                         cts->sync_period = tinfo->goal.period;
799         }
800
801         if (((cts->valid & CCB_TRANS_SYNC_RATE_VALID) != 0)
802          || ((cts->valid & CCB_TRANS_SYNC_OFFSET_VALID) != 0)
803          || ((cts->valid & CCB_TRANS_TQ_VALID) != 0)
804          || ((cts->valid & CCB_TRANS_DISC_VALID) != 0)) {
805                 u_int ppr_options;
806                 u_int maxsync;
807
808                 maxsync = AHD_SYNCRATE_MAX;
809                 ppr_options = 0;
810                 if (cts->sync_period <= AHD_SYNCRATE_DT
811                  && cts->bus_width == MSG_EXT_WDTR_BUS_16_BIT) {
812                         ppr_options = tinfo->user.ppr_options
813                                     | MSG_EXT_PPR_DT_REQ;
814                 }
815
816                 if ((*tagenable & devinfo.target_mask) == 0
817                  || (*discenable & devinfo.target_mask) == 0)
818                         ppr_options &= ~MSG_EXT_PPR_IU_REQ;
819
820                 ahd_find_syncrate(ahd, &cts->sync_period,
821                                   &ppr_options, maxsync);
822                 ahd_validate_offset(ahd, /*tinfo limit*/NULL,
823                                     cts->sync_period, &cts->sync_offset,
824                                     MSG_EXT_WDTR_BUS_8_BIT,
825                                     ROLE_UNKNOWN);
826
827                 /* We use a period of 0 to represent async */
828                 if (cts->sync_offset == 0) {
829                         cts->sync_period = 0;
830                         ppr_options = 0;
831                 }
832
833                 if (ppr_options != 0
834                  && tinfo->user.transport_version >= 3) {
835                         tinfo->goal.transport_version =
836                             tinfo->user.transport_version;
837                         tinfo->curr.transport_version =
838                             tinfo->user.transport_version;
839                 }
840                 
841                 ahd_set_syncrate(ahd, &devinfo, cts->sync_period,
842                                  cts->sync_offset, ppr_options,
843                                  update_type, /*paused*/FALSE);
844         }
845         cts->ccb_h.status = CAM_REQ_CMP;
846 #endif
847 }
848
849 static void
850 ahd_get_tran_settings(struct ahd_softc *ahd, int our_id, char channel,
851                       struct ccb_trans_settings *cts)
852 {
853 #ifdef AHD_NEW_TRAN_SETTINGS
854         struct  ahd_devinfo devinfo;
855         struct  ccb_trans_settings_scsi *scsi;
856         struct  ccb_trans_settings_spi *spi;
857         struct  ahd_initiator_tinfo *targ_info;
858         struct  ahd_tmode_tstate *tstate;
859         struct  ahd_transinfo *tinfo;
860
861         scsi = &cts->proto_specific.scsi;
862         spi = &cts->xport_specific.spi;
863         ahd_compile_devinfo(&devinfo, our_id,
864                             cts->ccb_h.target_id,
865                             cts->ccb_h.target_lun,
866                             channel, ROLE_UNKNOWN);
867         targ_info = ahd_fetch_transinfo(ahd, devinfo.channel,
868                                         devinfo.our_scsiid,
869                                         devinfo.target, &tstate);
870         
871         if (cts->type == CTS_TYPE_CURRENT_SETTINGS)
872                 tinfo = &targ_info->curr;
873         else
874                 tinfo = &targ_info->user;
875         
876         scsi->flags &= ~CTS_SCSI_FLAGS_TAG_ENB;
877         spi->flags &= ~CTS_SPI_FLAGS_DISC_ENB;
878         if (cts->type == CTS_TYPE_USER_SETTINGS) {
879                 if ((ahd->user_discenable & devinfo.target_mask) != 0)
880                         spi->flags |= CTS_SPI_FLAGS_DISC_ENB;
881
882                 if ((ahd->user_tagenable & devinfo.target_mask) != 0)
883                         scsi->flags |= CTS_SCSI_FLAGS_TAG_ENB;
884         } else {
885                 if ((tstate->discenable & devinfo.target_mask) != 0)
886                         spi->flags |= CTS_SPI_FLAGS_DISC_ENB;
887
888                 if ((tstate->tagenable & devinfo.target_mask) != 0)
889                         scsi->flags |= CTS_SCSI_FLAGS_TAG_ENB;
890         }
891         cts->protocol_version = tinfo->protocol_version;
892         cts->transport_version = tinfo->transport_version;
893
894         spi->sync_period = tinfo->period;
895         spi->sync_offset = tinfo->offset;
896         spi->bus_width = tinfo->width;
897         spi->ppr_options = tinfo->ppr_options;
898         
899         cts->protocol = PROTO_SCSI;
900         cts->transport = XPORT_SPI;
901         spi->valid = CTS_SPI_VALID_SYNC_RATE
902                    | CTS_SPI_VALID_SYNC_OFFSET
903                    | CTS_SPI_VALID_BUS_WIDTH
904                    | CTS_SPI_VALID_PPR_OPTIONS;
905
906         if (cts->ccb_h.target_lun != CAM_LUN_WILDCARD) {
907                 scsi->valid = CTS_SCSI_VALID_TQ;
908                 spi->valid |= CTS_SPI_VALID_DISC;
909         } else {
910                 scsi->valid = 0;
911         }
912
913         cts->ccb_h.status = CAM_REQ_CMP;
914 #else
915         struct  ahd_devinfo devinfo;
916         struct  ahd_initiator_tinfo *targ_info;
917         struct  ahd_tmode_tstate *tstate;
918         struct  ahd_transinfo *tinfo;
919
920         ahd_compile_devinfo(&devinfo, our_id,
921                             cts->ccb_h.target_id,
922                             cts->ccb_h.target_lun,
923                             channel, ROLE_UNKNOWN);
924         targ_info = ahd_fetch_transinfo(ahd, devinfo.channel,
925                                         devinfo.our_scsiid,
926                                         devinfo.target, &tstate);
927         
928         if ((cts->flags & CCB_TRANS_CURRENT_SETTINGS) != 0)
929                 tinfo = &targ_info->curr;
930         else
931                 tinfo = &targ_info->user;
932         
933         cts->flags &= ~(CCB_TRANS_DISC_ENB|CCB_TRANS_TAG_ENB);
934         if ((cts->flags & CCB_TRANS_CURRENT_SETTINGS) == 0) {
935                 if ((ahd->user_discenable & devinfo.target_mask) != 0)
936                         cts->flags |= CCB_TRANS_DISC_ENB;
937
938                 if ((ahd->user_tagenable & devinfo.target_mask) != 0)
939                         cts->flags |= CCB_TRANS_TAG_ENB;
940         } else {
941                 if ((tstate->discenable & devinfo.target_mask) != 0)
942                         cts->flags |= CCB_TRANS_DISC_ENB;
943
944                 if ((tstate->tagenable & devinfo.target_mask) != 0)
945                         cts->flags |= CCB_TRANS_TAG_ENB;
946         }
947         cts->sync_period = tinfo->period;
948         cts->sync_offset = tinfo->offset;
949         cts->bus_width = tinfo->width;
950         
951         cts->valid = CCB_TRANS_SYNC_RATE_VALID
952                    | CCB_TRANS_SYNC_OFFSET_VALID
953                    | CCB_TRANS_BUS_WIDTH_VALID;
954
955         if (cts->ccb_h.target_lun != CAM_LUN_WILDCARD)
956                 cts->valid |= CCB_TRANS_DISC_VALID|CCB_TRANS_TQ_VALID;
957
958         cts->ccb_h.status = CAM_REQ_CMP;
959 #endif
960 }
961
962 static void
963 ahd_async(void *callback_arg, uint32_t code, struct cam_path *path, void *arg)
964 {
965         struct ahd_softc *ahd;
966         struct cam_sim *sim;
967
968         sim = (struct cam_sim *)callback_arg;
969         ahd = (struct ahd_softc *)cam_sim_softc(sim);
970         switch (code) {
971         case AC_LOST_DEVICE:
972         {
973                 struct  ahd_devinfo devinfo;
974
975                 ahd_compile_devinfo(&devinfo, SIM_SCSI_ID(ahd, sim),
976                                     xpt_path_target_id(path),
977                                     xpt_path_lun_id(path),
978                                     SIM_CHANNEL(ahd, sim),
979                                     ROLE_UNKNOWN);
980
981                 /*
982                  * Revert to async/narrow transfers
983                  * for the next device.
984                  */
985                 ahd_lock();
986                 ahd_set_width(ahd, &devinfo, MSG_EXT_WDTR_BUS_8_BIT,
987                               AHD_TRANS_GOAL|AHD_TRANS_CUR, /*paused*/FALSE);
988                 ahd_set_syncrate(ahd, &devinfo, /*period*/0, /*offset*/0,
989                                  /*ppr_options*/0, AHD_TRANS_GOAL|AHD_TRANS_CUR,
990                                  /*paused*/FALSE);
991                 ahd_unlock();
992                 break;
993         }
994         default:
995                 break;
996         }
997 }
998
999 static void
1000 ahd_execute_scb(void *arg, bus_dma_segment_t *dm_segs, int nsegments,
1001                 int error)
1002 {
1003         struct  scb *scb;
1004         union   ccb *ccb;
1005         struct  ahd_softc *ahd;
1006         struct  ahd_initiator_tinfo *tinfo;
1007         struct  ahd_tmode_tstate *tstate;
1008         u_int   mask;
1009
1010         scb = (struct scb *)arg;
1011         ccb = scb->io_ctx;
1012         ahd = scb->ahd_softc;
1013
1014         if (error != 0) {
1015                 if (error == EFBIG)
1016                         ahd_set_transaction_status(scb, CAM_REQ_TOO_BIG);
1017                 else
1018                         ahd_set_transaction_status(scb, CAM_REQ_CMP_ERR);
1019                 if (nsegments != 0)
1020                         bus_dmamap_unload(ahd->buffer_dmat, scb->dmamap);
1021                 ahd_lock();
1022                 ahd_free_scb(ahd, scb);
1023                 ahd_unlock();
1024                 xpt_done(ccb);
1025                 return;
1026         }
1027         scb->sg_count = 0;
1028         if (nsegments != 0) {
1029                 void *sg;
1030                 bus_dmasync_op_t op;
1031                 u_int i;
1032
1033                 /* Copy the segments into our SG list */
1034                 for (i = nsegments, sg = scb->sg_list; i > 0; i--) {
1035
1036                         sg = ahd_sg_setup(ahd, scb, sg, dm_segs->ds_addr,
1037                                           dm_segs->ds_len,
1038                                           /*last*/i == 1);
1039                         dm_segs++;
1040                 }
1041                 
1042                 if ((ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_IN)
1043                         op = BUS_DMASYNC_PREREAD;
1044                 else
1045                         op = BUS_DMASYNC_PREWRITE;
1046
1047                 bus_dmamap_sync(ahd->buffer_dmat, scb->dmamap, op);
1048
1049                 if (ccb->ccb_h.func_code == XPT_CONT_TARGET_IO) {
1050                         struct target_data *tdata;
1051
1052                         tdata = &scb->hscb->shared_data.tdata;
1053                         tdata->target_phases |= DPHASE_PENDING;
1054                         if ((ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_OUT)
1055                                 tdata->data_phase = P_DATAOUT;
1056                         else
1057                                 tdata->data_phase = P_DATAIN;
1058                 }
1059         }
1060
1061         ahd_lock();
1062
1063         /*
1064          * Last time we need to check if this SCB needs to
1065          * be aborted.
1066          */
1067         if (ahd_get_transaction_status(scb) != CAM_REQ_INPROG) {
1068                 if (nsegments != 0)
1069                         bus_dmamap_unload(ahd->buffer_dmat,
1070                                           scb->dmamap);
1071                 ahd_free_scb(ahd, scb);
1072                 ahd_unlock();
1073                 xpt_done(ccb);
1074                 return;
1075         }
1076
1077         tinfo = ahd_fetch_transinfo(ahd, SCSIID_CHANNEL(ahd, scb->hscb->scsiid),
1078                                     SCSIID_OUR_ID(scb->hscb->scsiid),
1079                                     SCSIID_TARGET(ahd, scb->hscb->scsiid),
1080                                     &tstate);
1081
1082         mask = SCB_GET_TARGET_MASK(ahd, scb);
1083
1084         if ((tstate->discenable & mask) != 0
1085          && (ccb->ccb_h.flags & CAM_DIS_DISCONNECT) == 0)
1086                 scb->hscb->control |= DISCENB;
1087
1088         if ((tinfo->curr.ppr_options & MSG_EXT_PPR_IU_REQ) != 0) {
1089                 scb->flags |= SCB_PACKETIZED;
1090                 if (scb->hscb->task_management != 0)
1091                         scb->hscb->control &= ~MK_MESSAGE;
1092         }
1093
1094         if ((ccb->ccb_h.flags & CAM_NEGOTIATE) != 0
1095          && (tinfo->goal.width != 0
1096           || tinfo->goal.period != 0
1097           || tinfo->goal.ppr_options != 0)) {
1098                 scb->flags |= SCB_NEGOTIATE;
1099                 scb->hscb->control |= MK_MESSAGE;
1100         } else if ((tstate->auto_negotiate & mask) != 0) {
1101                 scb->flags |= SCB_AUTO_NEGOTIATE;
1102                 scb->hscb->control |= MK_MESSAGE;
1103         }
1104
1105         LIST_INSERT_HEAD(&ahd->pending_scbs, scb, pending_links);
1106
1107         ccb->ccb_h.status |= CAM_SIM_QUEUED;
1108
1109         if (ccb->ccb_h.timeout != CAM_TIME_INFINITY) {
1110                 uint64_t time;
1111
1112                 if (ccb->ccb_h.timeout == CAM_TIME_DEFAULT)
1113                         ccb->ccb_h.timeout = 5 * 1000;
1114
1115                 time = ccb->ccb_h.timeout;
1116                 time *= hz;
1117                 time /= 1000;
1118                 callout_reset(&ccb->ccb_h.timeout_ch, time, ahd_timeout, scb);
1119         }
1120
1121         if ((scb->flags & SCB_TARGET_IMMEDIATE) != 0) {
1122                 /* Define a mapping from our tag to the SCB. */
1123                 ahd->scb_data.scbindex[SCB_GET_TAG(scb)] = scb;
1124                 ahd_pause(ahd);
1125                 ahd_set_scbptr(ahd, SCB_GET_TAG(scb));
1126                 ahd_outb(ahd, RETURN_1, CONT_MSG_LOOP_TARG);
1127                 ahd_unpause(ahd);
1128         } else {
1129                 ahd_queue_scb(ahd, scb);
1130         }
1131
1132         ahd_unlock();
1133 }
1134
1135 static void
1136 ahd_poll(struct cam_sim *sim)
1137 {
1138         ahd_intr(cam_sim_softc(sim));
1139 }
1140
1141 static void
1142 ahd_setup_data(struct ahd_softc *ahd, struct cam_sim *sim,
1143                struct ccb_scsiio *csio, struct scb *scb)
1144 {
1145         struct hardware_scb *hscb;
1146         struct ccb_hdr *ccb_h;
1147         
1148         hscb = scb->hscb;
1149         ccb_h = &csio->ccb_h;
1150         
1151         csio->resid = 0;
1152         csio->sense_resid = 0;
1153         if (ccb_h->func_code == XPT_SCSI_IO) {
1154                 hscb->cdb_len = csio->cdb_len;
1155                 if ((ccb_h->flags & CAM_CDB_POINTER) != 0) {
1156
1157                         if (hscb->cdb_len > MAX_CDB_LEN
1158                          && (ccb_h->flags & CAM_CDB_PHYS) == 0) {
1159                                 /*
1160                                  * Should CAM start to support CDB sizes
1161                                  * greater than 16 bytes, we could use
1162                                  * the sense buffer to store the CDB.
1163                                  */
1164                                 ahd_set_transaction_status(scb,
1165                                                            CAM_REQ_INVALID);
1166                                 ahd_lock();
1167                                 ahd_free_scb(ahd, scb);
1168                                 ahd_unlock();
1169                                 xpt_done((union ccb *)csio);
1170                                 return;
1171                         }
1172                         if ((ccb_h->flags & CAM_CDB_PHYS) != 0) {
1173                                 hscb->shared_data.idata.cdb_from_host.cdbptr =
1174                                    ahd_htole64((uintptr_t)csio->cdb_io.cdb_ptr);
1175                                 hscb->shared_data.idata.cdb_from_host.cdblen =
1176                                    csio->cdb_len;
1177                                 hscb->cdb_len |= SCB_CDB_LEN_PTR;
1178                         } else {
1179                                 memcpy(hscb->shared_data.idata.cdb, 
1180                                        csio->cdb_io.cdb_ptr,
1181                                        hscb->cdb_len);
1182                         }
1183                 } else {
1184                         if (hscb->cdb_len > MAX_CDB_LEN) {
1185                                 ahd_set_transaction_status(scb,
1186                                                            CAM_REQ_INVALID);
1187                                 ahd_lock();
1188                                 ahd_free_scb(ahd, scb);
1189                                 ahd_unlock();
1190                                 xpt_done((union ccb *)csio);
1191                                 return;
1192                         }
1193                         memcpy(hscb->shared_data.idata.cdb,
1194                                csio->cdb_io.cdb_bytes, hscb->cdb_len);
1195                 }
1196         }
1197                 
1198         /* Only use S/G if there is a transfer */
1199         if ((ccb_h->flags & CAM_DIR_MASK) != CAM_DIR_NONE) {
1200                 if ((ccb_h->flags & CAM_SCATTER_VALID) == 0) {
1201                         /* We've been given a pointer to a single buffer */
1202                         if ((ccb_h->flags & CAM_DATA_PHYS) == 0) {
1203                                 int error;
1204
1205                                 crit_enter();
1206                                 error = bus_dmamap_load(ahd->buffer_dmat,
1207                                                         scb->dmamap,
1208                                                         csio->data_ptr,
1209                                                         csio->dxfer_len,
1210                                                         ahd_execute_scb,
1211                                                         scb, /*flags*/0);
1212                                 if (error == EINPROGRESS) {
1213                                         /*
1214                                          * So as to maintain ordering,
1215                                          * freeze the controller queue
1216                                          * until our mapping is
1217                                          * returned.
1218                                          */
1219                                         xpt_freeze_simq(sim,
1220                                                         /*count*/1);
1221                                         scb->io_ctx->ccb_h.status |=
1222                                             CAM_RELEASE_SIMQ;
1223                                 }
1224                                 crit_exit();
1225                         } else {
1226                                 struct bus_dma_segment seg;
1227
1228                                 /* Pointer to physical buffer */
1229                                 if (csio->dxfer_len > AHD_MAXTRANSFER_SIZE)
1230                                         panic("ahd_setup_data - Transfer size "
1231                                               "larger than can device max");
1232
1233                                 seg.ds_addr =
1234                                     (bus_addr_t)(vm_offset_t)csio->data_ptr;
1235                                 seg.ds_len = csio->dxfer_len;
1236                                 ahd_execute_scb(scb, &seg, 1, 0);
1237                         }
1238                 } else {
1239                         struct bus_dma_segment *segs;
1240
1241                         if ((ccb_h->flags & CAM_DATA_PHYS) != 0)
1242                                 panic("ahd_setup_data - Physical segment "
1243                                       "pointers unsupported");
1244
1245                         if ((ccb_h->flags & CAM_SG_LIST_PHYS) == 0)
1246                                 panic("ahd_setup_data - Virtual segment "
1247                                       "addresses unsupported");
1248
1249                         /* Just use the segments provided */
1250                         segs = (struct bus_dma_segment *)csio->data_ptr;
1251                         ahd_execute_scb(scb, segs, csio->sglist_cnt, 0);
1252                 }
1253         } else {
1254                 ahd_execute_scb(scb, NULL, 0, 0);
1255         }
1256 }
1257
1258 #if NOT_YET
1259 static void
1260 ahd_set_recoveryscb(struct ahd_softc *ahd, struct scb *scb) {
1261
1262         if ((scb->flags & SCB_RECOVERY_SCB) == 0) {
1263                 struct scb *list_scb;
1264
1265                 scb->flags |= SCB_RECOVERY_SCB;
1266
1267                 /*
1268                  * Take all queued, but not sent SCBs out of the equation.
1269                  * Also ensure that no new CCBs are queued to us while we
1270                  * try to fix this problem.
1271                  */
1272                 if ((scb->io_ctx->ccb_h.status & CAM_RELEASE_SIMQ) == 0) {
1273                         xpt_freeze_simq(SCB_GET_SIM(ahd, scb), /*count*/1);
1274                         scb->io_ctx->ccb_h.status |= CAM_RELEASE_SIMQ;
1275                 }
1276
1277                 /*
1278                  * Go through all of our pending SCBs and remove
1279                  * any scheduled timeouts for them.  We will reschedule
1280                  * them after we've successfully fixed this problem.
1281                  */
1282                 LIST_FOREACH(list_scb, &ahd->pending_scbs, pending_links) {
1283                         union ccb *ccb;
1284
1285                         ccb = list_scb->io_ctx;
1286                         callout_stop(&ccb->ccb_h.timeout_ch);
1287                 }
1288         }
1289 }
1290 #endif
1291
1292 void
1293 ahd_timeout(void *arg)
1294 {
1295         struct  scb       *scb;
1296         struct  ahd_softc *ahd;
1297         ahd_mode_state     saved_modes;
1298         int                target;
1299         int                lun;
1300         char               channel;
1301
1302 #if NOT_YET
1303         int                i;
1304         int                found;
1305         u_int              last_phase;
1306 #endif
1307
1308         scb = (struct scb *)arg; 
1309         ahd = (struct ahd_softc *)scb->ahd_softc;
1310
1311         ahd_lock();
1312
1313         ahd_pause_and_flushwork(ahd);
1314
1315         saved_modes = ahd_save_modes(ahd);
1316 #if 0
1317         ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI);
1318         ahd_outb(ahd, SCSISIGO, ACKO);
1319         kprintf("set ACK\n");
1320         ahd_outb(ahd, SCSISIGO, 0);
1321         kprintf("clearing Ack\n");
1322         ahd_restore_modes(ahd, saved_modes);
1323 #endif
1324         if ((scb->flags & SCB_ACTIVE) == 0) {
1325                 /* Previous timeout took care of me already */
1326                 kprintf("%s: Timedout SCB already complete. "
1327                        "Interrupts may not be functioning.\n", ahd_name(ahd));
1328                 ahd_unpause(ahd);
1329                 ahd_unlock();
1330                 return;
1331         }
1332
1333         target = SCB_GET_TARGET(ahd, scb);
1334         channel = SCB_GET_CHANNEL(ahd, scb);
1335         lun = SCB_GET_LUN(scb);
1336
1337         ahd_print_path(ahd, scb);
1338         kprintf("SCB 0x%x - timed out\n", SCB_GET_TAG(scb));
1339         ahd_dump_card_state(ahd);
1340         ahd_reset_channel(ahd, SIM_CHANNEL(ahd, sim),
1341                           /*initiate reset*/TRUE);
1342         ahd_unlock();
1343         return;
1344 #if NOT_YET
1345         last_phase = ahd_inb(ahd, LASTPHASE);
1346         if (scb->sg_count > 0) {
1347                 for (i = 0; i < scb->sg_count; i++) {
1348                         kprintf("sg[%d] - Addr 0x%x : Length %d\n",
1349                                i,
1350                                ((struct ahd_dma_seg *)scb->sg_list)[i].addr,
1351                                ((struct ahd_dma_seg *)scb->sg_list)[i].len
1352                                 & AHD_SG_LEN_MASK);
1353                 }
1354         }
1355         if (scb->flags & (SCB_DEVICE_RESET|SCB_ABORT)) {
1356                 /*
1357                  * Been down this road before.
1358                  * Do a full bus reset.
1359                  */
1360 bus_reset:
1361                 ahd_set_transaction_status(scb, CAM_CMD_TIMEOUT);
1362                 found = ahd_reset_channel(ahd, channel, /*Initiate Reset*/TRUE);
1363                 kprintf("%s: Issued Channel %c Bus Reset. "
1364                        "%d SCBs aborted\n", ahd_name(ahd), channel, found);
1365         } else {
1366                 /*
1367                  * If we are a target, transition to bus free and report
1368                  * the timeout.
1369                  * 
1370                  * The target/initiator that is holding up the bus may not
1371                  * be the same as the one that triggered this timeout
1372                  * (different commands have different timeout lengths).
1373                  * If the bus is idle and we are actiing as the initiator
1374                  * for this request, queue a BDR message to the timed out
1375                  * target.  Otherwise, if the timed out transaction is
1376                  * active:
1377                  *   Initiator transaction:
1378                  *      Stuff the message buffer with a BDR message and assert
1379                  *      ATN in the hopes that the target will let go of the bus
1380                  *      and go to the mesgout phase.  If this fails, we'll
1381                  *      get another timeout 2 seconds later which will attempt
1382                  *      a bus reset.
1383                  *
1384                  *   Target transaction:
1385                  *      Transition to BUS FREE and report the error.
1386                  *      It's good to be the target!
1387                  */
1388                 u_int active_scb_index;
1389                 u_int saved_scbptr;
1390
1391                 saved_scbptr = ahd_get_scbptr(ahd);
1392                 active_scb_index = saved_scbptr;
1393
1394                 if (last_phase != P_BUSFREE 
1395                   && (ahd_inb(ahd, SEQ_FLAGS) & NOT_IDENTIFIED) == 0
1396                   && (active_scb_index < ahd->scb_data.numscbs)) {
1397                         struct scb *active_scb;
1398
1399                         /*
1400                          * If the active SCB is not us, assume that
1401                          * the active SCB has a longer timeout than
1402                          * the timedout SCB, and wait for the active
1403                          * SCB to timeout.
1404                          */ 
1405                         active_scb = ahd_lookup_scb(ahd, active_scb_index);
1406                         if (active_scb != scb) {
1407                                 struct   ccb_hdr *ccbh;
1408                                 uint64_t newtimeout;
1409
1410                                 ahd_print_path(ahd, scb);
1411                                 kprintf("Other SCB Timeout%s",
1412                                        (scb->flags & SCB_OTHERTCL_TIMEOUT) != 0
1413                                        ? " again\n" : "\n");
1414                                 scb->flags |= SCB_OTHERTCL_TIMEOUT;
1415                                 newtimeout =
1416                                     MAX(active_scb->io_ctx->ccb_h.timeout,
1417                                         scb->io_ctx->ccb_h.timeout);
1418                                 newtimeout *= hz;
1419                                 newtimeout /= 1000;
1420                                 ccbh = &scb->io_ctx->ccb_h;
1421                                 callout_reset(&scb->io_ctx->ccb_h.timeout_ch,
1422                                     newtimeout, ahd_timeout, scb);
1423                                 ahd_unpause(ahd);
1424                                 ahd_unlock();
1425                                 return;
1426                         } 
1427
1428                         /* It's us */
1429                         if ((scb->hscb->control & TARGET_SCB) != 0) {
1430
1431                                 /*
1432                                  * Send back any queued up transactions
1433                                  * and properly record the error condition.
1434                                  */
1435                                 ahd_abort_scbs(ahd, SCB_GET_TARGET(ahd, scb),
1436                                                SCB_GET_CHANNEL(ahd, scb),
1437                                                SCB_GET_LUN(scb),
1438                                                SCB_GET_TAG(scb),
1439                                                ROLE_TARGET,
1440                                                CAM_CMD_TIMEOUT);
1441
1442                                 /* Will clear us from the bus */
1443                                 ahd_restart(ahd);
1444                                 ahd_unlock();
1445                                 return;
1446                         }
1447
1448                         ahd_set_recoveryscb(ahd, active_scb);
1449                         ahd_outb(ahd, MSG_OUT, HOST_MSG);
1450                         ahd_outb(ahd, SCSISIGO, last_phase|ATNO);
1451                         ahd_print_path(ahd, active_scb);
1452                         kprintf("BDR message in message buffer\n");
1453                         active_scb->flags |= SCB_DEVICE_RESET;
1454                         callout_reset(&active_scb->io_ctx->ccb_h.timeout_ch,
1455                             2 * hz, ahd_timeout, active_scb);
1456                         ahd_unpause(ahd);
1457                 } else {
1458                         int      disconnected;
1459
1460                         /* XXX Shouldn't panic.  Just punt instead? */
1461                         if ((scb->hscb->control & TARGET_SCB) != 0)
1462                                 panic("Timed-out target SCB but bus idle");
1463
1464                         if (last_phase != P_BUSFREE
1465                          && (ahd_inb(ahd, SSTAT0) & TARGET) != 0) {
1466                                 /* XXX What happened to the SCB? */
1467                                 /* Hung target selection.  Goto busfree */
1468                                 kprintf("%s: Hung target selection\n",
1469                                        ahd_name(ahd));
1470                                 ahd_restart(ahd);
1471                                 ahd_unlock();
1472                                 return;
1473                         }
1474
1475                         if (ahd_search_qinfifo(ahd, target, channel, lun,
1476                                                SCB_GET_TAG(scb), ROLE_INITIATOR,
1477                                                /*status*/0, SEARCH_COUNT) > 0) {
1478                                 disconnected = FALSE;
1479                         } else {
1480                                 disconnected = TRUE;
1481                         }
1482
1483                         if (disconnected) {
1484
1485                                 ahd_set_recoveryscb(ahd, scb);
1486                                 /*
1487                                  * Actually re-queue this SCB in an attempt
1488                                  * to select the device before it reconnects.
1489                                  * In either case (selection or reselection),
1490                                  * we will now issue a target reset to the
1491                                  * timed-out device.
1492                                  *
1493                                  * Set the MK_MESSAGE control bit indicating
1494                                  * that we desire to send a message.  We
1495                                  * also set the disconnected flag since
1496                                  * in the paging case there is no guarantee
1497                                  * that our SCB control byte matches the
1498                                  * version on the card.  We don't want the
1499                                  * sequencer to abort the command thinking
1500                                  * an unsolicited reselection occurred.
1501                                  */
1502                                 scb->hscb->control |= MK_MESSAGE|DISCONNECTED;
1503                                 scb->flags |= SCB_DEVICE_RESET;
1504
1505                                 /*
1506                                  * The sequencer will never re-reference the
1507                                  * in-core SCB.  To make sure we are notified
1508                                  * during reslection, set the MK_MESSAGE flag
1509                                  * in the card's copy of the SCB.
1510                                  */
1511                                 ahd_set_scbptr(ahd, SCB_GET_TAG(scb));
1512                                 ahd_outb(ahd, SCB_CONTROL,
1513                                          ahd_inb(ahd, SCB_CONTROL)|MK_MESSAGE);
1514
1515                                 /*
1516                                  * Clear out any entries in the QINFIFO first
1517                                  * so we are the next SCB for this target
1518                                  * to run.
1519                                  */
1520                                 ahd_search_qinfifo(ahd,
1521                                                    SCB_GET_TARGET(ahd, scb),
1522                                                    channel, SCB_GET_LUN(scb),
1523                                                    SCB_LIST_NULL,
1524                                                    ROLE_INITIATOR,
1525                                                    CAM_REQUEUE_REQ,
1526                                                    SEARCH_COMPLETE);
1527                                 ahd_print_path(ahd, scb);
1528                                 kprintf("Queuing a BDR SCB\n");
1529                                 ahd_qinfifo_requeue_tail(ahd, scb);
1530                                 ahd_set_scbptr(ahd, saved_scbptr);
1531                                 callout_reset(&scb->io_ctx->ccb_h.timeout_ch,
1532                                     2 * hz, ahd_timeout, scb);
1533                                 ahd_unpause(ahd);
1534                         } else {
1535                                 /* Go "immediatly" to the bus reset */
1536                                 /* This shouldn't happen */
1537                                 ahd_set_recoveryscb(ahd, scb);
1538                                 ahd_print_path(ahd, scb);
1539                                 kprintf("SCB %d: Immediate reset.  "
1540                                         "Flags = 0x%x\n", SCB_GET_TAG(scb),
1541                                         scb->flags);
1542                                 goto bus_reset;
1543                         }
1544                 }
1545         }
1546         ahd_unlock();
1547 #endif
1548 }
1549
1550 static void
1551 ahd_abort_ccb(struct ahd_softc *ahd, struct cam_sim *sim, union ccb *ccb)
1552 {
1553         union ccb *abort_ccb;
1554
1555         abort_ccb = ccb->cab.abort_ccb;
1556         switch (abort_ccb->ccb_h.func_code) {
1557 #ifdef AHD_TARGET_MODE
1558         case XPT_ACCEPT_TARGET_IO:
1559         case XPT_IMMED_NOTIFY:
1560         case XPT_CONT_TARGET_IO:
1561         {
1562                 struct ahd_tmode_tstate *tstate;
1563                 struct ahd_tmode_lstate *lstate;
1564                 struct ccb_hdr_slist *list;
1565                 cam_status status;
1566
1567                 status = ahd_find_tmode_devs(ahd, sim, abort_ccb, &tstate,
1568                                              &lstate, TRUE);
1569
1570                 if (status != CAM_REQ_CMP) {
1571                         ccb->ccb_h.status = status;
1572                         break;
1573                 }
1574
1575                 if (abort_ccb->ccb_h.func_code == XPT_ACCEPT_TARGET_IO)
1576                         list = &lstate->accept_tios;
1577                 else if (abort_ccb->ccb_h.func_code == XPT_IMMED_NOTIFY)
1578                         list = &lstate->immed_notifies;
1579                 else
1580                         list = NULL;
1581
1582                 if (list != NULL) {
1583                         struct ccb_hdr *curelm;
1584                         int found;
1585
1586                         curelm = SLIST_FIRST(list);
1587                         found = 0;
1588                         if (curelm == &abort_ccb->ccb_h) {
1589                                 found = 1;
1590                                 SLIST_REMOVE_HEAD(list, sim_links.sle);
1591                         } else {
1592                                 while(curelm != NULL) {
1593                                         struct ccb_hdr *nextelm;
1594
1595                                         nextelm =
1596                                             SLIST_NEXT(curelm, sim_links.sle);
1597
1598                                         if (nextelm == &abort_ccb->ccb_h) {
1599                                                 found = 1;
1600                                                 SLIST_NEXT(curelm,
1601                                                            sim_links.sle) =
1602                                                     SLIST_NEXT(nextelm,
1603                                                                sim_links.sle);
1604                                                 break;
1605                                         }
1606                                         curelm = nextelm;
1607                                 }
1608                         }
1609
1610                         if (found) {
1611                                 abort_ccb->ccb_h.status = CAM_REQ_ABORTED;
1612                                 xpt_done(abort_ccb);
1613                                 ccb->ccb_h.status = CAM_REQ_CMP;
1614                         } else {
1615                                 xpt_print_path(abort_ccb->ccb_h.path);
1616                                 kprintf("Not found\n");
1617                                 ccb->ccb_h.status = CAM_PATH_INVALID;
1618                         }
1619                         break;
1620                 }
1621                 /* FALLTHROUGH */
1622         }
1623 #endif
1624         case XPT_SCSI_IO:
1625                 /* XXX Fully implement the hard ones */
1626                 ccb->ccb_h.status = CAM_UA_ABORT;
1627                 break;
1628         default:
1629                 ccb->ccb_h.status = CAM_REQ_INVALID;
1630                 break;
1631         }
1632         xpt_done(ccb);
1633 }
1634
1635 void
1636 ahd_send_async(struct ahd_softc *ahd, char channel, u_int target,
1637                 u_int lun, ac_code code, void *opt_arg)
1638 {
1639         struct  ccb_trans_settings cts;
1640         struct cam_path *path;
1641         void *arg;
1642         int error;
1643
1644         arg = NULL;
1645         error = ahd_create_path(ahd, channel, target, lun, &path);
1646
1647         if (error != CAM_REQ_CMP)
1648                 return;
1649
1650         switch (code) {
1651         case AC_TRANSFER_NEG:
1652         {
1653 #ifdef AHD_NEW_TRAN_SETTINGS
1654                 struct  ccb_trans_settings_scsi *scsi;
1655         
1656                 cts.type = CTS_TYPE_CURRENT_SETTINGS;
1657                 scsi = &cts.proto_specific.scsi;
1658 #else
1659                 cts.flags = CCB_TRANS_CURRENT_SETTINGS;
1660 #endif
1661                 cts.ccb_h.path = path;
1662                 cts.ccb_h.target_id = target;
1663                 cts.ccb_h.target_lun = lun;
1664                 ahd_get_tran_settings(ahd, ahd->our_id, channel, &cts);
1665                 arg = &cts;
1666 #ifdef AHD_NEW_TRAN_SETTINGS
1667                 scsi->valid &= ~CTS_SCSI_VALID_TQ;
1668                 scsi->flags &= ~CTS_SCSI_FLAGS_TAG_ENB;
1669 #else
1670                 cts.valid &= ~CCB_TRANS_TQ_VALID;
1671                 cts.flags &= ~CCB_TRANS_TAG_ENB;
1672 #endif
1673                 if (opt_arg == NULL)
1674                         break;
1675                 if (*((ahd_queue_alg *)opt_arg) == AHD_QUEUE_TAGGED)
1676 #ifdef AHD_NEW_TRAN_SETTINGS
1677                         scsi->flags |= ~CTS_SCSI_FLAGS_TAG_ENB;
1678                 scsi->valid |= CTS_SCSI_VALID_TQ;
1679 #else
1680                         cts.flags |= CCB_TRANS_TAG_ENB;
1681                 cts.valid |= CCB_TRANS_TQ_VALID;
1682 #endif
1683                 break;
1684         }
1685         case AC_SENT_BDR:
1686         case AC_BUS_RESET:
1687                 break;
1688         default:
1689                 panic("ahd_send_async: Unexpected async event");
1690         }
1691         xpt_async(code, path, arg);
1692         xpt_free_path(path);
1693 }
1694
1695 void
1696 ahd_platform_set_tags(struct ahd_softc *ahd,
1697                       struct ahd_devinfo *devinfo, int enable)
1698 {
1699 }
1700
1701 int
1702 ahd_platform_alloc(struct ahd_softc *ahd, void *platform_arg)
1703 {
1704         ahd->platform_data = kmalloc(sizeof(struct ahd_platform_data), M_DEVBUF,
1705                                     M_INTWAIT | M_ZERO);
1706         return (0);
1707 }
1708
1709 void
1710 ahd_platform_free(struct ahd_softc *ahd)
1711 {
1712         struct ahd_platform_data *pdata;
1713
1714         pdata = ahd->platform_data;
1715         if (pdata != NULL) {
1716                 if (pdata->regs[0] != NULL)
1717                         bus_release_resource(ahd->dev_softc,
1718                                              pdata->regs_res_type[0],
1719                                              pdata->regs_res_id[0],
1720                                              pdata->regs[0]);
1721
1722                 if (pdata->regs[1] != NULL)
1723                         bus_release_resource(ahd->dev_softc,
1724                                              pdata->regs_res_type[1],
1725                                              pdata->regs_res_id[1],
1726                                              pdata->regs[1]);
1727
1728                 if (pdata->irq != NULL)
1729                         bus_release_resource(ahd->dev_softc,
1730                                              pdata->irq_res_type,
1731                                              0, pdata->irq);
1732
1733                 if (pdata->sim_b != NULL) {
1734                         xpt_async(AC_LOST_DEVICE, pdata->path_b, NULL);
1735                         xpt_free_path(pdata->path_b);
1736                         xpt_bus_deregister(cam_sim_path(pdata->sim_b));
1737                         cam_sim_free(pdata->sim_b);
1738                 }
1739                 if (pdata->sim != NULL) {
1740                         xpt_async(AC_LOST_DEVICE, pdata->path, NULL);
1741                         xpt_free_path(pdata->path);
1742                         xpt_bus_deregister(cam_sim_path(pdata->sim));
1743                         cam_sim_free(pdata->sim);
1744                 }
1745                 if (pdata->eh != NULL)
1746                         EVENTHANDLER_DEREGISTER(shutdown_post_sync, pdata->eh);
1747                 kfree(ahd->platform_data, M_DEVBUF);
1748         }
1749 }
1750
1751 int
1752 ahd_softc_comp(struct ahd_softc *lahd, struct ahd_softc *rahd)
1753 {
1754         /* We don't sort softcs under FreeBSD so report equal always */
1755         return (0);
1756 }
1757
1758 int
1759 ahd_detach(device_t dev)
1760 {
1761         struct ahd_softc *ahd;
1762
1763         device_printf(dev, "detaching device\n");
1764         ahd = device_get_softc(dev);
1765         ahd = ahd_find_softc(ahd);
1766         if (ahd == NULL) {
1767                 device_printf(dev, "aic7xxx already detached\n");
1768                 return (ENOENT);
1769         }
1770         ahd_lock();
1771         ahd_intr_enable(ahd, FALSE);
1772         bus_teardown_intr(dev, ahd->platform_data->irq, ahd->platform_data->ih);
1773         ahd_unlock();
1774         ahd_free(ahd);
1775         return (0);
1776 }
1777
1778 #if UNUSED
1779 static void
1780 ahd_dump_targcmd(struct target_cmd *cmd)
1781 {
1782         uint8_t *byte;
1783         uint8_t *last_byte;
1784         int i;
1785
1786         byte = &cmd->initiator_channel;
1787         /* Debugging info for received commands */
1788         last_byte = &cmd[1].initiator_channel;
1789
1790         i = 0;
1791         while (byte < last_byte) {
1792                 if (i == 0)
1793                         kprintf("\t");
1794                 kprintf("%#x", *byte++);
1795                 i++;
1796                 if (i == 8) {
1797                         kprintf("\n");
1798                         i = 0;
1799                 } else {
1800                         kprintf(", ");
1801                 }
1802         }
1803 }
1804 #endif
1805
1806 static int
1807 ahd_modevent(module_t mod, int type, void *data)
1808 {
1809         /* XXX Deal with busy status on unload. */
1810         return 0;
1811 }
1812   
1813 static moduledata_t ahd_mod = {
1814         "ahd",
1815         ahd_modevent,
1816         NULL
1817 };
1818
1819 /********************************** DDB Hooks *********************************/
1820 #ifdef DDB
1821 static struct ahd_softc *ahd_ddb_softc;
1822 static int ahd_ddb_paused;
1823 static int ahd_ddb_paused_on_entry;
1824 DB_COMMAND(ahd_set_unit, ahd_ddb_set_unit)
1825 {
1826         struct ahd_softc *list_ahd;
1827
1828         ahd_ddb_softc = NULL;
1829         TAILQ_FOREACH(list_ahd, &ahd_tailq, links) {
1830                 if (list_ahd->unit == addr)
1831                         ahd_ddb_softc = list_ahd;
1832         }
1833         if (ahd_ddb_softc == NULL)
1834                 db_error("No matching softc found!\n");
1835 }
1836
1837 DB_COMMAND(ahd_pause, ahd_ddb_pause)
1838 {
1839         if (ahd_ddb_softc == NULL) {
1840                 db_error("Must set unit with ahd_set_unit first!\n");
1841                 return;
1842         }
1843         if (ahd_ddb_paused == 0) {
1844                 ahd_ddb_paused++;
1845                 if (ahd_is_paused(ahd_ddb_softc)) {
1846                         ahd_ddb_paused_on_entry++;
1847                         return;
1848                 }
1849                 ahd_pause(ahd_ddb_softc);
1850         }
1851 }
1852
1853 DB_COMMAND(ahd_unpause, ahd_ddb_unpause)
1854 {
1855         if (ahd_ddb_softc == NULL) {
1856                 db_error("Must set unit with ahd_set_unit first!\n");
1857                 return;
1858         }
1859         if (ahd_ddb_paused != 0) {
1860                 ahd_ddb_paused = 0;
1861                 if (ahd_ddb_paused_on_entry)
1862                         return;
1863                 ahd_unpause(ahd_ddb_softc);
1864         } else if (ahd_ddb_paused_on_entry != 0) {
1865                 /* Two unpauses to clear a paused on entry. */
1866                 ahd_ddb_paused_on_entry = 0;
1867                 ahd_unpause(ahd_ddb_softc);
1868         }
1869 }
1870
1871 DB_COMMAND(ahd_in, ahd_ddb_in)
1872 {
1873         int c;
1874         int size;
1875  
1876         if (ahd_ddb_softc == NULL) {
1877                 db_error("Must set unit with ahd_set_unit first!\n");
1878                 return;
1879         }
1880         if (have_addr == 0)
1881                 return;
1882
1883         size = 1;
1884         while ((c = *modif++) != '\0') {
1885                 switch (c) {
1886                 case 'b':
1887                         size = 1;
1888                         break;
1889                 case 'w':
1890                         size = 2;
1891                         break;
1892                 case 'l':
1893                         size = 4;
1894                 break;
1895                 }
1896         }
1897
1898         if (count <= 0)
1899                 count = 1;
1900         while (--count >= 0) {
1901                 db_printf("%04lx (M)%x: \t", (u_long)addr,
1902                           ahd_inb(ahd_ddb_softc, MODE_PTR));
1903                 switch (size) {
1904                 case 1:
1905                         db_printf("%02x\n", ahd_inb(ahd_ddb_softc, addr));
1906                         break;
1907                 case 2:
1908                         db_printf("%04x\n", ahd_inw(ahd_ddb_softc, addr));
1909                         break;
1910                 case 4:
1911                         db_printf("%08x\n", ahd_inl(ahd_ddb_softc, addr));
1912                         break;
1913                 }
1914         }
1915 }
1916
1917 DB_SET(ahd_out, ahd_ddb_out, db_cmd_set, CS_MORE, NULL)
1918 {
1919         db_expr_t old_value;
1920         db_expr_t new_value;
1921         int       size;
1922  
1923         if (ahd_ddb_softc == NULL) {
1924                 db_error("Must set unit with ahd_set_unit first!\n");
1925                 return;
1926         }
1927
1928         switch (modif[0]) {
1929         case '\0':
1930         case 'b':
1931                 size = 1;
1932                 break;
1933         case 'h':
1934                 size = 2;
1935                 break;
1936         case 'l':
1937                 size = 4;
1938                 break;
1939         default:
1940                 db_error("Unknown size\n");
1941                 return;
1942         }
1943  
1944         while (db_expression(&new_value)) {
1945                 switch (size) {
1946                 default:
1947                 case 1:
1948                         old_value = ahd_inb(ahd_ddb_softc, addr);
1949                         ahd_outb(ahd_ddb_softc, addr, new_value);
1950                         break;
1951                 case 2:
1952                         old_value = ahd_inw(ahd_ddb_softc, addr);
1953                         ahd_outw(ahd_ddb_softc, addr, new_value);
1954                         break;
1955                 case 4:
1956                         old_value = ahd_inl(ahd_ddb_softc, addr);
1957                         ahd_outl(ahd_ddb_softc, addr, new_value);
1958                         break;
1959                 }
1960                 db_printf("%04lx (M)%x: \t0x%lx\t=\t0x%lx",
1961                           (u_long)addr, ahd_inb(ahd_ddb_softc, MODE_PTR),
1962                           (u_long)old_value, (u_long)new_value);
1963                 addr += size;
1964         }
1965         db_skip_to_eol();
1966 }
1967
1968 #endif
1969
1970
1971 DECLARE_MODULE(ahd, ahd_mod, SI_SUB_DRIVERS, SI_ORDER_MIDDLE);
1972 MODULE_DEPEND(ahd, cam, 1, 1, 1);
1973 MODULE_VERSION(ahd, 1);