Sync usage with man page.
[netbsd-mini2440.git] / sys / arch / sandpoint / stand / netboot / siisata.c
blobc9b11057c38890b89b0f90daedf613a1737dd43e
1 /* $NetBSD: siisata.c,v 1.7 2008/05/12 09:29:56 nisimura Exp $ */
3 /*-
4 * Copyright (c) 2008 The NetBSD Foundation, Inc.
5 * All rights reserved.
7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Tohru Nishimura.
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
32 #include <sys/param.h>
33 #include <sys/disklabel.h>
35 #include <dev/ic/wdcreg.h>
36 #include <dev/ata/atareg.h>
38 #include <lib/libsa/stand.h>
39 #include "globals.h"
42 * - no vtophys() translation, vaddr_t == paddr_t.
44 #define DEVTOV(pa) (uint32_t)(pa)
46 int siisata_match(unsigned, void *);
47 void *siisata_init(unsigned, void *);
49 static void map3112chan(unsigned, int, struct atac_channel *);
50 static void map3114chan(unsigned, int, struct atac_channel *);
52 int
53 siisata_match(unsigned tag, void *data)
55 unsigned v;
57 v = pcicfgread(tag, PCI_ID_REG);
58 switch (v) {
59 case PCI_DEVICE(0x1095, 0x3112): /* SiI 3112 SATALink */
60 case PCI_DEVICE(0x1095, 0x3512): /* 3512 SATALink */
61 case PCI_DEVICE(0x1095, 0x3114): /* SiI 3114 SATALink */
62 return 1;
64 return 0;
67 void *
68 siisata_init(unsigned tag, void *data)
70 unsigned val, chvalid;
71 struct atac_softc *l;
73 val = pcicfgread(tag, PCI_ID_REG);
74 if ((PCI_PRODUCT(val) & 0xf) == 4)
75 chvalid = 0xf; /* 4 channel model */
76 else
77 chvalid = 0x3; /* 2 channel model */
79 l = alloc(sizeof(struct atac_softc));
80 memset(l, 0, sizeof(struct atac_softc));
82 if ((PCI_PRODUCT(val) & 0xf) == 0x2) {
83 map3112chan(tag, 0, &l->channel[0]);
84 map3112chan(tag, 1, &l->channel[1]);
86 else {
87 map3114chan(tag, 0, &l->channel[0]);
88 map3114chan(tag, 1, &l->channel[1]);
89 map3114chan(tag, 2, &l->channel[2]);
90 map3114chan(tag, 3, &l->channel[3]);
92 l->chvalid = chvalid & (unsigned)data;
93 l->tag = tag;
94 return l;
97 /* BAR0-3 */
98 static const struct {
99 int cmd, ctl;
100 } regstd[2] = {
101 { 0x10, 0x14 },
102 { 0x18, 0x1c },
105 static void
106 map3112chan(unsigned tag, int ch, struct atac_channel *cp)
108 int i;
110 cp->c_cmdbase = (void *)DEVTOV(~07 & pcicfgread(tag, regstd[ch].cmd));
111 cp->c_ctlbase = (void *)DEVTOV(~03 & pcicfgread(tag, regstd[ch].ctl));
112 cp->c_data = (u_int16_t *)(cp->c_cmdbase + wd_data);
113 for (i = 0; i < 8; i++)
114 cp->c_cmdreg[i] = cp->c_cmdbase + i;
115 cp->c_cmdreg[wd_status] = cp->c_cmdreg[wd_command];
116 cp->c_cmdreg[wd_features] = cp->c_cmdreg[wd_precomp];
119 /* offset to BAR5 */
120 static const struct {
121 int IDE_TF0, IDE_TF8;
122 } reg3114[4] = {
123 { 0x080, 0x091 },
124 { 0x0c0, 0x0d1 },
125 { 0x280, 0x291 },
126 { 0x2c0, 0x2d1 },
129 static void
130 map3114chan(unsigned tag, int ch, struct atac_channel *cp)
132 int i;
133 uint8_t *ba5;
135 ba5 = (uint8_t *)DEVTOV(pcicfgread(tag, 0x24)); /* PCI_BAR5 */
136 cp->c_cmdbase = ba5 + reg3114[ch].IDE_TF0;
137 cp->c_ctlbase = ba5 + reg3114[ch].IDE_TF8;
138 cp->c_data = (u_int16_t *)(cp->c_cmdbase + wd_data);
139 for (i = 0; i < 8; i++)
140 cp->c_cmdreg[i] = cp->c_cmdbase + i;
141 cp->c_cmdreg[wd_status] = cp->c_cmdreg[wd_command];
142 cp->c_cmdreg[wd_features] = cp->c_cmdreg[wd_precomp];