-Wundef fixes.
[dragonfly.git] / sys / dev / disk / aic7xxx / aic7xxx_osm.c
1 /*
2  * Bus independent FreeBSD shim for the aic7xxx based Adaptec SCSI controllers
3  *
4  * Copyright (c) 1994-2001 Justin T. Gibbs.
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions, and the following disclaimer,
12  *    without modification.
13  * 2. The name of the author may not be used to endorse or promote products
14  *    derived from this software without specific prior written permission.
15  *
16  * Alternatively, this software may be distributed under the terms of the
17  * GNU Public License ("GPL").
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
20  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22  * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
23  * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29  * SUCH DAMAGE.
30  *
31  * $Id: //depot/aic7xxx/freebsd/dev/aic7xxx/aic7xxx_osm.c#20 $
32  *
33  * $FreeBSD: src/sys/dev/aic7xxx/aic7xxx_osm.c,v 1.44 2005/12/04 02:12:40 ru Exp $
34  * $DragonFly: src/sys/dev/disk/aic7xxx/aic7xxx_osm.c,v 1.18 2007/07/07 01:06:07 pavalos Exp $
35  */
36
37 #include "aic7xxx_osm.h"
38 #include "aic7xxx_inline.h"
39
40 #include <sys/kthread.h>
41
42 #ifndef AHC_TMODE_ENABLE
43 #define AHC_TMODE_ENABLE 0
44 #endif
45
46 #include "aic_osm_lib.c"
47
48 #define ccb_scb_ptr spriv_ptr0
49
50 devclass_t ahc_devclass;
51
52 #if 0
53 static void     ahc_dump_targcmd(struct target_cmd *cmd);
54 #endif
55 static int      ahc_modevent(module_t mod, int type, void *data);
56 static void     ahc_action(struct cam_sim *sim, union ccb *ccb);
57 static void     ahc_get_tran_settings(struct ahc_softc *ahc,
58                                       int our_id, char channel,
59                                       struct ccb_trans_settings *cts);
60 static void     ahc_async(void *callback_arg, uint32_t code,
61                           struct cam_path *path, void *arg);
62 static void     ahc_execute_scb(void *arg, bus_dma_segment_t *dm_segs,
63                                 int nsegments, int error);
64 static void     ahc_poll(struct cam_sim *sim);
65 static void     ahc_setup_data(struct ahc_softc *ahc, struct cam_sim *sim,
66                                struct ccb_scsiio *csio, struct scb *scb);
67 static void     ahc_abort_ccb(struct ahc_softc *ahc, struct cam_sim *sim,
68                               union ccb *ccb);
69 static int      ahc_create_path(struct ahc_softc *ahc,
70                                 char channel, u_int target, u_int lun,
71                                 struct cam_path **path);
72
73
74 static int
75 ahc_create_path(struct ahc_softc *ahc, char channel, u_int target,
76                 u_int lun, struct cam_path **path)
77 {
78         path_id_t path_id;
79
80         if (channel == 'B')
81                 path_id = cam_sim_path(ahc->platform_data->sim_b);
82         else 
83                 path_id = cam_sim_path(ahc->platform_data->sim);
84
85         return (xpt_create_path(path, /*periph*/NULL,
86                                 path_id, target, lun));
87 }
88
89 int
90 ahc_map_int(struct ahc_softc *ahc)
91 {
92         int error;
93         int zero;
94         int shareable;
95
96         zero = 0;
97         shareable = (ahc->flags & AHC_EDGE_INTERRUPT) ? 0: RF_SHAREABLE;
98         ahc->platform_data->irq =
99             bus_alloc_resource_any(ahc->dev_softc, SYS_RES_IRQ, &zero,
100                                    RF_ACTIVE | shareable);
101         if (ahc->platform_data->irq == NULL) {
102                 device_printf(ahc->dev_softc,
103                               "bus_alloc_resource() failed to allocate IRQ\n");
104                 return (ENOMEM);
105         }
106         ahc->platform_data->irq_res_type = SYS_RES_IRQ;
107
108         /* Hook up our interrupt handler */
109         error = bus_setup_intr(ahc->dev_softc, ahc->platform_data->irq,
110                                0, ahc_platform_intr, ahc,
111                                &ahc->platform_data->ih, NULL);
112
113         if (error != 0)
114                 device_printf(ahc->dev_softc, "bus_setup_intr() failed: %d\n",
115                               error);
116         return (error);
117 }
118
119 int
120 aic7770_map_registers(struct ahc_softc *ahc, u_int unused_ioport_arg)
121 {
122         struct  resource *regs;
123         int     rid;
124
125         rid = 0;
126         regs = bus_alloc_resource_any(ahc->dev_softc, SYS_RES_IOPORT, &rid,
127                                       RF_ACTIVE);
128         if (regs == NULL) {
129                 device_printf(ahc->dev_softc, "Unable to map I/O space?!\n");
130                 return ENOMEM;
131         }
132         ahc->platform_data->regs_res_type = SYS_RES_IOPORT;
133         ahc->platform_data->regs_res_id = rid,
134         ahc->platform_data->regs = regs;
135         ahc->tag = rman_get_bustag(regs);
136         ahc->bsh = rman_get_bushandle(regs);
137         return (0);
138 }
139
140 /*
141  * Attach all the sub-devices we can find
142  */
143 int
144 ahc_attach(struct ahc_softc *ahc)
145 {
146         char   ahc_info[256];
147         struct ccb_setasync csa;
148         int bus_id;
149         int bus_id2;
150         struct cam_sim *sim;
151         struct cam_sim *sim2;
152         struct cam_path *path;
153         struct cam_path *path2;
154         int count;
155
156         count = 0;
157         sim = NULL;
158         sim2 = NULL;
159
160         /*
161          * Create a thread to perform all recovery.
162          */
163         if (ahc_spawn_recovery_thread(ahc) != 0)
164                 goto fail;
165
166         ahc_controller_info(ahc, ahc_info);
167         kprintf("%s\n", ahc_info);
168         ahc_lock();
169
170         /*
171          * Attach secondary channel first if the user has
172          * declared it the primary channel.
173          */
174         if ((ahc->features & AHC_TWIN) != 0
175          && (ahc->flags & AHC_PRIMARY_CHANNEL) != 0) {
176                 bus_id = 1;
177                 bus_id2 = 0;
178         } else {
179                 bus_id = 0;
180                 bus_id2 = 1;
181         }
182
183         /*
184          * Construct our first channel SIM entry
185          */
186         sim = cam_sim_alloc(ahc_action, ahc_poll, "ahc", ahc,
187                             device_get_unit(ahc->dev_softc),
188                             1, AHC_MAX_QUEUE, NULL);
189         if (sim == NULL)
190                 goto fail;
191
192         if (xpt_bus_register(sim, bus_id) != CAM_SUCCESS) {
193                 cam_sim_free(sim);
194                 sim = NULL;
195                 goto fail;
196         }
197         
198         if (xpt_create_path(&path, /*periph*/NULL,
199                             cam_sim_path(sim), CAM_TARGET_WILDCARD,
200                             CAM_LUN_WILDCARD) != CAM_REQ_CMP) {
201                 xpt_bus_deregister(cam_sim_path(sim));
202                 cam_sim_free(sim);
203                 sim = NULL;
204                 goto fail;
205         }
206                 
207         xpt_setup_ccb(&csa.ccb_h, path, /*priority*/5);
208         csa.ccb_h.func_code = XPT_SASYNC_CB;
209         csa.event_enable = AC_LOST_DEVICE;
210         csa.callback = ahc_async;
211         csa.callback_arg = sim;
212         xpt_action((union ccb *)&csa);
213         count++;
214
215         if (ahc->features & AHC_TWIN) {
216                 sim2 = cam_sim_alloc(ahc_action, ahc_poll, "ahc",
217                                     ahc, device_get_unit(ahc->dev_softc), 1,
218                                     AHC_MAX_QUEUE, NULL);
219
220                 if (sim2 == NULL) {
221                         kprintf("ahc_attach: Unable to attach second "
222                                "bus due to resource shortage");
223                         goto fail;
224                 }
225                 
226                 if (xpt_bus_register(sim2, bus_id2) != CAM_SUCCESS) {
227                         kprintf("ahc_attach: Unable to attach second "
228                                "bus due to resource shortage");
229                         /*
230                          * We do not want to destroy the device queue
231                          * because the first bus is using it.
232                          */
233                         cam_sim_free(sim2);
234                         goto fail;
235                 }
236
237                 if (xpt_create_path(&path2, /*periph*/NULL,
238                                     cam_sim_path(sim2),
239                                     CAM_TARGET_WILDCARD,
240                                     CAM_LUN_WILDCARD) != CAM_REQ_CMP) {
241                         xpt_bus_deregister(cam_sim_path(sim2));
242                         cam_sim_free(sim2);
243                         sim2 = NULL;
244                         goto fail;
245                 }
246                 xpt_setup_ccb(&csa.ccb_h, path2, /*priority*/5);
247                 csa.ccb_h.func_code = XPT_SASYNC_CB;
248                 csa.event_enable = AC_LOST_DEVICE;
249                 csa.callback = ahc_async;
250                 csa.callback_arg = sim2;
251                 xpt_action((union ccb *)&csa);
252                 count++;
253         }
254
255 fail:
256         if ((ahc->features & AHC_TWIN) != 0
257          && (ahc->flags & AHC_PRIMARY_CHANNEL) != 0) {
258                 ahc->platform_data->sim_b = sim;
259                 ahc->platform_data->path_b = path;
260                 ahc->platform_data->sim = sim2;
261                 ahc->platform_data->path = path2;
262         } else {
263                 ahc->platform_data->sim = sim;
264                 ahc->platform_data->path = path;
265                 ahc->platform_data->sim_b = sim2;
266                 ahc->platform_data->path_b = path2;
267         }
268
269         if (count != 0) {
270                 /* We have to wait until after any system dumps... */
271                 ahc->platform_data->eh =
272                     EVENTHANDLER_REGISTER(shutdown_post_sync, ahc_shutdown,
273                                           ahc, SHUTDOWN_PRI_DEFAULT);
274                 ahc_intr_enable(ahc, TRUE);
275         }
276
277         ahc_unlock();
278         return (count);
279 }
280
281 /*
282  * Catch an interrupt from the adapter
283  */
284 void
285 ahc_platform_intr(void *arg)
286 {
287         struct  ahc_softc *ahc;
288
289         ahc = (struct ahc_softc *)arg; 
290         ahc_intr(ahc);
291 }
292
293 /*
294  * We have an scb which has been processed by the
295  * adaptor, now we look to see how the operation
296  * went.
297  */
298 void
299 ahc_done(struct ahc_softc *ahc, struct scb *scb)
300 {
301         union ccb *ccb;
302
303         CAM_DEBUG(scb->io_ctx->ccb_h.path, CAM_DEBUG_TRACE,
304                   ("ahc_done - scb %d\n", scb->hscb->tag));
305
306         ccb = scb->io_ctx;
307         LIST_REMOVE(scb, pending_links);
308         if ((scb->flags & SCB_TIMEDOUT) != 0)
309                 LIST_REMOVE(scb, timedout_links);
310         if ((scb->flags & SCB_UNTAGGEDQ) != 0) {
311                 struct scb_tailq *untagged_q;
312                 int target_offset;
313
314                 target_offset = SCB_GET_TARGET_OFFSET(ahc, scb);
315                 untagged_q = &ahc->untagged_queues[target_offset];
316                 TAILQ_REMOVE(untagged_q, scb, links.tqe);
317                 scb->flags &= ~SCB_UNTAGGEDQ;
318                 ahc_run_untagged_queue(ahc, untagged_q);
319         }
320
321         callout_stop(&ccb->ccb_h.timeout_ch);
322
323         if ((ccb->ccb_h.flags & CAM_DIR_MASK) != CAM_DIR_NONE) {
324                 bus_dmasync_op_t op;
325
326                 if ((ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_IN)
327                         op = BUS_DMASYNC_POSTREAD;
328                 else
329                         op = BUS_DMASYNC_POSTWRITE;
330                 bus_dmamap_sync(ahc->buffer_dmat, scb->dmamap, op);
331                 bus_dmamap_unload(ahc->buffer_dmat, scb->dmamap);
332         }
333
334         if (ccb->ccb_h.func_code == XPT_CONT_TARGET_IO) {
335                 struct cam_path *ccb_path;
336
337                 /*
338                  * If we have finally disconnected, clean up our
339                  * pending device state.
340                  * XXX - There may be error states that cause where
341                  *       we will remain connected.
342                  */
343                 ccb_path = ccb->ccb_h.path;
344                 if (ahc->pending_device != NULL
345                  && xpt_path_comp(ahc->pending_device->path, ccb_path) == 0) {
346
347                         if ((ccb->ccb_h.flags & CAM_SEND_STATUS) != 0) {
348                                 ahc->pending_device = NULL;
349                         } else {
350                                 if (bootverbose) {
351                                         xpt_print_path(ccb->ccb_h.path);
352                                         kprintf("Still connected\n");
353                                 }
354                                 aic_freeze_ccb(ccb);
355                         }
356                 }
357
358                 if (aic_get_transaction_status(scb) == CAM_REQ_INPROG)
359                         ccb->ccb_h.status |= CAM_REQ_CMP;
360                 ccb->ccb_h.status &= ~CAM_SIM_QUEUED;
361                 ahc_free_scb(ahc, scb);
362                 xpt_done(ccb);
363                 return;
364         }
365
366         /*
367          * If the recovery SCB completes, we have to be
368          * out of our timeout.
369          */
370         if ((scb->flags & SCB_RECOVERY_SCB) != 0) {
371                 struct  scb *list_scb;
372
373                 ahc->scb_data->recovery_scbs--;
374
375                 if (aic_get_transaction_status(scb) == CAM_BDR_SENT
376                  || aic_get_transaction_status(scb) == CAM_REQ_ABORTED)
377                         aic_set_transaction_status(scb, CAM_CMD_TIMEOUT);
378
379                 if (ahc->scb_data->recovery_scbs == 0) {
380                         /*
381                          * All recovery actions have completed successfully,
382                          * so reinstate the timeouts for all other pending
383                          * commands.
384                          */
385                          LIST_FOREACH(list_scb, &ahc->pending_scbs,
386                                       pending_links) {
387
388                                 aic_scb_timer_reset(list_scb,
389                                                     aic_get_timeout(scb));
390                         }
391
392                         ahc_print_path(ahc, scb);
393                         kprintf("no longer in timeout, status = %x\n",
394                                ccb->ccb_h.status);
395                 }
396         }
397
398         /* Don't clobber any existing error state */
399         if (aic_get_transaction_status(scb) == CAM_REQ_INPROG) {
400                 ccb->ccb_h.status |= CAM_REQ_CMP;
401         } else if ((scb->flags & SCB_SENSE) != 0) {
402                 /*
403                  * We performed autosense retrieval.
404                  *
405                  * Zero any sense not transferred by the
406                  * device.  The SCSI spec mandates that any
407                  * untransfered data should be assumed to be
408                  * zero.  Complete the 'bounce' of sense information
409                  * through buffers accessible via bus-space by
410                  * copying it into the clients csio.
411                  */
412                 memset(&ccb->csio.sense_data, 0, sizeof(ccb->csio.sense_data));
413                 memcpy(&ccb->csio.sense_data,
414                        ahc_get_sense_buf(ahc, scb),
415                        (aic_le32toh(scb->sg_list->len) & AHC_SG_LEN_MASK)
416                        - ccb->csio.sense_resid);
417                 scb->io_ctx->ccb_h.status |= CAM_AUTOSNS_VALID;
418         }
419         ccb->ccb_h.status &= ~CAM_SIM_QUEUED;
420         ahc_free_scb(ahc, scb);
421         xpt_done(ccb);
422 }
423
424 static void
425 ahc_action(struct cam_sim *sim, union ccb *ccb)
426 {
427         struct  ahc_softc *ahc;
428         struct  ahc_tmode_lstate *lstate;
429         u_int   target_id;
430         u_int   our_id;
431
432         CAM_DEBUG(ccb->ccb_h.path, CAM_DEBUG_TRACE, ("ahc_action\n"));
433         
434         ahc = (struct ahc_softc *)cam_sim_softc(sim);
435
436         target_id = ccb->ccb_h.target_id;
437         our_id = SIM_SCSI_ID(ahc, sim);
438         
439         switch (ccb->ccb_h.func_code) {
440         /* Common cases first */
441         case XPT_ACCEPT_TARGET_IO:      /* Accept Host Target Mode CDB */
442         case XPT_CONT_TARGET_IO:/* Continue Host Target I/O Connection*/
443         {
444                 struct     ahc_tmode_tstate *tstate;
445                 cam_status status;
446
447                 status = ahc_find_tmode_devs(ahc, sim, ccb, &tstate,
448                                              &lstate, TRUE);
449
450                 if (status != CAM_REQ_CMP) {
451                         if (ccb->ccb_h.func_code == XPT_CONT_TARGET_IO) {
452                                 /* Response from the black hole device */
453                                 tstate = NULL;
454                                 lstate = ahc->black_hole;
455                         } else {
456                                 ccb->ccb_h.status = status;
457                                 xpt_done(ccb);
458                                 break;
459                         }
460                 }
461                 if (ccb->ccb_h.func_code == XPT_ACCEPT_TARGET_IO) {
462
463                         ahc_lock();
464                         SLIST_INSERT_HEAD(&lstate->accept_tios, &ccb->ccb_h,
465                                           sim_links.sle);
466                         ccb->ccb_h.status = CAM_REQ_INPROG;
467                         if ((ahc->flags & AHC_TQINFIFO_BLOCKED) != 0)
468                                 ahc_run_tqinfifo(ahc, /*paused*/FALSE);
469                         ahc_unlock();
470                         break;
471                 }
472
473                 /*
474                  * The target_id represents the target we attempt to
475                  * select.  In target mode, this is the initiator of
476                  * the original command.
477                  */
478                 our_id = target_id;
479                 target_id = ccb->csio.init_id;
480                 /* FALLTHROUGH */
481         }
482         case XPT_SCSI_IO:       /* Execute the requested I/O operation */
483         case XPT_RESET_DEV:     /* Bus Device Reset the specified SCSI device */
484         {
485                 struct  scb *scb;
486                 struct  hardware_scb *hscb;     
487
488                 if ((ahc->flags & AHC_INITIATORROLE) == 0
489                  && (ccb->ccb_h.func_code == XPT_SCSI_IO
490                   || ccb->ccb_h.func_code == XPT_RESET_DEV)) {
491                         ccb->ccb_h.status = CAM_PROVIDE_FAIL;
492                         xpt_done(ccb);
493                         return;
494                 }
495
496                 /*
497                  * get an scb to use.
498                  */
499                 ahc_lock();
500                 if ((scb = ahc_get_scb(ahc)) == NULL) {
501         
502                         xpt_freeze_simq(sim, /*count*/1);
503                         ahc->flags |= AHC_RESOURCE_SHORTAGE;
504                         ahc_unlock();
505                         ccb->ccb_h.status = CAM_REQUEUE_REQ;
506                         xpt_done(ccb);
507                         return;
508                 }
509                 ahc_unlock();
510                 
511                 hscb = scb->hscb;
512                 
513                 CAM_DEBUG(ccb->ccb_h.path, CAM_DEBUG_SUBTRACE,
514                           ("start scb(%p)\n", scb));
515                 scb->io_ctx = ccb;
516                 /*
517                  * So we can find the SCB when an abort is requested
518                  */
519                 ccb->ccb_h.ccb_scb_ptr = scb;
520
521                 /*
522                  * Put all the arguments for the xfer in the scb
523                  */
524                 hscb->control = 0;
525                 hscb->scsiid = BUILD_SCSIID(ahc, sim, target_id, our_id);
526                 hscb->lun = ccb->ccb_h.target_lun;
527                 if (ccb->ccb_h.func_code == XPT_RESET_DEV) {
528                         hscb->cdb_len = 0;
529                         scb->flags |= SCB_DEVICE_RESET;
530                         hscb->control |= MK_MESSAGE;
531                         ahc_execute_scb(scb, NULL, 0, 0);
532                 } else {
533                         if (ccb->ccb_h.func_code == XPT_CONT_TARGET_IO) {
534                                 struct target_data *tdata;
535
536                                 tdata = &hscb->shared_data.tdata;
537                                 if (ahc->pending_device == lstate)
538                                         scb->flags |= SCB_TARGET_IMMEDIATE;
539                                 hscb->control |= TARGET_SCB;
540                                 scb->flags |= SCB_TARGET_SCB;
541                                 tdata->target_phases = 0;
542                                 if ((ccb->ccb_h.flags & CAM_SEND_STATUS) != 0) {
543                                         tdata->target_phases |= SPHASE_PENDING;
544                                         tdata->scsi_status =
545                                             ccb->csio.scsi_status;
546                                 }
547                                 if (ccb->ccb_h.flags & CAM_DIS_DISCONNECT)
548                                         tdata->target_phases |= NO_DISCONNECT;
549
550                                 tdata->initiator_tag = ccb->csio.tag_id;
551                         }
552                         if (ccb->ccb_h.flags & CAM_TAG_ACTION_VALID)
553                                 hscb->control |= ccb->csio.tag_action;
554                         
555                         ahc_setup_data(ahc, sim, &ccb->csio, scb);
556                 }
557                 break;
558         }
559         case XPT_NOTIFY_ACK:
560         case XPT_IMMED_NOTIFY:
561         {
562                 struct     ahc_tmode_tstate *tstate;
563                 struct     ahc_tmode_lstate *lstate;
564                 cam_status status;
565
566                 status = ahc_find_tmode_devs(ahc, sim, ccb, &tstate,
567                                              &lstate, TRUE);
568
569                 if (status != CAM_REQ_CMP) {
570                         ccb->ccb_h.status = status;
571                         xpt_done(ccb);
572                         break;
573                 }
574                 SLIST_INSERT_HEAD(&lstate->immed_notifies, &ccb->ccb_h,
575                                   sim_links.sle);
576                 ccb->ccb_h.status = CAM_REQ_INPROG;
577                 ahc_send_lstate_events(ahc, lstate);
578                 break;
579         }
580         case XPT_EN_LUN:                /* Enable LUN as a target */
581                 ahc_handle_en_lun(ahc, sim, ccb);
582                 xpt_done(ccb);
583                 break;
584         case XPT_ABORT:                 /* Abort the specified CCB */
585         {
586                 ahc_abort_ccb(ahc, sim, ccb);
587                 break;
588         }
589         case XPT_SET_TRAN_SETTINGS:
590         {
591 #ifdef AHC_NEW_TRAN_SETTINGS
592                 struct  ahc_devinfo devinfo;
593                 struct  ccb_trans_settings *cts;
594                 struct  ccb_trans_settings_scsi *scsi;
595                 struct  ccb_trans_settings_spi *spi;
596                 struct  ahc_initiator_tinfo *tinfo;
597                 struct  ahc_tmode_tstate *tstate;
598                 uint16_t *discenable;
599                 uint16_t *tagenable;
600                 u_int   update_type;
601
602                 cts = &ccb->cts;
603                 scsi = &cts->proto_specific.scsi;
604                 spi = &cts->xport_specific.spi;
605                 ahc_compile_devinfo(&devinfo, SIM_SCSI_ID(ahc, sim),
606                                     cts->ccb_h.target_id,
607                                     cts->ccb_h.target_lun,
608                                     SIM_CHANNEL(ahc, sim),
609                                     ROLE_UNKNOWN);
610                 tinfo = ahc_fetch_transinfo(ahc, devinfo.channel,
611                                             devinfo.our_scsiid,
612                                             devinfo.target, &tstate);
613                 update_type = 0;
614                 if (cts->type == CTS_TYPE_CURRENT_SETTINGS) {
615                         update_type |= AHC_TRANS_GOAL;
616                         discenable = &tstate->discenable;
617                         tagenable = &tstate->tagenable;
618                         tinfo->curr.protocol_version =
619                             cts->protocol_version;
620                         tinfo->curr.transport_version =
621                             cts->transport_version;
622                         tinfo->goal.protocol_version =
623                             cts->protocol_version;
624                         tinfo->goal.transport_version =
625                             cts->transport_version;
626                 } else if (cts->type == CTS_TYPE_USER_SETTINGS) {
627                         update_type |= AHC_TRANS_USER;
628                         discenable = &ahc->user_discenable;
629                         tagenable = &ahc->user_tagenable;
630                         tinfo->user.protocol_version =
631                             cts->protocol_version;
632                         tinfo->user.transport_version =
633                             cts->transport_version;
634                 } else {
635                         ccb->ccb_h.status = CAM_REQ_INVALID;
636                         xpt_done(ccb);
637                         break;
638                 }
639                 
640                 ahc_lock();
641
642                 if ((spi->valid & CTS_SPI_VALID_DISC) != 0) {
643                         if ((spi->flags & CTS_SPI_FLAGS_DISC_ENB) != 0)
644                                 *discenable |= devinfo.target_mask;
645                         else
646                                 *discenable &= ~devinfo.target_mask;
647                 }
648                 
649                 if ((scsi->valid & CTS_SCSI_VALID_TQ) != 0) {
650                         if ((scsi->flags & CTS_SCSI_FLAGS_TAG_ENB) != 0)
651                                 *tagenable |= devinfo.target_mask;
652                         else
653                                 *tagenable &= ~devinfo.target_mask;
654                 }       
655
656                 if ((spi->valid & CTS_SPI_VALID_BUS_WIDTH) != 0) {
657                         ahc_validate_width(ahc, /*tinfo limit*/NULL,
658                                            &spi->bus_width, ROLE_UNKNOWN);
659                         ahc_set_width(ahc, &devinfo, spi->bus_width,
660                                       update_type, /*paused*/FALSE);
661                 }
662
663                 if ((spi->valid & CTS_SPI_VALID_PPR_OPTIONS) == 0) {
664                         if (update_type == AHC_TRANS_USER)
665                                 spi->ppr_options = tinfo->user.ppr_options;
666                         else
667                                 spi->ppr_options = tinfo->goal.ppr_options;
668                 }
669
670                 if ((spi->valid & CTS_SPI_VALID_SYNC_OFFSET) == 0) {
671                         if (update_type == AHC_TRANS_USER)
672                                 spi->sync_offset = tinfo->user.offset;
673                         else
674                                 spi->sync_offset = tinfo->goal.offset;
675                 }
676
677                 if ((spi->valid & CTS_SPI_VALID_SYNC_RATE) == 0) {
678                         if (update_type == AHC_TRANS_USER)
679                                 spi->sync_period = tinfo->user.period;
680                         else
681                                 spi->sync_period = tinfo->goal.period;
682                 }
683
684                 if (((spi->valid & CTS_SPI_VALID_SYNC_RATE) != 0)
685                  || ((spi->valid & CTS_SPI_VALID_SYNC_OFFSET) != 0)) {
686                         struct ahc_syncrate *syncrate;
687                         u_int maxsync;
688
689                         if ((ahc->features & AHC_ULTRA2) != 0)
690                                 maxsync = AHC_SYNCRATE_DT;
691                         else if ((ahc->features & AHC_ULTRA) != 0)
692                                 maxsync = AHC_SYNCRATE_ULTRA;
693                         else
694                                 maxsync = AHC_SYNCRATE_FAST;
695
696                         if (spi->bus_width != MSG_EXT_WDTR_BUS_16_BIT)
697                                 spi->ppr_options &= ~MSG_EXT_PPR_DT_REQ;
698
699                         syncrate = ahc_find_syncrate(ahc, &spi->sync_period,
700                                                      &spi->ppr_options,
701                                                      maxsync);
702                         ahc_validate_offset(ahc, /*tinfo limit*/NULL,
703                                             syncrate, &spi->sync_offset,
704                                             spi->bus_width, ROLE_UNKNOWN);
705
706                         /* We use a period of 0 to represent async */
707                         if (spi->sync_offset == 0) {
708                                 spi->sync_period = 0;
709                                 spi->ppr_options = 0;
710                         }
711
712                         ahc_set_syncrate(ahc, &devinfo, syncrate,
713                                          spi->sync_period, spi->sync_offset,
714                                          spi->ppr_options, update_type,
715                                          /*paused*/FALSE);
716                 }
717                 ahc_unlock();
718                 ccb->ccb_h.status = CAM_REQ_CMP;
719                 xpt_done(ccb);
720 #else
721                 struct    ahc_devinfo devinfo;
722                 struct    ccb_trans_settings *cts;
723                 struct    ahc_initiator_tinfo *tinfo;
724                 struct    ahc_tmode_tstate *tstate;
725                 uint16_t *discenable;
726                 uint16_t *tagenable;
727                 u_int     update_type;
728
729                 cts = &ccb->cts;
730                 ahc_compile_devinfo(&devinfo, SIM_SCSI_ID(ahc, sim),
731                                     cts->ccb_h.target_id,
732                                     cts->ccb_h.target_lun,
733                                     SIM_CHANNEL(ahc, sim),
734                                     ROLE_UNKNOWN);
735                 tinfo = ahc_fetch_transinfo(ahc, devinfo.channel,
736                                             devinfo.our_scsiid,
737                                             devinfo.target, &tstate);
738                 update_type = 0;
739                 if ((cts->flags & CCB_TRANS_CURRENT_SETTINGS) != 0) {
740                         update_type |= AHC_TRANS_GOAL;
741                         discenable = &tstate->discenable;
742                         tagenable = &tstate->tagenable;
743                 } else if ((cts->flags & CCB_TRANS_USER_SETTINGS) != 0) {
744                         update_type |= AHC_TRANS_USER;
745                         discenable = &ahc->user_discenable;
746                         tagenable = &ahc->user_tagenable;
747                 } else {
748                         ccb->ccb_h.status = CAM_REQ_INVALID;
749                         xpt_done(ccb);
750                         break;
751                 }
752                 
753                 ahc_lock();
754
755                 if ((cts->valid & CCB_TRANS_DISC_VALID) != 0) {
756                         if ((cts->flags & CCB_TRANS_DISC_ENB) != 0)
757                                 *discenable |= devinfo.target_mask;
758                         else
759                                 *discenable &= ~devinfo.target_mask;
760                 }
761                 
762                 if ((cts->valid & CCB_TRANS_TQ_VALID) != 0) {
763                         if ((cts->flags & CCB_TRANS_TAG_ENB) != 0)
764                                 *tagenable |= devinfo.target_mask;
765                         else
766                                 *tagenable &= ~devinfo.target_mask;
767                 }       
768
769                 if ((cts->valid & CCB_TRANS_BUS_WIDTH_VALID) != 0) {
770                         ahc_validate_width(ahc, /*tinfo limit*/NULL,
771                                            &cts->bus_width, ROLE_UNKNOWN);
772                         ahc_set_width(ahc, &devinfo, cts->bus_width,
773                                       update_type, /*paused*/FALSE);
774                 }
775
776                 if ((cts->valid & CCB_TRANS_SYNC_OFFSET_VALID) == 0) {
777                         if (update_type == AHC_TRANS_USER)
778                                 cts->sync_offset = tinfo->user.offset;
779                         else
780                                 cts->sync_offset = tinfo->goal.offset;
781                 }
782
783                 if ((cts->valid & CCB_TRANS_SYNC_RATE_VALID) == 0) {
784                         if (update_type == AHC_TRANS_USER)
785                                 cts->sync_period = tinfo->user.period;
786                         else
787                                 cts->sync_period = tinfo->goal.period;
788                 }
789
790                 if (((cts->valid & CCB_TRANS_SYNC_RATE_VALID) != 0)
791                  || ((cts->valid & CCB_TRANS_SYNC_OFFSET_VALID) != 0)) {
792                         struct ahc_syncrate *syncrate;
793                         u_int ppr_options;
794                         u_int maxsync;
795
796                         if ((ahc->features & AHC_ULTRA2) != 0)
797                                 maxsync = AHC_SYNCRATE_DT;
798                         else if ((ahc->features & AHC_ULTRA) != 0)
799                                 maxsync = AHC_SYNCRATE_ULTRA;
800                         else
801                                 maxsync = AHC_SYNCRATE_FAST;
802
803                         ppr_options = 0;
804                         if (cts->sync_period <= 9
805                          && cts->bus_width == MSG_EXT_WDTR_BUS_16_BIT)
806                                 ppr_options = MSG_EXT_PPR_DT_REQ;
807
808                         syncrate = ahc_find_syncrate(ahc, &cts->sync_period,
809                                                      &ppr_options,
810                                                      maxsync);
811                         ahc_validate_offset(ahc, /*tinfo limit*/NULL,
812                                             syncrate, &cts->sync_offset,
813                                             MSG_EXT_WDTR_BUS_8_BIT,
814                                             ROLE_UNKNOWN);
815
816                         /* We use a period of 0 to represent async */
817                         if (cts->sync_offset == 0) {
818                                 cts->sync_period = 0;
819                                 ppr_options = 0;
820                         }
821
822                         if (ppr_options == MSG_EXT_PPR_DT_REQ
823                          && tinfo->user.transport_version >= 3) {
824                                 tinfo->goal.transport_version =
825                                     tinfo->user.transport_version;
826                                 tinfo->curr.transport_version =
827                                     tinfo->user.transport_version;
828                         }
829                         
830                         ahc_set_syncrate(ahc, &devinfo, syncrate,
831                                          cts->sync_period, cts->sync_offset,
832                                          ppr_options, update_type,
833                                          /*paused*/FALSE);
834                 }
835                 ahc_unlock();
836                 ccb->ccb_h.status = CAM_REQ_CMP;
837                 xpt_done(ccb);
838 #endif
839                 break;
840         }
841         case XPT_GET_TRAN_SETTINGS:
842         /* Get default/user set transfer settings for the target */
843         {
844
845                 ahc_lock();
846                 ahc_get_tran_settings(ahc, SIM_SCSI_ID(ahc, sim),
847                                       SIM_CHANNEL(ahc, sim), &ccb->cts);
848                 ahc_unlock();
849                 xpt_done(ccb);
850                 break;
851         }
852         case XPT_CALC_GEOMETRY:
853         {
854                 int extended;
855
856                 extended = SIM_IS_SCSIBUS_B(ahc, sim)
857                          ? ahc->flags & AHC_EXTENDED_TRANS_B
858                          : ahc->flags & AHC_EXTENDED_TRANS_A;
859                 cam_calc_geometry(&ccb->ccg, extended);
860                 xpt_done(ccb);
861                 break;
862         }
863         case XPT_RESET_BUS:             /* Reset the specified SCSI bus */
864         {
865                 int  found;
866                 
867                 ahc_lock();
868                 found = ahc_reset_channel(ahc, SIM_CHANNEL(ahc, sim),
869                                           /*initiate reset*/TRUE);
870                 ahc_unlock();
871                 if (bootverbose) {
872                         xpt_print_path(SIM_PATH(ahc, sim));
873                         kprintf("SCSI bus reset delivered. "
874                                "%d SCBs aborted.\n", found);
875                 }
876                 ccb->ccb_h.status = CAM_REQ_CMP;
877                 xpt_done(ccb);
878                 break;
879         }
880         case XPT_TERM_IO:               /* Terminate the I/O process */
881                 /* XXX Implement */
882                 ccb->ccb_h.status = CAM_REQ_INVALID;
883                 xpt_done(ccb);
884                 break;
885         case XPT_PATH_INQ:              /* Path routing inquiry */
886         {
887                 struct ccb_pathinq *cpi = &ccb->cpi;
888                 
889                 cpi->version_num = 1; /* XXX??? */
890                 cpi->hba_inquiry = PI_SDTR_ABLE|PI_TAG_ABLE;
891                 if ((ahc->features & AHC_WIDE) != 0)
892                         cpi->hba_inquiry |= PI_WIDE_16;
893                 if ((ahc->features & AHC_TARGETMODE) != 0) {
894                         cpi->target_sprt = PIT_PROCESSOR
895                                          | PIT_DISCONNECT
896                                          | PIT_TERM_IO;
897                 } else {
898                         cpi->target_sprt = 0;
899                 }
900                 cpi->hba_misc = 0;
901                 cpi->hba_eng_cnt = 0;
902                 cpi->max_target = (ahc->features & AHC_WIDE) ? 15 : 7;
903                 cpi->max_lun = AHC_NUM_LUNS - 1;
904                 if (SIM_IS_SCSIBUS_B(ahc, sim)) {
905                         cpi->initiator_id = ahc->our_id_b;
906                         if ((ahc->flags & AHC_RESET_BUS_B) == 0)
907                                 cpi->hba_misc |= PIM_NOBUSRESET;
908                 } else {
909                         cpi->initiator_id = ahc->our_id;
910                         if ((ahc->flags & AHC_RESET_BUS_A) == 0)
911                                 cpi->hba_misc |= PIM_NOBUSRESET;
912                 }
913                 cpi->bus_id = cam_sim_bus(sim);
914                 cpi->base_transfer_speed = 3300;
915                 strncpy(cpi->sim_vid, "FreeBSD", SIM_IDLEN);
916                 strncpy(cpi->hba_vid, "Adaptec", HBA_IDLEN);
917                 strncpy(cpi->dev_name, cam_sim_name(sim), DEV_IDLEN);
918                 cpi->unit_number = cam_sim_unit(sim);
919 #ifdef AHC_NEW_TRAN_SETTINGS
920                 cpi->protocol = PROTO_SCSI;
921                 cpi->protocol_version = SCSI_REV_2;
922                 cpi->transport = XPORT_SPI;
923                 cpi->transport_version = 2;
924                 cpi->xport_specific.spi.ppr_options = SID_SPI_CLOCK_ST;
925                 if ((ahc->features & AHC_DT) != 0) {
926                         cpi->transport_version = 3;
927                         cpi->xport_specific.spi.ppr_options =
928                             SID_SPI_CLOCK_DT_ST;
929                 }
930 #endif
931                 cpi->ccb_h.status = CAM_REQ_CMP;
932                 xpt_done(ccb);
933                 break;
934         }
935         default:
936                 ccb->ccb_h.status = CAM_PROVIDE_FAIL;
937                 xpt_done(ccb);
938                 break;
939         }
940 }
941
942 static void
943 ahc_get_tran_settings(struct ahc_softc *ahc, int our_id, char channel,
944                       struct ccb_trans_settings *cts)
945 {
946 #ifdef AHC_NEW_TRAN_SETTINGS
947         struct  ahc_devinfo devinfo;
948         struct  ccb_trans_settings_scsi *scsi;
949         struct  ccb_trans_settings_spi *spi;
950         struct  ahc_initiator_tinfo *targ_info;
951         struct  ahc_tmode_tstate *tstate;
952         struct  ahc_transinfo *tinfo;
953
954         scsi = &cts->proto_specific.scsi;
955         spi = &cts->xport_specific.spi;
956         ahc_compile_devinfo(&devinfo, our_id,
957                             cts->ccb_h.target_id,
958                             cts->ccb_h.target_lun,
959                             channel, ROLE_UNKNOWN);
960         targ_info = ahc_fetch_transinfo(ahc, devinfo.channel,
961                                         devinfo.our_scsiid,
962                                         devinfo.target, &tstate);
963         
964         if (cts->type == CTS_TYPE_CURRENT_SETTINGS)
965                 tinfo = &targ_info->curr;
966         else
967                 tinfo = &targ_info->user;
968         
969         scsi->flags &= ~CTS_SCSI_FLAGS_TAG_ENB;
970         spi->flags &= ~CTS_SPI_FLAGS_DISC_ENB;
971         if (cts->type == CTS_TYPE_USER_SETTINGS) {
972                 if ((ahc->user_discenable & devinfo.target_mask) != 0)
973                         spi->flags |= CTS_SPI_FLAGS_DISC_ENB;
974
975                 if ((ahc->user_tagenable & devinfo.target_mask) != 0)
976                         scsi->flags |= CTS_SCSI_FLAGS_TAG_ENB;
977         } else {
978                 if ((tstate->discenable & devinfo.target_mask) != 0)
979                         spi->flags |= CTS_SPI_FLAGS_DISC_ENB;
980
981                 if ((tstate->tagenable & devinfo.target_mask) != 0)
982                         scsi->flags |= CTS_SCSI_FLAGS_TAG_ENB;
983         }
984         cts->protocol_version = tinfo->protocol_version;
985         cts->transport_version = tinfo->transport_version;
986
987         spi->sync_period = tinfo->period;
988         spi->sync_offset = tinfo->offset;
989         spi->bus_width = tinfo->width;
990         spi->ppr_options = tinfo->ppr_options;
991         
992         cts->protocol = PROTO_SCSI;
993         cts->transport = XPORT_SPI;
994         spi->valid = CTS_SPI_VALID_SYNC_RATE
995                    | CTS_SPI_VALID_SYNC_OFFSET
996                    | CTS_SPI_VALID_BUS_WIDTH
997                    | CTS_SPI_VALID_PPR_OPTIONS;
998
999         if (cts->ccb_h.target_lun != CAM_LUN_WILDCARD) {
1000                 scsi->valid = CTS_SCSI_VALID_TQ;
1001                 spi->valid |= CTS_SPI_VALID_DISC;
1002         } else {
1003                 scsi->valid = 0;
1004         }
1005
1006         cts->ccb_h.status = CAM_REQ_CMP;
1007 #else
1008         struct  ahc_devinfo devinfo;
1009         struct  ahc_initiator_tinfo *targ_info;
1010         struct  ahc_tmode_tstate *tstate;
1011         struct  ahc_transinfo *tinfo;
1012
1013         ahc_compile_devinfo(&devinfo, our_id,
1014                             cts->ccb_h.target_id,
1015                             cts->ccb_h.target_lun,
1016                             channel, ROLE_UNKNOWN);
1017         targ_info = ahc_fetch_transinfo(ahc, devinfo.channel,
1018                                         devinfo.our_scsiid,
1019                                         devinfo.target, &tstate);
1020         
1021         if ((cts->flags & CCB_TRANS_CURRENT_SETTINGS) != 0)
1022                 tinfo = &targ_info->curr;
1023         else
1024                 tinfo = &targ_info->user;
1025         
1026         cts->flags &= ~(CCB_TRANS_DISC_ENB|CCB_TRANS_TAG_ENB);
1027         if ((cts->flags & CCB_TRANS_CURRENT_SETTINGS) == 0) {
1028                 if ((ahc->user_discenable & devinfo.target_mask) != 0)
1029                         cts->flags |= CCB_TRANS_DISC_ENB;
1030
1031                 if ((ahc->user_tagenable & devinfo.target_mask) != 0)
1032                         cts->flags |= CCB_TRANS_TAG_ENB;
1033         } else {
1034                 if ((tstate->discenable & devinfo.target_mask) != 0)
1035                         cts->flags |= CCB_TRANS_DISC_ENB;
1036
1037                 if ((tstate->tagenable & devinfo.target_mask) != 0)
1038                         cts->flags |= CCB_TRANS_TAG_ENB;
1039         }
1040         cts->sync_period = tinfo->period;
1041         cts->sync_offset = tinfo->offset;
1042         cts->bus_width = tinfo->width;
1043         
1044         cts->valid = CCB_TRANS_SYNC_RATE_VALID
1045                    | CCB_TRANS_SYNC_OFFSET_VALID
1046                    | CCB_TRANS_BUS_WIDTH_VALID;
1047
1048         if (cts->ccb_h.target_lun != CAM_LUN_WILDCARD)
1049                 cts->valid |= CCB_TRANS_DISC_VALID|CCB_TRANS_TQ_VALID;
1050
1051         cts->ccb_h.status = CAM_REQ_CMP;
1052 #endif
1053 }
1054
1055 static void
1056 ahc_async(void *callback_arg, uint32_t code, struct cam_path *path, void *arg)
1057 {
1058         struct ahc_softc *ahc;
1059         struct cam_sim *sim;
1060
1061         sim = (struct cam_sim *)callback_arg;
1062         ahc = (struct ahc_softc *)cam_sim_softc(sim);
1063         switch (code) {
1064         case AC_LOST_DEVICE:
1065         {
1066                 struct  ahc_devinfo devinfo;
1067
1068                 ahc_compile_devinfo(&devinfo, SIM_SCSI_ID(ahc, sim),
1069                                     xpt_path_target_id(path),
1070                                     xpt_path_lun_id(path),
1071                                     SIM_CHANNEL(ahc, sim),
1072                                     ROLE_UNKNOWN);
1073
1074                 /*
1075                  * Revert to async/narrow transfers
1076                  * for the next device.
1077                  */
1078                 ahc_lock();
1079                 ahc_set_width(ahc, &devinfo, MSG_EXT_WDTR_BUS_8_BIT,
1080                               AHC_TRANS_GOAL|AHC_TRANS_CUR, /*paused*/FALSE);
1081                 ahc_set_syncrate(ahc, &devinfo, /*syncrate*/NULL,
1082                                  /*period*/0, /*offset*/0, /*ppr_options*/0,
1083                                  AHC_TRANS_GOAL|AHC_TRANS_CUR,
1084                                  /*paused*/FALSE);
1085                 ahc_unlock();
1086                 break;
1087         }
1088         default:
1089                 break;
1090         }
1091 }
1092
1093 static void
1094 ahc_execute_scb(void *arg, bus_dma_segment_t *dm_segs, int nsegments,
1095                 int error)
1096 {
1097         struct  scb *scb;
1098         union   ccb *ccb;
1099         struct  ahc_softc *ahc;
1100         struct  ahc_initiator_tinfo *tinfo;
1101         struct  ahc_tmode_tstate *tstate;
1102         u_int   mask;
1103
1104         scb = (struct scb *)arg;
1105         ccb = scb->io_ctx;
1106         ahc = scb->ahc_softc;
1107
1108         if (error != 0) {
1109                 if (error == EFBIG)
1110                         aic_set_transaction_status(scb, CAM_REQ_TOO_BIG);
1111                 else
1112                         aic_set_transaction_status(scb, CAM_REQ_CMP_ERR);
1113                 if (nsegments != 0)
1114                         bus_dmamap_unload(ahc->buffer_dmat, scb->dmamap);
1115                 ahc_lock();
1116                 ahc_free_scb(ahc, scb);
1117                 ahc_unlock();
1118                 xpt_done(ccb);
1119                 return;
1120         }
1121         if (nsegments != 0) {
1122                 struct    ahc_dma_seg *sg;
1123                 bus_dma_segment_t *end_seg;
1124                 bus_dmasync_op_t op;
1125
1126                 end_seg = dm_segs + nsegments;
1127
1128                 /* Copy the segments into our SG list */
1129                 sg = scb->sg_list;
1130                 while (dm_segs < end_seg) {
1131                         uint32_t len;
1132
1133                         sg->addr = aic_htole32(dm_segs->ds_addr);
1134                         len = dm_segs->ds_len
1135                             | ((dm_segs->ds_addr >> 8) & 0x7F000000);
1136                         sg->len = aic_htole32(len);
1137                         sg++;
1138                         dm_segs++;
1139                 }
1140                 
1141                 /*
1142                  * Note where to find the SG entries in bus space.
1143                  * We also set the full residual flag which the 
1144                  * sequencer will clear as soon as a data transfer
1145                  * occurs.
1146                  */
1147                 scb->hscb->sgptr = aic_htole32(scb->sg_list_phys|SG_FULL_RESID);
1148
1149                 if ((ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_IN)
1150                         op = BUS_DMASYNC_PREREAD;
1151                 else
1152                         op = BUS_DMASYNC_PREWRITE;
1153
1154                 bus_dmamap_sync(ahc->buffer_dmat, scb->dmamap, op);
1155
1156                 if (ccb->ccb_h.func_code == XPT_CONT_TARGET_IO) {
1157                         struct target_data *tdata;
1158
1159                         tdata = &scb->hscb->shared_data.tdata;
1160                         tdata->target_phases |= DPHASE_PENDING;
1161                         /*
1162                          * CAM data direction is relative to the initiator.
1163                          */
1164                         if ((ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_OUT)
1165                                 tdata->data_phase = P_DATAOUT;
1166                         else
1167                                 tdata->data_phase = P_DATAIN;
1168
1169                         /*
1170                          * If the transfer is of an odd length and in the
1171                          * "in" direction (scsi->HostBus), then it may
1172                          * trigger a bug in the 'WideODD' feature of
1173                          * non-Ultra2 chips.  Force the total data-length
1174                          * to be even by adding an extra, 1 byte, SG,
1175                          * element.  We do this even if we are not currently
1176                          * negotiated wide as negotiation could occur before
1177                          * this command is executed.
1178                          */
1179                         if ((ahc->bugs & AHC_TMODE_WIDEODD_BUG) != 0
1180                          && (ccb->csio.dxfer_len & 0x1) != 0
1181                          && (ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_OUT) {
1182
1183                                 nsegments++;
1184                                 if (nsegments > AHC_NSEG) {
1185
1186                                         aic_set_transaction_status(scb,
1187                                             CAM_REQ_TOO_BIG);
1188                                         bus_dmamap_unload(ahc->buffer_dmat,
1189                                                           scb->dmamap);
1190                                         ahc_lock();
1191                                         ahc_free_scb(ahc, scb);
1192                                         ahc_unlock();
1193                                         xpt_done(ccb);
1194                                         return;
1195                                 }
1196                                 sg->addr = aic_htole32(ahc->dma_bug_buf);
1197                                 sg->len = aic_htole32(1);
1198                                 sg++;
1199                         }
1200                 }
1201                 sg--;
1202                 sg->len |= aic_htole32(AHC_DMA_LAST_SEG);
1203
1204                 /* Copy the first SG into the "current" data pointer area */
1205                 scb->hscb->dataptr = scb->sg_list->addr;
1206                 scb->hscb->datacnt = scb->sg_list->len;
1207         } else {
1208                 scb->hscb->sgptr = aic_htole32(SG_LIST_NULL);
1209                 scb->hscb->dataptr = 0;
1210                 scb->hscb->datacnt = 0;
1211         }
1212         
1213         scb->sg_count = nsegments;
1214
1215         ahc_lock();
1216
1217         /*
1218          * Last time we need to check if this SCB needs to
1219          * be aborted.
1220          */
1221         if (aic_get_transaction_status(scb) != CAM_REQ_INPROG) {
1222                 if (nsegments != 0)
1223                         bus_dmamap_unload(ahc->buffer_dmat, scb->dmamap);
1224                 ahc_free_scb(ahc, scb);
1225                 ahc_unlock();
1226                 xpt_done(ccb);
1227                 return;
1228         }
1229
1230         tinfo = ahc_fetch_transinfo(ahc, SCSIID_CHANNEL(ahc, scb->hscb->scsiid),
1231                                     SCSIID_OUR_ID(scb->hscb->scsiid),
1232                                     SCSIID_TARGET(ahc, scb->hscb->scsiid),
1233                                     &tstate);
1234
1235         mask = SCB_GET_TARGET_MASK(ahc, scb);
1236         scb->hscb->scsirate = tinfo->scsirate;
1237         scb->hscb->scsioffset = tinfo->curr.offset;
1238         if ((tstate->ultraenb & mask) != 0)
1239                 scb->hscb->control |= ULTRAENB;
1240
1241         if ((tstate->discenable & mask) != 0
1242          && (ccb->ccb_h.flags & CAM_DIS_DISCONNECT) == 0)
1243                 scb->hscb->control |= DISCENB;
1244
1245         if ((ccb->ccb_h.flags & CAM_NEGOTIATE) != 0
1246          && (tinfo->goal.width != 0
1247           || tinfo->goal.offset != 0
1248           || tinfo->goal.ppr_options != 0)) {
1249                 scb->flags |= SCB_NEGOTIATE;
1250                 scb->hscb->control |= MK_MESSAGE;
1251         } else if ((tstate->auto_negotiate & mask) != 0) {
1252                 scb->flags |= SCB_AUTO_NEGOTIATE;
1253                 scb->hscb->control |= MK_MESSAGE;
1254         }
1255
1256         LIST_INSERT_HEAD(&ahc->pending_scbs, scb, pending_links);
1257
1258         ccb->ccb_h.status |= CAM_SIM_QUEUED;
1259
1260         /*
1261          * We only allow one untagged transaction
1262          * per target in the initiator role unless
1263          * we are storing a full busy target *lun*
1264          * table in SCB space.
1265          */
1266         if ((scb->hscb->control & (TARGET_SCB|TAG_ENB)) == 0
1267          && (ahc->flags & AHC_SCB_BTT) == 0) {
1268                 struct scb_tailq *untagged_q;
1269                 int target_offset;
1270
1271                 target_offset = SCB_GET_TARGET_OFFSET(ahc, scb);
1272                 untagged_q = &(ahc->untagged_queues[target_offset]);
1273                 TAILQ_INSERT_TAIL(untagged_q, scb, links.tqe);
1274                 scb->flags |= SCB_UNTAGGEDQ;
1275                 if (TAILQ_FIRST(untagged_q) != scb) {
1276                         ahc_unlock();
1277                         return;
1278                 }
1279         }
1280         scb->flags |= SCB_ACTIVE;
1281
1282         /*
1283          * Timers are disabled while recovery is in progress.
1284          */
1285         aic_scb_timer_start(scb);
1286
1287         if ((scb->flags & SCB_TARGET_IMMEDIATE) != 0) {
1288                 /* Define a mapping from our tag to the SCB. */
1289                 ahc->scb_data->scbindex[scb->hscb->tag] = scb;
1290                 ahc_pause(ahc);
1291                 if ((ahc->flags & AHC_PAGESCBS) == 0)
1292                         ahc_outb(ahc, SCBPTR, scb->hscb->tag);
1293                 ahc_outb(ahc, TARG_IMMEDIATE_SCB, scb->hscb->tag);
1294                 ahc_unpause(ahc);
1295         } else {
1296                 ahc_queue_scb(ahc, scb);
1297         }
1298
1299         ahc_unlock();
1300 }
1301
1302 static void
1303 ahc_poll(struct cam_sim *sim)
1304 {
1305         struct ahc_softc *ahc;
1306
1307         ahc = (struct ahc_softc *)cam_sim_softc(sim);
1308         ahc_intr(ahc);
1309 }
1310
1311 static void
1312 ahc_setup_data(struct ahc_softc *ahc, struct cam_sim *sim,
1313                struct ccb_scsiio *csio, struct scb *scb)
1314 {
1315         struct hardware_scb *hscb;
1316         struct ccb_hdr *ccb_h;
1317         
1318         hscb = scb->hscb;
1319         ccb_h = &csio->ccb_h;
1320         
1321         csio->resid = 0;
1322         csio->sense_resid = 0;
1323         if (ccb_h->func_code == XPT_SCSI_IO) {
1324                 hscb->cdb_len = csio->cdb_len;
1325                 if ((ccb_h->flags & CAM_CDB_POINTER) != 0) {
1326
1327                         if (hscb->cdb_len > sizeof(hscb->cdb32)
1328                          || (ccb_h->flags & CAM_CDB_PHYS) != 0) {
1329                                 aic_set_transaction_status(scb,
1330                                                            CAM_REQ_INVALID);
1331                                 ahc_lock();
1332                                 ahc_free_scb(ahc, scb);
1333                                 ahc_unlock();
1334                                 xpt_done((union ccb *)csio);
1335                                 return;
1336                         }
1337                         if (hscb->cdb_len > 12) {
1338                                 memcpy(hscb->cdb32, 
1339                                        csio->cdb_io.cdb_ptr,
1340                                        hscb->cdb_len);
1341                                 scb->flags |= SCB_CDB32_PTR;
1342                         } else {
1343                                 memcpy(hscb->shared_data.cdb, 
1344                                        csio->cdb_io.cdb_ptr,
1345                                        hscb->cdb_len);
1346                         }
1347                 } else {
1348                         if (hscb->cdb_len > 12) {
1349                                 memcpy(hscb->cdb32, csio->cdb_io.cdb_bytes,
1350                                        hscb->cdb_len);
1351                                 scb->flags |= SCB_CDB32_PTR;
1352                         } else {
1353                                 memcpy(hscb->shared_data.cdb,
1354                                        csio->cdb_io.cdb_bytes,
1355                                        hscb->cdb_len);
1356                         }
1357                 }
1358         }
1359                 
1360         /* Only use S/G if there is a transfer */
1361         if ((ccb_h->flags & CAM_DIR_MASK) != CAM_DIR_NONE) {
1362                 if ((ccb_h->flags & CAM_SCATTER_VALID) == 0) {
1363                         /* We've been given a pointer to a single buffer */
1364                         if ((ccb_h->flags & CAM_DATA_PHYS) == 0) {
1365                                 int error;
1366
1367                                 crit_enter();
1368                                 error = bus_dmamap_load(ahc->buffer_dmat,
1369                                                         scb->dmamap,
1370                                                         csio->data_ptr,
1371                                                         csio->dxfer_len,
1372                                                         ahc_execute_scb,
1373                                                         scb, /*flags*/0);
1374                                 if (error == EINPROGRESS) {
1375                                         /*
1376                                          * So as to maintain ordering,
1377                                          * freeze the controller queue
1378                                          * until our mapping is
1379                                          * returned.
1380                                          */
1381                                         xpt_freeze_simq(sim,
1382                                                         /*count*/1);
1383                                         scb->io_ctx->ccb_h.status |=
1384                                             CAM_RELEASE_SIMQ;
1385                                 }
1386                                 crit_exit();
1387                         } else {
1388                                 struct bus_dma_segment seg;
1389
1390                                 /* Pointer to physical buffer */
1391                                 if (csio->dxfer_len > AHC_MAXTRANSFER_SIZE)
1392                                         panic("ahc_setup_data - Transfer size "
1393                                               "larger than can device max");
1394
1395                                 seg.ds_addr =
1396                                     (bus_addr_t)(vm_offset_t)csio->data_ptr;
1397                                 seg.ds_len = csio->dxfer_len;
1398                                 ahc_execute_scb(scb, &seg, 1, 0);
1399                         }
1400                 } else {
1401                         struct bus_dma_segment *segs;
1402
1403                         if ((ccb_h->flags & CAM_DATA_PHYS) != 0)
1404                                 panic("ahc_setup_data - Physical segment "
1405                                       "pointers unsupported");
1406
1407                         if ((ccb_h->flags & CAM_SG_LIST_PHYS) == 0)
1408                                 panic("ahc_setup_data - Virtual segment "
1409                                       "addresses unsupported");
1410
1411                         /* Just use the segments provided */
1412                         segs = (struct bus_dma_segment *)csio->data_ptr;
1413                         ahc_execute_scb(scb, segs, csio->sglist_cnt, 0);
1414                 }
1415         } else {
1416                 ahc_execute_scb(scb, NULL, 0, 0);
1417         }
1418 }
1419
1420 static void
1421 ahc_abort_ccb(struct ahc_softc *ahc, struct cam_sim *sim, union ccb *ccb)
1422 {
1423         union ccb *abort_ccb;
1424
1425         abort_ccb = ccb->cab.abort_ccb;
1426         switch (abort_ccb->ccb_h.func_code) {
1427         case XPT_ACCEPT_TARGET_IO:
1428         case XPT_IMMED_NOTIFY:
1429         case XPT_CONT_TARGET_IO:
1430         {
1431                 struct ahc_tmode_tstate *tstate;
1432                 struct ahc_tmode_lstate *lstate;
1433                 struct ccb_hdr_slist *list;
1434                 cam_status status;
1435
1436                 status = ahc_find_tmode_devs(ahc, sim, abort_ccb, &tstate,
1437                                              &lstate, TRUE);
1438
1439                 if (status != CAM_REQ_CMP) {
1440                         ccb->ccb_h.status = status;
1441                         break;
1442                 }
1443
1444                 if (abort_ccb->ccb_h.func_code == XPT_ACCEPT_TARGET_IO)
1445                         list = &lstate->accept_tios;
1446                 else if (abort_ccb->ccb_h.func_code == XPT_IMMED_NOTIFY)
1447                         list = &lstate->immed_notifies;
1448                 else
1449                         list = NULL;
1450
1451                 if (list != NULL) {
1452                         struct ccb_hdr *curelm;
1453                         int found;
1454
1455                         curelm = SLIST_FIRST(list);
1456                         found = 0;
1457                         if (curelm == &abort_ccb->ccb_h) {
1458                                 found = 1;
1459                                 SLIST_REMOVE_HEAD(list, sim_links.sle);
1460                         } else {
1461                                 while(curelm != NULL) {
1462                                         struct ccb_hdr *nextelm;
1463
1464                                         nextelm =
1465                                             SLIST_NEXT(curelm, sim_links.sle);
1466
1467                                         if (nextelm == &abort_ccb->ccb_h) {
1468                                                 found = 1;
1469                                                 SLIST_NEXT(curelm,
1470                                                            sim_links.sle) =
1471                                                     SLIST_NEXT(nextelm,
1472                                                                sim_links.sle);
1473                                                 break;
1474                                         }
1475                                         curelm = nextelm;
1476                                 }
1477                         }
1478
1479                         if (found) {
1480                                 abort_ccb->ccb_h.status = CAM_REQ_ABORTED;
1481                                 xpt_done(abort_ccb);
1482                                 ccb->ccb_h.status = CAM_REQ_CMP;
1483                         } else {
1484                                 xpt_print_path(abort_ccb->ccb_h.path);
1485                                 kprintf("Not found\n");
1486                                 ccb->ccb_h.status = CAM_PATH_INVALID;
1487                         }
1488                         break;
1489                 }
1490                 /* FALLTHROUGH */
1491         }
1492         case XPT_SCSI_IO:
1493                 /* XXX Fully implement the hard ones */
1494                 ccb->ccb_h.status = CAM_UA_ABORT;
1495                 break;
1496         default:
1497                 ccb->ccb_h.status = CAM_REQ_INVALID;
1498                 break;
1499         }
1500         xpt_done(ccb);
1501 }
1502
1503 void
1504 ahc_send_async(struct ahc_softc *ahc, char channel, u_int target,
1505                 u_int lun, ac_code code, void *opt_arg)
1506 {
1507         struct  ccb_trans_settings cts;
1508         struct cam_path *path;
1509         void *arg;
1510         int error;
1511
1512         arg = NULL;
1513         error = ahc_create_path(ahc, channel, target, lun, &path);
1514
1515         if (error != CAM_REQ_CMP)
1516                 return;
1517
1518         switch (code) {
1519         case AC_TRANSFER_NEG:
1520         {
1521 #ifdef AHC_NEW_TRAN_SETTINGS
1522                 struct  ccb_trans_settings_scsi *scsi;
1523         
1524                 cts.type = CTS_TYPE_CURRENT_SETTINGS;
1525                 scsi = &cts.proto_specific.scsi;
1526 #else
1527                 cts.flags = CCB_TRANS_CURRENT_SETTINGS;
1528 #endif
1529                 cts.ccb_h.path = path;
1530                 cts.ccb_h.target_id = target;
1531                 cts.ccb_h.target_lun = lun;
1532                 ahc_get_tran_settings(ahc, channel == 'A' ? ahc->our_id
1533                                                           : ahc->our_id_b,
1534                                       channel, &cts);
1535                 arg = &cts;
1536 #ifdef AHC_NEW_TRAN_SETTINGS
1537                 scsi->valid &= ~CTS_SCSI_VALID_TQ;
1538                 scsi->flags &= ~CTS_SCSI_FLAGS_TAG_ENB;
1539 #else
1540                 cts.valid &= ~CCB_TRANS_TQ_VALID;
1541                 cts.flags &= ~CCB_TRANS_TAG_ENB;
1542 #endif
1543                 if (opt_arg == NULL)
1544                         break;
1545                 if (*((ahc_queue_alg *)opt_arg) == AHC_QUEUE_TAGGED)
1546 #ifdef AHC_NEW_TRAN_SETTINGS
1547                         scsi->flags |= ~CTS_SCSI_FLAGS_TAG_ENB;
1548                 scsi->valid |= CTS_SCSI_VALID_TQ;
1549 #else
1550                         cts.flags |= CCB_TRANS_TAG_ENB;
1551                 cts.valid |= CCB_TRANS_TQ_VALID;
1552 #endif
1553                 break;
1554         }
1555         case AC_SENT_BDR:
1556         case AC_BUS_RESET:
1557                 break;
1558         default:
1559                 panic("ahc_send_async: Unexpected async event");
1560         }
1561         xpt_async(code, path, arg);
1562         xpt_free_path(path);
1563 }
1564
1565 void
1566 ahc_platform_set_tags(struct ahc_softc *ahc,
1567                       struct ahc_devinfo *devinfo, int enable)
1568 {
1569 }
1570
1571 int
1572 ahc_platform_alloc(struct ahc_softc *ahc, void *platform_arg)
1573 {
1574         ahc->platform_data = kmalloc(sizeof(struct ahc_platform_data), M_DEVBUF,
1575                                     M_INTWAIT | M_ZERO);
1576         return (0);
1577 }
1578
1579 void
1580 ahc_platform_free(struct ahc_softc *ahc)
1581 {
1582         struct ahc_platform_data *pdata;
1583
1584         pdata = ahc->platform_data;
1585         if (pdata != NULL) {
1586                 if (pdata->regs != NULL)
1587                         bus_release_resource(ahc->dev_softc,
1588                                              pdata->regs_res_type,
1589                                              pdata->regs_res_id,
1590                                              pdata->regs);
1591
1592                 if (pdata->irq != NULL)
1593                         bus_release_resource(ahc->dev_softc,
1594                                              pdata->irq_res_type,
1595                                              0, pdata->irq);
1596
1597                 if (pdata->sim_b != NULL) {
1598                         xpt_async(AC_LOST_DEVICE, pdata->path_b, NULL);
1599                         xpt_free_path(pdata->path_b);
1600                         xpt_bus_deregister(cam_sim_path(pdata->sim_b));
1601                         cam_sim_free(pdata->sim_b);
1602                 }
1603                 if (pdata->sim != NULL) {
1604                         xpt_async(AC_LOST_DEVICE, pdata->path, NULL);
1605                         xpt_free_path(pdata->path);
1606                         xpt_bus_deregister(cam_sim_path(pdata->sim));
1607                         cam_sim_free(pdata->sim);
1608                 }
1609                 if (pdata->eh != NULL)
1610                         EVENTHANDLER_DEREGISTER(shutdown_post_sync, pdata->eh);
1611                 kfree(ahc->platform_data, M_DEVBUF);
1612         }
1613 }
1614
1615 int
1616 ahc_softc_comp(struct ahc_softc *lahc, struct ahc_softc *rahc)
1617 {
1618         /* We don't sort softcs under FreeBSD so report equal always */
1619         return (0);
1620 }
1621
1622 int
1623 ahc_detach(device_t dev)
1624 {
1625         struct ahc_softc *ahc;
1626
1627         device_printf(dev, "detaching device\n");
1628         ahc = device_get_softc(dev);
1629         ahc = ahc_find_softc(ahc);
1630         if (ahc == NULL) {
1631                 device_printf(dev, "aic7xxx already detached\n");
1632                 return (ENOENT);
1633         }
1634         TAILQ_REMOVE(&ahc_tailq, ahc, links);
1635         ahc_lock();
1636         ahc_intr_enable(ahc, FALSE);
1637         bus_teardown_intr(dev, ahc->platform_data->irq, ahc->platform_data->ih);
1638         ahc_unlock();
1639         ahc_free(ahc);
1640         return (0);
1641 }
1642
1643 #if 0
1644 static void
1645 ahc_dump_targcmd(struct target_cmd *cmd)
1646 {
1647         uint8_t *byte;
1648         uint8_t *last_byte;
1649         int i;
1650
1651         byte = &cmd->initiator_channel;
1652         /* Debugging info for received commands */
1653         last_byte = &cmd[1].initiator_channel;
1654
1655         i = 0;
1656         while (byte < last_byte) {
1657                 if (i == 0)
1658                         kprintf("\t");
1659                 kprintf("%#x", *byte++);
1660                 i++;
1661                 if (i == 8) {
1662                         kprintf("\n");
1663                         i = 0;
1664                 } else {
1665                         kprintf(", ");
1666                 }
1667         }
1668 }
1669 #endif
1670
1671 static int
1672 ahc_modevent(module_t mod, int type, void *data)
1673 {
1674         /* XXX Deal with busy status on unload. */
1675         return 0;
1676 }
1677   
1678 static moduledata_t ahc_mod = {
1679         "ahc",
1680         ahc_modevent,
1681         NULL
1682 };
1683
1684 DECLARE_MODULE(ahc, ahc_mod, SI_SUB_DRIVERS, SI_ORDER_MIDDLE);
1685 MODULE_DEPEND(ahc, cam, 1, 1, 1);
1686 MODULE_VERSION(ahc, 1);