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