1 /* $NetBSD: siisata.c,v 1.7 2008/05/12 09:29:56 nisimura Exp $ */
4 * Copyright (c) 2008 The NetBSD Foundation, Inc.
7 * This code is derived from software contributed to The NetBSD Foundation
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
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>
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
*);
53 siisata_match(unsigned tag
, void *data
)
57 v
= pcicfgread(tag
, PCI_ID_REG
);
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 */
68 siisata_init(unsigned tag
, void *data
)
70 unsigned val
, chvalid
;
73 val
= pcicfgread(tag
, PCI_ID_REG
);
74 if ((PCI_PRODUCT(val
) & 0xf) == 4)
75 chvalid
= 0xf; /* 4 channel model */
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]);
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
;
106 map3112chan(unsigned tag
, int ch
, struct atac_channel
*cp
)
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
];
120 static const struct {
121 int IDE_TF0
, IDE_TF8
;
130 map3114chan(unsigned tag
, int ch
, struct atac_channel
*cp
)
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
];