1 /* $OpenBSD: aic7xxx_openbsd.c,v 1.21 2004/01/24 15:49:31 krw Exp $ */
2 /* $NetBSD: aic7xxx_osm.c,v 1.14 2003/11/02 11:07:44 wiz Exp $ */
3
4 /*
5 * Bus independent OpenBSD shim for the aic7xxx based adaptec SCSI controllers
6 *
7 * Copyright (c) 1994-2001 Justin T. Gibbs.
8 * Copyright (c) 2001-2002 Steve Murphree, Jr.
9 * All rights reserved.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions, and the following disclaimer,
16 * without modification.
17 * 2. The name of the author may not be used to endorse or promote products
18 * derived from this software without specific prior written permission.
19 *
20 * Alternatively, this software may be distributed under the terms of the
21 * GNU Public License ("GPL").
22 *
23 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
27 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33 * SUCH DAMAGE.
34 *
35 * //depot/aic7xxx/freebsd/dev/aic7xxx/aic7xxx_osm.c#12 $
36 *
37 * $FreeBSD: src/sys/dev/aic7xxx/aic7xxx_osm.c,v 1.31 2002/11/30 19:08:58 scottl Exp $
38 */
39 /*
40 * Ported from FreeBSD by Pascal Renauld, Network Storage Solutions, Inc. - April 2003
41 */
42
43 #include <sys/cdefs.h>
44 /* __KERNEL_RCSID(0, "$NetBSD: aic7xxx_osm.c,v 1.14 2003/11/02 11:07:44 wiz Exp $"); */
45
46 #include <dev/ic/aic7xxx_openbsd.h>
47 #include <dev/ic/aic7xxx_inline.h>
48
49 #ifndef AHC_TMODE_ENABLE
50 #define AHC_TMODE_ENABLE 0
51 #endif
52
53
54 int ahc_action(struct scsi_xfer *);
55 int ahc_execute_scb(void *, bus_dma_segment_t *, int);
56 int ahc_poll(struct ahc_softc *, int);
57 int ahc_setup_data(struct ahc_softc *, struct scsi_xfer *, struct scb *);
58 void ahc_set_recoveryscb(struct ahc_softc *, struct scb *);
59
60 void ahc_minphys(struct buf *);
61 void ahc_adapter_req_set_xfer_mode(struct ahc_softc *, struct scb *);
62
63
64 struct cfdriver ahc_cd = {
65 NULL, "ahc", DV_DULL
66 };
67
68 static struct scsi_adapter ahc_switch =
69 {
70 ahc_action,
71 ahc_minphys,
72 0,
73 0,
74 };
75
76 /* the below structure is so we have a default dev struct for our link struct */
77 static struct scsi_device ahc_dev =
78 {
79 NULL, /* Use default error handler */
80 NULL, /* have a queue, served by this */
81 NULL, /* have no async handler */
82 NULL, /* Use default 'done' routine */
83 };
84
85 /*
86 * Attach all the sub-devices we can find
87 */
88 int
ahc_attach(struct ahc_softc * ahc)89 ahc_attach(struct ahc_softc *ahc)
90 {
91 char ahc_info[256];
92 int i, s;
93
94 LIST_INIT(&ahc->pending_scbs);
95 for (i = 0; i < AHC_NUM_TARGETS; i++)
96 TAILQ_INIT(&ahc->untagged_queues[i]);
97
98 ahc_lock(ahc, &s);
99
100 /*
101 * fill in the prototype scsi_links.
102 */
103 ahc->sc_channel.adapter_target = ahc->our_id;
104 if (ahc->features & AHC_WIDE)
105 ahc->sc_channel.adapter_buswidth = 16;
106 ahc->sc_channel.adapter_softc = ahc;
107 ahc->sc_channel.adapter = &ahc_switch;
108 ahc->sc_channel.openings = 16;
109 ahc->sc_channel.device = &ahc_dev;
110
111 if (ahc->features & AHC_TWIN) {
112 /* Configure the second scsi bus */
113 ahc->sc_channel_b = ahc->sc_channel;
114 ahc->sc_channel_b.adapter_target = ahc->our_id_b;
115 }
116
117 if (bootverbose) {
118 ahc_controller_info(ahc, ahc_info, sizeof ahc_info);
119 printf("%s: %s\n", ahc->sc_dev.dv_xname, ahc_info);
120 }
121
122 ahc_intr_enable(ahc, TRUE);
123
124 if (ahc->flags & AHC_RESET_BUS_A)
125 ahc_reset_channel(ahc, 'A', TRUE);
126 if ((ahc->features & AHC_TWIN) && ahc->flags & AHC_RESET_BUS_B)
127 ahc_reset_channel(ahc, 'B', TRUE);
128
129 if ((ahc->flags & AHC_PRIMARY_CHANNEL) == 0) {
130 /*
131 * Ensure SCSI_IS_SCSIBUS_B() returns false for sc_channel
132 * until sc_channel_b has been properly initialized by scsi
133 * layer.
134 */
135 ahc->sc_channel_b.scsibus = 0xff;
136 ahc->sc_child = config_found((void *)&ahc->sc_dev,
137 &ahc->sc_channel, scsiprint);
138 if (ahc->features & AHC_TWIN)
139 ahc->sc_child_b = config_found((void *)&ahc->sc_dev,
140 &ahc->sc_channel_b, scsiprint);
141 } else {
142 /*
143 * Ensure SCSI_IS_SCSIBUS_B() returns false for sc_channel_b
144 * until sc_channel has been properly initialized by scsi
145 * layer.
146 */
147 ahc->sc_channel.scsibus = 0xff;
148 if (ahc->features & AHC_TWIN)
149 ahc->sc_child = config_found((void *)&ahc->sc_dev,
150 &ahc->sc_channel_b, scsiprint);
151 ahc->sc_child_b = config_found((void *)&ahc->sc_dev,
152 &ahc->sc_channel, scsiprint);
153 }
154
155 ahc_unlock(ahc, &s);
156 return (1);
157 }
158
159 /*
160 * Catch an interrupt from the adapter
161 */
162 int
ahc_platform_intr(void * arg)163 ahc_platform_intr(void *arg)
164 {
165 struct ahc_softc *ahc = (struct ahc_softc *)arg;
166
167 bus_dmamap_sync(ahc->parent_dmat, ahc->scb_data->hscb_dmamap,
168 0, ahc->scb_data->hscb_dmamap->dm_mapsize,
169 BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
170
171 return ahc_intr(ahc);
172 }
173
174 /*
175 * We have an scb which has been processed by the
176 * adaptor, now we look to see how the operation
177 * went.
178 */
179 void
ahc_done(struct ahc_softc * ahc,struct scb * scb)180 ahc_done(struct ahc_softc *ahc, struct scb *scb)
181 {
182 struct scsi_xfer *xs = scb->xs;
183 int s;
184
185 bus_dmamap_sync(ahc->parent_dmat, ahc->scb_data->hscb_dmamap,
186 0, ahc->scb_data->hscb_dmamap->dm_mapsize,
187 BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
188
189 LIST_REMOVE(scb, pending_links);
190 if ((scb->flags & SCB_UNTAGGEDQ) != 0) {
191 struct scb_tailq *untagged_q;
192 int target_offset;
193
194 target_offset = SCB_GET_TARGET_OFFSET(ahc, scb);
195 untagged_q = &ahc->untagged_queues[target_offset];
196 TAILQ_REMOVE(untagged_q, scb, links.tqe);
197 scb->flags &= ~SCB_UNTAGGEDQ;
198 ahc_run_untagged_queue(ahc, untagged_q);
199 }
200
201 timeout_del(&xs->stimeout);
202
203 if (xs->datalen) {
204 int op;
205
206 if ((xs->flags & SCSI_DATA_IN) != 0)
207 op = BUS_DMASYNC_POSTREAD;
208 else
209 op = BUS_DMASYNC_POSTWRITE;
210 bus_dmamap_sync(ahc->parent_dmat, scb->dmamap, 0,
211 scb->dmamap->dm_mapsize, op);
212 bus_dmamap_unload(ahc->parent_dmat, scb->dmamap);
213 }
214
215 /*
216 * If the recovery SCB completes, we have to be
217 * out of our timeout.
218 */
219 if ((scb->flags & SCB_RECOVERY_SCB) != 0) {
220 struct scb *list_scb;
221
222 /*
223 * We were able to complete the command successfully,
224 * so reinstate the timeouts for all other pending
225 * commands.
226 */
227 LIST_FOREACH(list_scb, &ahc->pending_scbs, pending_links) {
228 struct scsi_xfer *txs = list_scb->xs;
229 if (!(txs->flags & SCSI_POLL))
230 timeout_add(&list_scb->xs->stimeout,
231 (list_scb->xs->timeout * hz)/1000);
232 }
233
234 if (xs->error != CAM_REQ_INPROG)
235 ahc_set_transaction_status(scb, CAM_CMD_TIMEOUT);
236 ahc_print_path(ahc, scb);
237 printf("no longer in timeout, status = %x\n", xs->status);
238 }
239
240 /* Translate the CAM status code to a SCSI error code. */
241 switch (xs->error) {
242 case CAM_REQ_INPROG:
243 case CAM_REQ_CMP:
244 switch (xs->status) {
245 case SCSI_TASKSET_FULL:
246 /* SCSI Layer won't requeue, so we force infinite
247 * retries until queue space is available. XS_BUSY
248 * is dangerous because if the NOSLEEP flag is set
249 * it can cause the I/O to return EIO. XS_BUSY code
250 * falls through to XS_TIMEOUT anyway.
251 */
252 xs->error = XS_TIMEOUT;
253 xs->retries++;
254 break;
255 case SCSI_BUSY:
256 xs->error = XS_BUSY;
257 break;
258 case SCSI_CHECK:
259 case SCSI_TERMINATED:
260 if ((scb->flags & SCB_SENSE) == 0) {
261 /* CHECK on CHECK? */
262 xs->error = XS_DRIVER_STUFFUP;
263 } else
264 xs->error = XS_NOERROR;
265 break;
266 default:
267 xs->error = XS_NOERROR;
268 break;
269 }
270 break;
271 case CAM_BUSY:
272 xs->error = XS_BUSY;
273 break;
274 case CAM_CMD_TIMEOUT:
275 xs->error = XS_TIMEOUT;
276 break;
277 case CAM_BDR_SENT:
278 case CAM_SCSI_BUS_RESET:
279 xs->error = XS_RESET;
280 case CAM_REQUEUE_REQ:
281 xs->error = XS_TIMEOUT;
282 xs->retries++;
283 break;
284 case CAM_SEL_TIMEOUT:
285 xs->error = XS_SELTIMEOUT;
286 break;
287 default:
288 xs->error = XS_DRIVER_STUFFUP;
289 break;
290 }
291
292 /* Don't clobber any existing error state */
293 if (xs->error != XS_NOERROR) {
294 /* Don't clobber any existing error state */
295 } else if ((scb->flags & SCB_SENSE) != 0) {
296 /*
297 * We performed autosense retrieval.
298 *
299 * Zero any sense not transferred by the
300 * device. The SCSI spec mandates that any
301 * untransferred data should be assumed to be
302 * zero. Complete the 'bounce' of sense information
303 * through buffers accessible via bus-space by
304 * copying it into the clients csio.
305 */
306 memset(&xs->sense, 0, sizeof(struct scsi_sense_data));
307 memcpy(&xs->sense, ahc_get_sense_buf(ahc, scb),
308 ahc_le32toh(scb->sg_list->len) & AHC_SG_LEN_MASK);
309 xs->error = XS_SENSE;
310 }
311 if (scb->flags & SCB_FREEZE_QUEUE) {
312 scb->flags &= ~SCB_FREEZE_QUEUE;
313 }
314
315 ahc_lock(ahc, &s);
316 ahc_free_scb(ahc, scb);
317 ahc_unlock(ahc, &s);
318
319 xs->flags |= ITSDONE;
320 scsi_done(xs);
321 }
322
323 void
ahc_minphys(bp)324 ahc_minphys(bp)
325 struct buf *bp;
326 {
327 /*
328 * Even though the card can transfer up to 16megs per command
329 * we are limited by the number of segments in the dma segment
330 * list that we can hold. The worst case is that all pages are
331 * discontinuous physically, hence the "page per segment" limit
332 * enforced here.
333 */
334 if (bp->b_bcount > ((AHC_NSEG - 1) * PAGE_SIZE)) {
335 bp->b_bcount = ((AHC_NSEG - 1) * PAGE_SIZE);
336 }
337 minphys(bp);
338 }
339
340 int32_t
ahc_action(struct scsi_xfer * xs)341 ahc_action(struct scsi_xfer *xs)
342 {
343 struct ahc_softc *ahc;
344 struct scb *scb;
345 struct hardware_scb *hscb;
346 u_int target_id;
347 u_int our_id;
348 int s;
349 int dontqueue = 0;
350
351 SC_DEBUG(xs->sc_link, SDEV_DB3, ("ahc_action\n"));
352 ahc = (struct ahc_softc *)xs->sc_link->adapter_softc;
353
354 /* determine safety of software queueing */
355 dontqueue = xs->flags & SCSI_POLL;
356
357 target_id = xs->sc_link->target;
358 our_id = SCSI_SCSI_ID(ahc, xs->sc_link);
359
360 /*
361 * get an scb to use.
362 */
363 ahc_lock(ahc, &s);
364 if ((scb = ahc_get_scb(ahc)) == NULL) {
365 ahc_unlock(ahc, &s);
366 xs->error = XS_DRIVER_STUFFUP;
367 return (TRY_AGAIN_LATER);
368 }
369 ahc_unlock(ahc, &s);
370
371 hscb = scb->hscb;
372
373 SC_DEBUG(xs->sc_link, SDEV_DB3, ("start scb(%p)\n", scb));
374 scb->xs = xs;
375
376 /*
377 * Put all the arguments for the xfer in the scb
378 */
379 hscb->control = 0;
380 hscb->scsiid = BUILD_SCSIID(ahc, xs->sc_link, target_id, our_id);
381 hscb->lun = xs->sc_link->lun;
382 if (xs->xs_control & XS_CTL_RESET) {
383 hscb->cdb_len = 0;
384 scb->flags |= SCB_DEVICE_RESET;
385 hscb->control |= MK_MESSAGE;
386 ahc_execute_scb(scb, NULL, 0);
387 }
388
389 timeout_set(&xs->stimeout, ahc_timeout, scb);
390
391 return ahc_setup_data(ahc, xs, scb);
392 }
393
394 int
ahc_execute_scb(void * arg,bus_dma_segment_t * dm_segs,int nsegments)395 ahc_execute_scb(void *arg, bus_dma_segment_t *dm_segs, int nsegments)
396 {
397 struct scb *scb;
398 struct scsi_xfer *xs;
399 struct ahc_softc *ahc;
400 struct ahc_initiator_tinfo *tinfo;
401 struct ahc_tmode_tstate *tstate;
402
403 u_int mask;
404 int s;
405
406 scb = (struct scb *)arg;
407 xs = scb->xs;
408 xs->error = CAM_REQ_INPROG;
409 xs->status = 0;
410 ahc = (struct ahc_softc *)xs->sc_link->adapter_softc;
411
412 if (nsegments != 0) {
413 struct ahc_dma_seg *sg;
414 bus_dma_segment_t *end_seg;
415 int op;
416
417 end_seg = dm_segs + nsegments;
418
419 /* Copy the segments into our SG list */
420 sg = scb->sg_list;
421 while (dm_segs < end_seg) {
422 uint32_t len;
423
424 sg->addr = ahc_htole32(dm_segs->ds_addr);
425 len = dm_segs->ds_len
426 | ((dm_segs->ds_addr >> 8) & 0x7F000000);
427 sg->len = ahc_htole32(len);
428 sg++;
429 dm_segs++;
430 }
431
432 /*
433 * Note where to find the SG entries in bus space.
434 * We also set the full residual flag which the
435 * sequencer will clear as soon as a data transfer
436 * occurs.
437 */
438 scb->hscb->sgptr = ahc_htole32(scb->sg_list_phys|SG_FULL_RESID);
439
440 if ((xs->flags & SCSI_DATA_IN) != 0)
441 op = BUS_DMASYNC_PREREAD;
442 else
443 op = BUS_DMASYNC_PREWRITE;
444
445 bus_dmamap_sync(ahc->parent_dmat, scb->dmamap, 0,
446 scb->dmamap->dm_mapsize, op);
447
448 sg--;
449 sg->len |= ahc_htole32(AHC_DMA_LAST_SEG);
450
451 bus_dmamap_sync(ahc->parent_dmat, scb->sg_map->sg_dmamap,
452 0, scb->sg_map->sg_dmamap->dm_mapsize,
453 BUS_DMASYNC_PREWRITE);
454
455 /* Copy the first SG into the "current" data pointer area */
456 scb->hscb->dataptr = scb->sg_list->addr;
457 scb->hscb->datacnt = scb->sg_list->len;
458 } else {
459 scb->hscb->sgptr = ahc_htole32(SG_LIST_NULL);
460 scb->hscb->dataptr = 0;
461 scb->hscb->datacnt = 0;
462 }
463
464 scb->sg_count = nsegments;
465
466 ahc_lock(ahc, &s);
467
468 /*
469 * Last time we need to check if this SCB needs to
470 * be aborted.
471 */
472 if (xs->flags & ITSDONE) {
473 if (nsegments != 0)
474 bus_dmamap_unload(ahc->parent_dmat, scb->dmamap);
475
476 ahc_free_scb(ahc, scb);
477 ahc_unlock(ahc, &s);
478 return (COMPLETE);
479 }
480
481 tinfo = ahc_fetch_transinfo(ahc, SCSIID_CHANNEL(ahc, scb->hscb->scsiid),
482 SCSIID_OUR_ID(scb->hscb->scsiid),
483 SCSIID_TARGET(ahc, scb->hscb->scsiid),
484 &tstate);
485
486 mask = SCB_GET_TARGET_MASK(ahc, scb);
487 scb->hscb->scsirate = tinfo->scsirate;
488 scb->hscb->scsioffset = tinfo->curr.offset;
489
490 if ((tstate->ultraenb & mask) != 0)
491 scb->hscb->control |= ULTRAENB;
492
493 if ((tstate->discenable & mask) != 0)
494 scb->hscb->control |= DISCENB;
495
496 if ((tstate->auto_negotiate & mask) != 0) {
497 scb->flags |= SCB_AUTO_NEGOTIATE;
498 scb->hscb->control |= MK_MESSAGE;
499 }
500
501 if ((tstate->tagenable & mask) != 0)
502 scb->hscb->control |= TAG_ENB;
503
504 bus_dmamap_sync(ahc->parent_dmat, ahc->scb_data->hscb_dmamap,
505 0, ahc->scb_data->hscb_dmamap->dm_mapsize,
506 BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
507
508 LIST_INSERT_HEAD(&ahc->pending_scbs, scb, pending_links);
509
510 if (!(xs->flags & SCSI_POLL))
511 timeout_add(&xs->stimeout, (xs->timeout * hz) / 1000);
512
513 /*
514 * We only allow one untagged transaction
515 * per target in the initiator role unless
516 * we are storing a full busy target *lun*
517 * table in SCB space.
518 *
519 * This really should not be of any
520 * concern, as we take care to avoid this
521 * in ahc_done(). XXX smurph
522 */
523 if ((scb->hscb->control & (TARGET_SCB|TAG_ENB)) == 0
524 && (ahc->flags & AHC_SCB_BTT) == 0) {
525 struct scb_tailq *untagged_q;
526 int target_offset;
527
528 target_offset = SCB_GET_TARGET_OFFSET(ahc, scb);
529 untagged_q = &(ahc->untagged_queues[target_offset]);
530 TAILQ_INSERT_TAIL(untagged_q, scb, links.tqe);
531 scb->flags |= SCB_UNTAGGEDQ;
532 if (TAILQ_FIRST(untagged_q) != scb) {
533 if (xs->flags & SCSI_POLL)
534 goto poll;
535 else {
536 ahc_unlock(ahc, &s);
537 return (SUCCESSFULLY_QUEUED);
538 }
539 }
540 }
541 scb->flags |= SCB_ACTIVE;
542
543 if ((scb->flags & SCB_TARGET_IMMEDIATE) != 0) {
544 /* Define a mapping from our tag to the SCB. */
545 ahc->scb_data->scbindex[scb->hscb->tag] = scb;
546 ahc_pause(ahc);
547 if ((ahc->flags & AHC_PAGESCBS) == 0)
548 ahc_outb(ahc, SCBPTR, scb->hscb->tag);
549 ahc_outb(ahc, TARG_IMMEDIATE_SCB, scb->hscb->tag);
550 ahc_unpause(ahc);
551 } else {
552 ahc_queue_scb(ahc, scb);
553 }
554
555 if (!(xs->flags & SCSI_POLL)) {
556 if (ahc->inited_target[xs->sc_link->target] == 0) {
557 struct ahc_devinfo devinfo;
558
559 ahc_adapter_req_set_xfer_mode(ahc, scb);
560 ahc_scb_devinfo(ahc, &devinfo, scb);
561 ahc_update_neg_request(ahc, &devinfo, tstate, tinfo,
562 AHC_NEG_IF_NON_ASYNC);
563
564 ahc->inited_target[xs->sc_link->target] = 1;
565 }
566
567 ahc_unlock(ahc, &s);
568 return (SUCCESSFULLY_QUEUED);
569 }
570
571 /*
572 * If we can't use interrupts, poll for completion
573 */
574 poll:
575 SC_DEBUG(xs->sc_link, SDEV_DB3, ("cmd_poll\n"));
576
577 do {
578 if (ahc_poll(ahc, xs->timeout)) {
579 if (!(xs->flags & SCSI_SILENT))
580 printf("cmd fail\n");
581 ahc_timeout(scb);
582 break;
583 }
584 } while (!(xs->flags & ITSDONE));
585
586 ahc_unlock(ahc, &s);
587 return (COMPLETE);
588 }
589
590 int
ahc_poll(struct ahc_softc * ahc,int wait)591 ahc_poll(struct ahc_softc *ahc, int wait)
592 {
593 while (--wait) {
594 DELAY(1000);
595 if (ahc_inb(ahc, INTSTAT) & INT_PEND)
596 break;
597 }
598
599 if (wait == 0) {
600 printf("%s: board is not responding\n", ahc_name(ahc));
601 return (EIO);
602 }
603
604 ahc_intr((void *)ahc);
605 return (0);
606 }
607
608 int
ahc_setup_data(struct ahc_softc * ahc,struct scsi_xfer * xs,struct scb * scb)609 ahc_setup_data(struct ahc_softc *ahc, struct scsi_xfer *xs,
610 struct scb *scb)
611 {
612 struct hardware_scb *hscb;
613
614 hscb = scb->hscb;
615 xs->resid = xs->status = 0;
616 xs->error = CAM_REQ_INPROG;
617
618 hscb->cdb_len = xs->cmdlen;
619 if (hscb->cdb_len > sizeof(hscb->cdb32)) {
620 int s;
621
622 ahc_set_transaction_status(scb, CAM_REQ_INVALID);
623 ahc_lock(ahc, &s);
624 ahc_free_scb(ahc, scb);
625 ahc_unlock(ahc, &s);
626 xs->flags |= ITSDONE;
627 scsi_done(xs);
628 return (COMPLETE);
629 }
630
631 if (hscb->cdb_len > 12) {
632 memcpy(hscb->cdb32, xs->cmd, hscb->cdb_len);
633 scb->flags |= SCB_CDB32_PTR;
634 } else {
635 memcpy(hscb->shared_data.cdb, xs->cmd, hscb->cdb_len);
636 }
637
638 /* Only use S/G if there is a transfer */
639 if (xs->datalen) {
640 int error;
641
642 error = bus_dmamap_load(ahc->parent_dmat,
643 scb->dmamap, xs->data,
644 xs->datalen, NULL,
645 (xs->flags & SCSI_NOSLEEP) ?
646 BUS_DMA_NOWAIT : BUS_DMA_WAITOK);
647 if (error) {
648 #ifdef AHC_DEBUG
649 printf("%s: in ahc_setup_data(): bus_dmamap_load() "
650 "= %d\n",
651 ahc_name(ahc), error);
652 #endif
653 xs->error = XS_BUSY;
654 xs->flags |= ITSDONE;
655 scsi_done(xs);
656 return (TRY_AGAIN_LATER); /* XXX fvdl */
657 }
658 error = ahc_execute_scb(scb,
659 scb->dmamap->dm_segs,
660 scb->dmamap->dm_nsegs);
661 return error;
662 } else {
663 return ahc_execute_scb(scb, NULL, 0);
664 }
665 }
666
667 void
ahc_set_recoveryscb(struct ahc_softc * ahc,struct scb * scb)668 ahc_set_recoveryscb(struct ahc_softc *ahc, struct scb *scb) {
669
670 if ((scb->flags & SCB_RECOVERY_SCB) == 0) {
671 struct scb *list_scb;
672
673 scb->flags |= SCB_RECOVERY_SCB;
674
675 /*
676 * Go through all of our pending SCBs and remove
677 * any scheduled timeouts for them. We will reschedule
678 * them after we've successfully fixed this problem.
679 */
680 LIST_FOREACH(list_scb, &ahc->pending_scbs, pending_links) {
681 timeout_del(&list_scb->xs->stimeout);
682 }
683 }
684 }
685
686 void
ahc_timeout(void * arg)687 ahc_timeout(void *arg)
688 {
689 struct scb *scb;
690 struct ahc_softc *ahc;
691 int s;
692 int found;
693 u_int last_phase;
694 int target;
695 int lun;
696 int i;
697 char channel;
698
699 scb = (struct scb *)arg;
700 ahc = (struct ahc_softc *)scb->xs->sc_link->adapter_softc;
701
702 ahc_lock(ahc, &s);
703
704 ahc_pause_and_flushwork(ahc);
705
706 if ((scb->flags & SCB_ACTIVE) == 0) {
707 /* Previous timeout took care of me already */
708 printf("%s: Timedout SCB already complete. "
709 "Interrupts may not be functioning.\n", ahc_name(ahc));
710 ahc_unpause(ahc);
711 ahc_unlock(ahc, &s);
712 return;
713 }
714
715 target = SCB_GET_TARGET(ahc, scb);
716 channel = SCB_GET_CHANNEL(ahc, scb);
717 lun = SCB_GET_LUN(scb);
718
719 ahc_print_path(ahc, scb);
720 printf("SCB 0x%x - timed out\n", scb->hscb->tag);
721 ahc_dump_card_state(ahc);
722 last_phase = ahc_inb(ahc, LASTPHASE);
723 if (scb->sg_count > 0) {
724 for (i = 0; i < scb->sg_count; i++) {
725 printf("sg[%d] - Addr 0x%x : Length %d\n",
726 i,
727 scb->sg_list[i].addr,
728 scb->sg_list[i].len & AHC_SG_LEN_MASK);
729 }
730 }
731 if (scb->flags & (SCB_DEVICE_RESET|SCB_ABORT)) {
732 /*
733 * Been down this road before.
734 * Do a full bus reset.
735 */
736 bus_reset:
737 ahc_set_transaction_status(scb, CAM_CMD_TIMEOUT);
738 found = ahc_reset_channel(ahc, channel, /*Initiate Reset*/TRUE);
739 printf("%s: Issued Channel %c Bus Reset. "
740 "%d SCBs aborted\n", ahc_name(ahc), channel, found);
741 } else {
742 /*
743 * If we are a target, transition to bus free and report
744 * the timeout.
745 *
746 * The target/initiator that is holding up the bus may not
747 * be the same as the one that triggered this timeout
748 * (different commands have different timeout lengths).
749 * If the bus is idle and we are acting as the initiator
750 * for this request, queue a BDR message to the timed out
751 * target. Otherwise, if the timed out transaction is
752 * active:
753 * Initiator transaction:
754 * Stuff the message buffer with a BDR message and assert
755 * ATN in the hopes that the target will let go of the bus
756 * and go to the mesgout phase. If this fails, we'll
757 * get another timeout 2 seconds later which will attempt
758 * a bus reset.
759 *
760 * Target transaction:
761 * Transition to BUS FREE and report the error.
762 * It's good to be the target!
763 */
764 u_int active_scb_index;
765 u_int saved_scbptr;
766
767 bus_dmamap_sync(ahc->parent_dmat,
768 ahc->scb_data->hscb_dmamap,
769 0, ahc->scb_data->hscb_dmamap->dm_mapsize,
770 BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
771
772 saved_scbptr = ahc_inb(ahc, SCBPTR);
773 active_scb_index = ahc_inb(ahc, SCB_TAG);
774
775 if ((ahc_inb(ahc, SEQ_FLAGS) & NOT_IDENTIFIED) == 0
776 && (active_scb_index < ahc->scb_data->numscbs)) {
777 struct scb *active_scb;
778
779 /*
780 * If the active SCB is not us, assume that
781 * the active SCB has a longer timeout than
782 * the timedout SCB, and wait for the active
783 * SCB to timeout.
784 */
785 active_scb = ahc_lookup_scb(ahc, active_scb_index);
786 if (active_scb != scb) {
787 u_int newtimeout;
788
789 ahc_print_path(ahc, active_scb);
790 printf("Other SCB Timeout%s",
791 (scb->flags & SCB_OTHERTCL_TIMEOUT) != 0
792 ? " again\n" : "\n");
793 scb->flags |= SCB_OTHERTCL_TIMEOUT;
794 newtimeout = MAX(active_scb->xs->timeout,
795 scb->xs->timeout);
796 timeout_add(&scb->xs->stimeout,
797 (newtimeout * hz) / 1000);
798 ahc_unpause(ahc);
799 ahc_unlock(ahc, &s);
800 return;
801 }
802
803 /* It's us */
804 if ((scb->flags & SCB_TARGET_SCB) != 0) {
805
806 /*
807 * Send back any queued up transactions
808 * and properly record the error condition.
809 */
810 ahc_abort_scbs(ahc, SCB_GET_TARGET(ahc, scb),
811 SCB_GET_CHANNEL(ahc, scb),
812 SCB_GET_LUN(scb),
813 scb->hscb->tag,
814 ROLE_TARGET,
815 CAM_CMD_TIMEOUT);
816
817 /* Will clear us from the bus */
818 ahc_restart(ahc);
819 ahc_unlock(ahc, &s);
820 return;
821 }
822
823 ahc_set_recoveryscb(ahc, active_scb);
824 ahc_outb(ahc, MSG_OUT, HOST_MSG);
825 ahc_outb(ahc, SCSISIGO, last_phase|ATNO);
826 ahc_print_path(ahc, active_scb);
827 printf("BDR message in message buffer\n");
828 active_scb->flags |= SCB_DEVICE_RESET;
829 timeout_add(&active_scb->xs->stimeout, 2 * hz);
830 ahc_unpause(ahc);
831 } else {
832 int disconnected;
833
834 bus_dmamap_sync(ahc->parent_dmat,
835 ahc->scb_data->hscb_dmamap,
836 0, ahc->scb_data->hscb_dmamap->dm_mapsize,
837 BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
838 /* XXX Shouldn't panic. Just punt instead */
839 if ((scb->flags & SCB_TARGET_SCB) != 0)
840 panic("Timed-out target SCB but bus idle");
841
842 if (last_phase != P_BUSFREE
843 && (ahc_inb(ahc, SSTAT0) & TARGET) != 0) {
844 /* XXX What happened to the SCB? */
845 /* Hung target selection. Goto busfree */
846 printf("%s: Hung target selection\n",
847 ahc_name(ahc));
848 ahc_restart(ahc);
849 ahc_unlock(ahc, &s);
850 return;
851 }
852
853 if (ahc_search_qinfifo(ahc, target, channel, lun,
854 scb->hscb->tag, ROLE_INITIATOR,
855 /*status*/0, SEARCH_COUNT) > 0) {
856 disconnected = FALSE;
857 } else {
858 disconnected = TRUE;
859 }
860
861 if (disconnected) {
862
863 ahc_set_recoveryscb(ahc, scb);
864 /*
865 * Actually re-queue this SCB in an attempt
866 * to select the device before it reconnects.
867 * In either case (selection or reselection),
868 * we will now issue a target reset to the
869 * timed-out device.
870 *
871 * Set the MK_MESSAGE control bit indicating
872 * that we desire to send a message. We
873 * also set the disconnected flag since
874 * in the paging case there is no guarantee
875 * that our SCB control byte matches the
876 * version on the card. We don't want the
877 * sequencer to abort the command thinking
878 * an unsolicited reselection occurred.
879 */
880 scb->hscb->control |= MK_MESSAGE|DISCONNECTED;
881 scb->flags |= SCB_DEVICE_RESET;
882
883 /*
884 * Remove any cached copy of this SCB in the
885 * disconnected list in preparation for the
886 * queuing of our abort SCB. We use the
887 * same element in the SCB, SCB_NEXT, for
888 * both the qinfifo and the disconnected list.
889 */
890 ahc_search_disc_list(ahc, target, channel,
891 lun, scb->hscb->tag,
892 /*stop_on_first*/TRUE,
893 /*remove*/TRUE,
894 /*save_state*/FALSE);
895
896 /*
897 * In the non-paging case, the sequencer will
898 * never re-reference the in-core SCB.
899 * To make sure we are notified during
900 * reslection, set the MK_MESSAGE flag in
901 * the card's copy of the SCB.
902 */
903 if ((ahc->flags & AHC_PAGESCBS) == 0) {
904 ahc_outb(ahc, SCBPTR, scb->hscb->tag);
905 ahc_outb(ahc, SCB_CONTROL,
906 ahc_inb(ahc, SCB_CONTROL)
907 | MK_MESSAGE);
908 }
909
910 /*
911 * Clear out any entries in the QINFIFO first
912 * so we are the next SCB for this target
913 * to run.
914 */
915 ahc_search_qinfifo(ahc,
916 SCB_GET_TARGET(ahc, scb),
917 channel, SCB_GET_LUN(scb),
918 SCB_LIST_NULL,
919 ROLE_INITIATOR,
920 CAM_REQUEUE_REQ,
921 SEARCH_COMPLETE);
922 ahc_print_path(ahc, scb);
923 printf("Queuing a BDR SCB\n");
924 ahc_qinfifo_requeue_tail(ahc, scb);
925 ahc_outb(ahc, SCBPTR, saved_scbptr);
926 timeout_add(&scb->xs->stimeout, 2 * hz);
927 ahc_unpause(ahc);
928 } else {
929 /* Go "immediately" to the bus reset. */
930 /* This shouldn't happen. */
931 ahc_set_recoveryscb(ahc, scb);
932 ahc_print_path(ahc, scb);
933 printf("SCB %d: Immediate reset. "
934 "Flags = 0x%x\n", scb->hscb->tag,
935 scb->flags);
936 goto bus_reset;
937 }
938 }
939 }
940 ahc_unlock(ahc, &s);
941 }
942
943
944 void
ahc_platform_set_tags(struct ahc_softc * ahc,struct ahc_devinfo * devinfo,int alg)945 ahc_platform_set_tags(struct ahc_softc *ahc,
946 struct ahc_devinfo *devinfo, int alg)
947 {
948 struct ahc_tmode_tstate *tstate;
949
950 ahc_fetch_transinfo(ahc, devinfo->channel, devinfo->our_scsiid,
951 devinfo->target, &tstate);
952
953 /* XXXX Need to check quirks before doing this! XXXX */
954
955 switch (alg) {
956 case AHC_QUEUE_BASIC:
957 case AHC_QUEUE_TAGGED:
958 tstate->tagenable |= devinfo->target_mask;
959 break;
960 case AHC_QUEUE_NONE:
961 tstate->tagenable &= ~devinfo->target_mask;
962 break;
963 }
964 }
965
966 int
ahc_platform_alloc(struct ahc_softc * ahc,void * platform_arg)967 ahc_platform_alloc(struct ahc_softc *ahc, void *platform_arg)
968 {
969 if (sizeof(struct ahc_platform_data) > 0) {
970 ahc->platform_data = malloc(sizeof(struct ahc_platform_data),
971 M_DEVBUF, M_NOWAIT);
972 if (ahc->platform_data == NULL)
973 return (ENOMEM);
974 bzero(ahc->platform_data, sizeof(struct ahc_platform_data));
975 }
976
977 return (0);
978 }
979
980 void
ahc_platform_free(struct ahc_softc * ahc)981 ahc_platform_free(struct ahc_softc *ahc)
982 {
983 if (sizeof(struct ahc_platform_data) > 0)
984 free(ahc->platform_data, M_DEVBUF);
985 }
986
987 int
ahc_softc_comp(struct ahc_softc * lahc,struct ahc_softc * rahc)988 ahc_softc_comp(struct ahc_softc *lahc, struct ahc_softc *rahc)
989 {
990 return (0);
991 }
992
993 void
ahc_send_async(struct ahc_softc * ahc,char channel,u_int target,u_int lun,u_int code,void * opt_arg)994 ahc_send_async(struct ahc_softc *ahc, char channel, u_int target, u_int lun,
995 u_int code, void *opt_arg)
996 {
997 /* Nothing to do here for OpenBSD */
998 }
999
1000 void
ahc_adapter_req_set_xfer_mode(struct ahc_softc * ahc,struct scb * scb)1001 ahc_adapter_req_set_xfer_mode(struct ahc_softc *ahc, struct scb *scb)
1002 {
1003 struct ahc_initiator_tinfo *tinfo;
1004 struct ahc_tmode_tstate *tstate;
1005 struct ahc_syncrate *syncrate;
1006 struct ahc_devinfo devinfo;
1007 u_int16_t quirks;
1008 u_int width, ppr_options, period, offset;
1009 int s;
1010
1011 s = splbio();
1012
1013 ahc_scb_devinfo(ahc, &devinfo, scb);
1014 quirks = scb->xs->sc_link->quirks;
1015 tinfo = ahc_fetch_transinfo(ahc, devinfo.channel,
1016 devinfo.our_scsiid, devinfo.target, &tstate);
1017
1018 tstate->discenable |= (ahc->user_discenable & devinfo.target_mask);
1019
1020 if (quirks & SDEV_NOTAGS)
1021 tstate->tagenable &= ~devinfo.target_mask;
1022 else if (ahc->user_tagenable & devinfo.target_mask)
1023 tstate->tagenable |= devinfo.target_mask;
1024
1025 if (quirks & SDEV_NOWIDE)
1026 width = MSG_EXT_WDTR_BUS_8_BIT;
1027 else
1028 width = MSG_EXT_WDTR_BUS_16_BIT;
1029
1030 ahc_validate_width(ahc, NULL, &width, ROLE_UNKNOWN);
1031 if (width > tinfo->user.width)
1032 width = tinfo->user.width;
1033 ahc_set_width(ahc, &devinfo, width, AHC_TRANS_GOAL, FALSE);
1034
1035 if (quirks & SDEV_NOSYNC) {
1036 period = 0;
1037 offset = 0;
1038 } else {
1039 period = tinfo->user.period;
1040 offset = tinfo->user.offset;
1041 }
1042
1043 /* XXX Look at saved INQUIRY flags for PPR capabilities XXX */
1044 ppr_options = tinfo->user.ppr_options;
1045 /* XXX Other reasons to avoid ppr? XXX */
1046 if (width < MSG_EXT_WDTR_BUS_16_BIT)
1047 ppr_options = 0;
1048
1049 if ((tstate->discenable & devinfo.target_mask) == 0 ||
1050 (tstate->tagenable & devinfo.target_mask) == 0)
1051 ppr_options &= ~MSG_EXT_PPR_PROT_IUS;
1052
1053 syncrate = ahc_find_syncrate(ahc, &period, &ppr_options,
1054 AHC_SYNCRATE_MAX);
1055 ahc_validate_offset(ahc, NULL, syncrate, &offset, width,
1056 ROLE_UNKNOWN);
1057
1058 if (offset == 0) {
1059 period = 0;
1060 ppr_options = 0;
1061 }
1062
1063 if (ppr_options != 0 && tinfo->user.transport_version >= 3) {
1064 tinfo->goal.transport_version = tinfo->user.transport_version;
1065 tinfo->curr.transport_version = tinfo->user.transport_version;
1066 }
1067
1068 ahc_set_syncrate(ahc, &devinfo, syncrate, period, offset, ppr_options,
1069 AHC_TRANS_GOAL, FALSE);
1070
1071 splx(s);
1072 }
1073