MOXA linux-2.6.x / linux-2.6.9-uc0 from sdlinux-moxaart.tgz
[linux-2.6.9-moxart.git] / drivers / scsi / sata_via.c
blob44ffa9b90b186f4700a4840c0bc98b879ecb575d
1 /*
2 sata_via.c - VIA Serial ATA controllers
4 Maintained by: Jeff Garzik <jgarzik@pobox.com>
5 Please ALWAYS copy linux-ide@vger.kernel.org
6 on emails.
8 Copyright 2003-2004 Red Hat, Inc. All rights reserved.
9 Copyright 2003-2004 Jeff Garzik
11 The contents of this file are subject to the Open
12 Software License version 1.1 that can be found at
13 http://www.opensource.org/licenses/osl-1.1.txt and is included herein
14 by reference.
16 Alternatively, the contents of this file may be used under the terms
17 of the GNU General Public License version 2 (the "GPL") as distributed
18 in the kernel source COPYING file, in which case the provisions of
19 the GPL are applicable instead of the above. If you wish to allow
20 the use of your version of this file only under the terms of the
21 GPL and not to allow others to use your version of this file under
22 the OSL, indicate your decision by deleting the provisions above and
23 replace them with the notice and other provisions required by the GPL.
24 If you do not delete the provisions above, a recipient may use your
25 version of this file under either the OSL or the GPL.
29 #include <linux/kernel.h>
30 #include <linux/module.h>
31 #include <linux/pci.h>
32 #include <linux/init.h>
33 #include <linux/blkdev.h>
34 #include <linux/delay.h>
35 #include "scsi.h"
36 #include <scsi/scsi_host.h>
37 #include <linux/libata.h>
38 #include <asm/io.h>
40 #define DRV_NAME "sata_via"
41 #define DRV_VERSION "0.20"
43 enum {
44 via_sata = 0,
46 SATA_CHAN_ENAB = 0x40, /* SATA channel enable */
47 SATA_INT_GATE = 0x41, /* SATA interrupt gating */
48 SATA_NATIVE_MODE = 0x42, /* Native mode enable */
49 SATA_PATA_SHARING = 0x49, /* PATA/SATA sharing func ctrl */
51 PORT0 = (1 << 1),
52 PORT1 = (1 << 0),
54 ENAB_ALL = PORT0 | PORT1,
56 INT_GATE_ALL = PORT0 | PORT1,
58 NATIVE_MODE_ALL = (1 << 7) | (1 << 6) | (1 << 5) | (1 << 4),
60 SATA_EXT_PHY = (1 << 6), /* 0==use PATA, 1==ext phy */
61 SATA_2DEV = (1 << 5), /* SATA is master/slave */
64 static int svia_init_one (struct pci_dev *pdev, const struct pci_device_id *ent);
65 static u32 svia_scr_read (struct ata_port *ap, unsigned int sc_reg);
66 static void svia_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val);
68 static struct pci_device_id svia_pci_tbl[] = {
69 { 0x1106, 0x3149, PCI_ANY_ID, PCI_ANY_ID, 0, 0, via_sata },
71 { } /* terminate list */
74 static struct pci_driver svia_pci_driver = {
75 .name = DRV_NAME,
76 .id_table = svia_pci_tbl,
77 .probe = svia_init_one,
78 .remove = ata_pci_remove_one,
81 static Scsi_Host_Template svia_sht = {
82 .module = THIS_MODULE,
83 .name = DRV_NAME,
84 .ioctl = ata_scsi_ioctl,
85 .queuecommand = ata_scsi_queuecmd,
86 .eh_strategy_handler = ata_scsi_error,
87 .can_queue = ATA_DEF_QUEUE,
88 .this_id = ATA_SHT_THIS_ID,
89 .sg_tablesize = LIBATA_MAX_PRD,
90 .max_sectors = ATA_MAX_SECTORS,
91 .cmd_per_lun = ATA_SHT_CMD_PER_LUN,
92 .emulated = ATA_SHT_EMULATED,
93 .use_clustering = ATA_SHT_USE_CLUSTERING,
94 .proc_name = DRV_NAME,
95 .dma_boundary = ATA_DMA_BOUNDARY,
96 .slave_configure = ata_scsi_slave_config,
97 .bios_param = ata_std_bios_param,
100 static struct ata_port_operations svia_sata_ops = {
101 .port_disable = ata_port_disable,
103 .tf_load = ata_tf_load,
104 .tf_read = ata_tf_read,
105 .check_status = ata_check_status,
106 .exec_command = ata_exec_command,
107 .dev_select = ata_std_dev_select,
109 .phy_reset = sata_phy_reset,
111 .bmdma_setup = ata_bmdma_setup,
112 .bmdma_start = ata_bmdma_start,
113 .qc_prep = ata_qc_prep,
114 .qc_issue = ata_qc_issue_prot,
116 .eng_timeout = ata_eng_timeout,
118 .irq_handler = ata_interrupt,
119 .irq_clear = ata_bmdma_irq_clear,
121 .scr_read = svia_scr_read,
122 .scr_write = svia_scr_write,
124 .port_start = ata_port_start,
125 .port_stop = ata_port_stop,
128 static struct ata_port_info svia_port_info = {
129 .sht = &svia_sht,
130 .host_flags = ATA_FLAG_SATA | ATA_FLAG_SRST | ATA_FLAG_NO_LEGACY,
131 .pio_mask = 0x1f,
132 .mwdma_mask = 0x07,
133 .udma_mask = 0x7f,
134 .port_ops = &svia_sata_ops,
137 MODULE_AUTHOR("Jeff Garzik");
138 MODULE_DESCRIPTION("SCSI low-level driver for VIA SATA controllers");
139 MODULE_LICENSE("GPL");
140 MODULE_DEVICE_TABLE(pci, svia_pci_tbl);
142 static u32 svia_scr_read (struct ata_port *ap, unsigned int sc_reg)
144 if (sc_reg > SCR_CONTROL)
145 return 0xffffffffU;
146 return inl(ap->ioaddr.scr_addr + (4 * sc_reg));
149 static void svia_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val)
151 if (sc_reg > SCR_CONTROL)
152 return;
153 outl(val, ap->ioaddr.scr_addr + (4 * sc_reg));
156 static const unsigned int svia_bar_sizes[] = {
157 8, 4, 8, 4, 16, 256
160 static unsigned long svia_scr_addr(unsigned long addr, unsigned int port)
162 return addr + (port * 128);
165 static int svia_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
167 static int printed_version;
168 unsigned int i;
169 int rc;
170 struct ata_port_info *ppi;
171 struct ata_probe_ent *probe_ent;
172 u8 tmp8;
174 if (!printed_version++)
175 printk(KERN_DEBUG DRV_NAME " version " DRV_VERSION "\n");
177 rc = pci_enable_device(pdev);
178 if (rc)
179 return rc;
181 rc = pci_request_regions(pdev, DRV_NAME);
182 if (rc)
183 goto err_out;
185 pci_read_config_byte(pdev, SATA_PATA_SHARING, &tmp8);
186 if (tmp8 & SATA_2DEV) {
187 printk(KERN_ERR DRV_NAME "(%s): SATA master/slave not supported (0x%x)\n",
188 pci_name(pdev), (int) tmp8);
189 rc = -EIO;
190 goto err_out_regions;
193 for (i = 0; i < ARRAY_SIZE(svia_bar_sizes); i++)
194 if ((pci_resource_start(pdev, i) == 0) ||
195 (pci_resource_len(pdev, i) < svia_bar_sizes[i])) {
196 printk(KERN_ERR DRV_NAME "(%s): invalid PCI BAR %u (sz 0x%lx, val 0x%lx)\n",
197 pci_name(pdev), i,
198 pci_resource_start(pdev, i),
199 pci_resource_len(pdev, i));
200 rc = -ENODEV;
201 goto err_out_regions;
204 rc = pci_set_dma_mask(pdev, ATA_DMA_MASK);
205 if (rc)
206 goto err_out_regions;
207 rc = pci_set_consistent_dma_mask(pdev, ATA_DMA_MASK);
208 if (rc)
209 goto err_out_regions;
211 ppi = &svia_port_info;
212 probe_ent = ata_pci_init_native_mode(pdev, &ppi);
213 if (!probe_ent) {
214 printk(KERN_ERR DRV_NAME "(%s): out of memory\n",
215 pci_name(pdev));
216 rc = -ENOMEM;
217 goto err_out_regions;
220 probe_ent->port[0].scr_addr =
221 svia_scr_addr(pci_resource_start(pdev, 5), 0);
222 probe_ent->port[1].scr_addr =
223 svia_scr_addr(pci_resource_start(pdev, 5), 1);
225 pci_read_config_byte(pdev, PCI_INTERRUPT_LINE, &tmp8);
226 printk(KERN_INFO DRV_NAME "(%s): routed to hard irq line %d\n",
227 pci_name(pdev),
228 (int) (tmp8 & 0xf0) == 0xf0 ? 0 : tmp8 & 0x0f);
230 /* make sure SATA channels are enabled */
231 pci_read_config_byte(pdev, SATA_CHAN_ENAB, &tmp8);
232 if ((tmp8 & ENAB_ALL) != ENAB_ALL) {
233 printk(KERN_DEBUG DRV_NAME "(%s): enabling SATA channels (0x%x)\n",
234 pci_name(pdev), (int) tmp8);
235 tmp8 |= ENAB_ALL;
236 pci_write_config_byte(pdev, SATA_CHAN_ENAB, tmp8);
239 /* make sure interrupts for each channel sent to us */
240 pci_read_config_byte(pdev, SATA_INT_GATE, &tmp8);
241 if ((tmp8 & INT_GATE_ALL) != INT_GATE_ALL) {
242 printk(KERN_DEBUG DRV_NAME "(%s): enabling SATA channel interrupts (0x%x)\n",
243 pci_name(pdev), (int) tmp8);
244 tmp8 |= INT_GATE_ALL;
245 pci_write_config_byte(pdev, SATA_INT_GATE, tmp8);
248 /* make sure native mode is enabled */
249 pci_read_config_byte(pdev, SATA_NATIVE_MODE, &tmp8);
250 if ((tmp8 & NATIVE_MODE_ALL) != NATIVE_MODE_ALL) {
251 printk(KERN_DEBUG DRV_NAME "(%s): enabling SATA channel native mode (0x%x)\n",
252 pci_name(pdev), (int) tmp8);
253 tmp8 |= NATIVE_MODE_ALL;
254 pci_write_config_byte(pdev, SATA_NATIVE_MODE, tmp8);
257 pci_set_master(pdev);
259 /* FIXME: check ata_device_add return value */
260 ata_device_add(probe_ent);
261 kfree(probe_ent);
263 return 0;
265 err_out_regions:
266 pci_release_regions(pdev);
267 err_out:
268 pci_disable_device(pdev);
269 return rc;
272 static int __init svia_init(void)
274 return pci_module_init(&svia_pci_driver);
277 static void __exit svia_exit(void)
279 pci_unregister_driver(&svia_pci_driver);
282 module_init(svia_init);
283 module_exit(svia_exit);