dpt.c revision 1.70 1 /* $NetBSD: dpt.c,v 1.70 2014/03/16 05:20:27 dholland Exp $ */
2
3 /*-
4 * Copyright (c) 1997, 1998, 1999, 2000, 2001 The NetBSD Foundation, Inc.
5 * All rights reserved.
6 *
7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Andrew Doran, Charles M. Hannum and by Jason R. Thorpe of the Numerical
9 * Aerospace Simulation Facility, NASA Ames Research Center.
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 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in the
18 * documentation and/or other materials provided with the distribution.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
21 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
22 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
24 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30 * POSSIBILITY OF SUCH DAMAGE.
31 */
32
33 /*
34 * Copyright (c) 1996-2000 Distributed Processing Technology Corporation
35 * Copyright (c) 2000 Adaptec Corporation
36 * All rights reserved.
37 *
38 * TERMS AND CONDITIONS OF USE
39 *
40 * Redistribution and use in source form, with or without modification, are
41 * permitted provided that redistributions of source code must retain the
42 * above copyright notice, this list of conditions and the following disclaimer.
43 *
44 * This software is provided `as is' by Adaptec and any express or implied
45 * warranties, including, but not limited to, the implied warranties of
46 * merchantability and fitness for a particular purpose, are disclaimed. In no
47 * event shall Adaptec be liable for any direct, indirect, incidental, special,
48 * exemplary or consequential damages (including, but not limited to,
49 * procurement of substitute goods or services; loss of use, data, or profits;
50 * or business interruptions) however caused and on any theory of liability,
51 * whether in contract, strict liability, or tort (including negligence or
52 * otherwise) arising in any way out of the use of this driver software, even
53 * if advised of the possibility of such damage.
54 */
55
56 /*
57 * Portions of this code fall under the following copyright:
58 *
59 * Originally written by Julian Elischer (julian (at) tfs.com)
60 * for TRW Financial Systems for use under the MACH(2.5) operating system.
61 *
62 * TRW Financial Systems, in accordance with their agreement with Carnegie
63 * Mellon University, makes this software available to CMU to distribute
64 * or use in any manner that they see fit as long as this message is kept with
65 * the software. For this reason TFS also grants any other persons or
66 * organisations permission to use or modify this software.
67 *
68 * TFS supplies this software to be publicly redistributed
69 * on the understanding that TFS is not responsible for the correct
70 * functioning of this software in any circumstances.
71 */
72
73 #include <sys/cdefs.h>
74 __KERNEL_RCSID(0, "$NetBSD: dpt.c,v 1.70 2014/03/16 05:20:27 dholland Exp $");
75
76 #include <sys/param.h>
77 #include <sys/systm.h>
78 #include <sys/device.h>
79 #include <sys/queue.h>
80 #include <sys/buf.h>
81 #include <sys/endian.h>
82 #include <sys/conf.h>
83 #include <sys/kauth.h>
84 #include <sys/proc.h>
85 #include <sys/mutex.h>
86
87 #include <sys/bus.h>
88 #ifdef i386
89 #include <machine/pio.h>
90 #include <machine/cputypes.h>
91 #endif
92
93 #include <dev/scsipi/scsi_all.h>
94 #include <dev/scsipi/scsipi_all.h>
95 #include <dev/scsipi/scsiconf.h>
96
97 #include <dev/ic/dptreg.h>
98 #include <dev/ic/dptvar.h>
99
100 #include <dev/i2o/dptivar.h>
101
102 #ifdef DEBUG
103 #define DPRINTF(x) printf x
104 #else
105 #define DPRINTF(x)
106 #endif
107
108 #define dpt_inb(x, o) \
109 bus_space_read_1((x)->sc_iot, (x)->sc_ioh, (o))
110 #define dpt_outb(x, o, d) \
111 bus_space_write_1((x)->sc_iot, (x)->sc_ioh, (o), (d))
112
113 static const char * const dpt_cname[] = {
114 "3334", "SmartRAID IV",
115 "3332", "SmartRAID IV",
116 "2144", "SmartCache IV",
117 "2044", "SmartCache IV",
118 "2142", "SmartCache IV",
119 "2042", "SmartCache IV",
120 "2041", "SmartCache IV",
121 "3224", "SmartRAID III",
122 "3222", "SmartRAID III",
123 "3021", "SmartRAID III",
124 "2124", "SmartCache III",
125 "2024", "SmartCache III",
126 "2122", "SmartCache III",
127 "2022", "SmartCache III",
128 "2021", "SmartCache III",
129 "2012", "SmartCache Plus",
130 "2011", "SmartCache Plus",
131 NULL, "<unknown>",
132 };
133
134 static void *dpt_sdh;
135
136 dev_type_open(dptopen);
137 dev_type_ioctl(dptioctl);
138
139 const struct cdevsw dpt_cdevsw = {
140 .d_open = dptopen,
141 .d_close = nullclose,
142 .d_read = noread,
143 .d_write = nowrite,
144 .d_ioctl = dptioctl,
145 .d_stop = nostop,
146 .d_tty = notty,
147 .d_poll = nopoll,
148 .d_mmap = nommap,
149 .d_kqfilter = nokqfilter,
150 .d_flag = D_OTHER,
151 };
152
153 extern struct cfdriver dpt_cd;
154
155 static struct dpt_sig dpt_sig = {
156 { 'd', 'P', 't', 'S', 'i', 'G'},
157 SIG_VERSION,
158 #if defined(i386)
159 PROC_INTEL,
160 #elif defined(powerpc)
161 PROC_POWERPC,
162 #elif defined(alpha)
163 PROC_ALPHA,
164 #elif defined(__mips__)
165 PROC_MIPS,
166 #elif defined(sparc64)
167 PROC_ULTRASPARC,
168 #else
169 0xff,
170 #endif
171 #if defined(i386)
172 PROC_386 | PROC_486 | PROC_PENTIUM | PROC_SEXIUM,
173 #else
174 0,
175 #endif
176 FT_HBADRVR,
177 0,
178 OEM_DPT,
179 OS_FREE_BSD, /* XXX */
180 CAP_ABOVE16MB,
181 DEV_ALL,
182 ADF_ALL_EATA,
183 0,
184 0,
185 DPT_VERSION,
186 DPT_REVISION,
187 DPT_SUBREVISION,
188 DPT_MONTH,
189 DPT_DAY,
190 DPT_YEAR,
191 "" /* Will be filled later */
192 };
193
194 static void dpt_ccb_abort(struct dpt_softc *, struct dpt_ccb *);
195 static void dpt_ccb_done(struct dpt_softc *, struct dpt_ccb *);
196 static int dpt_ccb_map(struct dpt_softc *, struct dpt_ccb *);
197 static int dpt_ccb_poll(struct dpt_softc *, struct dpt_ccb *);
198 static void dpt_ccb_unmap(struct dpt_softc *, struct dpt_ccb *);
199 static int dpt_cmd(struct dpt_softc *, struct dpt_ccb *, int, int);
200 static void dpt_ctlrinfo(struct dpt_softc *, struct dpt_eata_ctlrinfo *);
201 static void dpt_hba_inquire(struct dpt_softc *, struct eata_inquiry_data **);
202 static void dpt_minphys(struct buf *);
203 static int dpt_passthrough(struct dpt_softc *, struct eata_ucp *,
204 struct lwp *);
205 static void dpt_scsipi_request(struct scsipi_channel *,
206 scsipi_adapter_req_t, void *);
207 static void dpt_shutdown(void *);
208 static void dpt_sysinfo(struct dpt_softc *, struct dpt_sysinfo *);
209 static int dpt_wait(struct dpt_softc *, u_int8_t, u_int8_t, int);
210
211 static inline struct dpt_ccb *dpt_ccb_alloc(struct dpt_softc *);
212 static inline void dpt_ccb_free(struct dpt_softc *, struct dpt_ccb *);
213
214 static inline struct dpt_ccb *
215 dpt_ccb_alloc(struct dpt_softc *sc)
216 {
217 struct dpt_ccb *ccb;
218 int s;
219
220 s = splbio();
221 ccb = SLIST_FIRST(&sc->sc_ccb_free);
222 SLIST_REMOVE_HEAD(&sc->sc_ccb_free, ccb_chain);
223 splx(s);
224
225 return (ccb);
226 }
227
228 static inline void
229 dpt_ccb_free(struct dpt_softc *sc, struct dpt_ccb *ccb)
230 {
231 int s;
232
233 ccb->ccb_flg = 0;
234 ccb->ccb_savesp = NULL;
235 s = splbio();
236 SLIST_INSERT_HEAD(&sc->sc_ccb_free, ccb, ccb_chain);
237 splx(s);
238 }
239
240 /*
241 * Handle an interrupt from the HBA.
242 */
243 int
244 dpt_intr(void *cookie)
245 {
246 struct dpt_softc *sc;
247 struct dpt_ccb *ccb;
248 struct eata_sp *sp;
249 int forus;
250
251 sc = cookie;
252 sp = sc->sc_stp;
253 forus = 0;
254
255 for (;;) {
256 /*
257 * HBA might have interrupted while we were dealing with the
258 * last completed command, since we ACK before we deal; keep
259 * polling.
260 */
261 if ((dpt_inb(sc, HA_AUX_STATUS) & HA_AUX_INTR) == 0)
262 break;
263 forus = 1;
264
265 bus_dmamap_sync(sc->sc_dmat, sc->sc_dmamap, sc->sc_stpoff,
266 sizeof(struct eata_sp), BUS_DMASYNC_POSTREAD);
267
268 /* Might have looped before HBA can reset HBA_AUX_INTR. */
269 if (sp->sp_ccbid == -1) {
270 DELAY(50);
271
272 if ((dpt_inb(sc, HA_AUX_STATUS) & HA_AUX_INTR) == 0)
273 return (0);
274
275 printf("%s: no status\n", device_xname(sc->sc_dev));
276
277 /* Re-sync DMA map */
278 bus_dmamap_sync(sc->sc_dmat, sc->sc_dmamap,
279 sc->sc_stpoff, sizeof(struct eata_sp),
280 BUS_DMASYNC_POSTREAD);
281 }
282
283 /* Make sure CCB ID from status packet is realistic. */
284 if ((u_int)sp->sp_ccbid >= sc->sc_nccbs) {
285 printf("%s: bogus status (returned CCB id %d)\n",
286 device_xname(sc->sc_dev), sp->sp_ccbid);
287
288 /* Ack the interrupt */
289 sp->sp_ccbid = -1;
290 (void)dpt_inb(sc, HA_STATUS);
291 continue;
292 }
293
294 /* Sync up DMA map and cache cmd status. */
295 ccb = sc->sc_ccbs + sp->sp_ccbid;
296
297 bus_dmamap_sync(sc->sc_dmat, sc->sc_dmamap, CCB_OFF(sc, ccb),
298 sizeof(struct dpt_ccb), BUS_DMASYNC_POSTWRITE);
299
300 ccb->ccb_hba_status = sp->sp_hba_status & 0x7f;
301 ccb->ccb_scsi_status = sp->sp_scsi_status;
302 if (ccb->ccb_savesp != NULL)
303 memcpy(ccb->ccb_savesp, sp, sizeof(*sp));
304
305 /*
306 * Ack the interrupt and process the CCB. If this
307 * is a private CCB it's up to dpt_ccb_poll() to
308 * notice.
309 */
310 sp->sp_ccbid = -1;
311 ccb->ccb_flg |= CCB_INTR;
312 (void)dpt_inb(sc, HA_STATUS);
313 if ((ccb->ccb_flg & CCB_PRIVATE) == 0)
314 dpt_ccb_done(sc, ccb);
315 else if ((ccb->ccb_flg & CCB_WAIT) != 0)
316 wakeup(ccb);
317 }
318
319 return (forus);
320 }
321
322 /*
323 * Initialize and attach the HBA. This is the entry point from bus
324 * specific probe-and-attach code.
325 */
326 void
327 dpt_init(struct dpt_softc *sc, const char *intrstr)
328 {
329 struct scsipi_adapter *adapt;
330 struct scsipi_channel *chan;
331 struct eata_inquiry_data *ei;
332 int i, j, rv, rseg, maxchannel, maxtarget, mapsize;
333 bus_dma_segment_t seg;
334 struct eata_cfg *ec;
335 struct dpt_ccb *ccb;
336 char model[__arraycount(ei->ei_model) + __arraycount(ei->ei_suffix) + 1];
337 char vendor[__arraycount(ei->ei_vendor) + 1];
338
339 ec = &sc->sc_ec;
340 snprintf(dpt_sig.dsDescription, sizeof(dpt_sig.dsDescription),
341 "NetBSD %s DPT driver", osrelease);
342 mutex_init(&sc->sc_lock, MUTEX_DEFAULT, IPL_NONE);
343
344 /*
345 * Allocate the CCB/status packet/scratch DMA map and load.
346 */
347 sc->sc_nccbs =
348 min(be16toh(*(int16_t *)ec->ec_queuedepth), DPT_MAX_CCBS);
349 sc->sc_stpoff = sc->sc_nccbs * sizeof(struct dpt_ccb);
350 sc->sc_scroff = sc->sc_stpoff + sizeof(struct eata_sp);
351 mapsize = sc->sc_nccbs * sizeof(struct dpt_ccb) +
352 DPT_SCRATCH_SIZE + sizeof(struct eata_sp);
353
354 if ((rv = bus_dmamem_alloc(sc->sc_dmat, mapsize,
355 PAGE_SIZE, 0, &seg, 1, &rseg, BUS_DMA_NOWAIT)) != 0) {
356 aprint_error_dev(sc->sc_dev, "unable to allocate CCBs, rv = %d\n", rv);
357 return;
358 }
359
360 if ((rv = bus_dmamem_map(sc->sc_dmat, &seg, rseg, mapsize,
361 (void **)&sc->sc_ccbs, BUS_DMA_NOWAIT|BUS_DMA_COHERENT)) != 0) {
362 aprint_error_dev(sc->sc_dev, "unable to map CCBs, rv = %d\n",
363 rv);
364 return;
365 }
366
367 if ((rv = bus_dmamap_create(sc->sc_dmat, mapsize,
368 mapsize, 1, 0, BUS_DMA_NOWAIT, &sc->sc_dmamap)) != 0) {
369 aprint_error_dev(sc->sc_dev, "unable to create CCB DMA map, rv = %d\n", rv);
370 return;
371 }
372
373 if ((rv = bus_dmamap_load(sc->sc_dmat, sc->sc_dmamap,
374 sc->sc_ccbs, mapsize, NULL, BUS_DMA_NOWAIT)) != 0) {
375 aprint_error_dev(sc->sc_dev, "unable to load CCB DMA map, rv = %d\n", rv);
376 return;
377 }
378
379 sc->sc_stp = (struct eata_sp *)((char *)sc->sc_ccbs + sc->sc_stpoff);
380 sc->sc_stppa = sc->sc_dmamap->dm_segs[0].ds_addr + sc->sc_stpoff;
381 sc->sc_scr = (char *)sc->sc_ccbs + sc->sc_scroff;
382 sc->sc_scrpa = sc->sc_dmamap->dm_segs[0].ds_addr + sc->sc_scroff;
383 sc->sc_stp->sp_ccbid = -1;
384
385 /*
386 * Create the CCBs.
387 */
388 SLIST_INIT(&sc->sc_ccb_free);
389 memset(sc->sc_ccbs, 0, sizeof(struct dpt_ccb) * sc->sc_nccbs);
390
391 for (i = 0, ccb = sc->sc_ccbs; i < sc->sc_nccbs; i++, ccb++) {
392 rv = bus_dmamap_create(sc->sc_dmat, DPT_MAX_XFER,
393 DPT_SG_SIZE, DPT_MAX_XFER, 0,
394 BUS_DMA_NOWAIT | BUS_DMA_ALLOCNOW,
395 &ccb->ccb_dmamap_xfer);
396 if (rv) {
397 aprint_error_dev(sc->sc_dev, "can't create ccb dmamap (%d)\n", rv);
398 break;
399 }
400
401 ccb->ccb_id = i;
402 ccb->ccb_ccbpa = sc->sc_dmamap->dm_segs[0].ds_addr +
403 CCB_OFF(sc, ccb);
404 SLIST_INSERT_HEAD(&sc->sc_ccb_free, ccb, ccb_chain);
405 }
406
407 if (i == 0) {
408 aprint_error_dev(sc->sc_dev, "unable to create CCBs\n");
409 return;
410 } else if (i != sc->sc_nccbs) {
411 aprint_error_dev(sc->sc_dev, "%d/%d CCBs created!\n",
412 i, sc->sc_nccbs);
413 sc->sc_nccbs = i;
414 }
415
416 /* Set shutdownhook before we start any device activity. */
417 if (dpt_sdh == NULL)
418 dpt_sdh = shutdownhook_establish(dpt_shutdown, NULL);
419
420 /* Get the inquiry data from the HBA. */
421 dpt_hba_inquire(sc, &ei);
422
423 /*
424 * dpt0 at pci0 dev 12 function 0: DPT SmartRAID III (PM3224A/9X-R)
425 * dpt0: interrupting at irq 10
426 * dpt0: 64 queued commands, 1 channel(s), adapter on ID(s) 7
427 */
428 for (i = 0; i < __arraycount(ei->ei_vendor) && ei->ei_vendor[i] != ' ';
429 i++)
430 vendor[i] = ei->ei_vendor[i];
431 vendor[i] = '\0';
432
433 for (i = 0; i < __arraycount(ei->ei_model) && ei->ei_model[i] != ' ';
434 i++)
435 model[i] = ei->ei_model[i];
436 for (j = 0; j < __arraycount(ei->ei_suffix) && ei->ei_suffix[j] != ' ';
437 i++, j++)
438 model[i] = ei->ei_suffix[j];
439 model[i] = '\0';
440
441 /* Find the marketing name for the board. */
442 for (i = 0; dpt_cname[i] != NULL; i += 2)
443 if (memcmp(ei->ei_model + 2, dpt_cname[i], 4) == 0)
444 break;
445
446 aprint_normal("%s %s (%s)\n", vendor, dpt_cname[i + 1], model);
447
448 if (intrstr != NULL)
449 aprint_normal_dev(sc->sc_dev, "interrupting at %s\n",
450 intrstr);
451
452 maxchannel = (ec->ec_feat3 & EC_F3_MAX_CHANNEL_MASK) >>
453 EC_F3_MAX_CHANNEL_SHIFT;
454 maxtarget = (ec->ec_feat3 & EC_F3_MAX_TARGET_MASK) >>
455 EC_F3_MAX_TARGET_SHIFT;
456
457 aprint_normal_dev(sc->sc_dev, "%d queued commands, %d channel(s), adapter on ID(s)",
458 sc->sc_nccbs, maxchannel + 1);
459
460 for (i = 0; i <= maxchannel; i++) {
461 sc->sc_hbaid[i] = ec->ec_hba[3 - i];
462 aprint_normal(" %d", sc->sc_hbaid[i]);
463 }
464 aprint_normal("\n");
465
466 /*
467 * Reset the SCSI controller chip(s) and bus. XXX Do we need to do
468 * this for each bus?
469 */
470 if (dpt_cmd(sc, NULL, CP_IMMEDIATE, CPI_BUS_RESET))
471 panic("%s: dpt_cmd failed", device_xname(sc->sc_dev));
472
473 /* Fill in the scsipi_adapter. */
474 adapt = &sc->sc_adapt;
475 memset(adapt, 0, sizeof(*adapt));
476 adapt->adapt_dev = sc->sc_dev;
477 adapt->adapt_nchannels = maxchannel + 1;
478 adapt->adapt_openings = sc->sc_nccbs - 1;
479 adapt->adapt_max_periph = sc->sc_nccbs - 1;
480 adapt->adapt_request = dpt_scsipi_request;
481 adapt->adapt_minphys = dpt_minphys;
482
483 for (i = 0; i <= maxchannel; i++) {
484 /* Fill in the scsipi_channel. */
485 chan = &sc->sc_chans[i];
486 memset(chan, 0, sizeof(*chan));
487 chan->chan_adapter = adapt;
488 chan->chan_bustype = &scsi_bustype;
489 chan->chan_channel = i;
490 chan->chan_ntargets = maxtarget + 1;
491 chan->chan_nluns = ec->ec_maxlun + 1;
492 chan->chan_id = sc->sc_hbaid[i];
493 config_found(sc->sc_dev, chan, scsiprint);
494 }
495 }
496
497 /*
498 * Read the EATA configuration from the HBA and perform some sanity checks.
499 */
500 int
501 dpt_readcfg(struct dpt_softc *sc)
502 {
503 struct eata_cfg *ec;
504 int i, j, stat;
505 u_int16_t *p;
506
507 ec = &sc->sc_ec;
508
509 /* Older firmware may puke if we talk to it too soon after reset. */
510 dpt_outb(sc, HA_COMMAND, CP_RESET);
511 DELAY(750000);
512
513 for (i = 1000; i; i--) {
514 if ((dpt_inb(sc, HA_STATUS) & HA_ST_READY) != 0)
515 break;
516 DELAY(2000);
517 }
518
519 if (i == 0) {
520 printf("%s: HBA not ready after reset (hba status:%02x)\n",
521 device_xname(sc->sc_dev), dpt_inb(sc, HA_STATUS));
522 return (-1);
523 }
524
525 while((((stat = dpt_inb(sc, HA_STATUS))
526 != (HA_ST_READY|HA_ST_SEEK_COMPLETE))
527 && (stat != (HA_ST_READY|HA_ST_SEEK_COMPLETE|HA_ST_ERROR))
528 && (stat != (HA_ST_READY|HA_ST_SEEK_COMPLETE|HA_ST_ERROR|HA_ST_DRQ)))
529 || (dpt_wait(sc, HA_ST_BUSY, 0, 2000))) {
530 /* RAID drives still spinning up? */
531 if(dpt_inb(sc, HA_ERROR) != 'D' ||
532 dpt_inb(sc, HA_ERROR + 1) != 'P' ||
533 dpt_inb(sc, HA_ERROR + 2) != 'T') {
534 printf("%s: HBA not ready\n", device_xname(sc->sc_dev));
535 return (-1);
536 }
537 }
538
539 /*
540 * Issue the read-config command and wait for the data to appear.
541 *
542 * Apparently certian firmware revisions won't DMA later on if we
543 * request the config data using PIO, but it makes it a lot easier
544 * as no DMA setup is required.
545 */
546 dpt_outb(sc, HA_COMMAND, CP_PIO_GETCFG);
547 memset(ec, 0, sizeof(*ec));
548 i = ((int)(uintptr_t)&((struct eata_cfg *)0)->ec_cfglen +
549 sizeof(ec->ec_cfglen)) >> 1;
550 p = (u_int16_t *)ec;
551
552 if (dpt_wait(sc, 0xFF, HA_ST_DATA_RDY, 2000)) {
553 printf("%s: cfg data didn't appear (hba status:%02x)\n",
554 device_xname(sc->sc_dev), dpt_inb(sc, HA_STATUS));
555 return (-1);
556 }
557
558 /* Begin reading. */
559 while (i--)
560 *p++ = bus_space_read_stream_2(sc->sc_iot, sc->sc_ioh, HA_DATA);
561
562 if ((i = ec->ec_cfglen) > (sizeof(struct eata_cfg)
563 - (int)(uintptr_t)(&(((struct eata_cfg *)0L)->ec_cfglen))
564 - sizeof(ec->ec_cfglen)))
565 i = sizeof(struct eata_cfg)
566 - (int)(uintptr_t)(&(((struct eata_cfg *)0L)->ec_cfglen))
567 - sizeof(ec->ec_cfglen);
568
569 j = i + (int)(uintptr_t)(&(((struct eata_cfg *)0L)->ec_cfglen)) +
570 sizeof(ec->ec_cfglen);
571 i >>= 1;
572
573 while (i--)
574 *p++ = bus_space_read_stream_2(sc->sc_iot, sc->sc_ioh, HA_DATA);
575
576 /* Flush until we have read 512 bytes. */
577 i = (512 - j + 1) >> 1;
578 while (i--)
579 (void)bus_space_read_stream_2(sc->sc_iot, sc->sc_ioh, HA_DATA);
580
581 /* Defaults for older firmware... */
582 if (p <= (u_short *)&ec->ec_hba[DPT_MAX_CHANNELS - 1])
583 ec->ec_hba[DPT_MAX_CHANNELS - 1] = 7;
584
585 if ((dpt_inb(sc, HA_STATUS) & HA_ST_ERROR) != 0) {
586 aprint_error_dev(sc->sc_dev, "HBA error\n");
587 return (-1);
588 }
589
590 if (memcmp(ec->ec_eatasig, "EATA", 4) != 0) {
591 aprint_error_dev(sc->sc_dev, "EATA signature mismatch\n");
592 return (-1);
593 }
594
595 if ((ec->ec_feat0 & EC_F0_HBA_VALID) == 0) {
596 aprint_error_dev(sc->sc_dev, "ec_hba field invalid\n");
597 return (-1);
598 }
599
600 if ((ec->ec_feat0 & EC_F0_DMA_SUPPORTED) == 0) {
601 aprint_error_dev(sc->sc_dev, "DMA not supported\n");
602 return (-1);
603 }
604
605 return (0);
606 }
607
608 /*
609 * Our `shutdownhook' to cleanly shut down the HBA. The HBA must flush all
610 * data from it's cache and mark array groups as clean.
611 *
612 * XXX This doesn't always work (i.e., the HBA may still be flushing after
613 * we tell root that it's safe to power off).
614 */
615 static void
616 dpt_shutdown(void *cookie)
617 {
618 extern struct cfdriver dpt_cd;
619 struct dpt_softc *sc;
620 int i;
621
622 printf("shutting down dpt devices...");
623
624 for (i = 0; i < dpt_cd.cd_ndevs; i++) {
625 if ((sc = device_lookup_private(&dpt_cd, i)) == NULL)
626 continue;
627 dpt_cmd(sc, NULL, CP_IMMEDIATE, CPI_POWEROFF_WARN);
628 }
629
630 delay(10000*1000);
631 printf(" done\n");
632 }
633
634 /*
635 * Send an EATA command to the HBA.
636 */
637 static int
638 dpt_cmd(struct dpt_softc *sc, struct dpt_ccb *ccb, int eatacmd, int icmd)
639 {
640 u_int32_t pa;
641 int i, s;
642
643 s = splbio();
644
645 for (i = 20000; i != 0; i--) {
646 if ((dpt_inb(sc, HA_AUX_STATUS) & HA_AUX_BUSY) == 0)
647 break;
648 DELAY(50);
649 }
650 if (i == 0) {
651 splx(s);
652 return (-1);
653 }
654
655 pa = (ccb != NULL ? ccb->ccb_ccbpa : 0);
656 dpt_outb(sc, HA_DMA_BASE + 0, (pa ) & 0xff);
657 dpt_outb(sc, HA_DMA_BASE + 1, (pa >> 8) & 0xff);
658 dpt_outb(sc, HA_DMA_BASE + 2, (pa >> 16) & 0xff);
659 dpt_outb(sc, HA_DMA_BASE + 3, (pa >> 24) & 0xff);
660
661 if (eatacmd == CP_IMMEDIATE)
662 dpt_outb(sc, HA_ICMD, icmd);
663
664 dpt_outb(sc, HA_COMMAND, eatacmd);
665
666 splx(s);
667 return (0);
668 }
669
670 /*
671 * Wait for the HBA status register to reach a specific state.
672 */
673 static int
674 dpt_wait(struct dpt_softc *sc, u_int8_t mask, u_int8_t state, int ms)
675 {
676
677 for (ms *= 10; ms != 0; ms--) {
678 if ((dpt_inb(sc, HA_STATUS) & mask) == state)
679 return (0);
680 DELAY(100);
681 }
682
683 return (-1);
684 }
685
686 /*
687 * Spin waiting for a command to finish. The timeout value from the CCB is
688 * used. The CCB must be marked with CCB_PRIVATE, otherwise it'll will get
689 * recycled before we get a look at it.
690 */
691 static int
692 dpt_ccb_poll(struct dpt_softc *sc, struct dpt_ccb *ccb)
693 {
694 int i, s;
695
696 #ifdef DEBUG
697 if ((ccb->ccb_flg & CCB_PRIVATE) == 0)
698 panic("dpt_ccb_poll: called for non-CCB_PRIVATE request");
699 #endif
700
701 s = splbio();
702
703 if ((ccb->ccb_flg & CCB_INTR) != 0) {
704 splx(s);
705 return (0);
706 }
707
708 for (i = ccb->ccb_timeout * 20; i != 0; i--) {
709 if ((dpt_inb(sc, HA_AUX_STATUS) & HA_AUX_INTR) != 0)
710 dpt_intr(sc);
711 if ((ccb->ccb_flg & CCB_INTR) != 0)
712 break;
713 DELAY(50);
714 }
715
716 splx(s);
717 return (i == 0);
718 }
719
720 /*
721 * We have a command which has been processed by the HBA, so now we look to
722 * see how the operation went. CCBs marked CCB_PRIVATE are not passed here
723 * by dpt_intr().
724 */
725 static void
726 dpt_ccb_done(struct dpt_softc *sc, struct dpt_ccb *ccb)
727 {
728 struct scsipi_xfer *xs;
729
730 xs = ccb->ccb_xs;
731
732 SC_DEBUG(xs->xs_periph, SCSIPI_DB2, ("dpt_ccb_done\n"));
733
734 /*
735 * If we were a data transfer, unload the map that described the
736 * data buffer.
737 */
738 if (xs->datalen != 0)
739 dpt_ccb_unmap(sc, ccb);
740
741 if (xs->error == XS_NOERROR) {
742 if (ccb->ccb_hba_status != SP_HBA_NO_ERROR) {
743 switch (ccb->ccb_hba_status) {
744 case SP_HBA_ERROR_SEL_TO:
745 xs->error = XS_SELTIMEOUT;
746 break;
747 case SP_HBA_ERROR_RESET:
748 xs->error = XS_RESET;
749 break;
750 default:
751 printf("%s: HBA status %x\n",
752 device_xname(sc->sc_dev), ccb->ccb_hba_status);
753 xs->error = XS_DRIVER_STUFFUP;
754 break;
755 }
756 } else if (ccb->ccb_scsi_status != SCSI_OK) {
757 switch (ccb->ccb_scsi_status) {
758 case SCSI_CHECK:
759 memcpy(&xs->sense.scsi_sense, &ccb->ccb_sense,
760 sizeof(xs->sense.scsi_sense));
761 xs->error = XS_SENSE;
762 break;
763 case SCSI_BUSY:
764 case SCSI_QUEUE_FULL:
765 xs->error = XS_BUSY;
766 break;
767 default:
768 scsipi_printaddr(xs->xs_periph);
769 printf("SCSI status %x\n",
770 ccb->ccb_scsi_status);
771 xs->error = XS_DRIVER_STUFFUP;
772 break;
773 }
774 } else
775 xs->resid = 0;
776
777 xs->status = ccb->ccb_scsi_status;
778 }
779
780 /* Free up the CCB and mark the command as done. */
781 dpt_ccb_free(sc, ccb);
782 scsipi_done(xs);
783 }
784
785 /*
786 * Specified CCB has timed out, abort it.
787 */
788 static void
789 dpt_ccb_abort(struct dpt_softc *sc, struct dpt_ccb *ccb)
790 {
791 struct scsipi_periph *periph;
792 struct scsipi_xfer *xs;
793 int s;
794
795 xs = ccb->ccb_xs;
796 periph = xs->xs_periph;
797
798 scsipi_printaddr(periph);
799 printf("timed out (status:%02x aux status:%02x)",
800 dpt_inb(sc, HA_STATUS), dpt_inb(sc, HA_AUX_STATUS));
801
802 s = splbio();
803
804 if ((ccb->ccb_flg & CCB_ABORT) != 0) {
805 /* Abort timed out, reset the HBA */
806 printf(" AGAIN, resetting HBA\n");
807 dpt_outb(sc, HA_COMMAND, CP_RESET);
808 DELAY(750000);
809 } else {
810 /* Abort the operation that has timed out */
811 printf("\n");
812 xs->error = XS_TIMEOUT;
813 ccb->ccb_timeout = DPT_ABORT_TIMEOUT;
814 ccb->ccb_flg |= CCB_ABORT;
815 /* Start the abort */
816 if (dpt_cmd(sc, ccb, CP_IMMEDIATE, CPI_SPEC_ABORT))
817 aprint_error_dev(sc->sc_dev, "dpt_cmd failed\n");
818 }
819
820 splx(s);
821 }
822
823 /*
824 * Map a data transfer.
825 */
826 static int
827 dpt_ccb_map(struct dpt_softc *sc, struct dpt_ccb *ccb)
828 {
829 struct scsipi_xfer *xs;
830 bus_dmamap_t xfer;
831 bus_dma_segment_t *ds;
832 struct eata_sg *sg;
833 struct eata_cp *cp;
834 int rv, i;
835
836 xs = ccb->ccb_xs;
837 xfer = ccb->ccb_dmamap_xfer;
838 cp = &ccb->ccb_eata_cp;
839
840 rv = bus_dmamap_load(sc->sc_dmat, xfer, xs->data, xs->datalen, NULL,
841 ((xs->xs_control & XS_CTL_NOSLEEP) != 0 ?
842 BUS_DMA_NOWAIT : BUS_DMA_WAITOK) | BUS_DMA_STREAMING |
843 ((xs->xs_control & XS_CTL_DATA_IN) ? BUS_DMA_READ : BUS_DMA_WRITE));
844
845 switch (rv) {
846 case 0:
847 break;
848 case ENOMEM:
849 case EAGAIN:
850 xs->error = XS_RESOURCE_SHORTAGE;
851 break;
852 default:
853 xs->error = XS_DRIVER_STUFFUP;
854 printf("%s: error %d loading map\n", device_xname(sc->sc_dev), rv);
855 break;
856 }
857
858 if (xs->error != XS_NOERROR) {
859 dpt_ccb_free(sc, ccb);
860 scsipi_done(xs);
861 return (-1);
862 }
863
864 bus_dmamap_sync(sc->sc_dmat, xfer, 0, xfer->dm_mapsize,
865 (xs->xs_control & XS_CTL_DATA_IN) != 0 ? BUS_DMASYNC_PREREAD :
866 BUS_DMASYNC_PREWRITE);
867
868 /* Don't bother using scatter/gather for just 1 seg */
869 if (xfer->dm_nsegs == 1) {
870 cp->cp_dataaddr = htobe32(xfer->dm_segs[0].ds_addr);
871 cp->cp_datalen = htobe32(xfer->dm_segs[0].ds_len);
872 } else {
873 /*
874 * Load the hardware scatter/gather map with
875 * the contents of the DMA map.
876 */
877 sg = ccb->ccb_sg;
878 ds = xfer->dm_segs;
879 for (i = 0; i < xfer->dm_nsegs; i++, sg++, ds++) {
880 sg->sg_addr = htobe32(ds->ds_addr);
881 sg->sg_len = htobe32(ds->ds_len);
882 }
883 cp->cp_dataaddr = htobe32(CCB_OFF(sc, ccb) +
884 sc->sc_dmamap->dm_segs[0].ds_addr +
885 offsetof(struct dpt_ccb, ccb_sg));
886 cp->cp_datalen = htobe32(i * sizeof(struct eata_sg));
887 cp->cp_ctl0 |= CP_C0_SCATTER;
888 }
889
890 return (0);
891 }
892
893 /*
894 * Unmap a transfer.
895 */
896 static void
897 dpt_ccb_unmap(struct dpt_softc *sc, struct dpt_ccb *ccb)
898 {
899
900 bus_dmamap_sync(sc->sc_dmat, ccb->ccb_dmamap_xfer, 0,
901 ccb->ccb_dmamap_xfer->dm_mapsize,
902 (ccb->ccb_eata_cp.cp_ctl0 & CP_C0_DATA_IN) != 0 ?
903 BUS_DMASYNC_POSTREAD : BUS_DMASYNC_POSTWRITE);
904 bus_dmamap_unload(sc->sc_dmat, ccb->ccb_dmamap_xfer);
905 }
906
907 /*
908 * Adjust the size of each I/O before it passes to the SCSI layer.
909 */
910 static void
911 dpt_minphys(struct buf *bp)
912 {
913
914 if (bp->b_bcount > DPT_MAX_XFER)
915 bp->b_bcount = DPT_MAX_XFER;
916 minphys(bp);
917 }
918
919 /*
920 * Start a SCSI command.
921 */
922 static void
923 dpt_scsipi_request(struct scsipi_channel *chan, scsipi_adapter_req_t req,
924 void *arg)
925 {
926 struct dpt_softc *sc;
927 struct scsipi_xfer *xs;
928 int flags;
929 struct scsipi_periph *periph;
930 struct dpt_ccb *ccb;
931 struct eata_cp *cp;
932
933 sc = device_private(chan->chan_adapter->adapt_dev);
934
935 switch (req) {
936 case ADAPTER_REQ_RUN_XFER:
937 xs = arg;
938 periph = xs->xs_periph;
939 flags = xs->xs_control;
940
941 #ifdef DIAGNOSTIC
942 /* Cmds must be no more than 12 bytes for us. */
943 if (xs->cmdlen > 12) {
944 xs->error = XS_DRIVER_STUFFUP;
945 scsipi_done(xs);
946 break;
947 }
948 #endif
949 /*
950 * XXX We can't reset devices just yet. Apparently some
951 * older firmware revisions don't even support it.
952 */
953 if ((flags & XS_CTL_RESET) != 0) {
954 xs->error = XS_DRIVER_STUFFUP;
955 scsipi_done(xs);
956 break;
957 }
958
959 /*
960 * Get a CCB and fill it.
961 */
962 ccb = dpt_ccb_alloc(sc);
963 ccb->ccb_xs = xs;
964 ccb->ccb_timeout = xs->timeout;
965
966 cp = &ccb->ccb_eata_cp;
967 memcpy(&cp->cp_cdb_cmd, xs->cmd, xs->cmdlen);
968 cp->cp_ccbid = ccb->ccb_id;
969 cp->cp_senselen = sizeof(ccb->ccb_sense);
970 cp->cp_stataddr = htobe32(sc->sc_stppa);
971 cp->cp_ctl0 = CP_C0_AUTO_SENSE;
972 cp->cp_ctl1 = 0;
973 cp->cp_ctl2 = 0;
974 cp->cp_ctl3 = periph->periph_target << CP_C3_ID_SHIFT;
975 cp->cp_ctl3 |= chan->chan_channel << CP_C3_CHANNEL_SHIFT;
976 cp->cp_ctl4 = periph->periph_lun << CP_C4_LUN_SHIFT;
977 cp->cp_ctl4 |= CP_C4_DIS_PRI | CP_C4_IDENTIFY;
978
979 if ((flags & XS_CTL_DATA_IN) != 0)
980 cp->cp_ctl0 |= CP_C0_DATA_IN;
981 if ((flags & XS_CTL_DATA_OUT) != 0)
982 cp->cp_ctl0 |= CP_C0_DATA_OUT;
983 if (sc->sc_hbaid[chan->chan_channel] == periph->periph_target)
984 cp->cp_ctl0 |= CP_C0_INTERPRET;
985
986 /* Synchronous xfers musn't write-back through the cache. */
987 if (xs->bp != NULL)
988 if ((xs->bp->b_flags & (B_ASYNC | B_READ)) == 0)
989 cp->cp_ctl2 |= CP_C2_NO_CACHE;
990
991 cp->cp_senseaddr =
992 htobe32(sc->sc_dmamap->dm_segs[0].ds_addr +
993 CCB_OFF(sc, ccb) + offsetof(struct dpt_ccb, ccb_sense));
994
995 if (xs->datalen != 0) {
996 if (dpt_ccb_map(sc, ccb))
997 break;
998 } else {
999 cp->cp_dataaddr = 0;
1000 cp->cp_datalen = 0;
1001 }
1002
1003 /* Sync up CCB and status packet. */
1004 bus_dmamap_sync(sc->sc_dmat, sc->sc_dmamap,
1005 CCB_OFF(sc, ccb), sizeof(struct dpt_ccb),
1006 BUS_DMASYNC_PREWRITE);
1007 bus_dmamap_sync(sc->sc_dmat, sc->sc_dmamap, sc->sc_stpoff,
1008 sizeof(struct eata_sp), BUS_DMASYNC_PREREAD);
1009
1010 /*
1011 * Start the command.
1012 */
1013 if ((xs->xs_control & XS_CTL_POLL) != 0)
1014 ccb->ccb_flg |= CCB_PRIVATE;
1015
1016 if (dpt_cmd(sc, ccb, CP_DMA_CMD, 0)) {
1017 aprint_error_dev(sc->sc_dev, "dpt_cmd failed\n");
1018 xs->error = XS_DRIVER_STUFFUP;
1019 if (xs->datalen != 0)
1020 dpt_ccb_unmap(sc, ccb);
1021 dpt_ccb_free(sc, ccb);
1022 break;
1023 }
1024
1025 if ((xs->xs_control & XS_CTL_POLL) == 0)
1026 break;
1027
1028 if (dpt_ccb_poll(sc, ccb)) {
1029 dpt_ccb_abort(sc, ccb);
1030 /* Wait for abort to complete... */
1031 if (dpt_ccb_poll(sc, ccb))
1032 dpt_ccb_abort(sc, ccb);
1033 }
1034
1035 dpt_ccb_done(sc, ccb);
1036 break;
1037
1038 case ADAPTER_REQ_GROW_RESOURCES:
1039 /*
1040 * Not supported, since we allocate the maximum number of
1041 * CCBs up front.
1042 */
1043 break;
1044
1045 case ADAPTER_REQ_SET_XFER_MODE:
1046 /*
1047 * This will be handled by the HBA itself, and we can't
1048 * modify that (ditto for tagged queueing).
1049 */
1050 break;
1051 }
1052 }
1053
1054 /*
1055 * Get inquiry data from the adapter.
1056 */
1057 static void
1058 dpt_hba_inquire(struct dpt_softc *sc, struct eata_inquiry_data **ei)
1059 {
1060 struct dpt_ccb *ccb;
1061 struct eata_cp *cp;
1062
1063 *ei = (struct eata_inquiry_data *)sc->sc_scr;
1064
1065 /* Get a CCB and mark as private */
1066 ccb = dpt_ccb_alloc(sc);
1067 ccb->ccb_flg |= CCB_PRIVATE;
1068 ccb->ccb_timeout = 200;
1069
1070 /* Put all the arguments into the CCB. */
1071 cp = &ccb->ccb_eata_cp;
1072 cp->cp_ccbid = ccb->ccb_id;
1073 cp->cp_senselen = sizeof(ccb->ccb_sense);
1074 cp->cp_senseaddr = 0;
1075 cp->cp_stataddr = htobe32(sc->sc_stppa);
1076 cp->cp_dataaddr = htobe32(sc->sc_scrpa);
1077 cp->cp_datalen = htobe32(sizeof(struct eata_inquiry_data));
1078 cp->cp_ctl0 = CP_C0_DATA_IN | CP_C0_INTERPRET;
1079 cp->cp_ctl1 = 0;
1080 cp->cp_ctl2 = 0;
1081 cp->cp_ctl3 = sc->sc_hbaid[0] << CP_C3_ID_SHIFT;
1082 cp->cp_ctl4 = CP_C4_DIS_PRI | CP_C4_IDENTIFY;
1083
1084 /* Put together the SCSI inquiry command. */
1085 memset(&cp->cp_cdb_cmd, 0, 12);
1086 cp->cp_cdb_cmd = INQUIRY;
1087 cp->cp_cdb_len = sizeof(struct eata_inquiry_data);
1088
1089 /* Sync up CCB, status packet and scratch area. */
1090 bus_dmamap_sync(sc->sc_dmat, sc->sc_dmamap, CCB_OFF(sc, ccb),
1091 sizeof(struct dpt_ccb), BUS_DMASYNC_PREWRITE);
1092 bus_dmamap_sync(sc->sc_dmat, sc->sc_dmamap, sc->sc_stpoff,
1093 sizeof(struct eata_sp), BUS_DMASYNC_PREREAD);
1094 bus_dmamap_sync(sc->sc_dmat, sc->sc_dmamap, sc->sc_scroff,
1095 sizeof(struct eata_inquiry_data), BUS_DMASYNC_PREREAD);
1096
1097 /* Start the command and poll on completion. */
1098 if (dpt_cmd(sc, ccb, CP_DMA_CMD, 0))
1099 panic("%s: dpt_cmd failed", device_xname(sc->sc_dev));
1100
1101 if (dpt_ccb_poll(sc, ccb))
1102 panic("%s: inquiry timed out", device_xname(sc->sc_dev));
1103
1104 if (ccb->ccb_hba_status != SP_HBA_NO_ERROR ||
1105 ccb->ccb_scsi_status != SCSI_OK)
1106 panic("%s: inquiry failed (hba:%02x scsi:%02x)",
1107 device_xname(sc->sc_dev), ccb->ccb_hba_status,
1108 ccb->ccb_scsi_status);
1109
1110 /* Sync up the DMA map and free CCB, returning. */
1111 bus_dmamap_sync(sc->sc_dmat, sc->sc_dmamap, sc->sc_scroff,
1112 sizeof(struct eata_inquiry_data), BUS_DMASYNC_POSTREAD);
1113 dpt_ccb_free(sc, ccb);
1114 }
1115
1116 int
1117 dptopen(dev_t dev, int flag, int mode, struct lwp *l)
1118 {
1119
1120 if (device_lookup(&dpt_cd, minor(dev)) == NULL)
1121 return (ENXIO);
1122
1123 return (0);
1124 }
1125
1126 int
1127 dptioctl(dev_t dev, u_long cmd, void *data, int flag, struct lwp *l)
1128 {
1129 struct dpt_softc *sc;
1130 int rv;
1131
1132 sc = device_lookup_private(&dpt_cd, minor(dev));
1133
1134 switch (cmd & 0xffff) {
1135 case DPT_SIGNATURE:
1136 memcpy(data, &dpt_sig, min(IOCPARM_LEN(cmd), sizeof(dpt_sig)));
1137 break;
1138
1139 case DPT_CTRLINFO:
1140 dpt_ctlrinfo(sc, (struct dpt_eata_ctlrinfo *)data);
1141 break;
1142
1143 case DPT_SYSINFO:
1144 dpt_sysinfo(sc, (struct dpt_sysinfo *)data);
1145 break;
1146
1147 case DPT_BLINKLED:
1148 /*
1149 * XXX Don't know how to get this from EATA boards. I think
1150 * it involves waiting for a "DPT" sequence from HA_ERROR
1151 * and then reading one of the HA_ICMD registers.
1152 */
1153 *(int *)data = 0;
1154 break;
1155
1156 case DPT_EATAUSRCMD:
1157 rv = kauth_authorize_device_passthru(l->l_cred, dev,
1158 KAUTH_REQ_DEVICE_RAWIO_PASSTHRU_ALL, data);
1159 if (rv)
1160 return (rv);
1161
1162 if (IOCPARM_LEN(cmd) < sizeof(struct eata_ucp)) {
1163 DPRINTF(("%s: ucp %lu vs %lu bytes\n",
1164 device_xname(sc->sc_dev), IOCPARM_LEN(cmd),
1165 (unsigned long int)sizeof(struct eata_ucp)));
1166 return (EINVAL);
1167 }
1168
1169 mutex_enter(&sc->sc_lock);
1170 rv = dpt_passthrough(sc, (struct eata_ucp *)data, l);
1171 mutex_exit(&sc->sc_lock);
1172
1173 return (rv);
1174
1175 default:
1176 DPRINTF(("%s: unknown ioctl %lx\n", device_xname(sc->sc_dev), cmd));
1177 return (ENOTTY);
1178 }
1179
1180 return (0);
1181 }
1182
1183 void
1184 dpt_ctlrinfo(struct dpt_softc *sc, struct dpt_eata_ctlrinfo *info)
1185 {
1186
1187 memset(info, 0, sizeof(*info));
1188 info->id = sc->sc_hbaid[0];
1189 info->vect = sc->sc_isairq;
1190 info->base = sc->sc_isaport;
1191 info->qdepth = sc->sc_nccbs;
1192 info->sgsize = DPT_SG_SIZE * sizeof(struct eata_sg);
1193 info->heads = 16;
1194 info->sectors = 63;
1195 info->do_drive32 = 1;
1196 info->primary = 1;
1197 info->cpLength = sizeof(struct eata_cp);
1198 info->spLength = sizeof(struct eata_sp);
1199 info->drqNum = sc->sc_isadrq;
1200 }
1201
1202 void
1203 dpt_sysinfo(struct dpt_softc *sc, struct dpt_sysinfo *info)
1204 {
1205 #ifdef i386
1206 int i, j;
1207 #endif
1208
1209 memset(info, 0, sizeof(*info));
1210
1211 #ifdef i386
1212 outb (0x70, 0x12);
1213 i = inb(0x71);
1214 j = i >> 4;
1215 if (i == 0x0f) {
1216 outb (0x70, 0x19);
1217 j = inb (0x71);
1218 }
1219 info->drive0CMOS = j;
1220
1221 j = i & 0x0f;
1222 if (i == 0x0f) {
1223 outb (0x70, 0x1a);
1224 j = inb (0x71);
1225 }
1226 info->drive1CMOS = j;
1227 info->processorFamily = dpt_sig.dsProcessorFamily;
1228
1229 /*
1230 * Get the conventional memory size from CMOS.
1231 */
1232 outb(0x70, 0x16);
1233 j = inb(0x71);
1234 j <<= 8;
1235 outb(0x70, 0x15);
1236 j |= inb(0x71);
1237 info->conventionalMemSize = j;
1238
1239 /*
1240 * Get the extended memory size from CMOS.
1241 */
1242 outb(0x70, 0x31);
1243 j = inb(0x71);
1244 j <<= 8;
1245 outb(0x70, 0x30);
1246 j |= inb(0x71);
1247 info->extendedMemSize = j;
1248
1249 switch (cpu_class) {
1250 case CPUCLASS_386:
1251 info->processorType = PROC_386;
1252 break;
1253 case CPUCLASS_486:
1254 info->processorType = PROC_486;
1255 break;
1256 case CPUCLASS_586:
1257 info->processorType = PROC_PENTIUM;
1258 break;
1259 case CPUCLASS_686:
1260 default:
1261 info->processorType = PROC_SEXIUM;
1262 break;
1263 }
1264
1265 info->flags = SI_CMOS_Valid | SI_BusTypeValid |
1266 SI_MemorySizeValid | SI_NO_SmartROM;
1267 #else
1268 info->flags = SI_BusTypeValid | SI_NO_SmartROM;
1269 #endif
1270
1271 info->busType = sc->sc_bustype;
1272 }
1273
1274 int
1275 dpt_passthrough(struct dpt_softc *sc, struct eata_ucp *ucp, struct lwp *l)
1276 {
1277 struct dpt_ccb *ccb;
1278 struct eata_sp sp;
1279 struct eata_cp *cp;
1280 struct eata_sg *sg;
1281 bus_dmamap_t xfer = 0; /* XXX: gcc */
1282 bus_dma_segment_t *ds;
1283 int datain = 0, s, rv = 0, i, uslen; /* XXX: gcc */
1284
1285 /*
1286 * Get a CCB and fill.
1287 */
1288 ccb = dpt_ccb_alloc(sc);
1289 ccb->ccb_flg |= CCB_PRIVATE | CCB_WAIT;
1290 ccb->ccb_timeout = 0;
1291 ccb->ccb_savesp = &sp;
1292
1293 cp = &ccb->ccb_eata_cp;
1294 memcpy(cp, ucp->ucp_cp, sizeof(ucp->ucp_cp));
1295 uslen = cp->cp_senselen;
1296 cp->cp_ccbid = ccb->ccb_id;
1297 cp->cp_senselen = sizeof(ccb->ccb_sense);
1298 cp->cp_senseaddr = htobe32(sc->sc_dmamap->dm_segs[0].ds_addr +
1299 CCB_OFF(sc, ccb) + offsetof(struct dpt_ccb, ccb_sense));
1300 cp->cp_stataddr = htobe32(sc->sc_stppa);
1301
1302 /*
1303 * Map data transfers.
1304 */
1305 if (ucp->ucp_dataaddr && ucp->ucp_datalen) {
1306 xfer = ccb->ccb_dmamap_xfer;
1307 datain = ((cp->cp_ctl0 & CP_C0_DATA_IN) != 0);
1308
1309 if (ucp->ucp_datalen > DPT_MAX_XFER) {
1310 DPRINTF(("%s: xfer too big\n", device_xname(sc->sc_dev)));
1311 dpt_ccb_free(sc, ccb);
1312 return (EFBIG);
1313 }
1314 rv = bus_dmamap_load(sc->sc_dmat, xfer,
1315 ucp->ucp_dataaddr, ucp->ucp_datalen, l->l_proc,
1316 BUS_DMA_WAITOK | BUS_DMA_STREAMING |
1317 (datain ? BUS_DMA_READ : BUS_DMA_WRITE));
1318 if (rv != 0) {
1319 DPRINTF(("%s: map failed; %d\n", device_xname(sc->sc_dev),
1320 rv));
1321 dpt_ccb_free(sc, ccb);
1322 return (rv);
1323 }
1324
1325 bus_dmamap_sync(sc->sc_dmat, xfer, 0, xfer->dm_mapsize,
1326 (datain ? BUS_DMASYNC_PREREAD : BUS_DMASYNC_PREWRITE));
1327
1328 sg = ccb->ccb_sg;
1329 ds = xfer->dm_segs;
1330 for (i = 0; i < xfer->dm_nsegs; i++, sg++, ds++) {
1331 sg->sg_addr = htobe32(ds->ds_addr);
1332 sg->sg_len = htobe32(ds->ds_len);
1333 }
1334 cp->cp_dataaddr = htobe32(CCB_OFF(sc, ccb) +
1335 sc->sc_dmamap->dm_segs[0].ds_addr +
1336 offsetof(struct dpt_ccb, ccb_sg));
1337 cp->cp_datalen = htobe32(i * sizeof(struct eata_sg));
1338 cp->cp_ctl0 |= CP_C0_SCATTER;
1339 } else {
1340 cp->cp_dataaddr = 0;
1341 cp->cp_datalen = 0;
1342 }
1343
1344 /*
1345 * Start the command and sleep on completion.
1346 */
1347 bus_dmamap_sync(sc->sc_dmat, sc->sc_dmamap, CCB_OFF(sc, ccb),
1348 sizeof(struct dpt_ccb), BUS_DMASYNC_PREWRITE);
1349 s = splbio();
1350 bus_dmamap_sync(sc->sc_dmat, sc->sc_dmamap, sc->sc_stpoff,
1351 sizeof(struct eata_sp), BUS_DMASYNC_PREREAD);
1352 if (dpt_cmd(sc, ccb, CP_DMA_CMD, 0))
1353 panic("%s: dpt_cmd failed", device_xname(sc->sc_dev));
1354 tsleep(ccb, PWAIT, "dptucmd", 0);
1355 splx(s);
1356
1357 /*
1358 * Sync up the DMA map and copy out results.
1359 */
1360 bus_dmamap_sync(sc->sc_dmat, sc->sc_dmamap, CCB_OFF(sc, ccb),
1361 sizeof(struct dpt_ccb), BUS_DMASYNC_POSTWRITE);
1362
1363 if (cp->cp_datalen != 0) {
1364 bus_dmamap_sync(sc->sc_dmat, xfer, 0, xfer->dm_mapsize,
1365 (datain ? BUS_DMASYNC_POSTREAD : BUS_DMASYNC_POSTWRITE));
1366 bus_dmamap_unload(sc->sc_dmat, xfer);
1367 }
1368
1369 if (ucp->ucp_stataddr != NULL) {
1370 rv = copyout(&sp, ucp->ucp_stataddr, sizeof(sp));
1371 if (rv != 0) {
1372 DPRINTF(("%s: sp copyout() failed\n",
1373 device_xname(sc->sc_dev)));
1374 }
1375 }
1376 if (rv == 0 && ucp->ucp_senseaddr != NULL) {
1377 i = min(uslen, sizeof(ccb->ccb_sense));
1378 rv = copyout(&ccb->ccb_sense, ucp->ucp_senseaddr, i);
1379 if (rv != 0) {
1380 DPRINTF(("%s: sense copyout() failed\n",
1381 device_xname(sc->sc_dev)));
1382 }
1383 }
1384
1385 ucp->ucp_hstatus = (u_int8_t)ccb->ccb_hba_status;
1386 ucp->ucp_tstatus = (u_int8_t)ccb->ccb_scsi_status;
1387 dpt_ccb_free(sc, ccb);
1388 return (rv);
1389 }
1390