1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0-only
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun * ACPI PATA driver
4*4882a593Smuzhiyun *
5*4882a593Smuzhiyun * (c) 2007 Red Hat
6*4882a593Smuzhiyun */
7*4882a593Smuzhiyun
8*4882a593Smuzhiyun #include <linux/kernel.h>
9*4882a593Smuzhiyun #include <linux/module.h>
10*4882a593Smuzhiyun #include <linux/pci.h>
11*4882a593Smuzhiyun #include <linux/blkdev.h>
12*4882a593Smuzhiyun #include <linux/delay.h>
13*4882a593Smuzhiyun #include <linux/device.h>
14*4882a593Smuzhiyun #include <linux/gfp.h>
15*4882a593Smuzhiyun #include <linux/acpi.h>
16*4882a593Smuzhiyun #include <linux/libata.h>
17*4882a593Smuzhiyun #include <linux/ata.h>
18*4882a593Smuzhiyun #include <scsi/scsi_host.h>
19*4882a593Smuzhiyun
20*4882a593Smuzhiyun #define DRV_NAME "pata_acpi"
21*4882a593Smuzhiyun #define DRV_VERSION "0.2.3"
22*4882a593Smuzhiyun
23*4882a593Smuzhiyun struct pata_acpi {
24*4882a593Smuzhiyun struct ata_acpi_gtm gtm;
25*4882a593Smuzhiyun void *last;
26*4882a593Smuzhiyun unsigned long mask[2];
27*4882a593Smuzhiyun };
28*4882a593Smuzhiyun
29*4882a593Smuzhiyun /**
30*4882a593Smuzhiyun * pacpi_pre_reset - check for 40/80 pin
31*4882a593Smuzhiyun * @ap: Port
32*4882a593Smuzhiyun * @deadline: deadline jiffies for the operation
33*4882a593Smuzhiyun *
34*4882a593Smuzhiyun * Perform the PATA port setup we need.
35*4882a593Smuzhiyun */
36*4882a593Smuzhiyun
pacpi_pre_reset(struct ata_link * link,unsigned long deadline)37*4882a593Smuzhiyun static int pacpi_pre_reset(struct ata_link *link, unsigned long deadline)
38*4882a593Smuzhiyun {
39*4882a593Smuzhiyun struct ata_port *ap = link->ap;
40*4882a593Smuzhiyun struct pata_acpi *acpi = ap->private_data;
41*4882a593Smuzhiyun if (ACPI_HANDLE(&ap->tdev) == NULL || ata_acpi_gtm(ap, &acpi->gtm) < 0)
42*4882a593Smuzhiyun return -ENODEV;
43*4882a593Smuzhiyun
44*4882a593Smuzhiyun return ata_sff_prereset(link, deadline);
45*4882a593Smuzhiyun }
46*4882a593Smuzhiyun
47*4882a593Smuzhiyun /**
48*4882a593Smuzhiyun * pacpi_cable_detect - cable type detection
49*4882a593Smuzhiyun * @ap: port to detect
50*4882a593Smuzhiyun *
51*4882a593Smuzhiyun * Perform device specific cable detection
52*4882a593Smuzhiyun */
53*4882a593Smuzhiyun
pacpi_cable_detect(struct ata_port * ap)54*4882a593Smuzhiyun static int pacpi_cable_detect(struct ata_port *ap)
55*4882a593Smuzhiyun {
56*4882a593Smuzhiyun struct pata_acpi *acpi = ap->private_data;
57*4882a593Smuzhiyun
58*4882a593Smuzhiyun if ((acpi->mask[0] | acpi->mask[1]) & (0xF8 << ATA_SHIFT_UDMA))
59*4882a593Smuzhiyun return ATA_CBL_PATA80;
60*4882a593Smuzhiyun else
61*4882a593Smuzhiyun return ATA_CBL_PATA40;
62*4882a593Smuzhiyun }
63*4882a593Smuzhiyun
64*4882a593Smuzhiyun /**
65*4882a593Smuzhiyun * pacpi_discover_modes - filter non ACPI modes
66*4882a593Smuzhiyun * @adev: ATA device
67*4882a593Smuzhiyun * @mask: proposed modes
68*4882a593Smuzhiyun *
69*4882a593Smuzhiyun * Try the modes available and see which ones the ACPI method will
70*4882a593Smuzhiyun * set up sensibly. From this we get a mask of ACPI modes we can use
71*4882a593Smuzhiyun */
72*4882a593Smuzhiyun
pacpi_discover_modes(struct ata_port * ap,struct ata_device * adev)73*4882a593Smuzhiyun static unsigned long pacpi_discover_modes(struct ata_port *ap, struct ata_device *adev)
74*4882a593Smuzhiyun {
75*4882a593Smuzhiyun struct pata_acpi *acpi = ap->private_data;
76*4882a593Smuzhiyun struct ata_acpi_gtm probe;
77*4882a593Smuzhiyun unsigned int xfer_mask;
78*4882a593Smuzhiyun
79*4882a593Smuzhiyun probe = acpi->gtm;
80*4882a593Smuzhiyun
81*4882a593Smuzhiyun ata_acpi_gtm(ap, &probe);
82*4882a593Smuzhiyun
83*4882a593Smuzhiyun xfer_mask = ata_acpi_gtm_xfermask(adev, &probe);
84*4882a593Smuzhiyun
85*4882a593Smuzhiyun if (xfer_mask & (0xF8 << ATA_SHIFT_UDMA))
86*4882a593Smuzhiyun ap->cbl = ATA_CBL_PATA80;
87*4882a593Smuzhiyun
88*4882a593Smuzhiyun return xfer_mask;
89*4882a593Smuzhiyun }
90*4882a593Smuzhiyun
91*4882a593Smuzhiyun /**
92*4882a593Smuzhiyun * pacpi_mode_filter - mode filter for ACPI
93*4882a593Smuzhiyun * @adev: device
94*4882a593Smuzhiyun * @mask: mask of valid modes
95*4882a593Smuzhiyun *
96*4882a593Smuzhiyun * Filter the valid mode list according to our own specific rules, in
97*4882a593Smuzhiyun * this case the list of discovered valid modes obtained by ACPI probing
98*4882a593Smuzhiyun */
99*4882a593Smuzhiyun
pacpi_mode_filter(struct ata_device * adev,unsigned long mask)100*4882a593Smuzhiyun static unsigned long pacpi_mode_filter(struct ata_device *adev, unsigned long mask)
101*4882a593Smuzhiyun {
102*4882a593Smuzhiyun struct pata_acpi *acpi = adev->link->ap->private_data;
103*4882a593Smuzhiyun return mask & acpi->mask[adev->devno];
104*4882a593Smuzhiyun }
105*4882a593Smuzhiyun
106*4882a593Smuzhiyun /**
107*4882a593Smuzhiyun * pacpi_set_piomode - set initial PIO mode data
108*4882a593Smuzhiyun * @ap: ATA interface
109*4882a593Smuzhiyun * @adev: ATA device
110*4882a593Smuzhiyun */
111*4882a593Smuzhiyun
pacpi_set_piomode(struct ata_port * ap,struct ata_device * adev)112*4882a593Smuzhiyun static void pacpi_set_piomode(struct ata_port *ap, struct ata_device *adev)
113*4882a593Smuzhiyun {
114*4882a593Smuzhiyun int unit = adev->devno;
115*4882a593Smuzhiyun struct pata_acpi *acpi = ap->private_data;
116*4882a593Smuzhiyun const struct ata_timing *t;
117*4882a593Smuzhiyun
118*4882a593Smuzhiyun if (!(acpi->gtm.flags & 0x10))
119*4882a593Smuzhiyun unit = 0;
120*4882a593Smuzhiyun
121*4882a593Smuzhiyun /* Now stuff the nS values into the structure */
122*4882a593Smuzhiyun t = ata_timing_find_mode(adev->pio_mode);
123*4882a593Smuzhiyun acpi->gtm.drive[unit].pio = t->cycle;
124*4882a593Smuzhiyun ata_acpi_stm(ap, &acpi->gtm);
125*4882a593Smuzhiyun /* See what mode we actually got */
126*4882a593Smuzhiyun ata_acpi_gtm(ap, &acpi->gtm);
127*4882a593Smuzhiyun }
128*4882a593Smuzhiyun
129*4882a593Smuzhiyun /**
130*4882a593Smuzhiyun * pacpi_set_dmamode - set initial DMA mode data
131*4882a593Smuzhiyun * @ap: ATA interface
132*4882a593Smuzhiyun * @adev: ATA device
133*4882a593Smuzhiyun */
134*4882a593Smuzhiyun
pacpi_set_dmamode(struct ata_port * ap,struct ata_device * adev)135*4882a593Smuzhiyun static void pacpi_set_dmamode(struct ata_port *ap, struct ata_device *adev)
136*4882a593Smuzhiyun {
137*4882a593Smuzhiyun int unit = adev->devno;
138*4882a593Smuzhiyun struct pata_acpi *acpi = ap->private_data;
139*4882a593Smuzhiyun const struct ata_timing *t;
140*4882a593Smuzhiyun
141*4882a593Smuzhiyun if (!(acpi->gtm.flags & 0x10))
142*4882a593Smuzhiyun unit = 0;
143*4882a593Smuzhiyun
144*4882a593Smuzhiyun /* Now stuff the nS values into the structure */
145*4882a593Smuzhiyun t = ata_timing_find_mode(adev->dma_mode);
146*4882a593Smuzhiyun if (adev->dma_mode >= XFER_UDMA_0) {
147*4882a593Smuzhiyun acpi->gtm.drive[unit].dma = t->udma;
148*4882a593Smuzhiyun acpi->gtm.flags |= (1 << (2 * unit));
149*4882a593Smuzhiyun } else {
150*4882a593Smuzhiyun acpi->gtm.drive[unit].dma = t->cycle;
151*4882a593Smuzhiyun acpi->gtm.flags &= ~(1 << (2 * unit));
152*4882a593Smuzhiyun }
153*4882a593Smuzhiyun ata_acpi_stm(ap, &acpi->gtm);
154*4882a593Smuzhiyun /* See what mode we actually got */
155*4882a593Smuzhiyun ata_acpi_gtm(ap, &acpi->gtm);
156*4882a593Smuzhiyun }
157*4882a593Smuzhiyun
158*4882a593Smuzhiyun /**
159*4882a593Smuzhiyun * pacpi_qc_issue - command issue
160*4882a593Smuzhiyun * @qc: command pending
161*4882a593Smuzhiyun *
162*4882a593Smuzhiyun * Called when the libata layer is about to issue a command. We wrap
163*4882a593Smuzhiyun * this interface so that we can load the correct ATA timings if
164*4882a593Smuzhiyun * necessary.
165*4882a593Smuzhiyun */
166*4882a593Smuzhiyun
pacpi_qc_issue(struct ata_queued_cmd * qc)167*4882a593Smuzhiyun static unsigned int pacpi_qc_issue(struct ata_queued_cmd *qc)
168*4882a593Smuzhiyun {
169*4882a593Smuzhiyun struct ata_port *ap = qc->ap;
170*4882a593Smuzhiyun struct ata_device *adev = qc->dev;
171*4882a593Smuzhiyun struct pata_acpi *acpi = ap->private_data;
172*4882a593Smuzhiyun
173*4882a593Smuzhiyun if (acpi->gtm.flags & 0x10)
174*4882a593Smuzhiyun return ata_bmdma_qc_issue(qc);
175*4882a593Smuzhiyun
176*4882a593Smuzhiyun if (adev != acpi->last) {
177*4882a593Smuzhiyun pacpi_set_piomode(ap, adev);
178*4882a593Smuzhiyun if (ata_dma_enabled(adev))
179*4882a593Smuzhiyun pacpi_set_dmamode(ap, adev);
180*4882a593Smuzhiyun acpi->last = adev;
181*4882a593Smuzhiyun }
182*4882a593Smuzhiyun return ata_bmdma_qc_issue(qc);
183*4882a593Smuzhiyun }
184*4882a593Smuzhiyun
185*4882a593Smuzhiyun /**
186*4882a593Smuzhiyun * pacpi_port_start - port setup
187*4882a593Smuzhiyun * @ap: ATA port being set up
188*4882a593Smuzhiyun *
189*4882a593Smuzhiyun * Use the port_start hook to maintain private control structures
190*4882a593Smuzhiyun */
191*4882a593Smuzhiyun
pacpi_port_start(struct ata_port * ap)192*4882a593Smuzhiyun static int pacpi_port_start(struct ata_port *ap)
193*4882a593Smuzhiyun {
194*4882a593Smuzhiyun struct pci_dev *pdev = to_pci_dev(ap->host->dev);
195*4882a593Smuzhiyun struct pata_acpi *acpi;
196*4882a593Smuzhiyun
197*4882a593Smuzhiyun if (ACPI_HANDLE(&ap->tdev) == NULL)
198*4882a593Smuzhiyun return -ENODEV;
199*4882a593Smuzhiyun
200*4882a593Smuzhiyun acpi = ap->private_data = devm_kzalloc(&pdev->dev, sizeof(struct pata_acpi), GFP_KERNEL);
201*4882a593Smuzhiyun if (ap->private_data == NULL)
202*4882a593Smuzhiyun return -ENOMEM;
203*4882a593Smuzhiyun acpi->mask[0] = pacpi_discover_modes(ap, &ap->link.device[0]);
204*4882a593Smuzhiyun acpi->mask[1] = pacpi_discover_modes(ap, &ap->link.device[1]);
205*4882a593Smuzhiyun return ata_bmdma_port_start(ap);
206*4882a593Smuzhiyun }
207*4882a593Smuzhiyun
208*4882a593Smuzhiyun static struct scsi_host_template pacpi_sht = {
209*4882a593Smuzhiyun ATA_BMDMA_SHT(DRV_NAME),
210*4882a593Smuzhiyun };
211*4882a593Smuzhiyun
212*4882a593Smuzhiyun static struct ata_port_operations pacpi_ops = {
213*4882a593Smuzhiyun .inherits = &ata_bmdma_port_ops,
214*4882a593Smuzhiyun .qc_issue = pacpi_qc_issue,
215*4882a593Smuzhiyun .cable_detect = pacpi_cable_detect,
216*4882a593Smuzhiyun .mode_filter = pacpi_mode_filter,
217*4882a593Smuzhiyun .set_piomode = pacpi_set_piomode,
218*4882a593Smuzhiyun .set_dmamode = pacpi_set_dmamode,
219*4882a593Smuzhiyun .prereset = pacpi_pre_reset,
220*4882a593Smuzhiyun .port_start = pacpi_port_start,
221*4882a593Smuzhiyun };
222*4882a593Smuzhiyun
223*4882a593Smuzhiyun
224*4882a593Smuzhiyun /**
225*4882a593Smuzhiyun * pacpi_init_one - Register ACPI ATA PCI device with kernel services
226*4882a593Smuzhiyun * @pdev: PCI device to register
227*4882a593Smuzhiyun * @ent: Entry in pacpi_pci_tbl matching with @pdev
228*4882a593Smuzhiyun *
229*4882a593Smuzhiyun * Called from kernel PCI layer.
230*4882a593Smuzhiyun *
231*4882a593Smuzhiyun * LOCKING:
232*4882a593Smuzhiyun * Inherited from PCI layer (may sleep).
233*4882a593Smuzhiyun *
234*4882a593Smuzhiyun * RETURNS:
235*4882a593Smuzhiyun * Zero on success, or -ERRNO value.
236*4882a593Smuzhiyun */
237*4882a593Smuzhiyun
pacpi_init_one(struct pci_dev * pdev,const struct pci_device_id * id)238*4882a593Smuzhiyun static int pacpi_init_one (struct pci_dev *pdev, const struct pci_device_id *id)
239*4882a593Smuzhiyun {
240*4882a593Smuzhiyun static const struct ata_port_info info = {
241*4882a593Smuzhiyun .flags = ATA_FLAG_SLAVE_POSS,
242*4882a593Smuzhiyun
243*4882a593Smuzhiyun .pio_mask = ATA_PIO4,
244*4882a593Smuzhiyun .mwdma_mask = ATA_MWDMA2,
245*4882a593Smuzhiyun .udma_mask = ATA_UDMA6,
246*4882a593Smuzhiyun
247*4882a593Smuzhiyun .port_ops = &pacpi_ops,
248*4882a593Smuzhiyun };
249*4882a593Smuzhiyun const struct ata_port_info *ppi[] = { &info, NULL };
250*4882a593Smuzhiyun if (pdev->vendor == PCI_VENDOR_ID_ATI) {
251*4882a593Smuzhiyun int rc = pcim_enable_device(pdev);
252*4882a593Smuzhiyun if (rc < 0)
253*4882a593Smuzhiyun return rc;
254*4882a593Smuzhiyun pcim_pin_device(pdev);
255*4882a593Smuzhiyun }
256*4882a593Smuzhiyun return ata_pci_bmdma_init_one(pdev, ppi, &pacpi_sht, NULL, 0);
257*4882a593Smuzhiyun }
258*4882a593Smuzhiyun
259*4882a593Smuzhiyun static const struct pci_device_id pacpi_pci_tbl[] = {
260*4882a593Smuzhiyun { PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_STORAGE_IDE << 8, 0xFFFFFF00UL, 1},
261*4882a593Smuzhiyun { } /* terminate list */
262*4882a593Smuzhiyun };
263*4882a593Smuzhiyun
264*4882a593Smuzhiyun static struct pci_driver pacpi_pci_driver = {
265*4882a593Smuzhiyun .name = DRV_NAME,
266*4882a593Smuzhiyun .id_table = pacpi_pci_tbl,
267*4882a593Smuzhiyun .probe = pacpi_init_one,
268*4882a593Smuzhiyun .remove = ata_pci_remove_one,
269*4882a593Smuzhiyun #ifdef CONFIG_PM_SLEEP
270*4882a593Smuzhiyun .suspend = ata_pci_device_suspend,
271*4882a593Smuzhiyun .resume = ata_pci_device_resume,
272*4882a593Smuzhiyun #endif
273*4882a593Smuzhiyun };
274*4882a593Smuzhiyun
275*4882a593Smuzhiyun module_pci_driver(pacpi_pci_driver);
276*4882a593Smuzhiyun
277*4882a593Smuzhiyun MODULE_AUTHOR("Alan Cox");
278*4882a593Smuzhiyun MODULE_DESCRIPTION("SCSI low-level driver for ATA in ACPI mode");
279*4882a593Smuzhiyun MODULE_LICENSE("GPL");
280*4882a593Smuzhiyun MODULE_DEVICE_TABLE(pci, pacpi_pci_tbl);
281*4882a593Smuzhiyun MODULE_VERSION(DRV_VERSION);
282