diff options
author | Jeff Garzik <jgarzik@pobox.com> | 2005-09-24 00:26:49 -0400 |
---|---|---|
committer | Jeff Garzik <jgarzik@pobox.com> | 2005-09-24 00:26:49 -0400 |
commit | 98ed72deebfd2b55b7e1bb94c8175b1169999212 (patch) | |
tree | f1682a68f65e0a38159f55a58c054779d749f8df /drivers/scsi/libata-core.c | |
parent | dbaa9a9d2b37d838125fb7f2b9fdc5dc5fa4eaa9 (diff) | |
parent | 87e807b6c461bbd449496a4c3ab78ab164a4ba97 (diff) |
Merge /spare/repo/linux-2.6/
Diffstat (limited to 'drivers/scsi/libata-core.c')
-rw-r--r-- | drivers/scsi/libata-core.c | 118 |
1 files changed, 72 insertions, 46 deletions
diff --git a/drivers/scsi/libata-core.c b/drivers/scsi/libata-core.c index 62095bdb173a..9182817612ae 100644 --- a/drivers/scsi/libata-core.c +++ b/drivers/scsi/libata-core.c | |||
@@ -2551,9 +2551,12 @@ static unsigned long ata_pio_poll(struct ata_port *ap) | |||
2551 | * | 2551 | * |
2552 | * LOCKING: | 2552 | * LOCKING: |
2553 | * None. (executing in kernel thread context) | 2553 | * None. (executing in kernel thread context) |
2554 | * | ||
2555 | * RETURNS: | ||
2556 | * Non-zero if qc completed, zero otherwise. | ||
2554 | */ | 2557 | */ |
2555 | 2558 | ||
2556 | static void ata_pio_complete (struct ata_port *ap) | 2559 | static int ata_pio_complete (struct ata_port *ap) |
2557 | { | 2560 | { |
2558 | struct ata_queued_cmd *qc; | 2561 | struct ata_queued_cmd *qc; |
2559 | u8 drv_stat; | 2562 | u8 drv_stat; |
@@ -2572,14 +2575,14 @@ static void ata_pio_complete (struct ata_port *ap) | |||
2572 | if (drv_stat & (ATA_BUSY | ATA_DRQ)) { | 2575 | if (drv_stat & (ATA_BUSY | ATA_DRQ)) { |
2573 | ap->pio_task_state = PIO_ST_LAST_POLL; | 2576 | ap->pio_task_state = PIO_ST_LAST_POLL; |
2574 | ap->pio_task_timeout = jiffies + ATA_TMOUT_PIO; | 2577 | ap->pio_task_timeout = jiffies + ATA_TMOUT_PIO; |
2575 | return; | 2578 | return 0; |
2576 | } | 2579 | } |
2577 | } | 2580 | } |
2578 | 2581 | ||
2579 | drv_stat = ata_wait_idle(ap); | 2582 | drv_stat = ata_wait_idle(ap); |
2580 | if (!ata_ok(drv_stat)) { | 2583 | if (!ata_ok(drv_stat)) { |
2581 | ap->pio_task_state = PIO_ST_ERR; | 2584 | ap->pio_task_state = PIO_ST_ERR; |
2582 | return; | 2585 | return 0; |
2583 | } | 2586 | } |
2584 | 2587 | ||
2585 | qc = ata_qc_from_tag(ap, ap->active_tag); | 2588 | qc = ata_qc_from_tag(ap, ap->active_tag); |
@@ -2588,6 +2591,10 @@ static void ata_pio_complete (struct ata_port *ap) | |||
2588 | ap->pio_task_state = PIO_ST_IDLE; | 2591 | ap->pio_task_state = PIO_ST_IDLE; |
2589 | 2592 | ||
2590 | ata_poll_qc_complete(qc, drv_stat); | 2593 | ata_poll_qc_complete(qc, drv_stat); |
2594 | |||
2595 | /* another command may start at this point */ | ||
2596 | |||
2597 | return 1; | ||
2591 | } | 2598 | } |
2592 | 2599 | ||
2593 | 2600 | ||
@@ -2795,7 +2802,7 @@ static void __atapi_pio_bytes(struct ata_queued_cmd *qc, unsigned int bytes) | |||
2795 | 2802 | ||
2796 | next_sg: | 2803 | next_sg: |
2797 | if (unlikely(qc->cursg >= qc->n_elem)) { | 2804 | if (unlikely(qc->cursg >= qc->n_elem)) { |
2798 | /* | 2805 | /* |
2799 | * The end of qc->sg is reached and the device expects | 2806 | * The end of qc->sg is reached and the device expects |
2800 | * more data to transfer. In order not to overrun qc->sg | 2807 | * more data to transfer. In order not to overrun qc->sg |
2801 | * and fulfill length specified in the byte count register, | 2808 | * and fulfill length specified in the byte count register, |
@@ -2807,7 +2814,7 @@ next_sg: | |||
2807 | unsigned int i; | 2814 | unsigned int i; |
2808 | 2815 | ||
2809 | if (words) /* warning if bytes > 1 */ | 2816 | if (words) /* warning if bytes > 1 */ |
2810 | printk(KERN_WARNING "ata%u: %u bytes trailing data\n", | 2817 | printk(KERN_WARNING "ata%u: %u bytes trailing data\n", |
2811 | ap->id, bytes); | 2818 | ap->id, bytes); |
2812 | 2819 | ||
2813 | for (i = 0; i < words; i++) | 2820 | for (i = 0; i < words; i++) |
@@ -2935,9 +2942,7 @@ static void ata_pio_block(struct ata_port *ap) | |||
2935 | if (is_atapi_taskfile(&qc->tf)) { | 2942 | if (is_atapi_taskfile(&qc->tf)) { |
2936 | /* no more data to transfer or unsupported ATAPI command */ | 2943 | /* no more data to transfer or unsupported ATAPI command */ |
2937 | if ((status & ATA_DRQ) == 0) { | 2944 | if ((status & ATA_DRQ) == 0) { |
2938 | ap->pio_task_state = PIO_ST_IDLE; | 2945 | ap->pio_task_state = PIO_ST_LAST; |
2939 | |||
2940 | ata_poll_qc_complete(qc, status); | ||
2941 | return; | 2946 | return; |
2942 | } | 2947 | } |
2943 | 2948 | ||
@@ -2973,7 +2978,12 @@ static void ata_pio_error(struct ata_port *ap) | |||
2973 | static void ata_pio_task(void *_data) | 2978 | static void ata_pio_task(void *_data) |
2974 | { | 2979 | { |
2975 | struct ata_port *ap = _data; | 2980 | struct ata_port *ap = _data; |
2976 | unsigned long timeout = 0; | 2981 | unsigned long timeout; |
2982 | int qc_completed; | ||
2983 | |||
2984 | fsm_start: | ||
2985 | timeout = 0; | ||
2986 | qc_completed = 0; | ||
2977 | 2987 | ||
2978 | switch (ap->pio_task_state) { | 2988 | switch (ap->pio_task_state) { |
2979 | case PIO_ST_IDLE: | 2989 | case PIO_ST_IDLE: |
@@ -2984,7 +2994,7 @@ static void ata_pio_task(void *_data) | |||
2984 | break; | 2994 | break; |
2985 | 2995 | ||
2986 | case PIO_ST_LAST: | 2996 | case PIO_ST_LAST: |
2987 | ata_pio_complete(ap); | 2997 | qc_completed = ata_pio_complete(ap); |
2988 | break; | 2998 | break; |
2989 | 2999 | ||
2990 | case PIO_ST_POLL: | 3000 | case PIO_ST_POLL: |
@@ -2999,10 +3009,9 @@ static void ata_pio_task(void *_data) | |||
2999 | } | 3009 | } |
3000 | 3010 | ||
3001 | if (timeout) | 3011 | if (timeout) |
3002 | queue_delayed_work(ata_wq, &ap->pio_task, | 3012 | queue_delayed_work(ata_wq, &ap->pio_task, timeout); |
3003 | timeout); | 3013 | else if (!qc_completed) |
3004 | else | 3014 | goto fsm_start; |
3005 | queue_work(ata_wq, &ap->pio_task); | ||
3006 | } | 3015 | } |
3007 | 3016 | ||
3008 | static void atapi_request_sense(struct ata_port *ap, struct ata_device *dev, | 3017 | static void atapi_request_sense(struct ata_port *ap, struct ata_device *dev, |
@@ -4213,6 +4222,53 @@ err_out: | |||
4213 | } | 4222 | } |
4214 | 4223 | ||
4215 | /** | 4224 | /** |
4225 | * ata_host_set_remove - PCI layer callback for device removal | ||
4226 | * @host_set: ATA host set that was removed | ||
4227 | * | ||
4228 | * Unregister all objects associated with this host set. Free those | ||
4229 | * objects. | ||
4230 | * | ||
4231 | * LOCKING: | ||
4232 | * Inherited from calling layer (may sleep). | ||
4233 | */ | ||
4234 | |||
4235 | |||
4236 | void ata_host_set_remove(struct ata_host_set *host_set) | ||
4237 | { | ||
4238 | struct ata_port *ap; | ||
4239 | unsigned int i; | ||
4240 | |||
4241 | for (i = 0; i < host_set->n_ports; i++) { | ||
4242 | ap = host_set->ports[i]; | ||
4243 | scsi_remove_host(ap->host); | ||
4244 | } | ||
4245 | |||
4246 | free_irq(host_set->irq, host_set); | ||
4247 | |||
4248 | for (i = 0; i < host_set->n_ports; i++) { | ||
4249 | ap = host_set->ports[i]; | ||
4250 | |||
4251 | ata_scsi_release(ap->host); | ||
4252 | |||
4253 | if ((ap->flags & ATA_FLAG_NO_LEGACY) == 0) { | ||
4254 | struct ata_ioports *ioaddr = &ap->ioaddr; | ||
4255 | |||
4256 | if (ioaddr->cmd_addr == 0x1f0) | ||
4257 | release_region(0x1f0, 8); | ||
4258 | else if (ioaddr->cmd_addr == 0x170) | ||
4259 | release_region(0x170, 8); | ||
4260 | } | ||
4261 | |||
4262 | scsi_host_put(ap->host); | ||
4263 | } | ||
4264 | |||
4265 | if (host_set->ops->host_stop) | ||
4266 | host_set->ops->host_stop(host_set); | ||
4267 | |||
4268 | kfree(host_set); | ||
4269 | } | ||
4270 | |||
4271 | /** | ||
4216 | * ata_scsi_release - SCSI layer callback hook for host unload | 4272 | * ata_scsi_release - SCSI layer callback hook for host unload |
4217 | * @host: libata host to be unloaded | 4273 | * @host: libata host to be unloaded |
4218 | * | 4274 | * |
@@ -4552,39 +4608,8 @@ void ata_pci_remove_one (struct pci_dev *pdev) | |||
4552 | { | 4608 | { |
4553 | struct device *dev = pci_dev_to_dev(pdev); | 4609 | struct device *dev = pci_dev_to_dev(pdev); |
4554 | struct ata_host_set *host_set = dev_get_drvdata(dev); | 4610 | struct ata_host_set *host_set = dev_get_drvdata(dev); |
4555 | struct ata_port *ap; | ||
4556 | unsigned int i; | ||
4557 | |||
4558 | for (i = 0; i < host_set->n_ports; i++) { | ||
4559 | ap = host_set->ports[i]; | ||
4560 | |||
4561 | scsi_remove_host(ap->host); | ||
4562 | } | ||
4563 | |||
4564 | free_irq(host_set->irq, host_set); | ||
4565 | |||
4566 | for (i = 0; i < host_set->n_ports; i++) { | ||
4567 | ap = host_set->ports[i]; | ||
4568 | |||
4569 | ata_scsi_release(ap->host); | ||
4570 | |||
4571 | if ((ap->flags & ATA_FLAG_NO_LEGACY) == 0) { | ||
4572 | struct ata_ioports *ioaddr = &ap->ioaddr; | ||
4573 | |||
4574 | if (ioaddr->cmd_addr == 0x1f0) | ||
4575 | release_region(0x1f0, 8); | ||
4576 | else if (ioaddr->cmd_addr == 0x170) | ||
4577 | release_region(0x170, 8); | ||
4578 | } | ||
4579 | |||
4580 | scsi_host_put(ap->host); | ||
4581 | } | ||
4582 | |||
4583 | if (host_set->ops->host_stop) | ||
4584 | host_set->ops->host_stop(host_set); | ||
4585 | |||
4586 | kfree(host_set); | ||
4587 | 4611 | ||
4612 | ata_host_set_remove(host_set); | ||
4588 | pci_release_regions(pdev); | 4613 | pci_release_regions(pdev); |
4589 | pci_disable_device(pdev); | 4614 | pci_disable_device(pdev); |
4590 | dev_set_drvdata(dev, NULL); | 4615 | dev_set_drvdata(dev, NULL); |
@@ -4654,6 +4679,7 @@ module_exit(ata_exit); | |||
4654 | EXPORT_SYMBOL_GPL(ata_std_bios_param); | 4679 | EXPORT_SYMBOL_GPL(ata_std_bios_param); |
4655 | EXPORT_SYMBOL_GPL(ata_std_ports); | 4680 | EXPORT_SYMBOL_GPL(ata_std_ports); |
4656 | EXPORT_SYMBOL_GPL(ata_device_add); | 4681 | EXPORT_SYMBOL_GPL(ata_device_add); |
4682 | EXPORT_SYMBOL_GPL(ata_host_set_remove); | ||
4657 | EXPORT_SYMBOL_GPL(ata_sg_init); | 4683 | EXPORT_SYMBOL_GPL(ata_sg_init); |
4658 | EXPORT_SYMBOL_GPL(ata_sg_init_one); | 4684 | EXPORT_SYMBOL_GPL(ata_sg_init_one); |
4659 | EXPORT_SYMBOL_GPL(ata_qc_complete); | 4685 | EXPORT_SYMBOL_GPL(ata_qc_complete); |