diff options
Diffstat (limited to 'drivers/ide/ide-probe.c')
-rw-r--r-- | drivers/ide/ide-probe.c | 117 |
1 files changed, 62 insertions, 55 deletions
diff --git a/drivers/ide/ide-probe.c b/drivers/ide/ide-probe.c index a776a6d73c54..b4f8ca106639 100644 --- a/drivers/ide/ide-probe.c +++ b/drivers/ide/ide-probe.c | |||
@@ -50,44 +50,44 @@ | |||
50 | 50 | ||
51 | static void generic_id(ide_drive_t *drive) | 51 | static void generic_id(ide_drive_t *drive) |
52 | { | 52 | { |
53 | drive->id->cyls = drive->cyl; | 53 | u16 *id = drive->id; |
54 | drive->id->heads = drive->head; | 54 | |
55 | drive->id->sectors = drive->sect; | 55 | id[ATA_ID_CUR_CYLS] = id[ATA_ID_CYLS] = drive->cyl; |
56 | drive->id->cur_cyls = drive->cyl; | 56 | id[ATA_ID_CUR_HEADS] = id[ATA_ID_HEADS] = drive->head; |
57 | drive->id->cur_heads = drive->head; | 57 | id[ATA_ID_CUR_SECTORS] = id[ATA_ID_SECTORS] = drive->sect; |
58 | drive->id->cur_sectors = drive->sect; | ||
59 | } | 58 | } |
60 | 59 | ||
61 | static void ide_disk_init_chs(ide_drive_t *drive) | 60 | static void ide_disk_init_chs(ide_drive_t *drive) |
62 | { | 61 | { |
63 | struct hd_driveid *id = drive->id; | 62 | u16 *id = drive->id; |
64 | 63 | ||
65 | /* Extract geometry if we did not already have one for the drive */ | 64 | /* Extract geometry if we did not already have one for the drive */ |
66 | if (!drive->cyl || !drive->head || !drive->sect) { | 65 | if (!drive->cyl || !drive->head || !drive->sect) { |
67 | drive->cyl = drive->bios_cyl = id->cyls; | 66 | drive->cyl = drive->bios_cyl = id[ATA_ID_CYLS]; |
68 | drive->head = drive->bios_head = id->heads; | 67 | drive->head = drive->bios_head = id[ATA_ID_HEADS]; |
69 | drive->sect = drive->bios_sect = id->sectors; | 68 | drive->sect = drive->bios_sect = id[ATA_ID_SECTORS]; |
70 | } | 69 | } |
71 | 70 | ||
72 | /* Handle logical geometry translation by the drive */ | 71 | /* Handle logical geometry translation by the drive */ |
73 | if ((id->field_valid & 1) && id->cur_cyls && | 72 | if ((id[ATA_ID_FIELD_VALID] & 1) && id[ATA_ID_CUR_CYLS] && |
74 | id->cur_heads && (id->cur_heads <= 16) && id->cur_sectors) { | 73 | id[ATA_ID_CUR_HEADS] && id[ATA_ID_CUR_HEADS] <= 16 && |
75 | drive->cyl = id->cur_cyls; | 74 | id[ATA_ID_CUR_SECTORS]) { |
76 | drive->head = id->cur_heads; | 75 | drive->cyl = id[ATA_ID_CUR_CYLS]; |
77 | drive->sect = id->cur_sectors; | 76 | drive->head = id[ATA_ID_CUR_HEADS]; |
77 | drive->sect = id[ATA_ID_CUR_SECTORS]; | ||
78 | } | 78 | } |
79 | 79 | ||
80 | /* Use physical geometry if what we have still makes no sense */ | 80 | /* Use physical geometry if what we have still makes no sense */ |
81 | if (drive->head > 16 && id->heads && id->heads <= 16) { | 81 | if (drive->head > 16 && id[ATA_ID_HEADS] && id[ATA_ID_HEADS] <= 16) { |
82 | drive->cyl = id->cyls; | 82 | drive->cyl = id[ATA_ID_CYLS]; |
83 | drive->head = id->heads; | 83 | drive->head = id[ATA_ID_HEADS]; |
84 | drive->sect = id->sectors; | 84 | drive->sect = id[ATA_ID_SECTORS]; |
85 | } | 85 | } |
86 | } | 86 | } |
87 | 87 | ||
88 | static void ide_disk_init_mult_count(ide_drive_t *drive) | 88 | static void ide_disk_init_mult_count(ide_drive_t *drive) |
89 | { | 89 | { |
90 | struct hd_driveid *id = drive->id; | 90 | struct hd_driveid *id = drive->driveid; |
91 | 91 | ||
92 | if (id->max_multsect) { | 92 | if (id->max_multsect) { |
93 | #ifdef CONFIG_IDEDISK_MULTI_MODE | 93 | #ifdef CONFIG_IDEDISK_MULTI_MODE |
@@ -118,10 +118,10 @@ static void ide_disk_init_mult_count(ide_drive_t *drive) | |||
118 | static inline void do_identify (ide_drive_t *drive, u8 cmd) | 118 | static inline void do_identify (ide_drive_t *drive, u8 cmd) |
119 | { | 119 | { |
120 | ide_hwif_t *hwif = HWIF(drive); | 120 | ide_hwif_t *hwif = HWIF(drive); |
121 | u16 *id = drive->id; | ||
122 | char *m = (char *)&id[ATA_ID_PROD]; | ||
121 | int bswap = 1; | 123 | int bswap = 1; |
122 | struct hd_driveid *id; | ||
123 | 124 | ||
124 | id = drive->id; | ||
125 | /* read 512 bytes of id info */ | 125 | /* read 512 bytes of id info */ |
126 | hwif->tp_ops->input_data(drive, NULL, id, SECTOR_SIZE); | 126 | hwif->tp_ops->input_data(drive, NULL, id, SECTOR_SIZE); |
127 | 127 | ||
@@ -138,23 +138,24 @@ static inline void do_identify (ide_drive_t *drive, u8 cmd) | |||
138 | * WIN_PIDENTIFY *usually* returns little-endian info. | 138 | * WIN_PIDENTIFY *usually* returns little-endian info. |
139 | */ | 139 | */ |
140 | if (cmd == WIN_PIDENTIFY) { | 140 | if (cmd == WIN_PIDENTIFY) { |
141 | if ((id->model[0] == 'N' && id->model[1] == 'E') /* NEC */ | 141 | if ((m[0] == 'N' && m[1] == 'E') || /* NEC */ |
142 | || (id->model[0] == 'F' && id->model[1] == 'X') /* Mitsumi */ | 142 | (m[0] == 'F' && m[1] == 'X') || /* Mitsumi */ |
143 | || (id->model[0] == 'P' && id->model[1] == 'i'))/* Pioneer */ | 143 | (m[0] == 'P' && m[1] == 'i')) /* Pioneer */ |
144 | /* Vertos drives may still be weird */ | 144 | /* Vertos drives may still be weird */ |
145 | bswap ^= 1; | 145 | bswap ^= 1; |
146 | } | 146 | } |
147 | ide_fixstring(id->model, sizeof(id->model), bswap); | 147 | |
148 | ide_fixstring(id->fw_rev, sizeof(id->fw_rev), bswap); | 148 | ide_fixstring(m, ATA_ID_PROD_LEN, bswap); |
149 | ide_fixstring(id->serial_no, sizeof(id->serial_no), bswap); | 149 | ide_fixstring((char *)&id[ATA_ID_FW_REV], ATA_ID_FW_REV_LEN, bswap); |
150 | ide_fixstring((char *)&id[ATA_ID_SERNO], ATA_ID_SERNO_LEN, bswap); | ||
150 | 151 | ||
151 | /* we depend on this a lot! */ | 152 | /* we depend on this a lot! */ |
152 | id->model[sizeof(id->model)-1] = '\0'; | 153 | m[ATA_ID_PROD_LEN - 1] = '\0'; |
153 | 154 | ||
154 | if (strstr(id->model, "E X A B Y T E N E S T")) | 155 | if (strstr(m, "E X A B Y T E N E S T")) |
155 | goto err_misc; | 156 | goto err_misc; |
156 | 157 | ||
157 | printk(KERN_INFO "%s: %s, ", drive->name, id->model); | 158 | printk(KERN_INFO "%s: %s, ", drive->name, m); |
158 | 159 | ||
159 | drive->present = 1; | 160 | drive->present = 1; |
160 | drive->dead = 0; | 161 | drive->dead = 0; |
@@ -163,15 +164,15 @@ static inline void do_identify (ide_drive_t *drive, u8 cmd) | |||
163 | * Check for an ATAPI device | 164 | * Check for an ATAPI device |
164 | */ | 165 | */ |
165 | if (cmd == WIN_PIDENTIFY) { | 166 | if (cmd == WIN_PIDENTIFY) { |
166 | u8 type = (id->config >> 8) & 0x1f; | 167 | u8 type = (id[ATA_ID_CONFIG] >> 8) & 0x1f; |
167 | 168 | ||
168 | printk(KERN_CONT "ATAPI "); | 169 | printk(KERN_CONT "ATAPI "); |
169 | switch (type) { | 170 | switch (type) { |
170 | case ide_floppy: | 171 | case ide_floppy: |
171 | if (!strstr(id->model, "CD-ROM")) { | 172 | if (!strstr(m, "CD-ROM")) { |
172 | if (!strstr(id->model, "oppy") && | 173 | if (!strstr(m, "oppy") && |
173 | !strstr(id->model, "poyp") && | 174 | !strstr(m, "poyp") && |
174 | !strstr(id->model, "ZIP")) | 175 | !strstr(m, "ZIP")) |
175 | printk(KERN_CONT "cdrom or floppy?, assuming "); | 176 | printk(KERN_CONT "cdrom or floppy?, assuming "); |
176 | if (drive->media != ide_cdrom) { | 177 | if (drive->media != ide_cdrom) { |
177 | printk(KERN_CONT "FLOPPY"); | 178 | printk(KERN_CONT "FLOPPY"); |
@@ -185,8 +186,7 @@ static inline void do_identify (ide_drive_t *drive, u8 cmd) | |||
185 | drive->removable = 1; | 186 | drive->removable = 1; |
186 | #ifdef CONFIG_PPC | 187 | #ifdef CONFIG_PPC |
187 | /* kludge for Apple PowerBook internal zip */ | 188 | /* kludge for Apple PowerBook internal zip */ |
188 | if (!strstr(id->model, "CD-ROM") && | 189 | if (!strstr(m, "CD-ROM") && strstr(m, "ZIP")) { |
189 | strstr(id->model, "ZIP")) { | ||
190 | printk(KERN_CONT "FLOPPY"); | 190 | printk(KERN_CONT "FLOPPY"); |
191 | type = ide_floppy; | 191 | type = ide_floppy; |
192 | break; | 192 | break; |
@@ -220,14 +220,13 @@ static inline void do_identify (ide_drive_t *drive, u8 cmd) | |||
220 | * 0x848a = CompactFlash device | 220 | * 0x848a = CompactFlash device |
221 | * These are *not* removable in Linux definition of the term | 221 | * These are *not* removable in Linux definition of the term |
222 | */ | 222 | */ |
223 | 223 | if (id[ATA_ID_CONFIG] != 0x848a && (id[ATA_ID_CONFIG] & (1 << 7))) | |
224 | if ((id->config != 0x848a) && (id->config & (1<<7))) | ||
225 | drive->removable = 1; | 224 | drive->removable = 1; |
226 | 225 | ||
227 | drive->media = ide_disk; | 226 | drive->media = ide_disk; |
228 | 227 | ||
229 | printk(KERN_CONT "%s DISK drive\n", | 228 | printk(KERN_CONT "%s DISK drive\n", |
230 | (id->config == 0x848a) ? "CFA" : "ATA"); | 229 | (id[ATA_ID_CONFIG] == 0x848a) ? "CFA" : "ATA"); |
231 | 230 | ||
232 | return; | 231 | return; |
233 | 232 | ||
@@ -525,7 +524,8 @@ static void enable_nest (ide_drive_t *drive) | |||
525 | const struct ide_tp_ops *tp_ops = hwif->tp_ops; | 524 | const struct ide_tp_ops *tp_ops = hwif->tp_ops; |
526 | u8 stat; | 525 | u8 stat; |
527 | 526 | ||
528 | printk(KERN_INFO "%s: enabling %s -- ", hwif->name, drive->id->model); | 527 | printk(KERN_INFO "%s: enabling %s -- ", |
528 | hwif->name, (char *)&drive->id[ATA_ID_PROD]); | ||
529 | 529 | ||
530 | SELECT_DRIVE(drive); | 530 | SELECT_DRIVE(drive); |
531 | msleep(50); | 531 | msleep(50); |
@@ -566,6 +566,8 @@ static void enable_nest (ide_drive_t *drive) | |||
566 | 566 | ||
567 | static inline u8 probe_for_drive (ide_drive_t *drive) | 567 | static inline u8 probe_for_drive (ide_drive_t *drive) |
568 | { | 568 | { |
569 | char *m; | ||
570 | |||
569 | /* | 571 | /* |
570 | * In order to keep things simple we have an id | 572 | * In order to keep things simple we have an id |
571 | * block for all drives at all times. If the device | 573 | * block for all drives at all times. If the device |
@@ -582,8 +584,10 @@ static inline u8 probe_for_drive (ide_drive_t *drive) | |||
582 | printk(KERN_ERR "ide: out of memory for id data.\n"); | 584 | printk(KERN_ERR "ide: out of memory for id data.\n"); |
583 | return 0; | 585 | return 0; |
584 | } | 586 | } |
585 | strcpy(drive->id->model, "UNKNOWN"); | 587 | |
586 | 588 | m = (char *)&drive->id[ATA_ID_PROD]; | |
589 | strcpy(m, "UNKNOWN"); | ||
590 | |||
587 | /* skip probing? */ | 591 | /* skip probing? */ |
588 | if (!drive->noprobe) | 592 | if (!drive->noprobe) |
589 | { | 593 | { |
@@ -595,7 +599,8 @@ static inline u8 probe_for_drive (ide_drive_t *drive) | |||
595 | if (!drive->present) | 599 | if (!drive->present) |
596 | /* drive not found */ | 600 | /* drive not found */ |
597 | return 0; | 601 | return 0; |
598 | if (strstr(drive->id->model, "E X A B Y T E N E S T")) | 602 | |
603 | if (strstr(m, "E X A B Y T E N E S T")) | ||
599 | enable_nest(drive); | 604 | enable_nest(drive); |
600 | 605 | ||
601 | /* identification failed? */ | 606 | /* identification failed? */ |
@@ -739,36 +744,38 @@ out: | |||
739 | 744 | ||
740 | /** | 745 | /** |
741 | * ide_undecoded_slave - look for bad CF adapters | 746 | * ide_undecoded_slave - look for bad CF adapters |
742 | * @drive1: drive | 747 | * @dev1: slave device |
743 | * | 748 | * |
744 | * Analyse the drives on the interface and attempt to decide if we | 749 | * Analyse the drives on the interface and attempt to decide if we |
745 | * have the same drive viewed twice. This occurs with crap CF adapters | 750 | * have the same drive viewed twice. This occurs with crap CF adapters |
746 | * and PCMCIA sometimes. | 751 | * and PCMCIA sometimes. |
747 | */ | 752 | */ |
748 | 753 | ||
749 | void ide_undecoded_slave(ide_drive_t *drive1) | 754 | void ide_undecoded_slave(ide_drive_t *dev1) |
750 | { | 755 | { |
751 | ide_drive_t *drive0 = &drive1->hwif->drives[0]; | 756 | ide_drive_t *dev0 = &dev1->hwif->drives[0]; |
752 | 757 | ||
753 | if ((drive1->dn & 1) == 0 || drive0->present == 0) | 758 | if ((dev1->dn & 1) == 0 || dev0->present == 0) |
754 | return; | 759 | return; |
755 | 760 | ||
756 | /* If the models don't match they are not the same product */ | 761 | /* If the models don't match they are not the same product */ |
757 | if (strcmp(drive0->id->model, drive1->id->model)) | 762 | if (strcmp((char *)&dev0->id[ATA_ID_PROD], |
763 | (char *)&dev1->id[ATA_ID_PROD])) | ||
758 | return; | 764 | return; |
759 | 765 | ||
760 | /* Serial numbers do not match */ | 766 | /* Serial numbers do not match */ |
761 | if (strncmp(drive0->id->serial_no, drive1->id->serial_no, 20)) | 767 | if (strncmp((char *)&dev0->id[ATA_ID_SERNO], |
768 | (char *)&dev1->id[ATA_ID_SERNO], ATA_ID_SERNO_LEN)) | ||
762 | return; | 769 | return; |
763 | 770 | ||
764 | /* No serial number, thankfully very rare for CF */ | 771 | /* No serial number, thankfully very rare for CF */ |
765 | if (drive0->id->serial_no[0] == 0) | 772 | if (*(char *)&dev0->id[ATA_ID_SERNO] == 0) |
766 | return; | 773 | return; |
767 | 774 | ||
768 | /* Appears to be an IDE flash adapter with decode bugs */ | 775 | /* Appears to be an IDE flash adapter with decode bugs */ |
769 | printk(KERN_WARNING "ide-probe: ignoring undecoded slave\n"); | 776 | printk(KERN_WARNING "ide-probe: ignoring undecoded slave\n"); |
770 | 777 | ||
771 | drive1->present = 0; | 778 | dev1->present = 0; |
772 | } | 779 | } |
773 | 780 | ||
774 | EXPORT_SYMBOL_GPL(ide_undecoded_slave); | 781 | EXPORT_SYMBOL_GPL(ide_undecoded_slave); |
@@ -852,7 +859,7 @@ static void ide_port_tune_devices(ide_hwif_t *hwif) | |||
852 | if (hwif->host_flags & IDE_HFLAG_NO_IO_32BIT) | 859 | if (hwif->host_flags & IDE_HFLAG_NO_IO_32BIT) |
853 | drive->no_io_32bit = 1; | 860 | drive->no_io_32bit = 1; |
854 | else | 861 | else |
855 | drive->no_io_32bit = drive->id->dword_io ? 1 : 0; | 862 | drive->no_io_32bit = drive->id[ATA_ID_DWORD_IO] ? 1 : 0; |
856 | } | 863 | } |
857 | } | 864 | } |
858 | 865 | ||