3 #include <conio.h> /* this is where Open Watcom hides the outp() etc. functions */
12 #include <hw/vga/vga.h>
13 #include <hw/pci/pci.h>
14 #include <hw/dos/dos.h>
15 #include <hw/8254/8254.h> /* 8254 timer */
16 #include <hw/8259/8259.h> /* 8259 PIC interrupts */
17 #include <hw/vga/vgagui.h>
18 #include <hw/vga/vgatty.h>
19 #include <hw/ide/idelib.h>
34 int do_ide_media_card_pass_through(struct ide_controller *ide,unsigned char which,unsigned char enable) {
35 struct ide_taskfile *tsk;
37 if (do_ide_controller_user_wait_busy_controller(ide) != 0 || do_ide_controller_user_wait_drive_ready(ide) < 0)
40 tsk = idelib_controller_get_taskfile(ide,-1/*selected drive*/);
41 idelib_controller_ack_irq(ide); /* <- make sure to ack IRQ */
42 idelib_controller_reset_irq_counter(ide);
43 tsk->features = (enable != 0 ? 1 : 0);
44 idelib_controller_apply_taskfile(ide,0x02/*base_io+1*/,IDELIB_TASKFILE_LBA48_UPDATE|IDELIB_TASKFILE_LBA48);
45 idelib_controller_write_command(ide,0xD1); /* <- (D1h) CHECK MEDIA CARD TYPE */
46 if (ide->flags.io_irq_enable) {
47 do_ide_controller_user_wait_irq(ide,1);
48 idelib_controller_ack_irq(ide); /* <- or else it won't fire again */
50 do_ide_controller_user_wait_busy_controller(ide);
51 do_ide_controller_user_wait_drive_ready(ide);
52 if (ide->last_status&1) return 1;
56 int do_ide_set_multiple_mode(struct ide_controller *ide,unsigned char which,unsigned char sz) {
57 struct ide_taskfile *tsk;
59 if (do_ide_controller_user_wait_busy_controller(ide) != 0 || do_ide_controller_user_wait_drive_ready(ide) < 0)
62 tsk = idelib_controller_get_taskfile(ide,-1/*selected drive*/);
63 idelib_controller_ack_irq(ide); /* <- make sure to ack IRQ */
64 idelib_controller_reset_irq_counter(ide);
65 tsk->sector_count = sz;
66 idelib_controller_apply_taskfile(ide,0x04/*base_io+2*/,IDELIB_TASKFILE_LBA48_UPDATE/*clear LBA48*/);
67 idelib_controller_write_command(ide,0xC6); /* <- (C6h) SET MULTIPLE MODE */
68 if (ide->flags.io_irq_enable) {
69 do_ide_controller_user_wait_irq(ide,1);
70 idelib_controller_ack_irq(ide); /* <- or else it won't fire again */
72 do_ide_controller_user_wait_busy_controller(ide);
73 do_ide_controller_user_wait_drive_ready(ide);
74 if (ide->last_status&1) return 1;
78 int do_ide_identify(unsigned char *info/*512*/,unsigned int sz,struct ide_controller *ide,unsigned char which,unsigned char command) {
81 if (do_ide_controller_user_wait_busy_controller(ide) != 0 || do_ide_controller_user_wait_drive_ready(ide) < 0)
84 idelib_controller_ack_irq(ide); /* <- make sure to ack IRQ */
85 idelib_controller_reset_irq_counter(ide);
86 idelib_controller_write_command(ide,command); /* <- (A1h) identify packet device (ECh) identify device */
87 if (ide->flags.io_irq_enable) {
88 do_ide_controller_user_wait_irq(ide,1);
89 idelib_controller_ack_irq(ide); /* <- or else it won't fire again */
91 do_ide_controller_user_wait_busy_controller(ide);
92 do_ide_controller_user_wait_drive_ready(ide);
93 if (ide->last_status&1) return 1;
96 do_ide_controller_user_wait_drive_drq(ide);
97 idelib_read_pio_general((unsigned char*)info,512,ide,IDELIB_PIO_WIDTH_DEFAULT);
101 int do_ide_flush(struct ide_controller *ide,unsigned char which,unsigned char lba48) {
102 if (do_ide_controller_user_wait_busy_controller(ide) != 0 || do_ide_controller_user_wait_drive_ready(ide) < 0)
105 idelib_controller_ack_irq(ide); /* <- make sure to ack IRQ */
106 idelib_controller_reset_irq_counter(ide);
107 idelib_controller_write_command(ide,lba48?0xEA:0xE7); /* <- (E7h) FLUSH CACHE (EA) FLUSH CACHE EXT */
108 if (ide->flags.io_irq_enable) {
109 do_ide_controller_user_wait_irq(ide,1);
110 idelib_controller_ack_irq(ide); /* <- or else it won't fire again */
112 do_ide_controller_user_wait_busy_controller(ide);
113 do_ide_controller_user_wait_drive_ready(ide);
114 if (ide->last_status&1) return 1;
118 int do_ide_device_diagnostic(struct ide_controller *ide,unsigned char which) {
119 if (do_ide_controller_user_wait_busy_controller(ide) != 0 || do_ide_controller_user_wait_drive_ready(ide) < 0)
122 idelib_controller_ack_irq(ide); /* <- make sure to ack IRQ */
123 idelib_controller_reset_irq_counter(ide);
124 idelib_controller_write_command(ide,0x90); /* <- (90h) EXECUTE DEVICE DIAGNOSTIC */
125 if (ide->flags.io_irq_enable) {
126 do_ide_controller_user_wait_irq(ide,1);
127 idelib_controller_ack_irq(ide); /* <- or else it won't fire again */
129 do_ide_controller_user_wait_busy_controller(ide);
130 do_ide_controller_user_wait_drive_ready(ide);
131 if (ide->last_status&1) return 1;
135 void do_ident_save(const char *basename,struct ide_controller *ide,unsigned char which,uint16_t *nfo/*512 bytes/256 words*/,unsigned char command) {
136 unsigned char range[512];
141 /* also record how the drive records SET MULTIPLE MODE */
143 vga_write("Scanning SET MULTIPLE MODE supported values\n");
144 for (r=0;r < 256;r++) {
145 /* set sector count, then use IDENTIFY DEVICE to read back the value */
146 if (do_ide_set_multiple_mode(ide,which,r) < 0)
148 if (do_ide_identify((unsigned char*)nfo,512,ide,which,command) < 0)
150 range[r] = nfo[59]&0xFF;
152 /* then set it back to "1" */
153 if (do_ide_set_multiple_mode(ide,which,1) < 0)
155 if (do_ide_identify((unsigned char*)nfo,512,ide,which,command) < 0)
157 range[r+256] = nfo[59]&0xFF;
163 /* restore the original value */
164 if (do_ide_set_multiple_mode(ide,which,orgl) < 0)
166 if (do_ide_identify((unsigned char*)nfo,512,ide,which,command) < 0)
169 /* we might be running off the IDE drive we're about to write to.
170 * so to avoid hangups in INT 13h and DOS we need to temporarily unhook the IRQ and
171 * reenable the IRQ for the BIOS */
172 do_ide_controller_enable_irq(ide,0);
173 idelib_enable_interrupt(ide,1); /* <- in case of stupid/lazy BIOS */
175 /* if SMARTDRV is resident, now is a good time to write to disk */
176 if (smartdrv_version != 0) {
177 for (r=0;r < 4;r++) smartdrv_flush();
180 /* OK. start writing */
181 sprintf(fname,"%s.ID",basename);
182 fd = open(fname,O_WRONLY|O_BINARY|O_CREAT|O_TRUNC,0666);
188 sprintf(fname,"%s.SMM",basename);
189 fd = open(fname,O_WRONLY|O_BINARY|O_CREAT|O_TRUNC,0666);
195 /* if SMARTDRV is resident, flush our snapshot to disk because we're going
196 * to take over the IDE controller again */
197 if (smartdrv_version != 0) {
198 for (r=0;r < 4;r++) smartdrv_flush();
201 /* OK. hook it again. */
202 do_ide_controller_enable_irq(ide,ide->flags.io_irq_enable);
205 void do_drive_identify_device_test(struct ide_controller *ide,unsigned char which,unsigned char command) {
210 r = do_ide_identify((unsigned char*)info,sizeof(info),ide,which,command);
212 /* ------------ PAGE 1 -------------*/
213 vga_write_color(0x0E); vga_clear();
215 vga_moveto(0,0); vga_write("Serial: ");
216 for (x=0;x < 10;x++) {
217 tmp[x*2 + 0] = info[10+x] >> 8;
218 tmp[x*2 + 1] = info[10+x] & 0xFF;
220 tmp[10*2] = 0; vga_write(tmp);
222 vga_write(" F/W rev: ");
223 for (x=0;x < 4;x++) {
224 tmp[x*2 + 0] = info[23+x] >> 8;
225 tmp[x*2 + 1] = info[23+x] & 0xFF;
227 tmp[4*2] = 0; vga_write(tmp);
229 vga_write(" Model: ");
230 for (x=0;x < 20;x++) {
231 tmp[x*2 + 0] = info[27+x] >> 8;
232 tmp[x*2 + 1] = info[27+x] & 0xFF;
234 tmp[20*2] = 0; vga_write(tmp);
237 sprintf(tmp,"Logical C/H/S: %u/%u/%u ",info[1],info[3],info[6]);
239 sprintf(tmp,"Current C/H/S: %u/%u/%u", info[54],info[55],info[56]);
243 sprintf(tmp,"Current Capacity: %lu Total user addressable: %lu",
244 (unsigned long)info[57] | ((unsigned long)info[58] << 16UL),
245 (unsigned long)info[60] | ((unsigned long)info[61] << 16UL));
249 sprintf(tmp,"LBA48 capacity: %llu",
250 (unsigned long long)info[100] | ((unsigned long long)info[101] << 16ULL) | ((unsigned long long)info[102] << 32ULL) | ((unsigned long long)info[103] << 48ULL));
254 vga_write_color(0x0D);
255 vga_write("For more information read ATA documentation. ENTER to continue, 'S' to save.");
259 vga_write_color(0x08);
263 for (x=0;x < 8;x++) {
264 sprintf(tmp,"+%u ",x);
268 for (x=0;x < 8;x++) {
269 sprintf(tmp,"%u ",x);
272 vga_write("HI/LO byte order");
274 /* data, page by page */
275 for (i=0;i < 2;i++) {
276 for (y=0;y < 16;y++) {
278 vga_write_color(0x08);
279 for (x=0;x < 8;x++) {
280 sprintf(tmp,"%04x ",(y*8)+(i*128)+x);
285 vga_write_color(0x0F);
286 for (x=0;x < 8;x++) {
287 sprintf(tmp,"%04x ",info[(y*8)+(i*128)+x]);
292 vga_write_color(0x0E);
293 for (x=0;x < 8;x++) {
294 vga_writec(sanitizechar(info[(y*8)+(i*128)+x] >> 8));
295 vga_writec(sanitizechar(info[(y*8)+(i*128)+x] & 0xFF));
299 /* wait for ENTER, ESC, or 'S' */
302 if (r == 's' || r == 'S') {
303 vga_write_color(0x0E); vga_clear(); vga_moveto(0,0);
304 do_ident_save(command == 0xA1 ? "ATAPI" : "ATA",ide,which,info,command);
305 vga_write("\nSaved. Hit ENTER to continue.\n");
306 wait_for_enter_or_escape();
309 else if (r == 27 || r == 13) {
314 /* ESC or 'S' to break out */
315 if (r == 's' || r == 27)
320 struct vga_msg_box vgabox;
322 common_ide_success_or_error_vga_msg_box(ide,&vgabox);
323 wait_for_enter_or_escape();
324 vga_msg_box_destroy(&vgabox);