diff options
Diffstat (limited to 'drivers/ata/pata_pcmcia.c')
-rw-r--r-- | drivers/ata/pata_pcmcia.c | 101 |
1 files changed, 88 insertions, 13 deletions
diff --git a/drivers/ata/pata_pcmcia.c b/drivers/ata/pata_pcmcia.c index fd36099428a4..3e7f6a9da28b 100644 --- a/drivers/ata/pata_pcmcia.c +++ b/drivers/ata/pata_pcmcia.c | |||
@@ -42,7 +42,7 @@ | |||
42 | 42 | ||
43 | 43 | ||
44 | #define DRV_NAME "pata_pcmcia" | 44 | #define DRV_NAME "pata_pcmcia" |
45 | #define DRV_VERSION "0.3.2" | 45 | #define DRV_VERSION "0.3.3" |
46 | 46 | ||
47 | /* | 47 | /* |
48 | * Private data structure to glue stuff together | 48 | * Private data structure to glue stuff together |
@@ -86,6 +86,47 @@ static int pcmcia_set_mode(struct ata_link *link, struct ata_device **r_failed_d | |||
86 | return ata_do_set_mode(link, r_failed_dev); | 86 | return ata_do_set_mode(link, r_failed_dev); |
87 | } | 87 | } |
88 | 88 | ||
89 | /** | ||
90 | * pcmcia_set_mode_8bit - PCMCIA specific mode setup | ||
91 | * @link: link | ||
92 | * @r_failed_dev: Return pointer for failed device | ||
93 | * | ||
94 | * For the simple emulated 8bit stuff the less we do the better. | ||
95 | */ | ||
96 | |||
97 | static int pcmcia_set_mode_8bit(struct ata_link *link, | ||
98 | struct ata_device **r_failed_dev) | ||
99 | { | ||
100 | return 0; | ||
101 | } | ||
102 | |||
103 | /** | ||
104 | * ata_data_xfer_8bit - Transfer data by 8bit PIO | ||
105 | * @dev: device to target | ||
106 | * @buf: data buffer | ||
107 | * @buflen: buffer length | ||
108 | * @rw: read/write | ||
109 | * | ||
110 | * Transfer data from/to the device data register by 8 bit PIO. | ||
111 | * | ||
112 | * LOCKING: | ||
113 | * Inherited from caller. | ||
114 | */ | ||
115 | |||
116 | static unsigned int ata_data_xfer_8bit(struct ata_device *dev, | ||
117 | unsigned char *buf, unsigned int buflen, int rw) | ||
118 | { | ||
119 | struct ata_port *ap = dev->link->ap; | ||
120 | |||
121 | if (rw == READ) | ||
122 | ioread8_rep(ap->ioaddr.data_addr, buf, buflen); | ||
123 | else | ||
124 | iowrite8_rep(ap->ioaddr.data_addr, buf, buflen); | ||
125 | |||
126 | return buflen; | ||
127 | } | ||
128 | |||
129 | |||
89 | static struct scsi_host_template pcmcia_sht = { | 130 | static struct scsi_host_template pcmcia_sht = { |
90 | .module = THIS_MODULE, | 131 | .module = THIS_MODULE, |
91 | .name = DRV_NAME, | 132 | .name = DRV_NAME, |
@@ -129,6 +170,31 @@ static struct ata_port_operations pcmcia_port_ops = { | |||
129 | .port_start = ata_sff_port_start, | 170 | .port_start = ata_sff_port_start, |
130 | }; | 171 | }; |
131 | 172 | ||
173 | static struct ata_port_operations pcmcia_8bit_port_ops = { | ||
174 | .set_mode = pcmcia_set_mode_8bit, | ||
175 | .tf_load = ata_tf_load, | ||
176 | .tf_read = ata_tf_read, | ||
177 | .check_status = ata_check_status, | ||
178 | .exec_command = ata_exec_command, | ||
179 | .dev_select = ata_std_dev_select, | ||
180 | |||
181 | .freeze = ata_bmdma_freeze, | ||
182 | .thaw = ata_bmdma_thaw, | ||
183 | .error_handler = ata_bmdma_error_handler, | ||
184 | .post_internal_cmd = ata_bmdma_post_internal_cmd, | ||
185 | .cable_detect = ata_cable_40wire, | ||
186 | |||
187 | .qc_prep = ata_qc_prep, | ||
188 | .qc_issue = ata_qc_issue_prot, | ||
189 | |||
190 | .data_xfer = ata_data_xfer_8bit, | ||
191 | |||
192 | .irq_clear = ata_bmdma_irq_clear, | ||
193 | .irq_on = ata_irq_on, | ||
194 | |||
195 | .port_start = ata_sff_port_start, | ||
196 | }; | ||
197 | |||
132 | #define CS_CHECK(fn, ret) \ | 198 | #define CS_CHECK(fn, ret) \ |
133 | do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0) | 199 | do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0) |
134 | 200 | ||
@@ -153,9 +219,12 @@ static int pcmcia_init_one(struct pcmcia_device *pdev) | |||
153 | cistpl_cftable_entry_t dflt; | 219 | cistpl_cftable_entry_t dflt; |
154 | } *stk = NULL; | 220 | } *stk = NULL; |
155 | cistpl_cftable_entry_t *cfg; | 221 | cistpl_cftable_entry_t *cfg; |
156 | int pass, last_ret = 0, last_fn = 0, is_kme = 0, ret = -ENOMEM; | 222 | int pass, last_ret = 0, last_fn = 0, is_kme = 0, ret = -ENOMEM, p; |
157 | unsigned long io_base, ctl_base; | 223 | unsigned long io_base, ctl_base; |
158 | void __iomem *io_addr, *ctl_addr; | 224 | void __iomem *io_addr, *ctl_addr; |
225 | int n_ports = 1; | ||
226 | |||
227 | struct ata_port_operations *ops = &pcmcia_port_ops; | ||
159 | 228 | ||
160 | info = kzalloc(sizeof(*info), GFP_KERNEL); | 229 | info = kzalloc(sizeof(*info), GFP_KERNEL); |
161 | if (info == NULL) | 230 | if (info == NULL) |
@@ -282,27 +351,32 @@ next_entry: | |||
282 | /* FIXME: Could be more ports at base + 0x10 but we only deal with | 351 | /* FIXME: Could be more ports at base + 0x10 but we only deal with |
283 | one right now */ | 352 | one right now */ |
284 | if (pdev->io.NumPorts1 >= 0x20) | 353 | if (pdev->io.NumPorts1 >= 0x20) |
285 | printk(KERN_WARNING DRV_NAME ": second channel not yet supported.\n"); | 354 | n_ports = 2; |
286 | 355 | ||
356 | if (pdev->manf_id == 0x0097 && pdev->card_id == 0x1620) | ||
357 | ops = &pcmcia_8bit_port_ops; | ||
287 | /* | 358 | /* |
288 | * Having done the PCMCIA plumbing the ATA side is relatively | 359 | * Having done the PCMCIA plumbing the ATA side is relatively |
289 | * sane. | 360 | * sane. |
290 | */ | 361 | */ |
291 | ret = -ENOMEM; | 362 | ret = -ENOMEM; |
292 | host = ata_host_alloc(&pdev->dev, 1); | 363 | host = ata_host_alloc(&pdev->dev, n_ports); |
293 | if (!host) | 364 | if (!host) |
294 | goto failed; | 365 | goto failed; |
295 | ap = host->ports[0]; | ||
296 | 366 | ||
297 | ap->ops = &pcmcia_port_ops; | 367 | for (p = 0; p < n_ports; p++) { |
298 | ap->pio_mask = 1; /* ISA so PIO 0 cycles */ | 368 | ap = host->ports[p]; |
299 | ap->flags |= ATA_FLAG_SLAVE_POSS; | ||
300 | ap->ioaddr.cmd_addr = io_addr; | ||
301 | ap->ioaddr.altstatus_addr = ctl_addr; | ||
302 | ap->ioaddr.ctl_addr = ctl_addr; | ||
303 | ata_std_ports(&ap->ioaddr); | ||
304 | 369 | ||
305 | ata_port_desc(ap, "cmd 0x%lx ctl 0x%lx", io_base, ctl_base); | 370 | ap->ops = ops; |
371 | ap->pio_mask = 1; /* ISA so PIO 0 cycles */ | ||
372 | ap->flags |= ATA_FLAG_SLAVE_POSS; | ||
373 | ap->ioaddr.cmd_addr = io_addr + 0x10 * p; | ||
374 | ap->ioaddr.altstatus_addr = ctl_addr + 0x10 * p; | ||
375 | ap->ioaddr.ctl_addr = ctl_addr + 0x10 * p; | ||
376 | ata_std_ports(&ap->ioaddr); | ||
377 | |||
378 | ata_port_desc(ap, "cmd 0x%lx ctl 0x%lx", io_base, ctl_base); | ||
379 | } | ||
306 | 380 | ||
307 | /* activate */ | 381 | /* activate */ |
308 | ret = ata_host_activate(host, pdev->irq.AssignedIRQ, ata_interrupt, | 382 | ret = ata_host_activate(host, pdev->irq.AssignedIRQ, ata_interrupt, |
@@ -360,6 +434,7 @@ static struct pcmcia_device_id pcmcia_devices[] = { | |||
360 | PCMCIA_DEVICE_MANF_CARD(0x0032, 0x0704), | 434 | PCMCIA_DEVICE_MANF_CARD(0x0032, 0x0704), |
361 | PCMCIA_DEVICE_MANF_CARD(0x0032, 0x2904), | 435 | PCMCIA_DEVICE_MANF_CARD(0x0032, 0x2904), |
362 | PCMCIA_DEVICE_MANF_CARD(0x0045, 0x0401), /* SanDisk CFA */ | 436 | PCMCIA_DEVICE_MANF_CARD(0x0045, 0x0401), /* SanDisk CFA */ |
437 | PCMCIA_DEVICE_MANF_CARD(0x0097, 0x1620), /* TI emulated */ | ||
363 | PCMCIA_DEVICE_MANF_CARD(0x0098, 0x0000), /* Toshiba */ | 438 | PCMCIA_DEVICE_MANF_CARD(0x0098, 0x0000), /* Toshiba */ |
364 | PCMCIA_DEVICE_MANF_CARD(0x00a4, 0x002d), | 439 | PCMCIA_DEVICE_MANF_CARD(0x00a4, 0x002d), |
365 | PCMCIA_DEVICE_MANF_CARD(0x00ce, 0x0000), /* Samsung */ | 440 | PCMCIA_DEVICE_MANF_CARD(0x00ce, 0x0000), /* Samsung */ |