diff options
Diffstat (limited to 'drivers/ata/pata_sil680.c')
-rw-r--r-- | drivers/ata/pata_sil680.c | 83 |
1 files changed, 55 insertions, 28 deletions
diff --git a/drivers/ata/pata_sil680.c b/drivers/ata/pata_sil680.c index 11942fd03b55..32cf0bfa8921 100644 --- a/drivers/ata/pata_sil680.c +++ b/drivers/ata/pata_sil680.c | |||
@@ -33,7 +33,7 @@ | |||
33 | #include <linux/libata.h> | 33 | #include <linux/libata.h> |
34 | 34 | ||
35 | #define DRV_NAME "pata_sil680" | 35 | #define DRV_NAME "pata_sil680" |
36 | #define DRV_VERSION "0.3.2" | 36 | #define DRV_VERSION "0.4.1" |
37 | 37 | ||
38 | /** | 38 | /** |
39 | * sil680_selreg - return register base | 39 | * sil680_selreg - return register base |
@@ -218,7 +218,6 @@ static struct scsi_host_template sil680_sht = { | |||
218 | .can_queue = ATA_DEF_QUEUE, | 218 | .can_queue = ATA_DEF_QUEUE, |
219 | .this_id = ATA_SHT_THIS_ID, | 219 | .this_id = ATA_SHT_THIS_ID, |
220 | .sg_tablesize = LIBATA_MAX_PRD, | 220 | .sg_tablesize = LIBATA_MAX_PRD, |
221 | .max_sectors = ATA_MAX_SECTORS, | ||
222 | .cmd_per_lun = ATA_SHT_CMD_PER_LUN, | 221 | .cmd_per_lun = ATA_SHT_CMD_PER_LUN, |
223 | .emulated = ATA_SHT_EMULATED, | 222 | .emulated = ATA_SHT_EMULATED, |
224 | .use_clustering = ATA_SHT_USE_CLUSTERING, | 223 | .use_clustering = ATA_SHT_USE_CLUSTERING, |
@@ -263,32 +262,20 @@ static struct ata_port_operations sil680_port_ops = { | |||
263 | .host_stop = ata_host_stop | 262 | .host_stop = ata_host_stop |
264 | }; | 263 | }; |
265 | 264 | ||
266 | static int sil680_init_one(struct pci_dev *pdev, const struct pci_device_id *id) | 265 | /** |
266 | * sil680_init_chip - chip setup | ||
267 | * @pdev: PCI device | ||
268 | * | ||
269 | * Perform all the chip setup which must be done both when the device | ||
270 | * is powered up on boot and when we resume in case we resumed from RAM. | ||
271 | * Returns the final clock settings. | ||
272 | */ | ||
273 | |||
274 | static u8 sil680_init_chip(struct pci_dev *pdev) | ||
267 | { | 275 | { |
268 | static struct ata_port_info info = { | ||
269 | .sht = &sil680_sht, | ||
270 | .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, | ||
271 | .pio_mask = 0x1f, | ||
272 | .mwdma_mask = 0x07, | ||
273 | .udma_mask = 0x7f, | ||
274 | .port_ops = &sil680_port_ops | ||
275 | }; | ||
276 | static struct ata_port_info info_slow = { | ||
277 | .sht = &sil680_sht, | ||
278 | .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, | ||
279 | .pio_mask = 0x1f, | ||
280 | .mwdma_mask = 0x07, | ||
281 | .udma_mask = 0x3f, | ||
282 | .port_ops = &sil680_port_ops | ||
283 | }; | ||
284 | static struct ata_port_info *port_info[2] = {&info, &info}; | ||
285 | static int printed_version; | ||
286 | u32 class_rev = 0; | 276 | u32 class_rev = 0; |
287 | u8 tmpbyte = 0; | 277 | u8 tmpbyte = 0; |
288 | 278 | ||
289 | if (!printed_version++) | ||
290 | dev_printk(KERN_DEBUG, &pdev->dev, "version " DRV_VERSION "\n"); | ||
291 | |||
292 | pci_read_config_dword(pdev, PCI_CLASS_REVISION, &class_rev); | 279 | pci_read_config_dword(pdev, PCI_CLASS_REVISION, &class_rev); |
293 | class_rev &= 0xff; | 280 | class_rev &= 0xff; |
294 | /* FIXME: double check */ | 281 | /* FIXME: double check */ |
@@ -323,8 +310,6 @@ static int sil680_init_one(struct pci_dev *pdev, const struct pci_device_id *id) | |||
323 | pci_read_config_byte(pdev, 0x8A, &tmpbyte); | 310 | pci_read_config_byte(pdev, 0x8A, &tmpbyte); |
324 | printk(KERN_INFO "sil680: BA5_EN = %d clock = %02X\n", | 311 | printk(KERN_INFO "sil680: BA5_EN = %d clock = %02X\n", |
325 | tmpbyte & 1, tmpbyte & 0x30); | 312 | tmpbyte & 1, tmpbyte & 0x30); |
326 | if ((tmpbyte & 0x30) == 0) | ||
327 | port_info[0] = port_info[1] = &info_slow; | ||
328 | 313 | ||
329 | pci_write_config_byte(pdev, 0xA1, 0x72); | 314 | pci_write_config_byte(pdev, 0xA1, 0x72); |
330 | pci_write_config_word(pdev, 0xA2, 0x328A); | 315 | pci_write_config_word(pdev, 0xA2, 0x328A); |
@@ -343,11 +328,51 @@ static int sil680_init_one(struct pci_dev *pdev, const struct pci_device_id *id) | |||
343 | case 0x20: printk(KERN_INFO "sil680: Using PCI clock.\n");break; | 328 | case 0x20: printk(KERN_INFO "sil680: Using PCI clock.\n");break; |
344 | /* This last case is _NOT_ ok */ | 329 | /* This last case is _NOT_ ok */ |
345 | case 0x30: printk(KERN_ERR "sil680: Clock disabled ?\n"); | 330 | case 0x30: printk(KERN_ERR "sil680: Clock disabled ?\n"); |
346 | return -EIO; | 331 | } |
332 | return tmpbyte & 0x30; | ||
333 | } | ||
334 | |||
335 | static int sil680_init_one(struct pci_dev *pdev, const struct pci_device_id *id) | ||
336 | { | ||
337 | static struct ata_port_info info = { | ||
338 | .sht = &sil680_sht, | ||
339 | .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, | ||
340 | .pio_mask = 0x1f, | ||
341 | .mwdma_mask = 0x07, | ||
342 | .udma_mask = 0x7f, | ||
343 | .port_ops = &sil680_port_ops | ||
344 | }; | ||
345 | static struct ata_port_info info_slow = { | ||
346 | .sht = &sil680_sht, | ||
347 | .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, | ||
348 | .pio_mask = 0x1f, | ||
349 | .mwdma_mask = 0x07, | ||
350 | .udma_mask = 0x3f, | ||
351 | .port_ops = &sil680_port_ops | ||
352 | }; | ||
353 | static struct ata_port_info *port_info[2] = {&info, &info}; | ||
354 | static int printed_version; | ||
355 | |||
356 | if (!printed_version++) | ||
357 | dev_printk(KERN_DEBUG, &pdev->dev, "version " DRV_VERSION "\n"); | ||
358 | |||
359 | switch(sil680_init_chip(pdev)) | ||
360 | { | ||
361 | case 0: | ||
362 | port_info[0] = port_info[1] = &info_slow; | ||
363 | break; | ||
364 | case 0x30: | ||
365 | return -ENODEV; | ||
347 | } | 366 | } |
348 | return ata_pci_init_one(pdev, port_info, 2); | 367 | return ata_pci_init_one(pdev, port_info, 2); |
349 | } | 368 | } |
350 | 369 | ||
370 | static int sil680_reinit_one(struct pci_dev *pdev) | ||
371 | { | ||
372 | sil680_init_chip(pdev); | ||
373 | return ata_pci_device_resume(pdev); | ||
374 | } | ||
375 | |||
351 | static const struct pci_device_id sil680[] = { | 376 | static const struct pci_device_id sil680[] = { |
352 | { PCI_VDEVICE(CMD, PCI_DEVICE_ID_SII_680), }, | 377 | { PCI_VDEVICE(CMD, PCI_DEVICE_ID_SII_680), }, |
353 | 378 | ||
@@ -358,7 +383,9 @@ static struct pci_driver sil680_pci_driver = { | |||
358 | .name = DRV_NAME, | 383 | .name = DRV_NAME, |
359 | .id_table = sil680, | 384 | .id_table = sil680, |
360 | .probe = sil680_init_one, | 385 | .probe = sil680_init_one, |
361 | .remove = ata_pci_remove_one | 386 | .remove = ata_pci_remove_one, |
387 | .suspend = ata_pci_device_suspend, | ||
388 | .resume = sil680_reinit_one, | ||
362 | }; | 389 | }; |
363 | 390 | ||
364 | static int __init sil680_init(void) | 391 | static int __init sil680_init(void) |