diff options
author | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-04-16 18:20:36 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-04-16 18:20:36 -0400 |
commit | 1da177e4c3f41524e886b7f1b8a0c1fc7321cac2 (patch) | |
tree | 0bba044c4ce775e45a88a51686b5d9f90697ea9d /drivers/scsi/ahci.c |
Linux-2.6.12-rc2v2.6.12-rc2
Initial git repository build. I'm not bothering with the full history,
even though we have it. We can create a separate "historical" git
archive of that later if we want to, and in the meantime it's about
3.2GB when imported into git - space that would just make the early
git days unnecessarily complicated, when we don't have a lot of good
infrastructure for it.
Let it rip!
Diffstat (limited to 'drivers/scsi/ahci.c')
-rw-r--r-- | drivers/scsi/ahci.c | 1065 |
1 files changed, 1065 insertions, 0 deletions
diff --git a/drivers/scsi/ahci.c b/drivers/scsi/ahci.c new file mode 100644 index 000000000000..3a15b13e747a --- /dev/null +++ b/drivers/scsi/ahci.c | |||
@@ -0,0 +1,1065 @@ | |||
1 | /* | ||
2 | * ahci.c - AHCI SATA support | ||
3 | * | ||
4 | * Copyright 2004 Red Hat, Inc. | ||
5 | * | ||
6 | * The contents of this file are subject to the Open | ||
7 | * Software License version 1.1 that can be found at | ||
8 | * http://www.opensource.org/licenses/osl-1.1.txt and is included herein | ||
9 | * by reference. | ||
10 | * | ||
11 | * Alternatively, the contents of this file may be used under the terms | ||
12 | * of the GNU General Public License version 2 (the "GPL") as distributed | ||
13 | * in the kernel source COPYING file, in which case the provisions of | ||
14 | * the GPL are applicable instead of the above. If you wish to allow | ||
15 | * the use of your version of this file only under the terms of the | ||
16 | * GPL and not to allow others to use your version of this file under | ||
17 | * the OSL, indicate your decision by deleting the provisions above and | ||
18 | * replace them with the notice and other provisions required by the GPL. | ||
19 | * If you do not delete the provisions above, a recipient may use your | ||
20 | * version of this file under either the OSL or the GPL. | ||
21 | * | ||
22 | * Version 1.0 of the AHCI specification: | ||
23 | * http://www.intel.com/technology/serialata/pdf/rev1_0.pdf | ||
24 | * | ||
25 | */ | ||
26 | |||
27 | #include <linux/kernel.h> | ||
28 | #include <linux/module.h> | ||
29 | #include <linux/pci.h> | ||
30 | #include <linux/init.h> | ||
31 | #include <linux/blkdev.h> | ||
32 | #include <linux/delay.h> | ||
33 | #include <linux/interrupt.h> | ||
34 | #include <linux/sched.h> | ||
35 | #include "scsi.h" | ||
36 | #include <scsi/scsi_host.h> | ||
37 | #include <linux/libata.h> | ||
38 | #include <asm/io.h> | ||
39 | |||
40 | #define DRV_NAME "ahci" | ||
41 | #define DRV_VERSION "1.00" | ||
42 | |||
43 | |||
44 | enum { | ||
45 | AHCI_PCI_BAR = 5, | ||
46 | AHCI_MAX_SG = 168, /* hardware max is 64K */ | ||
47 | AHCI_DMA_BOUNDARY = 0xffffffff, | ||
48 | AHCI_USE_CLUSTERING = 0, | ||
49 | AHCI_CMD_SLOT_SZ = 32 * 32, | ||
50 | AHCI_RX_FIS_SZ = 256, | ||
51 | AHCI_CMD_TBL_HDR = 0x80, | ||
52 | AHCI_CMD_TBL_SZ = AHCI_CMD_TBL_HDR + (AHCI_MAX_SG * 16), | ||
53 | AHCI_PORT_PRIV_DMA_SZ = AHCI_CMD_SLOT_SZ + AHCI_CMD_TBL_SZ + | ||
54 | AHCI_RX_FIS_SZ, | ||
55 | AHCI_IRQ_ON_SG = (1 << 31), | ||
56 | AHCI_CMD_ATAPI = (1 << 5), | ||
57 | AHCI_CMD_WRITE = (1 << 6), | ||
58 | |||
59 | RX_FIS_D2H_REG = 0x40, /* offset of D2H Register FIS data */ | ||
60 | |||
61 | board_ahci = 0, | ||
62 | |||
63 | /* global controller registers */ | ||
64 | HOST_CAP = 0x00, /* host capabilities */ | ||
65 | HOST_CTL = 0x04, /* global host control */ | ||
66 | HOST_IRQ_STAT = 0x08, /* interrupt status */ | ||
67 | HOST_PORTS_IMPL = 0x0c, /* bitmap of implemented ports */ | ||
68 | HOST_VERSION = 0x10, /* AHCI spec. version compliancy */ | ||
69 | |||
70 | /* HOST_CTL bits */ | ||
71 | HOST_RESET = (1 << 0), /* reset controller; self-clear */ | ||
72 | HOST_IRQ_EN = (1 << 1), /* global IRQ enable */ | ||
73 | HOST_AHCI_EN = (1 << 31), /* AHCI enabled */ | ||
74 | |||
75 | /* HOST_CAP bits */ | ||
76 | HOST_CAP_64 = (1 << 31), /* PCI DAC (64-bit DMA) support */ | ||
77 | |||
78 | /* registers for each SATA port */ | ||
79 | PORT_LST_ADDR = 0x00, /* command list DMA addr */ | ||
80 | PORT_LST_ADDR_HI = 0x04, /* command list DMA addr hi */ | ||
81 | PORT_FIS_ADDR = 0x08, /* FIS rx buf addr */ | ||
82 | PORT_FIS_ADDR_HI = 0x0c, /* FIS rx buf addr hi */ | ||
83 | PORT_IRQ_STAT = 0x10, /* interrupt status */ | ||
84 | PORT_IRQ_MASK = 0x14, /* interrupt enable/disable mask */ | ||
85 | PORT_CMD = 0x18, /* port command */ | ||
86 | PORT_TFDATA = 0x20, /* taskfile data */ | ||
87 | PORT_SIG = 0x24, /* device TF signature */ | ||
88 | PORT_CMD_ISSUE = 0x38, /* command issue */ | ||
89 | PORT_SCR = 0x28, /* SATA phy register block */ | ||
90 | PORT_SCR_STAT = 0x28, /* SATA phy register: SStatus */ | ||
91 | PORT_SCR_CTL = 0x2c, /* SATA phy register: SControl */ | ||
92 | PORT_SCR_ERR = 0x30, /* SATA phy register: SError */ | ||
93 | PORT_SCR_ACT = 0x34, /* SATA phy register: SActive */ | ||
94 | |||
95 | /* PORT_IRQ_{STAT,MASK} bits */ | ||
96 | PORT_IRQ_COLD_PRES = (1 << 31), /* cold presence detect */ | ||
97 | PORT_IRQ_TF_ERR = (1 << 30), /* task file error */ | ||
98 | PORT_IRQ_HBUS_ERR = (1 << 29), /* host bus fatal error */ | ||
99 | PORT_IRQ_HBUS_DATA_ERR = (1 << 28), /* host bus data error */ | ||
100 | PORT_IRQ_IF_ERR = (1 << 27), /* interface fatal error */ | ||
101 | PORT_IRQ_IF_NONFATAL = (1 << 26), /* interface non-fatal error */ | ||
102 | PORT_IRQ_OVERFLOW = (1 << 24), /* xfer exhausted available S/G */ | ||
103 | PORT_IRQ_BAD_PMP = (1 << 23), /* incorrect port multiplier */ | ||
104 | |||
105 | PORT_IRQ_PHYRDY = (1 << 22), /* PhyRdy changed */ | ||
106 | PORT_IRQ_DEV_ILCK = (1 << 7), /* device interlock */ | ||
107 | PORT_IRQ_CONNECT = (1 << 6), /* port connect change status */ | ||
108 | PORT_IRQ_SG_DONE = (1 << 5), /* descriptor processed */ | ||
109 | PORT_IRQ_UNK_FIS = (1 << 4), /* unknown FIS rx'd */ | ||
110 | PORT_IRQ_SDB_FIS = (1 << 3), /* Set Device Bits FIS rx'd */ | ||
111 | PORT_IRQ_DMAS_FIS = (1 << 2), /* DMA Setup FIS rx'd */ | ||
112 | PORT_IRQ_PIOS_FIS = (1 << 1), /* PIO Setup FIS rx'd */ | ||
113 | PORT_IRQ_D2H_REG_FIS = (1 << 0), /* D2H Register FIS rx'd */ | ||
114 | |||
115 | PORT_IRQ_FATAL = PORT_IRQ_TF_ERR | | ||
116 | PORT_IRQ_HBUS_ERR | | ||
117 | PORT_IRQ_HBUS_DATA_ERR | | ||
118 | PORT_IRQ_IF_ERR, | ||
119 | DEF_PORT_IRQ = PORT_IRQ_FATAL | PORT_IRQ_PHYRDY | | ||
120 | PORT_IRQ_CONNECT | PORT_IRQ_SG_DONE | | ||
121 | PORT_IRQ_UNK_FIS | PORT_IRQ_SDB_FIS | | ||
122 | PORT_IRQ_DMAS_FIS | PORT_IRQ_PIOS_FIS | | ||
123 | PORT_IRQ_D2H_REG_FIS, | ||
124 | |||
125 | /* PORT_CMD bits */ | ||
126 | PORT_CMD_LIST_ON = (1 << 15), /* cmd list DMA engine running */ | ||
127 | PORT_CMD_FIS_ON = (1 << 14), /* FIS DMA engine running */ | ||
128 | PORT_CMD_FIS_RX = (1 << 4), /* Enable FIS receive DMA engine */ | ||
129 | PORT_CMD_POWER_ON = (1 << 2), /* Power up device */ | ||
130 | PORT_CMD_SPIN_UP = (1 << 1), /* Spin up device */ | ||
131 | PORT_CMD_START = (1 << 0), /* Enable port DMA engine */ | ||
132 | |||
133 | PORT_CMD_ICC_ACTIVE = (0x1 << 28), /* Put i/f in active state */ | ||
134 | PORT_CMD_ICC_PARTIAL = (0x2 << 28), /* Put i/f in partial state */ | ||
135 | PORT_CMD_ICC_SLUMBER = (0x6 << 28), /* Put i/f in slumber state */ | ||
136 | }; | ||
137 | |||
138 | struct ahci_cmd_hdr { | ||
139 | u32 opts; | ||
140 | u32 status; | ||
141 | u32 tbl_addr; | ||
142 | u32 tbl_addr_hi; | ||
143 | u32 reserved[4]; | ||
144 | }; | ||
145 | |||
146 | struct ahci_sg { | ||
147 | u32 addr; | ||
148 | u32 addr_hi; | ||
149 | u32 reserved; | ||
150 | u32 flags_size; | ||
151 | }; | ||
152 | |||
153 | struct ahci_host_priv { | ||
154 | unsigned long flags; | ||
155 | u32 cap; /* cache of HOST_CAP register */ | ||
156 | u32 port_map; /* cache of HOST_PORTS_IMPL reg */ | ||
157 | }; | ||
158 | |||
159 | struct ahci_port_priv { | ||
160 | struct ahci_cmd_hdr *cmd_slot; | ||
161 | dma_addr_t cmd_slot_dma; | ||
162 | void *cmd_tbl; | ||
163 | dma_addr_t cmd_tbl_dma; | ||
164 | struct ahci_sg *cmd_tbl_sg; | ||
165 | void *rx_fis; | ||
166 | dma_addr_t rx_fis_dma; | ||
167 | }; | ||
168 | |||
169 | static u32 ahci_scr_read (struct ata_port *ap, unsigned int sc_reg); | ||
170 | static void ahci_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val); | ||
171 | static int ahci_init_one (struct pci_dev *pdev, const struct pci_device_id *ent); | ||
172 | static int ahci_qc_issue(struct ata_queued_cmd *qc); | ||
173 | static irqreturn_t ahci_interrupt (int irq, void *dev_instance, struct pt_regs *regs); | ||
174 | static void ahci_phy_reset(struct ata_port *ap); | ||
175 | static void ahci_irq_clear(struct ata_port *ap); | ||
176 | static void ahci_eng_timeout(struct ata_port *ap); | ||
177 | static int ahci_port_start(struct ata_port *ap); | ||
178 | static void ahci_port_stop(struct ata_port *ap); | ||
179 | static void ahci_host_stop(struct ata_host_set *host_set); | ||
180 | static void ahci_tf_read(struct ata_port *ap, struct ata_taskfile *tf); | ||
181 | static void ahci_qc_prep(struct ata_queued_cmd *qc); | ||
182 | static u8 ahci_check_status(struct ata_port *ap); | ||
183 | static u8 ahci_check_err(struct ata_port *ap); | ||
184 | static inline int ahci_host_intr(struct ata_port *ap, struct ata_queued_cmd *qc); | ||
185 | |||
186 | static Scsi_Host_Template ahci_sht = { | ||
187 | .module = THIS_MODULE, | ||
188 | .name = DRV_NAME, | ||
189 | .ioctl = ata_scsi_ioctl, | ||
190 | .queuecommand = ata_scsi_queuecmd, | ||
191 | .eh_strategy_handler = ata_scsi_error, | ||
192 | .can_queue = ATA_DEF_QUEUE, | ||
193 | .this_id = ATA_SHT_THIS_ID, | ||
194 | .sg_tablesize = AHCI_MAX_SG, | ||
195 | .max_sectors = ATA_MAX_SECTORS, | ||
196 | .cmd_per_lun = ATA_SHT_CMD_PER_LUN, | ||
197 | .emulated = ATA_SHT_EMULATED, | ||
198 | .use_clustering = AHCI_USE_CLUSTERING, | ||
199 | .proc_name = DRV_NAME, | ||
200 | .dma_boundary = AHCI_DMA_BOUNDARY, | ||
201 | .slave_configure = ata_scsi_slave_config, | ||
202 | .bios_param = ata_std_bios_param, | ||
203 | .ordered_flush = 1, | ||
204 | }; | ||
205 | |||
206 | static struct ata_port_operations ahci_ops = { | ||
207 | .port_disable = ata_port_disable, | ||
208 | |||
209 | .check_status = ahci_check_status, | ||
210 | .check_altstatus = ahci_check_status, | ||
211 | .check_err = ahci_check_err, | ||
212 | .dev_select = ata_noop_dev_select, | ||
213 | |||
214 | .tf_read = ahci_tf_read, | ||
215 | |||
216 | .phy_reset = ahci_phy_reset, | ||
217 | |||
218 | .qc_prep = ahci_qc_prep, | ||
219 | .qc_issue = ahci_qc_issue, | ||
220 | |||
221 | .eng_timeout = ahci_eng_timeout, | ||
222 | |||
223 | .irq_handler = ahci_interrupt, | ||
224 | .irq_clear = ahci_irq_clear, | ||
225 | |||
226 | .scr_read = ahci_scr_read, | ||
227 | .scr_write = ahci_scr_write, | ||
228 | |||
229 | .port_start = ahci_port_start, | ||
230 | .port_stop = ahci_port_stop, | ||
231 | .host_stop = ahci_host_stop, | ||
232 | }; | ||
233 | |||
234 | static struct ata_port_info ahci_port_info[] = { | ||
235 | /* board_ahci */ | ||
236 | { | ||
237 | .sht = &ahci_sht, | ||
238 | .host_flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | | ||
239 | ATA_FLAG_SATA_RESET | ATA_FLAG_MMIO | | ||
240 | ATA_FLAG_PIO_DMA, | ||
241 | .pio_mask = 0x03, /* pio3-4 */ | ||
242 | .udma_mask = 0x7f, /* udma0-6 ; FIXME */ | ||
243 | .port_ops = &ahci_ops, | ||
244 | }, | ||
245 | }; | ||
246 | |||
247 | static struct pci_device_id ahci_pci_tbl[] = { | ||
248 | { PCI_VENDOR_ID_INTEL, 0x2652, PCI_ANY_ID, PCI_ANY_ID, 0, 0, | ||
249 | board_ahci }, /* ICH6 */ | ||
250 | { PCI_VENDOR_ID_INTEL, 0x2653, PCI_ANY_ID, PCI_ANY_ID, 0, 0, | ||
251 | board_ahci }, /* ICH6M */ | ||
252 | { PCI_VENDOR_ID_INTEL, 0x27c1, PCI_ANY_ID, PCI_ANY_ID, 0, 0, | ||
253 | board_ahci }, /* ICH7 */ | ||
254 | { PCI_VENDOR_ID_INTEL, 0x27c5, PCI_ANY_ID, PCI_ANY_ID, 0, 0, | ||
255 | board_ahci }, /* ICH7M */ | ||
256 | { PCI_VENDOR_ID_INTEL, 0x27c3, PCI_ANY_ID, PCI_ANY_ID, 0, 0, | ||
257 | board_ahci }, /* ICH7R */ | ||
258 | { PCI_VENDOR_ID_AL, 0x5288, PCI_ANY_ID, PCI_ANY_ID, 0, 0, | ||
259 | board_ahci }, /* ULi M5288 */ | ||
260 | { } /* terminate list */ | ||
261 | }; | ||
262 | |||
263 | |||
264 | static struct pci_driver ahci_pci_driver = { | ||
265 | .name = DRV_NAME, | ||
266 | .id_table = ahci_pci_tbl, | ||
267 | .probe = ahci_init_one, | ||
268 | .remove = ata_pci_remove_one, | ||
269 | }; | ||
270 | |||
271 | |||
272 | static inline unsigned long ahci_port_base_ul (unsigned long base, unsigned int port) | ||
273 | { | ||
274 | return base + 0x100 + (port * 0x80); | ||
275 | } | ||
276 | |||
277 | static inline void *ahci_port_base (void *base, unsigned int port) | ||
278 | { | ||
279 | return (void *) ahci_port_base_ul((unsigned long)base, port); | ||
280 | } | ||
281 | |||
282 | static void ahci_host_stop(struct ata_host_set *host_set) | ||
283 | { | ||
284 | struct ahci_host_priv *hpriv = host_set->private_data; | ||
285 | kfree(hpriv); | ||
286 | } | ||
287 | |||
288 | static int ahci_port_start(struct ata_port *ap) | ||
289 | { | ||
290 | struct device *dev = ap->host_set->dev; | ||
291 | struct ahci_host_priv *hpriv = ap->host_set->private_data; | ||
292 | struct ahci_port_priv *pp; | ||
293 | int rc; | ||
294 | void *mem, *mmio = ap->host_set->mmio_base; | ||
295 | void *port_mmio = ahci_port_base(mmio, ap->port_no); | ||
296 | dma_addr_t mem_dma; | ||
297 | |||
298 | rc = ata_port_start(ap); | ||
299 | if (rc) | ||
300 | return rc; | ||
301 | |||
302 | pp = kmalloc(sizeof(*pp), GFP_KERNEL); | ||
303 | if (!pp) { | ||
304 | rc = -ENOMEM; | ||
305 | goto err_out; | ||
306 | } | ||
307 | memset(pp, 0, sizeof(*pp)); | ||
308 | |||
309 | mem = dma_alloc_coherent(dev, AHCI_PORT_PRIV_DMA_SZ, &mem_dma, GFP_KERNEL); | ||
310 | if (!mem) { | ||
311 | rc = -ENOMEM; | ||
312 | goto err_out_kfree; | ||
313 | } | ||
314 | memset(mem, 0, AHCI_PORT_PRIV_DMA_SZ); | ||
315 | |||
316 | /* | ||
317 | * First item in chunk of DMA memory: 32-slot command table, | ||
318 | * 32 bytes each in size | ||
319 | */ | ||
320 | pp->cmd_slot = mem; | ||
321 | pp->cmd_slot_dma = mem_dma; | ||
322 | |||
323 | mem += AHCI_CMD_SLOT_SZ; | ||
324 | mem_dma += AHCI_CMD_SLOT_SZ; | ||
325 | |||
326 | /* | ||
327 | * Second item: Received-FIS area | ||
328 | */ | ||
329 | pp->rx_fis = mem; | ||
330 | pp->rx_fis_dma = mem_dma; | ||
331 | |||
332 | mem += AHCI_RX_FIS_SZ; | ||
333 | mem_dma += AHCI_RX_FIS_SZ; | ||
334 | |||
335 | /* | ||
336 | * Third item: data area for storing a single command | ||
337 | * and its scatter-gather table | ||
338 | */ | ||
339 | pp->cmd_tbl = mem; | ||
340 | pp->cmd_tbl_dma = mem_dma; | ||
341 | |||
342 | pp->cmd_tbl_sg = mem + AHCI_CMD_TBL_HDR; | ||
343 | |||
344 | ap->private_data = pp; | ||
345 | |||
346 | if (hpriv->cap & HOST_CAP_64) | ||
347 | writel((pp->cmd_slot_dma >> 16) >> 16, port_mmio + PORT_LST_ADDR_HI); | ||
348 | writel(pp->cmd_slot_dma & 0xffffffff, port_mmio + PORT_LST_ADDR); | ||
349 | readl(port_mmio + PORT_LST_ADDR); /* flush */ | ||
350 | |||
351 | if (hpriv->cap & HOST_CAP_64) | ||
352 | writel((pp->rx_fis_dma >> 16) >> 16, port_mmio + PORT_FIS_ADDR_HI); | ||
353 | writel(pp->rx_fis_dma & 0xffffffff, port_mmio + PORT_FIS_ADDR); | ||
354 | readl(port_mmio + PORT_FIS_ADDR); /* flush */ | ||
355 | |||
356 | writel(PORT_CMD_ICC_ACTIVE | PORT_CMD_FIS_RX | | ||
357 | PORT_CMD_POWER_ON | PORT_CMD_SPIN_UP | | ||
358 | PORT_CMD_START, port_mmio + PORT_CMD); | ||
359 | readl(port_mmio + PORT_CMD); /* flush */ | ||
360 | |||
361 | return 0; | ||
362 | |||
363 | err_out_kfree: | ||
364 | kfree(pp); | ||
365 | err_out: | ||
366 | ata_port_stop(ap); | ||
367 | return rc; | ||
368 | } | ||
369 | |||
370 | |||
371 | static void ahci_port_stop(struct ata_port *ap) | ||
372 | { | ||
373 | struct device *dev = ap->host_set->dev; | ||
374 | struct ahci_port_priv *pp = ap->private_data; | ||
375 | void *mmio = ap->host_set->mmio_base; | ||
376 | void *port_mmio = ahci_port_base(mmio, ap->port_no); | ||
377 | u32 tmp; | ||
378 | |||
379 | tmp = readl(port_mmio + PORT_CMD); | ||
380 | tmp &= ~(PORT_CMD_START | PORT_CMD_FIS_RX); | ||
381 | writel(tmp, port_mmio + PORT_CMD); | ||
382 | readl(port_mmio + PORT_CMD); /* flush */ | ||
383 | |||
384 | /* spec says 500 msecs for each PORT_CMD_{START,FIS_RX} bit, so | ||
385 | * this is slightly incorrect. | ||
386 | */ | ||
387 | msleep(500); | ||
388 | |||
389 | ap->private_data = NULL; | ||
390 | dma_free_coherent(dev, AHCI_PORT_PRIV_DMA_SZ, | ||
391 | pp->cmd_slot, pp->cmd_slot_dma); | ||
392 | kfree(pp); | ||
393 | ata_port_stop(ap); | ||
394 | } | ||
395 | |||
396 | static u32 ahci_scr_read (struct ata_port *ap, unsigned int sc_reg_in) | ||
397 | { | ||
398 | unsigned int sc_reg; | ||
399 | |||
400 | switch (sc_reg_in) { | ||
401 | case SCR_STATUS: sc_reg = 0; break; | ||
402 | case SCR_CONTROL: sc_reg = 1; break; | ||
403 | case SCR_ERROR: sc_reg = 2; break; | ||
404 | case SCR_ACTIVE: sc_reg = 3; break; | ||
405 | default: | ||
406 | return 0xffffffffU; | ||
407 | } | ||
408 | |||
409 | return readl((void *) ap->ioaddr.scr_addr + (sc_reg * 4)); | ||
410 | } | ||
411 | |||
412 | |||
413 | static void ahci_scr_write (struct ata_port *ap, unsigned int sc_reg_in, | ||
414 | u32 val) | ||
415 | { | ||
416 | unsigned int sc_reg; | ||
417 | |||
418 | switch (sc_reg_in) { | ||
419 | case SCR_STATUS: sc_reg = 0; break; | ||
420 | case SCR_CONTROL: sc_reg = 1; break; | ||
421 | case SCR_ERROR: sc_reg = 2; break; | ||
422 | case SCR_ACTIVE: sc_reg = 3; break; | ||
423 | default: | ||
424 | return; | ||
425 | } | ||
426 | |||
427 | writel(val, (void *) ap->ioaddr.scr_addr + (sc_reg * 4)); | ||
428 | } | ||
429 | |||
430 | static void ahci_phy_reset(struct ata_port *ap) | ||
431 | { | ||
432 | void __iomem *port_mmio = (void __iomem *) ap->ioaddr.cmd_addr; | ||
433 | struct ata_taskfile tf; | ||
434 | struct ata_device *dev = &ap->device[0]; | ||
435 | u32 tmp; | ||
436 | |||
437 | __sata_phy_reset(ap); | ||
438 | |||
439 | if (ap->flags & ATA_FLAG_PORT_DISABLED) | ||
440 | return; | ||
441 | |||
442 | tmp = readl(port_mmio + PORT_SIG); | ||
443 | tf.lbah = (tmp >> 24) & 0xff; | ||
444 | tf.lbam = (tmp >> 16) & 0xff; | ||
445 | tf.lbal = (tmp >> 8) & 0xff; | ||
446 | tf.nsect = (tmp) & 0xff; | ||
447 | |||
448 | dev->class = ata_dev_classify(&tf); | ||
449 | if (!ata_dev_present(dev)) | ||
450 | ata_port_disable(ap); | ||
451 | } | ||
452 | |||
453 | static u8 ahci_check_status(struct ata_port *ap) | ||
454 | { | ||
455 | void *mmio = (void *) ap->ioaddr.cmd_addr; | ||
456 | |||
457 | return readl(mmio + PORT_TFDATA) & 0xFF; | ||
458 | } | ||
459 | |||
460 | static u8 ahci_check_err(struct ata_port *ap) | ||
461 | { | ||
462 | void *mmio = (void *) ap->ioaddr.cmd_addr; | ||
463 | |||
464 | return (readl(mmio + PORT_TFDATA) >> 8) & 0xFF; | ||
465 | } | ||
466 | |||
467 | static void ahci_tf_read(struct ata_port *ap, struct ata_taskfile *tf) | ||
468 | { | ||
469 | struct ahci_port_priv *pp = ap->private_data; | ||
470 | u8 *d2h_fis = pp->rx_fis + RX_FIS_D2H_REG; | ||
471 | |||
472 | ata_tf_from_fis(d2h_fis, tf); | ||
473 | } | ||
474 | |||
475 | static void ahci_fill_sg(struct ata_queued_cmd *qc) | ||
476 | { | ||
477 | struct ahci_port_priv *pp = qc->ap->private_data; | ||
478 | unsigned int i; | ||
479 | |||
480 | VPRINTK("ENTER\n"); | ||
481 | |||
482 | /* | ||
483 | * Next, the S/G list. | ||
484 | */ | ||
485 | for (i = 0; i < qc->n_elem; i++) { | ||
486 | u32 sg_len; | ||
487 | dma_addr_t addr; | ||
488 | |||
489 | addr = sg_dma_address(&qc->sg[i]); | ||
490 | sg_len = sg_dma_len(&qc->sg[i]); | ||
491 | |||
492 | pp->cmd_tbl_sg[i].addr = cpu_to_le32(addr & 0xffffffff); | ||
493 | pp->cmd_tbl_sg[i].addr_hi = cpu_to_le32((addr >> 16) >> 16); | ||
494 | pp->cmd_tbl_sg[i].flags_size = cpu_to_le32(sg_len - 1); | ||
495 | } | ||
496 | } | ||
497 | |||
498 | static void ahci_qc_prep(struct ata_queued_cmd *qc) | ||
499 | { | ||
500 | struct ahci_port_priv *pp = qc->ap->private_data; | ||
501 | u32 opts; | ||
502 | const u32 cmd_fis_len = 5; /* five dwords */ | ||
503 | |||
504 | /* | ||
505 | * Fill in command slot information (currently only one slot, | ||
506 | * slot 0, is currently since we don't do queueing) | ||
507 | */ | ||
508 | |||
509 | opts = (qc->n_elem << 16) | cmd_fis_len; | ||
510 | if (qc->tf.flags & ATA_TFLAG_WRITE) | ||
511 | opts |= AHCI_CMD_WRITE; | ||
512 | |||
513 | switch (qc->tf.protocol) { | ||
514 | case ATA_PROT_ATAPI: | ||
515 | case ATA_PROT_ATAPI_NODATA: | ||
516 | case ATA_PROT_ATAPI_DMA: | ||
517 | opts |= AHCI_CMD_ATAPI; | ||
518 | break; | ||
519 | |||
520 | default: | ||
521 | /* do nothing */ | ||
522 | break; | ||
523 | } | ||
524 | |||
525 | pp->cmd_slot[0].opts = cpu_to_le32(opts); | ||
526 | pp->cmd_slot[0].status = 0; | ||
527 | pp->cmd_slot[0].tbl_addr = cpu_to_le32(pp->cmd_tbl_dma & 0xffffffff); | ||
528 | pp->cmd_slot[0].tbl_addr_hi = cpu_to_le32((pp->cmd_tbl_dma >> 16) >> 16); | ||
529 | |||
530 | /* | ||
531 | * Fill in command table information. First, the header, | ||
532 | * a SATA Register - Host to Device command FIS. | ||
533 | */ | ||
534 | ata_tf_to_fis(&qc->tf, pp->cmd_tbl, 0); | ||
535 | |||
536 | if (!(qc->flags & ATA_QCFLAG_DMAMAP)) | ||
537 | return; | ||
538 | |||
539 | ahci_fill_sg(qc); | ||
540 | } | ||
541 | |||
542 | static void ahci_intr_error(struct ata_port *ap, u32 irq_stat) | ||
543 | { | ||
544 | void *mmio = ap->host_set->mmio_base; | ||
545 | void *port_mmio = ahci_port_base(mmio, ap->port_no); | ||
546 | u32 tmp; | ||
547 | int work; | ||
548 | |||
549 | /* stop DMA */ | ||
550 | tmp = readl(port_mmio + PORT_CMD); | ||
551 | tmp &= ~PORT_CMD_START; | ||
552 | writel(tmp, port_mmio + PORT_CMD); | ||
553 | |||
554 | /* wait for engine to stop. TODO: this could be | ||
555 | * as long as 500 msec | ||
556 | */ | ||
557 | work = 1000; | ||
558 | while (work-- > 0) { | ||
559 | tmp = readl(port_mmio + PORT_CMD); | ||
560 | if ((tmp & PORT_CMD_LIST_ON) == 0) | ||
561 | break; | ||
562 | udelay(10); | ||
563 | } | ||
564 | |||
565 | /* clear SATA phy error, if any */ | ||
566 | tmp = readl(port_mmio + PORT_SCR_ERR); | ||
567 | writel(tmp, port_mmio + PORT_SCR_ERR); | ||
568 | |||
569 | /* if DRQ/BSY is set, device needs to be reset. | ||
570 | * if so, issue COMRESET | ||
571 | */ | ||
572 | tmp = readl(port_mmio + PORT_TFDATA); | ||
573 | if (tmp & (ATA_BUSY | ATA_DRQ)) { | ||
574 | writel(0x301, port_mmio + PORT_SCR_CTL); | ||
575 | readl(port_mmio + PORT_SCR_CTL); /* flush */ | ||
576 | udelay(10); | ||
577 | writel(0x300, port_mmio + PORT_SCR_CTL); | ||
578 | readl(port_mmio + PORT_SCR_CTL); /* flush */ | ||
579 | } | ||
580 | |||
581 | /* re-start DMA */ | ||
582 | tmp = readl(port_mmio + PORT_CMD); | ||
583 | tmp |= PORT_CMD_START; | ||
584 | writel(tmp, port_mmio + PORT_CMD); | ||
585 | readl(port_mmio + PORT_CMD); /* flush */ | ||
586 | |||
587 | printk(KERN_WARNING "ata%u: error occurred, port reset\n", ap->id); | ||
588 | } | ||
589 | |||
590 | static void ahci_eng_timeout(struct ata_port *ap) | ||
591 | { | ||
592 | void *mmio = ap->host_set->mmio_base; | ||
593 | void *port_mmio = ahci_port_base(mmio, ap->port_no); | ||
594 | struct ata_queued_cmd *qc; | ||
595 | |||
596 | DPRINTK("ENTER\n"); | ||
597 | |||
598 | ahci_intr_error(ap, readl(port_mmio + PORT_IRQ_STAT)); | ||
599 | |||
600 | qc = ata_qc_from_tag(ap, ap->active_tag); | ||
601 | if (!qc) { | ||
602 | printk(KERN_ERR "ata%u: BUG: timeout without command\n", | ||
603 | ap->id); | ||
604 | } else { | ||
605 | /* hack alert! We cannot use the supplied completion | ||
606 | * function from inside the ->eh_strategy_handler() thread. | ||
607 | * libata is the only user of ->eh_strategy_handler() in | ||
608 | * any kernel, so the default scsi_done() assumes it is | ||
609 | * not being called from the SCSI EH. | ||
610 | */ | ||
611 | qc->scsidone = scsi_finish_command; | ||
612 | ata_qc_complete(qc, ATA_ERR); | ||
613 | } | ||
614 | |||
615 | } | ||
616 | |||
617 | static inline int ahci_host_intr(struct ata_port *ap, struct ata_queued_cmd *qc) | ||
618 | { | ||
619 | void *mmio = ap->host_set->mmio_base; | ||
620 | void *port_mmio = ahci_port_base(mmio, ap->port_no); | ||
621 | u32 status, serr, ci; | ||
622 | |||
623 | serr = readl(port_mmio + PORT_SCR_ERR); | ||
624 | writel(serr, port_mmio + PORT_SCR_ERR); | ||
625 | |||
626 | status = readl(port_mmio + PORT_IRQ_STAT); | ||
627 | writel(status, port_mmio + PORT_IRQ_STAT); | ||
628 | |||
629 | ci = readl(port_mmio + PORT_CMD_ISSUE); | ||
630 | if (likely((ci & 0x1) == 0)) { | ||
631 | if (qc) { | ||
632 | ata_qc_complete(qc, 0); | ||
633 | qc = NULL; | ||
634 | } | ||
635 | } | ||
636 | |||
637 | if (status & PORT_IRQ_FATAL) { | ||
638 | ahci_intr_error(ap, status); | ||
639 | if (qc) | ||
640 | ata_qc_complete(qc, ATA_ERR); | ||
641 | } | ||
642 | |||
643 | return 1; | ||
644 | } | ||
645 | |||
646 | static void ahci_irq_clear(struct ata_port *ap) | ||
647 | { | ||
648 | /* TODO */ | ||
649 | } | ||
650 | |||
651 | static irqreturn_t ahci_interrupt (int irq, void *dev_instance, struct pt_regs *regs) | ||
652 | { | ||
653 | struct ata_host_set *host_set = dev_instance; | ||
654 | struct ahci_host_priv *hpriv; | ||
655 | unsigned int i, handled = 0; | ||
656 | void *mmio; | ||
657 | u32 irq_stat, irq_ack = 0; | ||
658 | |||
659 | VPRINTK("ENTER\n"); | ||
660 | |||
661 | hpriv = host_set->private_data; | ||
662 | mmio = host_set->mmio_base; | ||
663 | |||
664 | /* sigh. 0xffffffff is a valid return from h/w */ | ||
665 | irq_stat = readl(mmio + HOST_IRQ_STAT); | ||
666 | irq_stat &= hpriv->port_map; | ||
667 | if (!irq_stat) | ||
668 | return IRQ_NONE; | ||
669 | |||
670 | spin_lock(&host_set->lock); | ||
671 | |||
672 | for (i = 0; i < host_set->n_ports; i++) { | ||
673 | struct ata_port *ap; | ||
674 | u32 tmp; | ||
675 | |||
676 | VPRINTK("port %u\n", i); | ||
677 | ap = host_set->ports[i]; | ||
678 | tmp = irq_stat & (1 << i); | ||
679 | if (tmp && ap) { | ||
680 | struct ata_queued_cmd *qc; | ||
681 | qc = ata_qc_from_tag(ap, ap->active_tag); | ||
682 | if (ahci_host_intr(ap, qc)) | ||
683 | irq_ack |= (1 << i); | ||
684 | } | ||
685 | } | ||
686 | |||
687 | if (irq_ack) { | ||
688 | writel(irq_ack, mmio + HOST_IRQ_STAT); | ||
689 | handled = 1; | ||
690 | } | ||
691 | |||
692 | spin_unlock(&host_set->lock); | ||
693 | |||
694 | VPRINTK("EXIT\n"); | ||
695 | |||
696 | return IRQ_RETVAL(handled); | ||
697 | } | ||
698 | |||
699 | static int ahci_qc_issue(struct ata_queued_cmd *qc) | ||
700 | { | ||
701 | struct ata_port *ap = qc->ap; | ||
702 | void *port_mmio = (void *) ap->ioaddr.cmd_addr; | ||
703 | |||
704 | writel(1, port_mmio + PORT_SCR_ACT); | ||
705 | readl(port_mmio + PORT_SCR_ACT); /* flush */ | ||
706 | |||
707 | writel(1, port_mmio + PORT_CMD_ISSUE); | ||
708 | readl(port_mmio + PORT_CMD_ISSUE); /* flush */ | ||
709 | |||
710 | return 0; | ||
711 | } | ||
712 | |||
713 | static void ahci_setup_port(struct ata_ioports *port, unsigned long base, | ||
714 | unsigned int port_idx) | ||
715 | { | ||
716 | VPRINTK("ENTER, base==0x%lx, port_idx %u\n", base, port_idx); | ||
717 | base = ahci_port_base_ul(base, port_idx); | ||
718 | VPRINTK("base now==0x%lx\n", base); | ||
719 | |||
720 | port->cmd_addr = base; | ||
721 | port->scr_addr = base + PORT_SCR; | ||
722 | |||
723 | VPRINTK("EXIT\n"); | ||
724 | } | ||
725 | |||
726 | static int ahci_host_init(struct ata_probe_ent *probe_ent) | ||
727 | { | ||
728 | struct ahci_host_priv *hpriv = probe_ent->private_data; | ||
729 | struct pci_dev *pdev = to_pci_dev(probe_ent->dev); | ||
730 | void __iomem *mmio = probe_ent->mmio_base; | ||
731 | u32 tmp, cap_save; | ||
732 | u16 tmp16; | ||
733 | unsigned int i, j, using_dac; | ||
734 | int rc; | ||
735 | void __iomem *port_mmio; | ||
736 | |||
737 | cap_save = readl(mmio + HOST_CAP); | ||
738 | cap_save &= ( (1<<28) | (1<<17) ); | ||
739 | cap_save |= (1 << 27); | ||
740 | |||
741 | /* global controller reset */ | ||
742 | tmp = readl(mmio + HOST_CTL); | ||
743 | if ((tmp & HOST_RESET) == 0) { | ||
744 | writel(tmp | HOST_RESET, mmio + HOST_CTL); | ||
745 | readl(mmio + HOST_CTL); /* flush */ | ||
746 | } | ||
747 | |||
748 | /* reset must complete within 1 second, or | ||
749 | * the hardware should be considered fried. | ||
750 | */ | ||
751 | ssleep(1); | ||
752 | |||
753 | tmp = readl(mmio + HOST_CTL); | ||
754 | if (tmp & HOST_RESET) { | ||
755 | printk(KERN_ERR DRV_NAME "(%s): controller reset failed (0x%x)\n", | ||
756 | pci_name(pdev), tmp); | ||
757 | return -EIO; | ||
758 | } | ||
759 | |||
760 | writel(HOST_AHCI_EN, mmio + HOST_CTL); | ||
761 | (void) readl(mmio + HOST_CTL); /* flush */ | ||
762 | writel(cap_save, mmio + HOST_CAP); | ||
763 | writel(0xf, mmio + HOST_PORTS_IMPL); | ||
764 | (void) readl(mmio + HOST_PORTS_IMPL); /* flush */ | ||
765 | |||
766 | pci_read_config_word(pdev, 0x92, &tmp16); | ||
767 | tmp16 |= 0xf; | ||
768 | pci_write_config_word(pdev, 0x92, tmp16); | ||
769 | |||
770 | hpriv->cap = readl(mmio + HOST_CAP); | ||
771 | hpriv->port_map = readl(mmio + HOST_PORTS_IMPL); | ||
772 | probe_ent->n_ports = (hpriv->cap & 0x1f) + 1; | ||
773 | |||
774 | VPRINTK("cap 0x%x port_map 0x%x n_ports %d\n", | ||
775 | hpriv->cap, hpriv->port_map, probe_ent->n_ports); | ||
776 | |||
777 | using_dac = hpriv->cap & HOST_CAP_64; | ||
778 | if (using_dac && | ||
779 | !pci_set_dma_mask(pdev, DMA_64BIT_MASK)) { | ||
780 | rc = pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK); | ||
781 | if (rc) { | ||
782 | rc = pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK); | ||
783 | if (rc) { | ||
784 | printk(KERN_ERR DRV_NAME "(%s): 64-bit DMA enable failed\n", | ||
785 | pci_name(pdev)); | ||
786 | return rc; | ||
787 | } | ||
788 | } | ||
789 | |||
790 | hpriv->flags |= HOST_CAP_64; | ||
791 | } else { | ||
792 | rc = pci_set_dma_mask(pdev, DMA_32BIT_MASK); | ||
793 | if (rc) { | ||
794 | printk(KERN_ERR DRV_NAME "(%s): 32-bit DMA enable failed\n", | ||
795 | pci_name(pdev)); | ||
796 | return rc; | ||
797 | } | ||
798 | rc = pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK); | ||
799 | if (rc) { | ||
800 | printk(KERN_ERR DRV_NAME "(%s): 32-bit consistent DMA enable failed\n", | ||
801 | pci_name(pdev)); | ||
802 | return rc; | ||
803 | } | ||
804 | } | ||
805 | |||
806 | for (i = 0; i < probe_ent->n_ports; i++) { | ||
807 | #if 0 /* BIOSen initialize this incorrectly */ | ||
808 | if (!(hpriv->port_map & (1 << i))) | ||
809 | continue; | ||
810 | #endif | ||
811 | |||
812 | port_mmio = ahci_port_base(mmio, i); | ||
813 | VPRINTK("mmio %p port_mmio %p\n", mmio, port_mmio); | ||
814 | |||
815 | ahci_setup_port(&probe_ent->port[i], | ||
816 | (unsigned long) mmio, i); | ||
817 | |||
818 | /* make sure port is not active */ | ||
819 | tmp = readl(port_mmio + PORT_CMD); | ||
820 | VPRINTK("PORT_CMD 0x%x\n", tmp); | ||
821 | if (tmp & (PORT_CMD_LIST_ON | PORT_CMD_FIS_ON | | ||
822 | PORT_CMD_FIS_RX | PORT_CMD_START)) { | ||
823 | tmp &= ~(PORT_CMD_LIST_ON | PORT_CMD_FIS_ON | | ||
824 | PORT_CMD_FIS_RX | PORT_CMD_START); | ||
825 | writel(tmp, port_mmio + PORT_CMD); | ||
826 | readl(port_mmio + PORT_CMD); /* flush */ | ||
827 | |||
828 | /* spec says 500 msecs for each bit, so | ||
829 | * this is slightly incorrect. | ||
830 | */ | ||
831 | msleep(500); | ||
832 | } | ||
833 | |||
834 | writel(PORT_CMD_SPIN_UP, port_mmio + PORT_CMD); | ||
835 | |||
836 | j = 0; | ||
837 | while (j < 100) { | ||
838 | msleep(10); | ||
839 | tmp = readl(port_mmio + PORT_SCR_STAT); | ||
840 | if ((tmp & 0xf) == 0x3) | ||
841 | break; | ||
842 | j++; | ||
843 | } | ||
844 | |||
845 | tmp = readl(port_mmio + PORT_SCR_ERR); | ||
846 | VPRINTK("PORT_SCR_ERR 0x%x\n", tmp); | ||
847 | writel(tmp, port_mmio + PORT_SCR_ERR); | ||
848 | |||
849 | /* ack any pending irq events for this port */ | ||
850 | tmp = readl(port_mmio + PORT_IRQ_STAT); | ||
851 | VPRINTK("PORT_IRQ_STAT 0x%x\n", tmp); | ||
852 | if (tmp) | ||
853 | writel(tmp, port_mmio + PORT_IRQ_STAT); | ||
854 | |||
855 | writel(1 << i, mmio + HOST_IRQ_STAT); | ||
856 | |||
857 | /* set irq mask (enables interrupts) */ | ||
858 | writel(DEF_PORT_IRQ, port_mmio + PORT_IRQ_MASK); | ||
859 | } | ||
860 | |||
861 | tmp = readl(mmio + HOST_CTL); | ||
862 | VPRINTK("HOST_CTL 0x%x\n", tmp); | ||
863 | writel(tmp | HOST_IRQ_EN, mmio + HOST_CTL); | ||
864 | tmp = readl(mmio + HOST_CTL); | ||
865 | VPRINTK("HOST_CTL 0x%x\n", tmp); | ||
866 | |||
867 | pci_set_master(pdev); | ||
868 | |||
869 | return 0; | ||
870 | } | ||
871 | |||
872 | /* move to PCI layer, integrate w/ MSI stuff */ | ||
873 | static void pci_enable_intx(struct pci_dev *pdev) | ||
874 | { | ||
875 | u16 pci_command; | ||
876 | |||
877 | pci_read_config_word(pdev, PCI_COMMAND, &pci_command); | ||
878 | if (pci_command & PCI_COMMAND_INTX_DISABLE) { | ||
879 | pci_command &= ~PCI_COMMAND_INTX_DISABLE; | ||
880 | pci_write_config_word(pdev, PCI_COMMAND, pci_command); | ||
881 | } | ||
882 | } | ||
883 | |||
884 | static void ahci_print_info(struct ata_probe_ent *probe_ent) | ||
885 | { | ||
886 | struct ahci_host_priv *hpriv = probe_ent->private_data; | ||
887 | struct pci_dev *pdev = to_pci_dev(probe_ent->dev); | ||
888 | void *mmio = probe_ent->mmio_base; | ||
889 | u32 vers, cap, impl, speed; | ||
890 | const char *speed_s; | ||
891 | u16 cc; | ||
892 | const char *scc_s; | ||
893 | |||
894 | vers = readl(mmio + HOST_VERSION); | ||
895 | cap = hpriv->cap; | ||
896 | impl = hpriv->port_map; | ||
897 | |||
898 | speed = (cap >> 20) & 0xf; | ||
899 | if (speed == 1) | ||
900 | speed_s = "1.5"; | ||
901 | else if (speed == 2) | ||
902 | speed_s = "3"; | ||
903 | else | ||
904 | speed_s = "?"; | ||
905 | |||
906 | pci_read_config_word(pdev, 0x0a, &cc); | ||
907 | if (cc == 0x0101) | ||
908 | scc_s = "IDE"; | ||
909 | else if (cc == 0x0106) | ||
910 | scc_s = "SATA"; | ||
911 | else if (cc == 0x0104) | ||
912 | scc_s = "RAID"; | ||
913 | else | ||
914 | scc_s = "unknown"; | ||
915 | |||
916 | printk(KERN_INFO DRV_NAME "(%s) AHCI %02x%02x.%02x%02x " | ||
917 | "%u slots %u ports %s Gbps 0x%x impl %s mode\n" | ||
918 | , | ||
919 | pci_name(pdev), | ||
920 | |||
921 | (vers >> 24) & 0xff, | ||
922 | (vers >> 16) & 0xff, | ||
923 | (vers >> 8) & 0xff, | ||
924 | vers & 0xff, | ||
925 | |||
926 | ((cap >> 8) & 0x1f) + 1, | ||
927 | (cap & 0x1f) + 1, | ||
928 | speed_s, | ||
929 | impl, | ||
930 | scc_s); | ||
931 | |||
932 | printk(KERN_INFO DRV_NAME "(%s) flags: " | ||
933 | "%s%s%s%s%s%s" | ||
934 | "%s%s%s%s%s%s%s\n" | ||
935 | , | ||
936 | pci_name(pdev), | ||
937 | |||
938 | cap & (1 << 31) ? "64bit " : "", | ||
939 | cap & (1 << 30) ? "ncq " : "", | ||
940 | cap & (1 << 28) ? "ilck " : "", | ||
941 | cap & (1 << 27) ? "stag " : "", | ||
942 | cap & (1 << 26) ? "pm " : "", | ||
943 | cap & (1 << 25) ? "led " : "", | ||
944 | |||
945 | cap & (1 << 24) ? "clo " : "", | ||
946 | cap & (1 << 19) ? "nz " : "", | ||
947 | cap & (1 << 18) ? "only " : "", | ||
948 | cap & (1 << 17) ? "pmp " : "", | ||
949 | cap & (1 << 15) ? "pio " : "", | ||
950 | cap & (1 << 14) ? "slum " : "", | ||
951 | cap & (1 << 13) ? "part " : "" | ||
952 | ); | ||
953 | } | ||
954 | |||
955 | static int ahci_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) | ||
956 | { | ||
957 | static int printed_version; | ||
958 | struct ata_probe_ent *probe_ent = NULL; | ||
959 | struct ahci_host_priv *hpriv; | ||
960 | unsigned long base; | ||
961 | void *mmio_base; | ||
962 | unsigned int board_idx = (unsigned int) ent->driver_data; | ||
963 | int pci_dev_busy = 0; | ||
964 | int rc; | ||
965 | |||
966 | VPRINTK("ENTER\n"); | ||
967 | |||
968 | if (!printed_version++) | ||
969 | printk(KERN_DEBUG DRV_NAME " version " DRV_VERSION "\n"); | ||
970 | |||
971 | rc = pci_enable_device(pdev); | ||
972 | if (rc) | ||
973 | return rc; | ||
974 | |||
975 | rc = pci_request_regions(pdev, DRV_NAME); | ||
976 | if (rc) { | ||
977 | pci_dev_busy = 1; | ||
978 | goto err_out; | ||
979 | } | ||
980 | |||
981 | pci_enable_intx(pdev); | ||
982 | |||
983 | probe_ent = kmalloc(sizeof(*probe_ent), GFP_KERNEL); | ||
984 | if (probe_ent == NULL) { | ||
985 | rc = -ENOMEM; | ||
986 | goto err_out_regions; | ||
987 | } | ||
988 | |||
989 | memset(probe_ent, 0, sizeof(*probe_ent)); | ||
990 | probe_ent->dev = pci_dev_to_dev(pdev); | ||
991 | INIT_LIST_HEAD(&probe_ent->node); | ||
992 | |||
993 | mmio_base = ioremap(pci_resource_start(pdev, AHCI_PCI_BAR), | ||
994 | pci_resource_len(pdev, AHCI_PCI_BAR)); | ||
995 | if (mmio_base == NULL) { | ||
996 | rc = -ENOMEM; | ||
997 | goto err_out_free_ent; | ||
998 | } | ||
999 | base = (unsigned long) mmio_base; | ||
1000 | |||
1001 | hpriv = kmalloc(sizeof(*hpriv), GFP_KERNEL); | ||
1002 | if (!hpriv) { | ||
1003 | rc = -ENOMEM; | ||
1004 | goto err_out_iounmap; | ||
1005 | } | ||
1006 | memset(hpriv, 0, sizeof(*hpriv)); | ||
1007 | |||
1008 | probe_ent->sht = ahci_port_info[board_idx].sht; | ||
1009 | probe_ent->host_flags = ahci_port_info[board_idx].host_flags; | ||
1010 | probe_ent->pio_mask = ahci_port_info[board_idx].pio_mask; | ||
1011 | probe_ent->udma_mask = ahci_port_info[board_idx].udma_mask; | ||
1012 | probe_ent->port_ops = ahci_port_info[board_idx].port_ops; | ||
1013 | |||
1014 | probe_ent->irq = pdev->irq; | ||
1015 | probe_ent->irq_flags = SA_SHIRQ; | ||
1016 | probe_ent->mmio_base = mmio_base; | ||
1017 | probe_ent->private_data = hpriv; | ||
1018 | |||
1019 | /* initialize adapter */ | ||
1020 | rc = ahci_host_init(probe_ent); | ||
1021 | if (rc) | ||
1022 | goto err_out_hpriv; | ||
1023 | |||
1024 | ahci_print_info(probe_ent); | ||
1025 | |||
1026 | /* FIXME: check ata_device_add return value */ | ||
1027 | ata_device_add(probe_ent); | ||
1028 | kfree(probe_ent); | ||
1029 | |||
1030 | return 0; | ||
1031 | |||
1032 | err_out_hpriv: | ||
1033 | kfree(hpriv); | ||
1034 | err_out_iounmap: | ||
1035 | iounmap(mmio_base); | ||
1036 | err_out_free_ent: | ||
1037 | kfree(probe_ent); | ||
1038 | err_out_regions: | ||
1039 | pci_release_regions(pdev); | ||
1040 | err_out: | ||
1041 | if (!pci_dev_busy) | ||
1042 | pci_disable_device(pdev); | ||
1043 | return rc; | ||
1044 | } | ||
1045 | |||
1046 | |||
1047 | static int __init ahci_init(void) | ||
1048 | { | ||
1049 | return pci_module_init(&ahci_pci_driver); | ||
1050 | } | ||
1051 | |||
1052 | |||
1053 | static void __exit ahci_exit(void) | ||
1054 | { | ||
1055 | pci_unregister_driver(&ahci_pci_driver); | ||
1056 | } | ||
1057 | |||
1058 | |||
1059 | MODULE_AUTHOR("Jeff Garzik"); | ||
1060 | MODULE_DESCRIPTION("AHCI SATA low-level driver"); | ||
1061 | MODULE_LICENSE("GPL"); | ||
1062 | MODULE_DEVICE_TABLE(pci, ahci_pci_tbl); | ||
1063 | |||
1064 | module_init(ahci_init); | ||
1065 | module_exit(ahci_exit); | ||