Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
pata_jmicron.c
Go to the documentation of this file.
1 /*
2  * pata_jmicron.c - JMicron ATA driver for non AHCI mode. This drives the
3  * PATA port of the controller. The SATA ports are
4  * driven by AHCI in the usual configuration although
5  * this driver can handle other setups if we need it.
6  *
7  * (c) 2006 Red Hat
8  */
9 
10 #include <linux/kernel.h>
11 #include <linux/module.h>
12 #include <linux/pci.h>
13 #include <linux/init.h>
14 #include <linux/blkdev.h>
15 #include <linux/delay.h>
16 #include <linux/device.h>
17 #include <scsi/scsi_host.h>
18 #include <linux/libata.h>
19 #include <linux/ata.h>
20 
21 #define DRV_NAME "pata_jmicron"
22 #define DRV_VERSION "0.1.5"
23 
24 typedef enum {
27  PORT_SATA = 2,
28 } port_type;
29 
42 static int jmicron_pre_reset(struct ata_link *link, unsigned long deadline)
43 {
44  struct ata_port *ap = link->ap;
45  struct pci_dev *pdev = to_pci_dev(ap->host->dev);
46  u32 control;
47  u32 control5;
48  int port_mask = 1<< (4 * ap->port_no);
49  int port = ap->port_no;
50  port_type port_map[2];
51 
52  /* Check if our port is enabled */
53  pci_read_config_dword(pdev, 0x40, &control);
54  if ((control & port_mask) == 0)
55  return -ENOENT;
56 
57  /* There are two basic mappings. One has the two SATA ports merged
58  as master/slave and the secondary as PATA, the other has only the
59  SATA port mapped */
60  if (control & (1 << 23)) {
61  port_map[0] = PORT_SATA;
62  port_map[1] = PORT_PATA0;
63  } else {
64  port_map[0] = PORT_SATA;
65  port_map[1] = PORT_SATA;
66  }
67 
68  /* The 365/366 may have this bit set to map the second PATA port
69  as the internal primary channel */
70  pci_read_config_dword(pdev, 0x80, &control5);
71  if (control5 & (1<<24))
72  port_map[0] = PORT_PATA1;
73 
74  /* The two ports may then be logically swapped by the firmware */
75  if (control & (1 << 22))
76  port = port ^ 1;
77 
78  /*
79  * Now we know which physical port we are talking about we can
80  * actually do our cable checking etc. Thankfully we don't need
81  * to do the plumbing for other cases.
82  */
83  switch (port_map[port]) {
84  case PORT_PATA0:
85  if ((control & (1 << 5)) == 0)
86  return -ENOENT;
87  if (control & (1 << 3)) /* 40/80 pin primary */
88  ap->cbl = ATA_CBL_PATA40;
89  else
90  ap->cbl = ATA_CBL_PATA80;
91  break;
92  case PORT_PATA1:
93  /* Bit 21 is set if the port is enabled */
94  if ((control5 & (1 << 21)) == 0)
95  return -ENOENT;
96  if (control5 & (1 << 19)) /* 40/80 pin secondary */
97  ap->cbl = ATA_CBL_PATA40;
98  else
99  ap->cbl = ATA_CBL_PATA80;
100  break;
101  case PORT_SATA:
102  ap->cbl = ATA_CBL_SATA;
103  break;
104  }
105  return ata_sff_prereset(link, deadline);
106 }
107 
108 /* No PIO or DMA methods needed for this device */
109 
110 static struct scsi_host_template jmicron_sht = {
111  ATA_BMDMA_SHT(DRV_NAME),
112 };
113 
114 static struct ata_port_operations jmicron_ops = {
115  .inherits = &ata_bmdma_port_ops,
116  .prereset = jmicron_pre_reset,
117 };
118 
119 
134 static int jmicron_init_one (struct pci_dev *pdev, const struct pci_device_id *id)
135 {
136  static const struct ata_port_info info = {
137  .flags = ATA_FLAG_SLAVE_POSS,
138 
139  .pio_mask = ATA_PIO4,
140  .mwdma_mask = ATA_MWDMA2,
141  .udma_mask = ATA_UDMA5,
142 
143  .port_ops = &jmicron_ops,
144  };
145  const struct ata_port_info *ppi[] = { &info, NULL };
146 
147  return ata_pci_bmdma_init_one(pdev, ppi, &jmicron_sht, NULL, 0);
148 }
149 
150 static const struct pci_device_id jmicron_pci_tbl[] = {
152  PCI_CLASS_STORAGE_IDE << 8, 0xffff00, 0 },
153  { } /* terminate list */
154 };
155 
156 static struct pci_driver jmicron_pci_driver = {
157  .name = DRV_NAME,
158  .id_table = jmicron_pci_tbl,
159  .probe = jmicron_init_one,
160  .remove = ata_pci_remove_one,
161 #ifdef CONFIG_PM
162  .suspend = ata_pci_device_suspend,
163  .resume = ata_pci_device_resume,
164 #endif
165 };
166 
167 module_pci_driver(jmicron_pci_driver);
168 
169 MODULE_AUTHOR("Alan Cox");
170 MODULE_DESCRIPTION("SCSI low-level driver for Jmicron PATA ports");
171 MODULE_LICENSE("GPL");
172 MODULE_DEVICE_TABLE(pci, jmicron_pci_tbl);
174