Blame view

drivers/ata/pata_sl82c105.c 9.47 KB
669a5db41   Jeff Garzik   [libata] Add a bu...
1
2
3
  /*
   * pata_sl82c105.c 	- SL82C105 PATA for new ATA layer
   *			  (C) 2005 Red Hat Inc
81452182b   Bartlomiej Zolnierkiewicz   pata_sl82c105: ad...
4
   *			  (C) 2011 Bartlomiej Zolnierkiewicz
669a5db41   Jeff Garzik   [libata] Add a bu...
5
6
7
8
9
   *
   * Based in part on linux/drivers/ide/pci/sl82c105.c
   * 		SL82C105/Winbond 553 IDE driver
   *
   * and in part on the documentation and errata sheet
16728da99   Alan Cox   pata_sl82c105: re...
10
11
12
13
14
15
16
   *
   *
   * Note: The controller like many controllers has shared timings for
   * PIO and DMA. We thus flip to the DMA timings in dma_start and flip back
   * in the dma_stop function. Thus we actually don't need a set_dmamode
   * method as the PIO method is always called and will set the right PIO
   * timing parameters.
669a5db41   Jeff Garzik   [libata] Add a bu...
17
   */
85cd7251b   Jeff Garzik   [libata #pata-dri...
18

669a5db41   Jeff Garzik   [libata] Add a bu...
19
20
21
22
23
24
25
26
27
28
  #include <linux/kernel.h>
  #include <linux/module.h>
  #include <linux/pci.h>
  #include <linux/init.h>
  #include <linux/blkdev.h>
  #include <linux/delay.h>
  #include <scsi/scsi_host.h>
  #include <linux/libata.h>
  
  #define DRV_NAME "pata_sl82c105"
92ba5d02d   Alan Cox   pata_sl82c105: du...
29
  #define DRV_VERSION "0.3.3"
669a5db41   Jeff Garzik   [libata] Add a bu...
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
  
  enum {
  	/*
  	 * SL82C105 PCI config register 0x40 bits.
  	 */
  	CTRL_IDE_IRQB	=	(1 << 30),
  	CTRL_IDE_IRQA   =	(1 << 28),
  	CTRL_LEGIRQ     =	(1 << 11),
  	CTRL_P1F16      =	(1 << 5),
  	CTRL_P1EN       =	(1 << 4),
  	CTRL_P0F16      =	(1 << 1),
  	CTRL_P0EN       =	(1 << 0)
  };
  
  /**
   *	sl82c105_pre_reset		-	probe begin
cc0680a58   Tejun Heo   libata-link: link...
46
   *	@link: ATA link
d4b2bab4f   Tejun Heo   libata: add deadl...
47
   *	@deadline: deadline jiffies for the operation
669a5db41   Jeff Garzik   [libata] Add a bu...
48
49
50
   *
   *	Set up cable type and use generic probe init
   */
85cd7251b   Jeff Garzik   [libata #pata-dri...
51

cc0680a58   Tejun Heo   libata-link: link...
52
  static int sl82c105_pre_reset(struct ata_link *link, unsigned long deadline)
669a5db41   Jeff Garzik   [libata] Add a bu...
53
54
55
56
57
  {
  	static const struct pci_bits sl82c105_enable_bits[] = {
  		{ 0x40, 1, 0x01, 0x01 },
  		{ 0x40, 1, 0x10, 0x10 }
  	};
cc0680a58   Tejun Heo   libata-link: link...
58
  	struct ata_port *ap = link->ap;
669a5db41   Jeff Garzik   [libata] Add a bu...
59
  	struct pci_dev *pdev = to_pci_dev(ap->host->dev);
c961922b7   Alan Cox   [PATCH] libata-eh...
60
61
  	if (ap->port_no && !pci_test_config_bits(pdev, &sl82c105_enable_bits[ap->port_no]))
  		return -ENOENT;
9363c3825   Tejun Heo   libata: rename SF...
62
  	return ata_sff_prereset(link, deadline);
669a5db41   Jeff Garzik   [libata] Add a bu...
63
  }
669a5db41   Jeff Garzik   [libata] Add a bu...
64
65
66
67
68
69
70
71
72
73
  /**
   *	sl82c105_configure_piomode	-	set chip PIO timing
   *	@ap: ATA interface
   *	@adev: ATA device
   *	@pio: PIO mode
   *
   *	Called to do the PIO mode setup. Our timing registers are shared
   *	so a configure_dmamode call will undo any work we do here and vice
   *	versa
   */
85cd7251b   Jeff Garzik   [libata #pata-dri...
74

669a5db41   Jeff Garzik   [libata] Add a bu...
75
76
77
78
79
80
81
82
  static void sl82c105_configure_piomode(struct ata_port *ap, struct ata_device *adev, int pio)
  {
  	struct pci_dev *pdev = to_pci_dev(ap->host->dev);
  	static u16 pio_timing[5] = {
  		0x50D, 0x407, 0x304, 0x242, 0x240
  	};
  	u16 dummy;
  	int timing = 0x44 + (8 * ap->port_no) + (4 * adev->devno);
85cd7251b   Jeff Garzik   [libata #pata-dri...
83

669a5db41   Jeff Garzik   [libata] Add a bu...
84
85
86
87
88
89
90
91
92
93
94
95
96
  	pci_write_config_word(pdev, timing, pio_timing[pio]);
  	/* Can we lose this oddity of the old driver */
  	pci_read_config_word(pdev, timing, &dummy);
  }
  
  /**
   *	sl82c105_set_piomode	-	set initial PIO mode data
   *	@ap: ATA interface
   *	@adev: ATA device
   *
   *	Called to do the PIO mode setup. Our timing registers are shared
   *	but we want to set the PIO timing by default.
   */
85cd7251b   Jeff Garzik   [libata #pata-dri...
97

669a5db41   Jeff Garzik   [libata] Add a bu...
98
99
100
101
102
103
104
105
106
107
108
109
110
  static void sl82c105_set_piomode(struct ata_port *ap, struct ata_device *adev)
  {
  	sl82c105_configure_piomode(ap, adev, adev->pio_mode - XFER_PIO_0);
  }
  
  /**
   *	sl82c105_configure_dmamode	-	set DMA mode in chip
   *	@ap: ATA interface
   *	@adev: ATA device
   *
   *	Load DMA cycle times into the chip ready for a DMA transfer
   *	to occur.
   */
85cd7251b   Jeff Garzik   [libata #pata-dri...
111

669a5db41   Jeff Garzik   [libata] Add a bu...
112
113
114
115
116
117
118
119
120
  static void sl82c105_configure_dmamode(struct ata_port *ap, struct ata_device *adev)
  {
  	struct pci_dev *pdev = to_pci_dev(ap->host->dev);
  	static u16 dma_timing[3] = {
  		0x707, 0x201, 0x200
  	};
  	u16 dummy;
  	int timing = 0x44 + (8 * ap->port_no) + (4 * adev->devno);
  	int dma = adev->dma_mode - XFER_MW_DMA_0;
85cd7251b   Jeff Garzik   [libata #pata-dri...
121

669a5db41   Jeff Garzik   [libata] Add a bu...
122
123
124
125
126
127
  	pci_write_config_word(pdev, timing, dma_timing[dma]);
  	/* Can we lose this oddity of the old driver */
  	pci_read_config_word(pdev, timing, &dummy);
  }
  
  /**
669a5db41   Jeff Garzik   [libata] Add a bu...
128
129
130
131
   *	sl82c105_reset_engine	-	Reset the DMA engine
   *	@ap: ATA interface
   *
   *	The sl82c105 has some serious problems with the DMA engine
85cd7251b   Jeff Garzik   [libata #pata-dri...
132
   *	when transfers don't run as expected or ATAPI is used. The
669a5db41   Jeff Garzik   [libata] Add a bu...
133
134
135
   *	recommended fix is to reset the engine each use using a chip
   *	test register.
   */
85cd7251b   Jeff Garzik   [libata #pata-dri...
136

669a5db41   Jeff Garzik   [libata] Add a bu...
137
138
139
140
  static void sl82c105_reset_engine(struct ata_port *ap)
  {
  	struct pci_dev *pdev = to_pci_dev(ap->host->dev);
  	u16 val;
85cd7251b   Jeff Garzik   [libata #pata-dri...
141

669a5db41   Jeff Garzik   [libata] Add a bu...
142
143
144
145
146
147
148
149
150
151
  	pci_read_config_word(pdev, 0x7E, &val);
  	pci_write_config_word(pdev, 0x7E, val | 4);
  	pci_write_config_word(pdev, 0x7E, val & ~4);
  }
  
  /**
   *	sl82c105_bmdma_start		-	DMA engine begin
   *	@qc: ATA command
   *
   *	Reset the DMA engine each use as recommended by the errata
85cd7251b   Jeff Garzik   [libata #pata-dri...
152
   *	document.
669a5db41   Jeff Garzik   [libata] Add a bu...
153
154
155
156
   *
   *	FIXME: if we switch clock at BMDMA start/end we might get better
   *	PIO performance on DMA capable devices.
   */
85cd7251b   Jeff Garzik   [libata #pata-dri...
157

669a5db41   Jeff Garzik   [libata] Add a bu...
158
159
160
  static void sl82c105_bmdma_start(struct ata_queued_cmd *qc)
  {
  	struct ata_port *ap = qc->ap;
8361cd79f   Olaf Hering   add delay around ...
161
  	udelay(100);
669a5db41   Jeff Garzik   [libata] Add a bu...
162
  	sl82c105_reset_engine(ap);
8361cd79f   Olaf Hering   add delay around ...
163
  	udelay(100);
85cd7251b   Jeff Garzik   [libata #pata-dri...
164

669a5db41   Jeff Garzik   [libata] Add a bu...
165
166
  	/* Set the clocks for DMA */
  	sl82c105_configure_dmamode(ap, qc->dev);
85cd7251b   Jeff Garzik   [libata #pata-dri...
167
  	/* Activate DMA */
669a5db41   Jeff Garzik   [libata] Add a bu...
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
  	ata_bmdma_start(qc);
  }
  
  /**
   *	sl82c105_bmdma_end		-	DMA engine stop
   *	@qc: ATA command
   *
   *	Reset the DMA engine each use as recommended by the errata
   *	document.
   *
   *	This function is also called to turn off DMA when a timeout occurs
   *	during DMA operation. In both cases we need to reset the engine,
   *	so no actual eng_timeout handler is required.
   *
   *	We assume bmdma_stop is always called if bmdma_start as called. If
   *	not then we may need to wrap qc_issue.
   */
85cd7251b   Jeff Garzik   [libata #pata-dri...
185

669a5db41   Jeff Garzik   [libata] Add a bu...
186
187
188
189
190
191
  static void sl82c105_bmdma_stop(struct ata_queued_cmd *qc)
  {
  	struct ata_port *ap = qc->ap;
  
  	ata_bmdma_stop(qc);
  	sl82c105_reset_engine(ap);
8361cd79f   Olaf Hering   add delay around ...
192
  	udelay(100);
85cd7251b   Jeff Garzik   [libata #pata-dri...
193

669a5db41   Jeff Garzik   [libata] Add a bu...
194
195
  	/* This will redo the initial setup of the DMA device to matching
  	   PIO timings */
16728da99   Alan Cox   pata_sl82c105: re...
196
  	sl82c105_set_piomode(ap, qc->dev);
669a5db41   Jeff Garzik   [libata] Add a bu...
197
  }
92ba5d02d   Alan Cox   pata_sl82c105: du...
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
  /**
   *	sl82c105_qc_defer	-	implement serialization
   *	@qc: command
   *
   *	We must issue one command per host not per channel because
   *	of the reset bug.
   *
   *	Q: is the scsi host lock sufficient ?
   */
  
  static int sl82c105_qc_defer(struct ata_queued_cmd *qc)
  {
  	struct ata_host *host = qc->ap->host;
  	struct ata_port *alt = host->ports[1 ^ qc->ap->port_no];
  	int rc;
c85665ffa   Jeff Garzik   drivers/ata: trim...
213
  	/* First apply the usual rules */
92ba5d02d   Alan Cox   pata_sl82c105: du...
214
215
216
217
218
219
220
221
222
223
  	rc = ata_std_qc_defer(qc);
  	if (rc != 0)
  		return rc;
  
  	/* Now apply serialization rules. Only allow a command if the
  	   other channel state machine is idle */
  	if (alt && alt->qc_active)
  		return	ATA_DEFER_PORT;
  	return 0;
  }
f7a437dda   Sergei Shtylyov   pata_sl82c105: im...
224
225
226
227
228
229
230
231
232
  static bool sl82c105_sff_irq_check(struct ata_port *ap)
  {
  	struct pci_dev *pdev	= to_pci_dev(ap->host->dev);
  	u32 val, mask		= ap->port_no ? CTRL_IDE_IRQB : CTRL_IDE_IRQA;
  
  	pci_read_config_dword(pdev, 0x40, &val);
  
  	return val & mask;
  }
669a5db41   Jeff Garzik   [libata] Add a bu...
233
  static struct scsi_host_template sl82c105_sht = {
68d1d07b5   Tejun Heo   libata: implement...
234
  	ATA_BMDMA_SHT(DRV_NAME),
669a5db41   Jeff Garzik   [libata] Add a bu...
235
236
237
  };
  
  static struct ata_port_operations sl82c105_port_ops = {
029cfd6b7   Tejun Heo   libata: implement...
238
239
  	.inherits	= &ata_bmdma_port_ops,
  	.qc_defer	= sl82c105_qc_defer,
669a5db41   Jeff Garzik   [libata] Add a bu...
240
241
  	.bmdma_start 	= sl82c105_bmdma_start,
  	.bmdma_stop	= sl82c105_bmdma_stop,
029cfd6b7   Tejun Heo   libata: implement...
242
243
  	.cable_detect	= ata_cable_40wire,
  	.set_piomode	= sl82c105_set_piomode,
a1efdaba2   Tejun Heo   libata: make rese...
244
  	.prereset	= sl82c105_pre_reset,
f7a437dda   Sergei Shtylyov   pata_sl82c105: im...
245
  	.sff_irq_check	= sl82c105_sff_irq_check,
85cd7251b   Jeff Garzik   [libata #pata-dri...
246
  };
669a5db41   Jeff Garzik   [libata] Add a bu...
247
248
249
250
251
252
253
254
255
  
  /**
   *	sl82c105_bridge_revision	-	find bridge version
   *	@pdev: PCI device for the ATA function
   *
   *	Locates the PCI bridge associated with the ATA function and
   *	providing it is a Winbond 553 reports the revision. If it cannot
   *	find a revision or the right device it returns -1
   */
85cd7251b   Jeff Garzik   [libata #pata-dri...
256

669a5db41   Jeff Garzik   [libata] Add a bu...
257
258
259
  static int sl82c105_bridge_revision(struct pci_dev *pdev)
  {
  	struct pci_dev *bridge;
669a5db41   Jeff Garzik   [libata] Add a bu...
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
  
  	/*
  	 * The bridge should be part of the same device, but function 0.
  	 */
  	bridge = pci_get_slot(pdev->bus,
  			       PCI_DEVFN(PCI_SLOT(pdev->devfn), 0));
  	if (!bridge)
  		return -1;
  
  	/*
  	 * Make sure it is a Winbond 553 and is an ISA bridge.
  	 */
  	if (bridge->vendor != PCI_VENDOR_ID_WINBOND ||
  	    bridge->device != PCI_DEVICE_ID_WINBOND_83C553 ||
  	    bridge->class >> 8 != PCI_CLASS_BRIDGE_ISA) {
  	    	pci_dev_put(bridge);
  		return -1;
  	}
  	/*
  	 * We need to find function 0's revision, not function 1
  	 */
669a5db41   Jeff Garzik   [libata] Add a bu...
281
  	pci_dev_put(bridge);
44c10138f   Auke Kok   PCI: Change all d...
282
  	return bridge->revision;
669a5db41   Jeff Garzik   [libata] Add a bu...
283
  }
81452182b   Bartlomiej Zolnierkiewicz   pata_sl82c105: ad...
284
285
286
287
288
289
290
291
  static void sl82c105_fixup(struct pci_dev *pdev)
  {
  	u32 val;
  
  	pci_read_config_dword(pdev, 0x40, &val);
  	val |= CTRL_P0EN | CTRL_P0F16 | CTRL_P1F16;
  	pci_write_config_dword(pdev, 0x40, val);
  }
85cd7251b   Jeff Garzik   [libata #pata-dri...
292

669a5db41   Jeff Garzik   [libata] Add a bu...
293
294
  static int sl82c105_init_one(struct pci_dev *dev, const struct pci_device_id *id)
  {
1626aeb88   Tejun Heo   libata: clean up ...
295
  	static const struct ata_port_info info_dma = {
1d2808fd3   Jeff Garzik   [libata] PATA dri...
296
  		.flags = ATA_FLAG_SLAVE_POSS,
14bdef982   Erik Inge Bolsø   [libata] convert ...
297
298
  		.pio_mask = ATA_PIO4,
  		.mwdma_mask = ATA_MWDMA2,
669a5db41   Jeff Garzik   [libata] Add a bu...
299
300
  		.port_ops = &sl82c105_port_ops
  	};
1626aeb88   Tejun Heo   libata: clean up ...
301
  	static const struct ata_port_info info_early = {
1d2808fd3   Jeff Garzik   [libata] PATA dri...
302
  		.flags = ATA_FLAG_SLAVE_POSS,
14bdef982   Erik Inge Bolsø   [libata] convert ...
303
  		.pio_mask = ATA_PIO4,
669a5db41   Jeff Garzik   [libata] Add a bu...
304
305
  		.port_ops = &sl82c105_port_ops
  	};
1626aeb88   Tejun Heo   libata: clean up ...
306
307
  	/* for now use only the first port */
  	const struct ata_port_info *ppi[] = { &info_early,
92ba5d02d   Alan Cox   pata_sl82c105: du...
308
  					       NULL };
669a5db41   Jeff Garzik   [libata] Add a bu...
309
  	int rev;
f08048e94   Tejun Heo   libata: PCI devic...
310
311
312
313
314
  	int rc;
  
  	rc = pcim_enable_device(dev);
  	if (rc)
  		return rc;
669a5db41   Jeff Garzik   [libata] Add a bu...
315
316
  
  	rev = sl82c105_bridge_revision(dev);
85cd7251b   Jeff Garzik   [libata #pata-dri...
317

669a5db41   Jeff Garzik   [libata] Add a bu...
318
  	if (rev == -1)
a44fec1fc   Joe Perches   ata: Convert dev_...
319
320
321
  		dev_warn(&dev->dev,
  			 "pata_sl82c105: Unable to find bridge, disabling DMA
  ");
669a5db41   Jeff Garzik   [libata] Add a bu...
322
  	else if (rev <= 5)
a44fec1fc   Joe Perches   ata: Convert dev_...
323
324
325
  		dev_warn(&dev->dev,
  			 "pata_sl82c105: Early bridge revision, no DMA available
  ");
1626aeb88   Tejun Heo   libata: clean up ...
326
327
  	else
  		ppi[0] = &info_dma;
85cd7251b   Jeff Garzik   [libata #pata-dri...
328

81452182b   Bartlomiej Zolnierkiewicz   pata_sl82c105: ad...
329
  	sl82c105_fixup(dev);
669a5db41   Jeff Garzik   [libata] Add a bu...
330

1c5afdf7a   Tejun Heo   libata-sff: separ...
331
  	return ata_pci_bmdma_init_one(dev, ppi, &sl82c105_sht, NULL, 0);
669a5db41   Jeff Garzik   [libata] Add a bu...
332
  }
81452182b   Bartlomiej Zolnierkiewicz   pata_sl82c105: ad...
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
  #ifdef CONFIG_PM
  static int sl82c105_reinit_one(struct pci_dev *pdev)
  {
  	struct ata_host *host = dev_get_drvdata(&pdev->dev);
  	int rc;
  
  	rc = ata_pci_device_do_resume(pdev);
  	if (rc)
  		return rc;
  
  	sl82c105_fixup(pdev);
  
  	ata_host_resume(host);
  	return 0;
  }
  #endif
2d2744fc8   Jeff Garzik   [libata] PCI ID t...
349
350
351
352
  static const struct pci_device_id sl82c105[] = {
  	{ PCI_VDEVICE(WINBOND, PCI_DEVICE_ID_WINBOND_82C105), },
  
  	{ },
669a5db41   Jeff Garzik   [libata] Add a bu...
353
354
355
356
357
358
  };
  
  static struct pci_driver sl82c105_pci_driver = {
  	.name 		= DRV_NAME,
  	.id_table	= sl82c105,
  	.probe 		= sl82c105_init_one,
81452182b   Bartlomiej Zolnierkiewicz   pata_sl82c105: ad...
359
360
361
362
363
  	.remove		= ata_pci_remove_one,
  #ifdef CONFIG_PM
  	.suspend	= ata_pci_device_suspend,
  	.resume		= sl82c105_reinit_one,
  #endif
669a5db41   Jeff Garzik   [libata] Add a bu...
364
365
366
367
368
369
  };
  
  static int __init sl82c105_init(void)
  {
  	return pci_register_driver(&sl82c105_pci_driver);
  }
669a5db41   Jeff Garzik   [libata] Add a bu...
370
371
372
373
  static void __exit sl82c105_exit(void)
  {
  	pci_unregister_driver(&sl82c105_pci_driver);
  }
669a5db41   Jeff Garzik   [libata] Add a bu...
374
375
376
377
378
379
380
381
  MODULE_AUTHOR("Alan Cox");
  MODULE_DESCRIPTION("low-level driver for Sl82c105");
  MODULE_LICENSE("GPL");
  MODULE_DEVICE_TABLE(pci, sl82c105);
  MODULE_VERSION(DRV_VERSION);
  
  module_init(sl82c105_init);
  module_exit(sl82c105_exit);