diff options
Diffstat (limited to 'drivers/ide/ide.c')
-rw-r--r-- | drivers/ide/ide.c | 360 |
1 files changed, 27 insertions, 333 deletions
diff --git a/drivers/ide/ide.c b/drivers/ide/ide.c index 300431d080a9..2b8453510e09 100644 --- a/drivers/ide/ide.c +++ b/drivers/ide/ide.c | |||
@@ -86,13 +86,10 @@ static const u8 ide_hwif_to_major[] = { IDE0_MAJOR, IDE1_MAJOR, | |||
86 | IDE6_MAJOR, IDE7_MAJOR, | 86 | IDE6_MAJOR, IDE7_MAJOR, |
87 | IDE8_MAJOR, IDE9_MAJOR }; | 87 | IDE8_MAJOR, IDE9_MAJOR }; |
88 | 88 | ||
89 | static int idebus_parameter; /* holds the "idebus=" parameter */ | ||
90 | static int system_bus_speed; /* holds what we think is VESA/PCI bus speed */ | ||
91 | |||
92 | DEFINE_MUTEX(ide_cfg_mtx); | 89 | DEFINE_MUTEX(ide_cfg_mtx); |
93 | __cacheline_aligned_in_smp DEFINE_SPINLOCK(ide_lock); | ||
94 | 90 | ||
95 | int noautodma = 0; | 91 | __cacheline_aligned_in_smp DEFINE_SPINLOCK(ide_lock); |
92 | EXPORT_SYMBOL(ide_lock); | ||
96 | 93 | ||
97 | ide_hwif_t ide_hwifs[MAX_HWIFS]; /* master data repository */ | 94 | ide_hwif_t ide_hwifs[MAX_HWIFS]; /* master data repository */ |
98 | 95 | ||
@@ -139,7 +136,6 @@ static void ide_port_init_devices_data(ide_hwif_t *hwif) | |||
139 | drive->media = ide_disk; | 136 | drive->media = ide_disk; |
140 | drive->select.all = (unit<<4)|0xa0; | 137 | drive->select.all = (unit<<4)|0xa0; |
141 | drive->hwif = hwif; | 138 | drive->hwif = hwif; |
142 | drive->ctl = 0x08; | ||
143 | drive->ready_stat = READY_STAT; | 139 | drive->ready_stat = READY_STAT; |
144 | drive->bad_wstat = BAD_W_STAT; | 140 | drive->bad_wstat = BAD_W_STAT; |
145 | drive->special.b.recalibrate = 1; | 141 | drive->special.b.recalibrate = 1; |
@@ -154,32 +150,9 @@ static void ide_port_init_devices_data(ide_hwif_t *hwif) | |||
154 | } | 150 | } |
155 | } | 151 | } |
156 | 152 | ||
157 | /* | ||
158 | * init_ide_data() sets reasonable default values into all fields | ||
159 | * of all instances of the hwifs and drives, but only on the first call. | ||
160 | * Subsequent calls have no effect (they don't wipe out anything). | ||
161 | * | ||
162 | * This routine is normally called at driver initialization time, | ||
163 | * but may also be called MUCH earlier during kernel "command-line" | ||
164 | * parameter processing. As such, we cannot depend on any other parts | ||
165 | * of the kernel (such as memory allocation) to be functioning yet. | ||
166 | * | ||
167 | * This is too bad, as otherwise we could dynamically allocate the | ||
168 | * ide_drive_t structs as needed, rather than always consuming memory | ||
169 | * for the max possible number (MAX_HWIFS * MAX_DRIVES) of them. | ||
170 | * | ||
171 | * FIXME: We should stuff the setup data into __init and copy the | ||
172 | * relevant hwifs/allocate them properly during boot. | ||
173 | */ | ||
174 | #define MAGIC_COOKIE 0x12345678 | ||
175 | static void __init init_ide_data (void) | 153 | static void __init init_ide_data (void) |
176 | { | 154 | { |
177 | unsigned int index; | 155 | unsigned int index; |
178 | static unsigned long magic_cookie = MAGIC_COOKIE; | ||
179 | |||
180 | if (magic_cookie != MAGIC_COOKIE) | ||
181 | return; /* already initialized */ | ||
182 | magic_cookie = 0; | ||
183 | 156 | ||
184 | /* Initialise all interface structures */ | 157 | /* Initialise all interface structures */ |
185 | for (index = 0; index < MAX_HWIFS; ++index) { | 158 | for (index = 0; index < MAX_HWIFS; ++index) { |
@@ -189,38 +162,6 @@ static void __init init_ide_data (void) | |||
189 | } | 162 | } |
190 | } | 163 | } |
191 | 164 | ||
192 | /** | ||
193 | * ide_system_bus_speed - guess bus speed | ||
194 | * | ||
195 | * ide_system_bus_speed() returns what we think is the system VESA/PCI | ||
196 | * bus speed (in MHz). This is used for calculating interface PIO timings. | ||
197 | * The default is 40 for known PCI systems, 50 otherwise. | ||
198 | * The "idebus=xx" parameter can be used to override this value. | ||
199 | * The actual value to be used is computed/displayed the first time | ||
200 | * through. Drivers should only use this as a last resort. | ||
201 | * | ||
202 | * Returns a guessed speed in MHz. | ||
203 | */ | ||
204 | |||
205 | static int ide_system_bus_speed(void) | ||
206 | { | ||
207 | #ifdef CONFIG_PCI | ||
208 | static struct pci_device_id pci_default[] = { | ||
209 | { PCI_DEVICE(PCI_ANY_ID, PCI_ANY_ID) }, | ||
210 | { } | ||
211 | }; | ||
212 | #else | ||
213 | #define pci_default 0 | ||
214 | #endif /* CONFIG_PCI */ | ||
215 | |||
216 | /* user supplied value */ | ||
217 | if (idebus_parameter) | ||
218 | return idebus_parameter; | ||
219 | |||
220 | /* safe default value for PCI or VESA and PCI*/ | ||
221 | return pci_dev_present(pci_default) ? 33 : 50; | ||
222 | } | ||
223 | |||
224 | void ide_remove_port_from_hwgroup(ide_hwif_t *hwif) | 165 | void ide_remove_port_from_hwgroup(ide_hwif_t *hwif) |
225 | { | 166 | { |
226 | ide_hwgroup_t *hwgroup = hwif->hwgroup; | 167 | ide_hwgroup_t *hwgroup = hwif->hwgroup; |
@@ -498,7 +439,7 @@ out: | |||
498 | 439 | ||
499 | int set_pio_mode(ide_drive_t *drive, int arg) | 440 | int set_pio_mode(ide_drive_t *drive, int arg) |
500 | { | 441 | { |
501 | struct request rq; | 442 | struct request *rq; |
502 | ide_hwif_t *hwif = drive->hwif; | 443 | ide_hwif_t *hwif = drive->hwif; |
503 | const struct ide_port_ops *port_ops = hwif->port_ops; | 444 | const struct ide_port_ops *port_ops = hwif->port_ops; |
504 | 445 | ||
@@ -512,12 +453,15 @@ int set_pio_mode(ide_drive_t *drive, int arg) | |||
512 | if (drive->special.b.set_tune) | 453 | if (drive->special.b.set_tune) |
513 | return -EBUSY; | 454 | return -EBUSY; |
514 | 455 | ||
515 | ide_init_drive_cmd(&rq); | 456 | rq = blk_get_request(drive->queue, READ, __GFP_WAIT); |
516 | rq.cmd_type = REQ_TYPE_ATA_TASKFILE; | 457 | rq->cmd_type = REQ_TYPE_ATA_TASKFILE; |
517 | 458 | ||
518 | drive->tune_req = (u8) arg; | 459 | drive->tune_req = (u8) arg; |
519 | drive->special.b.set_tune = 1; | 460 | drive->special.b.set_tune = 1; |
520 | (void) ide_do_drive_cmd(drive, &rq, ide_wait); | 461 | |
462 | blk_execute_rq(drive->queue, NULL, rq, 0); | ||
463 | blk_put_request(rq); | ||
464 | |||
521 | return 0; | 465 | return 0; |
522 | } | 466 | } |
523 | 467 | ||
@@ -537,25 +481,11 @@ static int set_unmaskirq(ide_drive_t *drive, int arg) | |||
537 | return 0; | 481 | return 0; |
538 | } | 482 | } |
539 | 483 | ||
540 | /** | ||
541 | * system_bus_clock - clock guess | ||
542 | * | ||
543 | * External version of the bus clock guess used by very old IDE drivers | ||
544 | * for things like VLB timings. Should not be used. | ||
545 | */ | ||
546 | |||
547 | int system_bus_clock (void) | ||
548 | { | ||
549 | return system_bus_speed; | ||
550 | } | ||
551 | |||
552 | EXPORT_SYMBOL(system_bus_clock); | ||
553 | |||
554 | static int generic_ide_suspend(struct device *dev, pm_message_t mesg) | 484 | static int generic_ide_suspend(struct device *dev, pm_message_t mesg) |
555 | { | 485 | { |
556 | ide_drive_t *drive = dev->driver_data; | 486 | ide_drive_t *drive = dev->driver_data; |
557 | ide_hwif_t *hwif = HWIF(drive); | 487 | ide_hwif_t *hwif = HWIF(drive); |
558 | struct request rq; | 488 | struct request *rq; |
559 | struct request_pm_state rqpm; | 489 | struct request_pm_state rqpm; |
560 | ide_task_t args; | 490 | ide_task_t args; |
561 | int ret; | 491 | int ret; |
@@ -564,18 +494,19 @@ static int generic_ide_suspend(struct device *dev, pm_message_t mesg) | |||
564 | if (!(drive->dn % 2)) | 494 | if (!(drive->dn % 2)) |
565 | ide_acpi_get_timing(hwif); | 495 | ide_acpi_get_timing(hwif); |
566 | 496 | ||
567 | blk_rq_init(NULL, &rq); | ||
568 | memset(&rqpm, 0, sizeof(rqpm)); | 497 | memset(&rqpm, 0, sizeof(rqpm)); |
569 | memset(&args, 0, sizeof(args)); | 498 | memset(&args, 0, sizeof(args)); |
570 | rq.cmd_type = REQ_TYPE_PM_SUSPEND; | 499 | rq = blk_get_request(drive->queue, READ, __GFP_WAIT); |
571 | rq.special = &args; | 500 | rq->cmd_type = REQ_TYPE_PM_SUSPEND; |
572 | rq.data = &rqpm; | 501 | rq->special = &args; |
502 | rq->data = &rqpm; | ||
573 | rqpm.pm_step = ide_pm_state_start_suspend; | 503 | rqpm.pm_step = ide_pm_state_start_suspend; |
574 | if (mesg.event == PM_EVENT_PRETHAW) | 504 | if (mesg.event == PM_EVENT_PRETHAW) |
575 | mesg.event = PM_EVENT_FREEZE; | 505 | mesg.event = PM_EVENT_FREEZE; |
576 | rqpm.pm_state = mesg.event; | 506 | rqpm.pm_state = mesg.event; |
577 | 507 | ||
578 | ret = ide_do_drive_cmd(drive, &rq, ide_wait); | 508 | ret = blk_execute_rq(drive->queue, NULL, rq, 0); |
509 | blk_put_request(rq); | ||
579 | /* only call ACPI _PS3 after both drivers are suspended */ | 510 | /* only call ACPI _PS3 after both drivers are suspended */ |
580 | if (!ret && (((drive->dn % 2) && hwif->drives[0].present | 511 | if (!ret && (((drive->dn % 2) && hwif->drives[0].present |
581 | && hwif->drives[1].present) | 512 | && hwif->drives[1].present) |
@@ -589,7 +520,7 @@ static int generic_ide_resume(struct device *dev) | |||
589 | { | 520 | { |
590 | ide_drive_t *drive = dev->driver_data; | 521 | ide_drive_t *drive = dev->driver_data; |
591 | ide_hwif_t *hwif = HWIF(drive); | 522 | ide_hwif_t *hwif = HWIF(drive); |
592 | struct request rq; | 523 | struct request *rq; |
593 | struct request_pm_state rqpm; | 524 | struct request_pm_state rqpm; |
594 | ide_task_t args; | 525 | ide_task_t args; |
595 | int err; | 526 | int err; |
@@ -602,16 +533,18 @@ static int generic_ide_resume(struct device *dev) | |||
602 | 533 | ||
603 | ide_acpi_exec_tfs(drive); | 534 | ide_acpi_exec_tfs(drive); |
604 | 535 | ||
605 | blk_rq_init(NULL, &rq); | ||
606 | memset(&rqpm, 0, sizeof(rqpm)); | 536 | memset(&rqpm, 0, sizeof(rqpm)); |
607 | memset(&args, 0, sizeof(args)); | 537 | memset(&args, 0, sizeof(args)); |
608 | rq.cmd_type = REQ_TYPE_PM_RESUME; | 538 | rq = blk_get_request(drive->queue, READ, __GFP_WAIT); |
609 | rq.special = &args; | 539 | rq->cmd_type = REQ_TYPE_PM_RESUME; |
610 | rq.data = &rqpm; | 540 | rq->cmd_flags |= REQ_PREEMPT; |
541 | rq->special = &args; | ||
542 | rq->data = &rqpm; | ||
611 | rqpm.pm_step = ide_pm_state_start_resume; | 543 | rqpm.pm_step = ide_pm_state_start_resume; |
612 | rqpm.pm_state = PM_EVENT_ON; | 544 | rqpm.pm_state = PM_EVENT_ON; |
613 | 545 | ||
614 | err = ide_do_drive_cmd(drive, &rq, ide_head_wait); | 546 | err = blk_execute_rq(drive->queue, NULL, rq, 1); |
547 | blk_put_request(rq); | ||
615 | 548 | ||
616 | if (err == 0 && dev->driver) { | 549 | if (err == 0 && dev->driver) { |
617 | ide_driver_t *drv = to_ide_driver(dev->driver); | 550 | ide_driver_t *drv = to_ide_driver(dev->driver); |
@@ -764,212 +697,6 @@ set_val: | |||
764 | 697 | ||
765 | EXPORT_SYMBOL(generic_ide_ioctl); | 698 | EXPORT_SYMBOL(generic_ide_ioctl); |
766 | 699 | ||
767 | /* | ||
768 | * stridx() returns the offset of c within s, | ||
769 | * or -1 if c is '\0' or not found within s. | ||
770 | */ | ||
771 | static int __init stridx (const char *s, char c) | ||
772 | { | ||
773 | char *i = strchr(s, c); | ||
774 | return (i && c) ? i - s : -1; | ||
775 | } | ||
776 | |||
777 | /* | ||
778 | * match_parm() does parsing for ide_setup(): | ||
779 | * | ||
780 | * 1. the first char of s must be '='. | ||
781 | * 2. if the remainder matches one of the supplied keywords, | ||
782 | * the index (1 based) of the keyword is negated and returned. | ||
783 | * 3. if the remainder is a series of no more than max_vals numbers | ||
784 | * separated by commas, the numbers are saved in vals[] and a | ||
785 | * count of how many were saved is returned. Base10 is assumed, | ||
786 | * and base16 is allowed when prefixed with "0x". | ||
787 | * 4. otherwise, zero is returned. | ||
788 | */ | ||
789 | static int __init match_parm (char *s, const char *keywords[], int vals[], int max_vals) | ||
790 | { | ||
791 | static const char *decimal = "0123456789"; | ||
792 | static const char *hex = "0123456789abcdef"; | ||
793 | int i, n; | ||
794 | |||
795 | if (*s++ == '=') { | ||
796 | /* | ||
797 | * Try matching against the supplied keywords, | ||
798 | * and return -(index+1) if we match one | ||
799 | */ | ||
800 | if (keywords != NULL) { | ||
801 | for (i = 0; *keywords != NULL; ++i) { | ||
802 | if (!strcmp(s, *keywords++)) | ||
803 | return -(i+1); | ||
804 | } | ||
805 | } | ||
806 | /* | ||
807 | * Look for a series of no more than "max_vals" | ||
808 | * numeric values separated by commas, in base10, | ||
809 | * or base16 when prefixed with "0x". | ||
810 | * Return a count of how many were found. | ||
811 | */ | ||
812 | for (n = 0; (i = stridx(decimal, *s)) >= 0;) { | ||
813 | vals[n] = i; | ||
814 | while ((i = stridx(decimal, *++s)) >= 0) | ||
815 | vals[n] = (vals[n] * 10) + i; | ||
816 | if (*s == 'x' && !vals[n]) { | ||
817 | while ((i = stridx(hex, *++s)) >= 0) | ||
818 | vals[n] = (vals[n] * 0x10) + i; | ||
819 | } | ||
820 | if (++n == max_vals) | ||
821 | break; | ||
822 | if (*s == ',' || *s == ';') | ||
823 | ++s; | ||
824 | } | ||
825 | if (!*s) | ||
826 | return n; | ||
827 | } | ||
828 | return 0; /* zero = nothing matched */ | ||
829 | } | ||
830 | |||
831 | /* | ||
832 | * ide_setup() gets called VERY EARLY during initialization, | ||
833 | * to handle kernel "command line" strings beginning with "hdx=" or "ide". | ||
834 | * | ||
835 | * Remember to update Documentation/ide/ide.txt if you change something here. | ||
836 | */ | ||
837 | static int __init ide_setup(char *s) | ||
838 | { | ||
839 | ide_hwif_t *hwif; | ||
840 | ide_drive_t *drive; | ||
841 | unsigned int hw, unit; | ||
842 | int vals[3]; | ||
843 | const char max_drive = 'a' + ((MAX_HWIFS * MAX_DRIVES) - 1); | ||
844 | |||
845 | if (strncmp(s,"hd",2) == 0 && s[2] == '=') /* hd= is for hd.c */ | ||
846 | return 0; /* driver and not us */ | ||
847 | |||
848 | if (strncmp(s,"ide",3) && strncmp(s,"idebus",6) && strncmp(s,"hd",2)) | ||
849 | return 0; | ||
850 | |||
851 | printk(KERN_INFO "ide_setup: %s", s); | ||
852 | init_ide_data (); | ||
853 | |||
854 | #ifdef CONFIG_BLK_DEV_IDEDOUBLER | ||
855 | if (!strcmp(s, "ide=doubler")) { | ||
856 | extern int ide_doubler; | ||
857 | |||
858 | printk(" : Enabled support for IDE doublers\n"); | ||
859 | ide_doubler = 1; | ||
860 | goto obsolete_option; | ||
861 | } | ||
862 | #endif /* CONFIG_BLK_DEV_IDEDOUBLER */ | ||
863 | |||
864 | if (!strcmp(s, "ide=nodma")) { | ||
865 | printk(" : Prevented DMA\n"); | ||
866 | noautodma = 1; | ||
867 | goto obsolete_option; | ||
868 | } | ||
869 | |||
870 | #ifdef CONFIG_BLK_DEV_IDEACPI | ||
871 | if (!strcmp(s, "ide=noacpi")) { | ||
872 | //printk(" : Disable IDE ACPI support.\n"); | ||
873 | ide_noacpi = 1; | ||
874 | goto obsolete_option; | ||
875 | } | ||
876 | if (!strcmp(s, "ide=acpigtf")) { | ||
877 | //printk(" : Enable IDE ACPI _GTF support.\n"); | ||
878 | ide_acpigtf = 1; | ||
879 | goto obsolete_option; | ||
880 | } | ||
881 | if (!strcmp(s, "ide=acpionboot")) { | ||
882 | //printk(" : Call IDE ACPI methods on boot.\n"); | ||
883 | ide_acpionboot = 1; | ||
884 | goto obsolete_option; | ||
885 | } | ||
886 | #endif /* CONFIG_BLK_DEV_IDEACPI */ | ||
887 | |||
888 | /* | ||
889 | * Look for drive options: "hdx=" | ||
890 | */ | ||
891 | if (s[0] == 'h' && s[1] == 'd' && s[2] >= 'a' && s[2] <= max_drive) { | ||
892 | const char *hd_words[] = { | ||
893 | "none", "noprobe", "nowerr", "cdrom", "nodma", | ||
894 | "-6", "-7", "-8", "-9", "-10", | ||
895 | "noflush", "remap", "remap63", "scsi", NULL }; | ||
896 | unit = s[2] - 'a'; | ||
897 | hw = unit / MAX_DRIVES; | ||
898 | unit = unit % MAX_DRIVES; | ||
899 | hwif = &ide_hwifs[hw]; | ||
900 | drive = &hwif->drives[unit]; | ||
901 | if (strncmp(s + 4, "ide-", 4) == 0) { | ||
902 | strlcpy(drive->driver_req, s + 4, sizeof(drive->driver_req)); | ||
903 | goto obsolete_option; | ||
904 | } | ||
905 | switch (match_parm(&s[3], hd_words, vals, 3)) { | ||
906 | case -1: /* "none" */ | ||
907 | case -2: /* "noprobe" */ | ||
908 | drive->noprobe = 1; | ||
909 | goto obsolete_option; | ||
910 | case -3: /* "nowerr" */ | ||
911 | drive->bad_wstat = BAD_R_STAT; | ||
912 | goto obsolete_option; | ||
913 | case -4: /* "cdrom" */ | ||
914 | drive->present = 1; | ||
915 | drive->media = ide_cdrom; | ||
916 | /* an ATAPI device ignores DRDY */ | ||
917 | drive->ready_stat = 0; | ||
918 | goto obsolete_option; | ||
919 | case -5: /* nodma */ | ||
920 | drive->nodma = 1; | ||
921 | goto obsolete_option; | ||
922 | case -11: /* noflush */ | ||
923 | drive->noflush = 1; | ||
924 | goto obsolete_option; | ||
925 | case -12: /* "remap" */ | ||
926 | drive->remap_0_to_1 = 1; | ||
927 | goto obsolete_option; | ||
928 | case -13: /* "remap63" */ | ||
929 | drive->sect0 = 63; | ||
930 | goto obsolete_option; | ||
931 | case -14: /* "scsi" */ | ||
932 | drive->scsi = 1; | ||
933 | goto obsolete_option; | ||
934 | case 3: /* cyl,head,sect */ | ||
935 | drive->media = ide_disk; | ||
936 | drive->ready_stat = READY_STAT; | ||
937 | drive->cyl = drive->bios_cyl = vals[0]; | ||
938 | drive->head = drive->bios_head = vals[1]; | ||
939 | drive->sect = drive->bios_sect = vals[2]; | ||
940 | drive->present = 1; | ||
941 | drive->forced_geom = 1; | ||
942 | goto obsolete_option; | ||
943 | default: | ||
944 | goto bad_option; | ||
945 | } | ||
946 | } | ||
947 | |||
948 | if (s[0] != 'i' || s[1] != 'd' || s[2] != 'e') | ||
949 | goto bad_option; | ||
950 | /* | ||
951 | * Look for bus speed option: "idebus=" | ||
952 | */ | ||
953 | if (s[3] == 'b' && s[4] == 'u' && s[5] == 's') { | ||
954 | if (match_parm(&s[6], NULL, vals, 1) != 1) | ||
955 | goto bad_option; | ||
956 | if (vals[0] >= 20 && vals[0] <= 66) { | ||
957 | idebus_parameter = vals[0]; | ||
958 | } else | ||
959 | printk(" -- BAD BUS SPEED! Expected value from 20 to 66"); | ||
960 | goto obsolete_option; | ||
961 | } | ||
962 | |||
963 | bad_option: | ||
964 | printk(" -- BAD OPTION\n"); | ||
965 | return 1; | ||
966 | obsolete_option: | ||
967 | printk(" -- OBSOLETE OPTION, WILL BE REMOVED SOON!\n"); | ||
968 | return 1; | ||
969 | } | ||
970 | |||
971 | EXPORT_SYMBOL(ide_lock); | ||
972 | |||
973 | static int ide_bus_match(struct device *dev, struct device_driver *drv) | 700 | static int ide_bus_match(struct device *dev, struct device_driver *drv) |
974 | { | 701 | { |
975 | return 1; | 702 | return 1; |
@@ -1281,11 +1008,6 @@ static int __init ide_init(void) | |||
1281 | int ret; | 1008 | int ret; |
1282 | 1009 | ||
1283 | printk(KERN_INFO "Uniform Multi-Platform E-IDE driver\n"); | 1010 | printk(KERN_INFO "Uniform Multi-Platform E-IDE driver\n"); |
1284 | system_bus_speed = ide_system_bus_speed(); | ||
1285 | |||
1286 | printk(KERN_INFO "ide: Assuming %dMHz system bus speed " | ||
1287 | "for PIO modes%s\n", system_bus_speed, | ||
1288 | idebus_parameter ? "" : "; override with idebus=xx"); | ||
1289 | 1011 | ||
1290 | ret = bus_register(&ide_bus_type); | 1012 | ret = bus_register(&ide_bus_type); |
1291 | if (ret < 0) { | 1013 | if (ret < 0) { |
@@ -1311,32 +1033,7 @@ out_port_class: | |||
1311 | return ret; | 1033 | return ret; |
1312 | } | 1034 | } |
1313 | 1035 | ||
1314 | #ifdef MODULE | 1036 | static void __exit ide_exit(void) |
1315 | static char *options = NULL; | ||
1316 | module_param(options, charp, 0); | ||
1317 | MODULE_LICENSE("GPL"); | ||
1318 | |||
1319 | static void __init parse_options (char *line) | ||
1320 | { | ||
1321 | char *next = line; | ||
1322 | |||
1323 | if (line == NULL || !*line) | ||
1324 | return; | ||
1325 | while ((line = next) != NULL) { | ||
1326 | if ((next = strchr(line,' ')) != NULL) | ||
1327 | *next++ = 0; | ||
1328 | if (!ide_setup(line)) | ||
1329 | printk (KERN_INFO "Unknown option '%s'\n", line); | ||
1330 | } | ||
1331 | } | ||
1332 | |||
1333 | int __init init_module (void) | ||
1334 | { | ||
1335 | parse_options(options); | ||
1336 | return ide_init(); | ||
1337 | } | ||
1338 | |||
1339 | void __exit cleanup_module (void) | ||
1340 | { | 1037 | { |
1341 | proc_ide_destroy(); | 1038 | proc_ide_destroy(); |
1342 | 1039 | ||
@@ -1345,10 +1042,7 @@ void __exit cleanup_module (void) | |||
1345 | bus_unregister(&ide_bus_type); | 1042 | bus_unregister(&ide_bus_type); |
1346 | } | 1043 | } |
1347 | 1044 | ||
1348 | #else /* !MODULE */ | ||
1349 | |||
1350 | __setup("", ide_setup); | ||
1351 | |||
1352 | module_init(ide_init); | 1045 | module_init(ide_init); |
1046 | module_exit(ide_exit); | ||
1353 | 1047 | ||
1354 | #endif /* MODULE */ | 1048 | MODULE_LICENSE("GPL"); |