aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/scsi/libata-core.c133
-rw-r--r--drivers/scsi/sata_nv.c2
-rw-r--r--drivers/scsi/sata_sis.c2
-rw-r--r--drivers/scsi/sata_uli.c2
-rw-r--r--drivers/scsi/sata_via.c2
-rw-r--r--include/linux/libata.h6
6 files changed, 85 insertions, 62 deletions
diff --git a/drivers/scsi/libata-core.c b/drivers/scsi/libata-core.c
index 03d422e99e58..82ec7f30bf3f 100644
--- a/drivers/scsi/libata-core.c
+++ b/drivers/scsi/libata-core.c
@@ -4363,85 +4363,87 @@ void ata_pci_host_stop (struct ata_host_set *host_set)
4363 * ata_pci_init_native_mode - Initialize native-mode driver 4363 * ata_pci_init_native_mode - Initialize native-mode driver
4364 * @pdev: pci device to be initialized 4364 * @pdev: pci device to be initialized
4365 * @port: array[2] of pointers to port info structures. 4365 * @port: array[2] of pointers to port info structures.
4366 * @ports: bitmap of ports present
4366 * 4367 *
4367 * Utility function which allocates and initializes an 4368 * Utility function which allocates and initializes an
4368 * ata_probe_ent structure for a standard dual-port 4369 * ata_probe_ent structure for a standard dual-port
4369 * PIO-based IDE controller. The returned ata_probe_ent 4370 * PIO-based IDE controller. The returned ata_probe_ent
4370 * structure can be passed to ata_device_add(). The returned 4371 * structure can be passed to ata_device_add(). The returned
4371 * ata_probe_ent structure should then be freed with kfree(). 4372 * ata_probe_ent structure should then be freed with kfree().
4373 *
4374 * The caller need only pass the address of the primary port, the
4375 * secondary will be deduced automatically. If the device has non
4376 * standard secondary port mappings this function can be called twice,
4377 * once for each interface.
4372 */ 4378 */
4373 4379
4374struct ata_probe_ent * 4380struct ata_probe_ent *
4375ata_pci_init_native_mode(struct pci_dev *pdev, struct ata_port_info **port) 4381ata_pci_init_native_mode(struct pci_dev *pdev, struct ata_port_info **port, int ports)
4376{ 4382{
4377 struct ata_probe_ent *probe_ent = 4383 struct ata_probe_ent *probe_ent =
4378 ata_probe_ent_alloc(pci_dev_to_dev(pdev), port[0]); 4384 ata_probe_ent_alloc(pci_dev_to_dev(pdev), port[0]);
4385 int p = 0;
4386
4379 if (!probe_ent) 4387 if (!probe_ent)
4380 return NULL; 4388 return NULL;
4381 4389
4382 probe_ent->n_ports = 2;
4383 probe_ent->irq = pdev->irq; 4390 probe_ent->irq = pdev->irq;
4384 probe_ent->irq_flags = SA_SHIRQ; 4391 probe_ent->irq_flags = SA_SHIRQ;
4385 4392
4386 probe_ent->port[0].cmd_addr = pci_resource_start(pdev, 0); 4393 if (ports & ATA_PORT_PRIMARY) {
4387 probe_ent->port[0].altstatus_addr = 4394 probe_ent->port[p].cmd_addr = pci_resource_start(pdev, 0);
4388 probe_ent->port[0].ctl_addr = 4395 probe_ent->port[p].altstatus_addr =
4389 pci_resource_start(pdev, 1) | ATA_PCI_CTL_OFS; 4396 probe_ent->port[p].ctl_addr =
4390 probe_ent->port[0].bmdma_addr = pci_resource_start(pdev, 4); 4397 pci_resource_start(pdev, 1) | ATA_PCI_CTL_OFS;
4391 4398 probe_ent->port[p].bmdma_addr = pci_resource_start(pdev, 4);
4392 probe_ent->port[1].cmd_addr = pci_resource_start(pdev, 2); 4399 ata_std_ports(&probe_ent->port[p]);
4393 probe_ent->port[1].altstatus_addr = 4400 p++;
4394 probe_ent->port[1].ctl_addr = 4401 }
4395 pci_resource_start(pdev, 3) | ATA_PCI_CTL_OFS;
4396 probe_ent->port[1].bmdma_addr = pci_resource_start(pdev, 4) + 8;
4397 4402
4398 ata_std_ports(&probe_ent->port[0]); 4403 if (ports & ATA_PORT_SECONDARY) {
4399 ata_std_ports(&probe_ent->port[1]); 4404 probe_ent->port[p].cmd_addr = pci_resource_start(pdev, 2);
4405 probe_ent->port[p].altstatus_addr =
4406 probe_ent->port[p].ctl_addr =
4407 pci_resource_start(pdev, 3) | ATA_PCI_CTL_OFS;
4408 probe_ent->port[p].bmdma_addr = pci_resource_start(pdev, 4) + 8;
4409 ata_std_ports(&probe_ent->port[p]);
4410 p++;
4411 }
4400 4412
4413 probe_ent->n_ports = p;
4401 return probe_ent; 4414 return probe_ent;
4402} 4415}
4403 4416
4404static struct ata_probe_ent * 4417static struct ata_probe_ent *ata_pci_init_legacy_port(struct pci_dev *pdev, struct ata_port_info **port, int port_num)
4405ata_pci_init_legacy_mode(struct pci_dev *pdev, struct ata_port_info **port,
4406 struct ata_probe_ent **ppe2)
4407{ 4418{
4408 struct ata_probe_ent *probe_ent, *probe_ent2; 4419 struct ata_probe_ent *probe_ent;
4409 4420
4410 probe_ent = ata_probe_ent_alloc(pci_dev_to_dev(pdev), port[0]); 4421 probe_ent = ata_probe_ent_alloc(pci_dev_to_dev(pdev), port[0]);
4411 if (!probe_ent) 4422 if (!probe_ent)
4412 return NULL; 4423 return NULL;
4413 probe_ent2 = ata_probe_ent_alloc(pci_dev_to_dev(pdev), port[1]);
4414 if (!probe_ent2) {
4415 kfree(probe_ent);
4416 return NULL;
4417 }
4418
4419 probe_ent->n_ports = 1;
4420 probe_ent->irq = 14;
4421 4424
4422 probe_ent->hard_port_no = 0; 4425
4423 probe_ent->legacy_mode = 1; 4426 probe_ent->legacy_mode = 1;
4424 4427 probe_ent->n_ports = 1;
4425 probe_ent2->n_ports = 1; 4428 probe_ent->hard_port_no = port_num;
4426 probe_ent2->irq = 15; 4429
4427 4430 switch(port_num)
4428 probe_ent2->hard_port_no = 1; 4431 {
4429 probe_ent2->legacy_mode = 1; 4432 case 0:
4430 4433 probe_ent->irq = 14;
4431 probe_ent->port[0].cmd_addr = 0x1f0; 4434 probe_ent->port[0].cmd_addr = 0x1f0;
4432 probe_ent->port[0].altstatus_addr = 4435 probe_ent->port[0].altstatus_addr =
4433 probe_ent->port[0].ctl_addr = 0x3f6; 4436 probe_ent->port[0].ctl_addr = 0x3f6;
4434 probe_ent->port[0].bmdma_addr = pci_resource_start(pdev, 4); 4437 break;
4435 4438 case 1:
4436 probe_ent2->port[0].cmd_addr = 0x170; 4439 probe_ent->irq = 15;
4437 probe_ent2->port[0].altstatus_addr = 4440 probe_ent->port[0].cmd_addr = 0x170;
4438 probe_ent2->port[0].ctl_addr = 0x376; 4441 probe_ent->port[0].altstatus_addr =
4439 probe_ent2->port[0].bmdma_addr = pci_resource_start(pdev, 4)+8; 4442 probe_ent->port[0].ctl_addr = 0x376;
4440 4443 break;
4444 }
4445 probe_ent->port[0].bmdma_addr = pci_resource_start(pdev, 4) + 8 * port_num;
4441 ata_std_ports(&probe_ent->port[0]); 4446 ata_std_ports(&probe_ent->port[0]);
4442 ata_std_ports(&probe_ent2->port[0]);
4443
4444 *ppe2 = probe_ent2;
4445 return probe_ent; 4447 return probe_ent;
4446} 4448}
4447 4449
@@ -4470,7 +4472,7 @@ ata_pci_init_legacy_mode(struct pci_dev *pdev, struct ata_port_info **port,
4470int ata_pci_init_one (struct pci_dev *pdev, struct ata_port_info **port_info, 4472int ata_pci_init_one (struct pci_dev *pdev, struct ata_port_info **port_info,
4471 unsigned int n_ports) 4473 unsigned int n_ports)
4472{ 4474{
4473 struct ata_probe_ent *probe_ent, *probe_ent2 = NULL; 4475 struct ata_probe_ent *probe_ent = NULL, *probe_ent2 = NULL;
4474 struct ata_port_info *port[2]; 4476 struct ata_port_info *port[2];
4475 u8 tmp8, mask; 4477 u8 tmp8, mask;
4476 unsigned int legacy_mode = 0; 4478 unsigned int legacy_mode = 0;
@@ -4487,7 +4489,7 @@ int ata_pci_init_one (struct pci_dev *pdev, struct ata_port_info **port_info,
4487 4489
4488 if ((port[0]->host_flags & ATA_FLAG_NO_LEGACY) == 0 4490 if ((port[0]->host_flags & ATA_FLAG_NO_LEGACY) == 0
4489 && (pdev->class >> 8) == PCI_CLASS_STORAGE_IDE) { 4491 && (pdev->class >> 8) == PCI_CLASS_STORAGE_IDE) {
4490 /* TODO: support transitioning to native mode? */ 4492 /* TODO: What if one channel is in native mode ... */
4491 pci_read_config_byte(pdev, PCI_CLASS_PROG, &tmp8); 4493 pci_read_config_byte(pdev, PCI_CLASS_PROG, &tmp8);
4492 mask = (1 << 2) | (1 << 0); 4494 mask = (1 << 2) | (1 << 0);
4493 if ((tmp8 & mask) != mask) 4495 if ((tmp8 & mask) != mask)
@@ -4495,11 +4497,20 @@ int ata_pci_init_one (struct pci_dev *pdev, struct ata_port_info **port_info,
4495 } 4497 }
4496 4498
4497 /* FIXME... */ 4499 /* FIXME... */
4498 if ((!legacy_mode) && (n_ports > 1)) { 4500 if ((!legacy_mode) && (n_ports > 2)) {
4499 printk(KERN_ERR "ata: BUG: native mode, n_ports > 1\n"); 4501 printk(KERN_ERR "ata: BUG: native mode, n_ports > 2\n");
4500 return -EINVAL; 4502 n_ports = 2;
4503 /* For now */
4501 } 4504 }
4502 4505
4506 /* FIXME: Really for ATA it isn't safe because the device may be
4507 multi-purpose and we want to leave it alone if it was already
4508 enabled. Secondly for shared use as Arjan says we want refcounting
4509
4510 Checking dev->is_enabled is insufficient as this is not set at
4511 boot for the primary video which is BIOS enabled
4512 */
4513
4503 rc = pci_enable_device(pdev); 4514 rc = pci_enable_device(pdev);
4504 if (rc) 4515 if (rc)
4505 return rc; 4516 return rc;
@@ -4510,6 +4521,7 @@ int ata_pci_init_one (struct pci_dev *pdev, struct ata_port_info **port_info,
4510 goto err_out; 4521 goto err_out;
4511 } 4522 }
4512 4523
4524 /* FIXME: Should use platform specific mappers for legacy port ranges */
4513 if (legacy_mode) { 4525 if (legacy_mode) {
4514 if (!request_region(0x1f0, 8, "libata")) { 4526 if (!request_region(0x1f0, 8, "libata")) {
4515 struct resource *conflict, res; 4527 struct resource *conflict, res;
@@ -4554,10 +4566,17 @@ int ata_pci_init_one (struct pci_dev *pdev, struct ata_port_info **port_info,
4554 goto err_out_regions; 4566 goto err_out_regions;
4555 4567
4556 if (legacy_mode) { 4568 if (legacy_mode) {
4557 probe_ent = ata_pci_init_legacy_mode(pdev, port, &probe_ent2); 4569 if (legacy_mode & (1 << 0))
4558 } else 4570 probe_ent = ata_pci_init_legacy_port(pdev, port, 0);
4559 probe_ent = ata_pci_init_native_mode(pdev, port); 4571 if (legacy_mode & (1 << 1))
4560 if (!probe_ent) { 4572 probe_ent2 = ata_pci_init_legacy_port(pdev, port, 1);
4573 } else {
4574 if (n_ports == 2)
4575 probe_ent = ata_pci_init_native_mode(pdev, port, ATA_PORT_PRIMARY | ATA_PORT_SECONDARY);
4576 else
4577 probe_ent = ata_pci_init_native_mode(pdev, port, ATA_PORT_PRIMARY);
4578 }
4579 if (!probe_ent && !probe_ent2) {
4561 rc = -ENOMEM; 4580 rc = -ENOMEM;
4562 goto err_out_regions; 4581 goto err_out_regions;
4563 } 4582 }
diff --git a/drivers/scsi/sata_nv.c b/drivers/scsi/sata_nv.c
index c05653c7779d..749ff92d8c63 100644
--- a/drivers/scsi/sata_nv.c
+++ b/drivers/scsi/sata_nv.c
@@ -405,7 +405,7 @@ static int nv_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
405 rc = -ENOMEM; 405 rc = -ENOMEM;
406 406
407 ppi = &nv_port_info; 407 ppi = &nv_port_info;
408 probe_ent = ata_pci_init_native_mode(pdev, &ppi); 408 probe_ent = ata_pci_init_native_mode(pdev, &ppi, ATA_PORT_PRIMARY | ATA_PORT_SECONDARY);
409 if (!probe_ent) 409 if (!probe_ent)
410 goto err_out_regions; 410 goto err_out_regions;
411 411
diff --git a/drivers/scsi/sata_sis.c b/drivers/scsi/sata_sis.c
index b227e51d12f4..0761a3234fcf 100644
--- a/drivers/scsi/sata_sis.c
+++ b/drivers/scsi/sata_sis.c
@@ -263,7 +263,7 @@ static int sis_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
263 goto err_out_regions; 263 goto err_out_regions;
264 264
265 ppi = &sis_port_info; 265 ppi = &sis_port_info;
266 probe_ent = ata_pci_init_native_mode(pdev, &ppi); 266 probe_ent = ata_pci_init_native_mode(pdev, &ppi, ATA_PORT_PRIMARY | ATA_PORT_SECONDARY);
267 if (!probe_ent) { 267 if (!probe_ent) {
268 rc = -ENOMEM; 268 rc = -ENOMEM;
269 goto err_out_regions; 269 goto err_out_regions;
diff --git a/drivers/scsi/sata_uli.c b/drivers/scsi/sata_uli.c
index 4c9fb8b71be1..9c06f2abe7f7 100644
--- a/drivers/scsi/sata_uli.c
+++ b/drivers/scsi/sata_uli.c
@@ -202,7 +202,7 @@ static int uli_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
202 goto err_out_regions; 202 goto err_out_regions;
203 203
204 ppi = &uli_port_info; 204 ppi = &uli_port_info;
205 probe_ent = ata_pci_init_native_mode(pdev, &ppi); 205 probe_ent = ata_pci_init_native_mode(pdev, &ppi, ATA_PORT_PRIMARY | ATA_PORT_SECONDARY);
206 if (!probe_ent) { 206 if (!probe_ent) {
207 rc = -ENOMEM; 207 rc = -ENOMEM;
208 goto err_out_regions; 208 goto err_out_regions;
diff --git a/drivers/scsi/sata_via.c b/drivers/scsi/sata_via.c
index 128b996b07b7..565872479b9a 100644
--- a/drivers/scsi/sata_via.c
+++ b/drivers/scsi/sata_via.c
@@ -212,7 +212,7 @@ static struct ata_probe_ent *vt6420_init_probe_ent(struct pci_dev *pdev)
212 struct ata_probe_ent *probe_ent; 212 struct ata_probe_ent *probe_ent;
213 struct ata_port_info *ppi = &svia_port_info; 213 struct ata_port_info *ppi = &svia_port_info;
214 214
215 probe_ent = ata_pci_init_native_mode(pdev, &ppi); 215 probe_ent = ata_pci_init_native_mode(pdev, &ppi, ATA_PORT_PRIMARY | ATA_PORT_SECONDARY);
216 if (!probe_ent) 216 if (!probe_ent)
217 return NULL; 217 return NULL;
218 218
diff --git a/include/linux/libata.h b/include/linux/libata.h
index 4739a75b983d..4d45179872cc 100644
--- a/include/linux/libata.h
+++ b/include/linux/libata.h
@@ -155,6 +155,10 @@ enum {
155 ATA_SHIFT_UDMA = 0, 155 ATA_SHIFT_UDMA = 0,
156 ATA_SHIFT_MWDMA = 8, 156 ATA_SHIFT_MWDMA = 8,
157 ATA_SHIFT_PIO = 11, 157 ATA_SHIFT_PIO = 11,
158
159 /* Masks for port functions */
160 ATA_PORT_PRIMARY = (1 << 0),
161 ATA_PORT_SECONDARY = (1 << 1),
158}; 162};
159 163
160enum hsm_task_states { 164enum hsm_task_states {
@@ -458,7 +462,7 @@ struct pci_bits {
458 462
459extern void ata_pci_host_stop (struct ata_host_set *host_set); 463extern void ata_pci_host_stop (struct ata_host_set *host_set);
460extern struct ata_probe_ent * 464extern struct ata_probe_ent *
461ata_pci_init_native_mode(struct pci_dev *pdev, struct ata_port_info **port); 465ata_pci_init_native_mode(struct pci_dev *pdev, struct ata_port_info **port, int portmask);
462extern int pci_test_config_bits(struct pci_dev *pdev, struct pci_bits *bits); 466extern int pci_test_config_bits(struct pci_dev *pdev, struct pci_bits *bits);
463 467
464#endif /* CONFIG_PCI */ 468#endif /* CONFIG_PCI */