diff options
Diffstat (limited to 'drivers/ide')
-rw-r--r-- | drivers/ide/ide-cd.c | 5 | ||||
-rw-r--r-- | drivers/ide/ide-disk.c | 138 | ||||
-rw-r--r-- | drivers/ide/ide-floppy.c | 1 | ||||
-rw-r--r-- | drivers/ide/ide-io.c | 11 | ||||
-rw-r--r-- | drivers/ide/ide-tape.c | 1 | ||||
-rw-r--r-- | drivers/ide/ide.c | 60 | ||||
-rw-r--r-- | drivers/ide/legacy/ide-cs.c | 132 |
7 files changed, 171 insertions, 177 deletions
diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c index b4d7a3efb90f..d31117eb95aa 100644 --- a/drivers/ide/ide-cd.c +++ b/drivers/ide/ide-cd.c | |||
@@ -614,7 +614,7 @@ static void cdrom_end_request (ide_drive_t *drive, int uptodate) | |||
614 | */ | 614 | */ |
615 | spin_lock_irqsave(&ide_lock, flags); | 615 | spin_lock_irqsave(&ide_lock, flags); |
616 | end_that_request_chunk(failed, 0, failed->data_len); | 616 | end_that_request_chunk(failed, 0, failed->data_len); |
617 | end_that_request_last(failed); | 617 | end_that_request_last(failed, 0); |
618 | spin_unlock_irqrestore(&ide_lock, flags); | 618 | spin_unlock_irqrestore(&ide_lock, flags); |
619 | } | 619 | } |
620 | 620 | ||
@@ -1735,7 +1735,7 @@ end_request: | |||
1735 | 1735 | ||
1736 | spin_lock_irqsave(&ide_lock, flags); | 1736 | spin_lock_irqsave(&ide_lock, flags); |
1737 | blkdev_dequeue_request(rq); | 1737 | blkdev_dequeue_request(rq); |
1738 | end_that_request_last(rq); | 1738 | end_that_request_last(rq, 1); |
1739 | HWGROUP(drive)->rq = NULL; | 1739 | HWGROUP(drive)->rq = NULL; |
1740 | spin_unlock_irqrestore(&ide_lock, flags); | 1740 | spin_unlock_irqrestore(&ide_lock, flags); |
1741 | return ide_stopped; | 1741 | return ide_stopped; |
@@ -3509,6 +3509,7 @@ static int __init ide_cdrom_init(void) | |||
3509 | return driver_register(&ide_cdrom_driver.gen_driver); | 3509 | return driver_register(&ide_cdrom_driver.gen_driver); |
3510 | } | 3510 | } |
3511 | 3511 | ||
3512 | MODULE_ALIAS("ide:*m-cdrom*"); | ||
3512 | module_init(ide_cdrom_init); | 3513 | module_init(ide_cdrom_init); |
3513 | module_exit(ide_cdrom_exit); | 3514 | module_exit(ide_cdrom_exit); |
3514 | MODULE_LICENSE("GPL"); | 3515 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/ide/ide-disk.c b/drivers/ide/ide-disk.c index 449522f0540c..4b441720b6ba 100644 --- a/drivers/ide/ide-disk.c +++ b/drivers/ide/ide-disk.c | |||
@@ -681,50 +681,9 @@ static ide_proc_entry_t idedisk_proc[] = { | |||
681 | 681 | ||
682 | #endif /* CONFIG_PROC_FS */ | 682 | #endif /* CONFIG_PROC_FS */ |
683 | 683 | ||
684 | static void idedisk_end_flush(request_queue_t *q, struct request *flush_rq) | 684 | static void idedisk_prepare_flush(request_queue_t *q, struct request *rq) |
685 | { | 685 | { |
686 | ide_drive_t *drive = q->queuedata; | 686 | ide_drive_t *drive = q->queuedata; |
687 | struct request *rq = flush_rq->end_io_data; | ||
688 | int good_sectors = rq->hard_nr_sectors; | ||
689 | int bad_sectors; | ||
690 | sector_t sector; | ||
691 | |||
692 | if (flush_rq->errors & ABRT_ERR) { | ||
693 | printk(KERN_ERR "%s: barrier support doesn't work\n", drive->name); | ||
694 | blk_queue_ordered(drive->queue, QUEUE_ORDERED_NONE); | ||
695 | blk_queue_issue_flush_fn(drive->queue, NULL); | ||
696 | good_sectors = 0; | ||
697 | } else if (flush_rq->errors) { | ||
698 | good_sectors = 0; | ||
699 | if (blk_barrier_preflush(rq)) { | ||
700 | sector = ide_get_error_location(drive,flush_rq->buffer); | ||
701 | if ((sector >= rq->hard_sector) && | ||
702 | (sector < rq->hard_sector + rq->hard_nr_sectors)) | ||
703 | good_sectors = sector - rq->hard_sector; | ||
704 | } | ||
705 | } | ||
706 | |||
707 | if (flush_rq->errors) | ||
708 | printk(KERN_ERR "%s: failed barrier write: " | ||
709 | "sector=%Lx(good=%d/bad=%d)\n", | ||
710 | drive->name, (unsigned long long)rq->sector, | ||
711 | good_sectors, | ||
712 | (int) (rq->hard_nr_sectors-good_sectors)); | ||
713 | |||
714 | bad_sectors = rq->hard_nr_sectors - good_sectors; | ||
715 | |||
716 | if (good_sectors) | ||
717 | __ide_end_request(drive, rq, 1, good_sectors); | ||
718 | if (bad_sectors) | ||
719 | __ide_end_request(drive, rq, 0, bad_sectors); | ||
720 | } | ||
721 | |||
722 | static int idedisk_prepare_flush(request_queue_t *q, struct request *rq) | ||
723 | { | ||
724 | ide_drive_t *drive = q->queuedata; | ||
725 | |||
726 | if (!drive->wcache) | ||
727 | return 0; | ||
728 | 687 | ||
729 | memset(rq->cmd, 0, sizeof(rq->cmd)); | 688 | memset(rq->cmd, 0, sizeof(rq->cmd)); |
730 | 689 | ||
@@ -735,9 +694,8 @@ static int idedisk_prepare_flush(request_queue_t *q, struct request *rq) | |||
735 | rq->cmd[0] = WIN_FLUSH_CACHE; | 694 | rq->cmd[0] = WIN_FLUSH_CACHE; |
736 | 695 | ||
737 | 696 | ||
738 | rq->flags |= REQ_DRIVE_TASK | REQ_SOFTBARRIER; | 697 | rq->flags |= REQ_DRIVE_TASK; |
739 | rq->buffer = rq->cmd; | 698 | rq->buffer = rq->cmd; |
740 | return 1; | ||
741 | } | 699 | } |
742 | 700 | ||
743 | static int idedisk_issue_flush(request_queue_t *q, struct gendisk *disk, | 701 | static int idedisk_issue_flush(request_queue_t *q, struct gendisk *disk, |
@@ -794,27 +752,64 @@ static int set_nowerr(ide_drive_t *drive, int arg) | |||
794 | return 0; | 752 | return 0; |
795 | } | 753 | } |
796 | 754 | ||
755 | static void update_ordered(ide_drive_t *drive) | ||
756 | { | ||
757 | struct hd_driveid *id = drive->id; | ||
758 | unsigned ordered = QUEUE_ORDERED_NONE; | ||
759 | prepare_flush_fn *prep_fn = NULL; | ||
760 | issue_flush_fn *issue_fn = NULL; | ||
761 | |||
762 | if (drive->wcache) { | ||
763 | unsigned long long capacity; | ||
764 | int barrier; | ||
765 | /* | ||
766 | * We must avoid issuing commands a drive does not | ||
767 | * understand or we may crash it. We check flush cache | ||
768 | * is supported. We also check we have the LBA48 flush | ||
769 | * cache if the drive capacity is too large. By this | ||
770 | * time we have trimmed the drive capacity if LBA48 is | ||
771 | * not available so we don't need to recheck that. | ||
772 | */ | ||
773 | capacity = idedisk_capacity(drive); | ||
774 | barrier = ide_id_has_flush_cache(id) && | ||
775 | (drive->addressing == 0 || capacity <= (1ULL << 28) || | ||
776 | ide_id_has_flush_cache_ext(id)); | ||
777 | |||
778 | printk(KERN_INFO "%s: cache flushes %ssupported\n", | ||
779 | drive->name, barrier ? "" : "not"); | ||
780 | |||
781 | if (barrier) { | ||
782 | ordered = QUEUE_ORDERED_DRAIN_FLUSH; | ||
783 | prep_fn = idedisk_prepare_flush; | ||
784 | issue_fn = idedisk_issue_flush; | ||
785 | } | ||
786 | } else | ||
787 | ordered = QUEUE_ORDERED_DRAIN; | ||
788 | |||
789 | blk_queue_ordered(drive->queue, ordered, prep_fn); | ||
790 | blk_queue_issue_flush_fn(drive->queue, issue_fn); | ||
791 | } | ||
792 | |||
797 | static int write_cache(ide_drive_t *drive, int arg) | 793 | static int write_cache(ide_drive_t *drive, int arg) |
798 | { | 794 | { |
799 | ide_task_t args; | 795 | ide_task_t args; |
800 | int err; | 796 | int err = 1; |
801 | |||
802 | if (!ide_id_has_flush_cache(drive->id)) | ||
803 | return 1; | ||
804 | 797 | ||
805 | memset(&args, 0, sizeof(ide_task_t)); | 798 | if (ide_id_has_flush_cache(drive->id)) { |
806 | args.tfRegister[IDE_FEATURE_OFFSET] = (arg) ? | 799 | memset(&args, 0, sizeof(ide_task_t)); |
800 | args.tfRegister[IDE_FEATURE_OFFSET] = (arg) ? | ||
807 | SETFEATURES_EN_WCACHE : SETFEATURES_DIS_WCACHE; | 801 | SETFEATURES_EN_WCACHE : SETFEATURES_DIS_WCACHE; |
808 | args.tfRegister[IDE_COMMAND_OFFSET] = WIN_SETFEATURES; | 802 | args.tfRegister[IDE_COMMAND_OFFSET] = WIN_SETFEATURES; |
809 | args.command_type = IDE_DRIVE_TASK_NO_DATA; | 803 | args.command_type = IDE_DRIVE_TASK_NO_DATA; |
810 | args.handler = &task_no_data_intr; | 804 | args.handler = &task_no_data_intr; |
805 | err = ide_raw_taskfile(drive, &args, NULL); | ||
806 | if (err == 0) | ||
807 | drive->wcache = arg; | ||
808 | } | ||
811 | 809 | ||
812 | err = ide_raw_taskfile(drive, &args, NULL); | 810 | update_ordered(drive); |
813 | if (err) | ||
814 | return err; | ||
815 | 811 | ||
816 | drive->wcache = arg; | 812 | return err; |
817 | return 0; | ||
818 | } | 813 | } |
819 | 814 | ||
820 | static int do_idedisk_flushcache (ide_drive_t *drive) | 815 | static int do_idedisk_flushcache (ide_drive_t *drive) |
@@ -888,7 +883,6 @@ static void idedisk_setup (ide_drive_t *drive) | |||
888 | { | 883 | { |
889 | struct hd_driveid *id = drive->id; | 884 | struct hd_driveid *id = drive->id; |
890 | unsigned long long capacity; | 885 | unsigned long long capacity; |
891 | int barrier; | ||
892 | 886 | ||
893 | idedisk_add_settings(drive); | 887 | idedisk_add_settings(drive); |
894 | 888 | ||
@@ -992,31 +986,6 @@ static void idedisk_setup (ide_drive_t *drive) | |||
992 | drive->wcache = 1; | 986 | drive->wcache = 1; |
993 | 987 | ||
994 | write_cache(drive, 1); | 988 | write_cache(drive, 1); |
995 | |||
996 | /* | ||
997 | * We must avoid issuing commands a drive does not understand | ||
998 | * or we may crash it. We check flush cache is supported. We also | ||
999 | * check we have the LBA48 flush cache if the drive capacity is | ||
1000 | * too large. By this time we have trimmed the drive capacity if | ||
1001 | * LBA48 is not available so we don't need to recheck that. | ||
1002 | */ | ||
1003 | barrier = 0; | ||
1004 | if (ide_id_has_flush_cache(id)) | ||
1005 | barrier = 1; | ||
1006 | if (drive->addressing == 1) { | ||
1007 | /* Can't issue the correct flush ? */ | ||
1008 | if (capacity > (1ULL << 28) && !ide_id_has_flush_cache_ext(id)) | ||
1009 | barrier = 0; | ||
1010 | } | ||
1011 | |||
1012 | printk(KERN_INFO "%s: cache flushes %ssupported\n", | ||
1013 | drive->name, barrier ? "" : "not "); | ||
1014 | if (barrier) { | ||
1015 | blk_queue_ordered(drive->queue, QUEUE_ORDERED_FLUSH); | ||
1016 | drive->queue->prepare_flush_fn = idedisk_prepare_flush; | ||
1017 | drive->queue->end_flush_fn = idedisk_end_flush; | ||
1018 | blk_queue_issue_flush_fn(drive->queue, idedisk_issue_flush); | ||
1019 | } | ||
1020 | } | 989 | } |
1021 | 990 | ||
1022 | static void ide_cacheflush_p(ide_drive_t *drive) | 991 | static void ide_cacheflush_p(ide_drive_t *drive) |
@@ -1271,6 +1240,7 @@ static int __init idedisk_init(void) | |||
1271 | return driver_register(&idedisk_driver.gen_driver); | 1240 | return driver_register(&idedisk_driver.gen_driver); |
1272 | } | 1241 | } |
1273 | 1242 | ||
1243 | MODULE_ALIAS("ide:*m-disk*"); | ||
1274 | module_init(idedisk_init); | 1244 | module_init(idedisk_init); |
1275 | module_exit(idedisk_exit); | 1245 | module_exit(idedisk_exit); |
1276 | MODULE_LICENSE("GPL"); | 1246 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/ide/ide-floppy.c b/drivers/ide/ide-floppy.c index 9e293c8063dc..fba3fffc2d66 100644 --- a/drivers/ide/ide-floppy.c +++ b/drivers/ide/ide-floppy.c | |||
@@ -2197,6 +2197,7 @@ static int __init idefloppy_init(void) | |||
2197 | return driver_register(&idefloppy_driver.gen_driver); | 2197 | return driver_register(&idefloppy_driver.gen_driver); |
2198 | } | 2198 | } |
2199 | 2199 | ||
2200 | MODULE_ALIAS("ide:*m-floppy*"); | ||
2200 | module_init(idefloppy_init); | 2201 | module_init(idefloppy_init); |
2201 | module_exit(idefloppy_exit); | 2202 | module_exit(idefloppy_exit); |
2202 | MODULE_LICENSE("GPL"); | 2203 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/ide/ide-io.c b/drivers/ide/ide-io.c index ecfafcdafea4..b5dc6df8e67d 100644 --- a/drivers/ide/ide-io.c +++ b/drivers/ide/ide-io.c | |||
@@ -89,7 +89,7 @@ int __ide_end_request(ide_drive_t *drive, struct request *rq, int uptodate, | |||
89 | 89 | ||
90 | blkdev_dequeue_request(rq); | 90 | blkdev_dequeue_request(rq); |
91 | HWGROUP(drive)->rq = NULL; | 91 | HWGROUP(drive)->rq = NULL; |
92 | end_that_request_last(rq); | 92 | end_that_request_last(rq, uptodate); |
93 | ret = 0; | 93 | ret = 0; |
94 | } | 94 | } |
95 | return ret; | 95 | return ret; |
@@ -119,10 +119,7 @@ int ide_end_request (ide_drive_t *drive, int uptodate, int nr_sectors) | |||
119 | if (!nr_sectors) | 119 | if (!nr_sectors) |
120 | nr_sectors = rq->hard_cur_sectors; | 120 | nr_sectors = rq->hard_cur_sectors; |
121 | 121 | ||
122 | if (blk_complete_barrier_rq_locked(drive->queue, rq, nr_sectors)) | 122 | ret = __ide_end_request(drive, rq, uptodate, nr_sectors); |
123 | ret = rq->nr_sectors != 0; | ||
124 | else | ||
125 | ret = __ide_end_request(drive, rq, uptodate, nr_sectors); | ||
126 | 123 | ||
127 | spin_unlock_irqrestore(&ide_lock, flags); | 124 | spin_unlock_irqrestore(&ide_lock, flags); |
128 | return ret; | 125 | return ret; |
@@ -247,7 +244,7 @@ static void ide_complete_pm_request (ide_drive_t *drive, struct request *rq) | |||
247 | } | 244 | } |
248 | blkdev_dequeue_request(rq); | 245 | blkdev_dequeue_request(rq); |
249 | HWGROUP(drive)->rq = NULL; | 246 | HWGROUP(drive)->rq = NULL; |
250 | end_that_request_last(rq); | 247 | end_that_request_last(rq, 1); |
251 | spin_unlock_irqrestore(&ide_lock, flags); | 248 | spin_unlock_irqrestore(&ide_lock, flags); |
252 | } | 249 | } |
253 | 250 | ||
@@ -379,7 +376,7 @@ void ide_end_drive_cmd (ide_drive_t *drive, u8 stat, u8 err) | |||
379 | blkdev_dequeue_request(rq); | 376 | blkdev_dequeue_request(rq); |
380 | HWGROUP(drive)->rq = NULL; | 377 | HWGROUP(drive)->rq = NULL; |
381 | rq->errors = err; | 378 | rq->errors = err; |
382 | end_that_request_last(rq); | 379 | end_that_request_last(rq, !rq->errors); |
383 | spin_unlock_irqrestore(&ide_lock, flags); | 380 | spin_unlock_irqrestore(&ide_lock, flags); |
384 | } | 381 | } |
385 | 382 | ||
diff --git a/drivers/ide/ide-tape.c b/drivers/ide/ide-tape.c index 7d7944ed4158..fab9b2b02504 100644 --- a/drivers/ide/ide-tape.c +++ b/drivers/ide/ide-tape.c | |||
@@ -4947,6 +4947,7 @@ out: | |||
4947 | return error; | 4947 | return error; |
4948 | } | 4948 | } |
4949 | 4949 | ||
4950 | MODULE_ALIAS("ide:*m-tape*"); | ||
4950 | module_init(idetape_init); | 4951 | module_init(idetape_init); |
4951 | module_exit(idetape_exit); | 4952 | module_exit(idetape_exit); |
4952 | MODULE_ALIAS_CHARDEV_MAJOR(IDETAPE_MAJOR); | 4953 | MODULE_ALIAS_CHARDEV_MAJOR(IDETAPE_MAJOR); |
diff --git a/drivers/ide/ide.c b/drivers/ide/ide.c index 8af179b531c3..4b524f6b3ecd 100644 --- a/drivers/ide/ide.c +++ b/drivers/ide/ide.c | |||
@@ -1904,9 +1904,69 @@ static int ide_bus_match(struct device *dev, struct device_driver *drv) | |||
1904 | return 1; | 1904 | return 1; |
1905 | } | 1905 | } |
1906 | 1906 | ||
1907 | static char *media_string(ide_drive_t *drive) | ||
1908 | { | ||
1909 | switch (drive->media) { | ||
1910 | case ide_disk: | ||
1911 | return "disk"; | ||
1912 | case ide_cdrom: | ||
1913 | return "cdrom"; | ||
1914 | case ide_tape: | ||
1915 | return "tape"; | ||
1916 | case ide_floppy: | ||
1917 | return "floppy"; | ||
1918 | default: | ||
1919 | return "UNKNOWN"; | ||
1920 | } | ||
1921 | } | ||
1922 | |||
1923 | static ssize_t media_show(struct device *dev, struct device_attribute *attr, char *buf) | ||
1924 | { | ||
1925 | ide_drive_t *drive = to_ide_device(dev); | ||
1926 | return sprintf(buf, "%s\n", media_string(drive)); | ||
1927 | } | ||
1928 | |||
1929 | static ssize_t drivename_show(struct device *dev, struct device_attribute *attr, char *buf) | ||
1930 | { | ||
1931 | ide_drive_t *drive = to_ide_device(dev); | ||
1932 | return sprintf(buf, "%s\n", drive->name); | ||
1933 | } | ||
1934 | |||
1935 | static ssize_t modalias_show(struct device *dev, struct device_attribute *attr, char *buf) | ||
1936 | { | ||
1937 | ide_drive_t *drive = to_ide_device(dev); | ||
1938 | return sprintf(buf, "ide:m-%s\n", media_string(drive)); | ||
1939 | } | ||
1940 | |||
1941 | static struct device_attribute ide_dev_attrs[] = { | ||
1942 | __ATTR_RO(media), | ||
1943 | __ATTR_RO(drivename), | ||
1944 | __ATTR_RO(modalias), | ||
1945 | __ATTR_NULL | ||
1946 | }; | ||
1947 | |||
1948 | static int ide_uevent(struct device *dev, char **envp, int num_envp, | ||
1949 | char *buffer, int buffer_size) | ||
1950 | { | ||
1951 | ide_drive_t *drive = to_ide_device(dev); | ||
1952 | int i = 0; | ||
1953 | int length = 0; | ||
1954 | |||
1955 | add_uevent_var(envp, num_envp, &i, buffer, buffer_size, &length, | ||
1956 | "MEDIA=%s", media_string(drive)); | ||
1957 | add_uevent_var(envp, num_envp, &i, buffer, buffer_size, &length, | ||
1958 | "DRIVENAME=%s", drive->name); | ||
1959 | add_uevent_var(envp, num_envp, &i, buffer, buffer_size, &length, | ||
1960 | "MODALIAS=ide:m-%s", media_string(drive)); | ||
1961 | envp[i] = NULL; | ||
1962 | return 0; | ||
1963 | } | ||
1964 | |||
1907 | struct bus_type ide_bus_type = { | 1965 | struct bus_type ide_bus_type = { |
1908 | .name = "ide", | 1966 | .name = "ide", |
1909 | .match = ide_bus_match, | 1967 | .match = ide_bus_match, |
1968 | .uevent = ide_uevent, | ||
1969 | .dev_attrs = ide_dev_attrs, | ||
1910 | .suspend = generic_ide_suspend, | 1970 | .suspend = generic_ide_suspend, |
1911 | .resume = generic_ide_resume, | 1971 | .resume = generic_ide_resume, |
1912 | }; | 1972 | }; |
diff --git a/drivers/ide/legacy/ide-cs.c b/drivers/ide/legacy/ide-cs.c index ef79805218e4..4c2af9020905 100644 --- a/drivers/ide/legacy/ide-cs.c +++ b/drivers/ide/legacy/ide-cs.c | |||
@@ -88,15 +88,12 @@ typedef struct ide_info_t { | |||
88 | } ide_info_t; | 88 | } ide_info_t; |
89 | 89 | ||
90 | static void ide_release(dev_link_t *); | 90 | static void ide_release(dev_link_t *); |
91 | static int ide_event(event_t event, int priority, | 91 | static void ide_config(dev_link_t *); |
92 | event_callback_args_t *args); | 92 | |
93 | static void ide_detach(struct pcmcia_device *p_dev); | ||
93 | 94 | ||
94 | static dev_info_t dev_info = "ide-cs"; | ||
95 | 95 | ||
96 | static dev_link_t *ide_attach(void); | ||
97 | static void ide_detach(dev_link_t *); | ||
98 | 96 | ||
99 | static dev_link_t *dev_list = NULL; | ||
100 | 97 | ||
101 | /*====================================================================== | 98 | /*====================================================================== |
102 | 99 | ||
@@ -106,18 +103,17 @@ static dev_link_t *dev_list = NULL; | |||
106 | 103 | ||
107 | ======================================================================*/ | 104 | ======================================================================*/ |
108 | 105 | ||
109 | static dev_link_t *ide_attach(void) | 106 | static int ide_attach(struct pcmcia_device *p_dev) |
110 | { | 107 | { |
111 | ide_info_t *info; | 108 | ide_info_t *info; |
112 | dev_link_t *link; | 109 | dev_link_t *link; |
113 | client_reg_t client_reg; | 110 | |
114 | int ret; | ||
115 | |||
116 | DEBUG(0, "ide_attach()\n"); | 111 | DEBUG(0, "ide_attach()\n"); |
117 | 112 | ||
118 | /* Create new ide device */ | 113 | /* Create new ide device */ |
119 | info = kzalloc(sizeof(*info), GFP_KERNEL); | 114 | info = kzalloc(sizeof(*info), GFP_KERNEL); |
120 | if (!info) return NULL; | 115 | if (!info) |
116 | return -ENOMEM; | ||
121 | link = &info->link; link->priv = info; | 117 | link = &info->link; link->priv = info; |
122 | 118 | ||
123 | link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO; | 119 | link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO; |
@@ -128,21 +124,14 @@ static dev_link_t *ide_attach(void) | |||
128 | link->conf.Attributes = CONF_ENABLE_IRQ; | 124 | link->conf.Attributes = CONF_ENABLE_IRQ; |
129 | link->conf.Vcc = 50; | 125 | link->conf.Vcc = 50; |
130 | link->conf.IntType = INT_MEMORY_AND_IO; | 126 | link->conf.IntType = INT_MEMORY_AND_IO; |
131 | 127 | ||
132 | /* Register with Card Services */ | 128 | link->handle = p_dev; |
133 | link->next = dev_list; | 129 | p_dev->instance = link; |
134 | dev_list = link; | 130 | |
135 | client_reg.dev_info = &dev_info; | 131 | link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; |
136 | client_reg.Version = 0x0210; | 132 | ide_config(link); |
137 | client_reg.event_callback_args.client_data = link; | 133 | |
138 | ret = pcmcia_register_client(&link->handle, &client_reg); | 134 | return 0; |
139 | if (ret != CS_SUCCESS) { | ||
140 | cs_error(link->handle, RegisterClient, ret); | ||
141 | ide_detach(link); | ||
142 | return NULL; | ||
143 | } | ||
144 | |||
145 | return link; | ||
146 | } /* ide_attach */ | 135 | } /* ide_attach */ |
147 | 136 | ||
148 | /*====================================================================== | 137 | /*====================================================================== |
@@ -154,32 +143,16 @@ static dev_link_t *ide_attach(void) | |||
154 | 143 | ||
155 | ======================================================================*/ | 144 | ======================================================================*/ |
156 | 145 | ||
157 | static void ide_detach(dev_link_t *link) | 146 | static void ide_detach(struct pcmcia_device *p_dev) |
158 | { | 147 | { |
159 | dev_link_t **linkp; | 148 | dev_link_t *link = dev_to_instance(p_dev); |
160 | int ret; | ||
161 | 149 | ||
162 | DEBUG(0, "ide_detach(0x%p)\n", link); | 150 | DEBUG(0, "ide_detach(0x%p)\n", link); |
163 | |||
164 | /* Locate device structure */ | ||
165 | for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next) | ||
166 | if (*linkp == link) break; | ||
167 | if (*linkp == NULL) | ||
168 | return; | ||
169 | 151 | ||
170 | if (link->state & DEV_CONFIG) | 152 | if (link->state & DEV_CONFIG) |
171 | ide_release(link); | 153 | ide_release(link); |
172 | 154 | ||
173 | if (link->handle) { | ||
174 | ret = pcmcia_deregister_client(link->handle); | ||
175 | if (ret != CS_SUCCESS) | ||
176 | cs_error(link->handle, DeregisterClient, ret); | ||
177 | } | ||
178 | |||
179 | /* Unlink, free device structure */ | ||
180 | *linkp = link->next; | ||
181 | kfree(link->priv); | 155 | kfree(link->priv); |
182 | |||
183 | } /* ide_detach */ | 156 | } /* ide_detach */ |
184 | 157 | ||
185 | static int idecs_register(unsigned long io, unsigned long ctl, unsigned long irq, struct pcmcia_device *handle) | 158 | static int idecs_register(unsigned long io, unsigned long ctl, unsigned long irq, struct pcmcia_device *handle) |
@@ -406,6 +379,28 @@ void ide_release(dev_link_t *link) | |||
406 | 379 | ||
407 | } /* ide_release */ | 380 | } /* ide_release */ |
408 | 381 | ||
382 | static int ide_suspend(struct pcmcia_device *dev) | ||
383 | { | ||
384 | dev_link_t *link = dev_to_instance(dev); | ||
385 | |||
386 | link->state |= DEV_SUSPEND; | ||
387 | if (link->state & DEV_CONFIG) | ||
388 | pcmcia_release_configuration(link->handle); | ||
389 | |||
390 | return 0; | ||
391 | } | ||
392 | |||
393 | static int ide_resume(struct pcmcia_device *dev) | ||
394 | { | ||
395 | dev_link_t *link = dev_to_instance(dev); | ||
396 | |||
397 | link->state &= ~DEV_SUSPEND; | ||
398 | if (DEV_OK(link)) | ||
399 | pcmcia_request_configuration(link->handle, &link->conf); | ||
400 | |||
401 | return 0; | ||
402 | } | ||
403 | |||
409 | /*====================================================================== | 404 | /*====================================================================== |
410 | 405 | ||
411 | The card status event handler. Mostly, this schedules other | 406 | The card status event handler. Mostly, this schedules other |
@@ -415,48 +410,15 @@ void ide_release(dev_link_t *link) | |||
415 | 410 | ||
416 | ======================================================================*/ | 411 | ======================================================================*/ |
417 | 412 | ||
418 | int ide_event(event_t event, int priority, | ||
419 | event_callback_args_t *args) | ||
420 | { | ||
421 | dev_link_t *link = args->client_data; | ||
422 | |||
423 | DEBUG(1, "ide_event(0x%06x)\n", event); | ||
424 | |||
425 | switch (event) { | ||
426 | case CS_EVENT_CARD_REMOVAL: | ||
427 | link->state &= ~DEV_PRESENT; | ||
428 | if (link->state & DEV_CONFIG) | ||
429 | ide_release(link); | ||
430 | break; | ||
431 | case CS_EVENT_CARD_INSERTION: | ||
432 | link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; | ||
433 | ide_config(link); | ||
434 | break; | ||
435 | case CS_EVENT_PM_SUSPEND: | ||
436 | link->state |= DEV_SUSPEND; | ||
437 | /* Fall through... */ | ||
438 | case CS_EVENT_RESET_PHYSICAL: | ||
439 | if (link->state & DEV_CONFIG) | ||
440 | pcmcia_release_configuration(link->handle); | ||
441 | break; | ||
442 | case CS_EVENT_PM_RESUME: | ||
443 | link->state &= ~DEV_SUSPEND; | ||
444 | /* Fall through... */ | ||
445 | case CS_EVENT_CARD_RESET: | ||
446 | if (DEV_OK(link)) | ||
447 | pcmcia_request_configuration(link->handle, &link->conf); | ||
448 | break; | ||
449 | } | ||
450 | return 0; | ||
451 | } /* ide_event */ | ||
452 | |||
453 | static struct pcmcia_device_id ide_ids[] = { | 413 | static struct pcmcia_device_id ide_ids[] = { |
454 | PCMCIA_DEVICE_FUNC_ID(4), | 414 | PCMCIA_DEVICE_FUNC_ID(4), |
415 | PCMCIA_DEVICE_MANF_CARD(0x0007, 0x0000), /* Hitachi */ | ||
455 | PCMCIA_DEVICE_MANF_CARD(0x0032, 0x0704), | 416 | PCMCIA_DEVICE_MANF_CARD(0x0032, 0x0704), |
456 | PCMCIA_DEVICE_MANF_CARD(0x0045, 0x0401), | 417 | PCMCIA_DEVICE_MANF_CARD(0x0045, 0x0401), |
457 | PCMCIA_DEVICE_MANF_CARD(0x0098, 0x0000), /* Toshiba */ | 418 | PCMCIA_DEVICE_MANF_CARD(0x0098, 0x0000), /* Toshiba */ |
458 | PCMCIA_DEVICE_MANF_CARD(0x00a4, 0x002d), | 419 | PCMCIA_DEVICE_MANF_CARD(0x00a4, 0x002d), |
459 | PCMCIA_DEVICE_MANF_CARD(0x00ce, 0x0000), /* Samsung */ | 420 | PCMCIA_DEVICE_MANF_CARD(0x00ce, 0x0000), /* Samsung */ |
421 | PCMCIA_DEVICE_MANF_CARD(0x0319, 0x0000), /* Hitachi */ | ||
460 | PCMCIA_DEVICE_MANF_CARD(0x2080, 0x0001), | 422 | PCMCIA_DEVICE_MANF_CARD(0x2080, 0x0001), |
461 | PCMCIA_DEVICE_MANF_CARD(0x4e01, 0x0200), /* Lexar */ | 423 | PCMCIA_DEVICE_MANF_CARD(0x4e01, 0x0200), /* Lexar */ |
462 | PCMCIA_DEVICE_PROD_ID123("Caravelle", "PSC-IDE ", "PSC000", 0x8c36137c, 0xd0693ab8, 0x2768a9f0), | 424 | PCMCIA_DEVICE_PROD_ID123("Caravelle", "PSC-IDE ", "PSC000", 0x8c36137c, 0xd0693ab8, 0x2768a9f0), |
@@ -471,6 +433,8 @@ static struct pcmcia_device_id ide_ids[] = { | |||
471 | PCMCIA_DEVICE_PROD_ID12("EXP ", "CD-ROM", 0x0a5c52fd, 0x66536591), | 433 | PCMCIA_DEVICE_PROD_ID12("EXP ", "CD-ROM", 0x0a5c52fd, 0x66536591), |
472 | PCMCIA_DEVICE_PROD_ID12("EXP ", "PnPIDE", 0x0a5c52fd, 0x0c694728), | 434 | PCMCIA_DEVICE_PROD_ID12("EXP ", "PnPIDE", 0x0a5c52fd, 0x0c694728), |
473 | PCMCIA_DEVICE_PROD_ID12("FREECOM", "PCCARD-IDE", 0x5714cbf7, 0x48e0ab8e), | 435 | PCMCIA_DEVICE_PROD_ID12("FREECOM", "PCCARD-IDE", 0x5714cbf7, 0x48e0ab8e), |
436 | PCMCIA_DEVICE_PROD_ID12("HITACHI", "FLASH", 0xf4f43949, 0x9eb86aae), | ||
437 | PCMCIA_DEVICE_PROD_ID12("HITACHI", "microdrive", 0xf4f43949, 0xa6d76178), | ||
474 | PCMCIA_DEVICE_PROD_ID12("IBM", "IBM17JSSFP20", 0xb569a6e5, 0xf2508753), | 438 | PCMCIA_DEVICE_PROD_ID12("IBM", "IBM17JSSFP20", 0xb569a6e5, 0xf2508753), |
475 | PCMCIA_DEVICE_PROD_ID12("IO DATA", "CBIDE2 ", 0x547e66dc, 0x8671043b), | 439 | PCMCIA_DEVICE_PROD_ID12("IO DATA", "CBIDE2 ", 0x547e66dc, 0x8671043b), |
476 | PCMCIA_DEVICE_PROD_ID12("IO DATA", "PCIDE", 0x547e66dc, 0x5c5ab149), | 440 | PCMCIA_DEVICE_PROD_ID12("IO DATA", "PCIDE", 0x547e66dc, 0x5c5ab149), |
@@ -494,10 +458,11 @@ static struct pcmcia_driver ide_cs_driver = { | |||
494 | .drv = { | 458 | .drv = { |
495 | .name = "ide-cs", | 459 | .name = "ide-cs", |
496 | }, | 460 | }, |
497 | .attach = ide_attach, | 461 | .probe = ide_attach, |
498 | .event = ide_event, | 462 | .remove = ide_detach, |
499 | .detach = ide_detach, | ||
500 | .id_table = ide_ids, | 463 | .id_table = ide_ids, |
464 | .suspend = ide_suspend, | ||
465 | .resume = ide_resume, | ||
501 | }; | 466 | }; |
502 | 467 | ||
503 | static int __init init_ide_cs(void) | 468 | static int __init init_ide_cs(void) |
@@ -508,7 +473,6 @@ static int __init init_ide_cs(void) | |||
508 | static void __exit exit_ide_cs(void) | 473 | static void __exit exit_ide_cs(void) |
509 | { | 474 | { |
510 | pcmcia_unregister_driver(&ide_cs_driver); | 475 | pcmcia_unregister_driver(&ide_cs_driver); |
511 | BUG_ON(dev_list != NULL); | ||
512 | } | 476 | } |
513 | 477 | ||
514 | late_initcall(init_ide_cs); | 478 | late_initcall(init_ide_cs); |