Palacios Public Git Repository

To checkout Palacios execute

  git clone http://v3vee.org/palacios/palacios.web/palacios.git
This will give you the master branch. You probably want the devel branch or one of the release branches. To switch to the devel branch, simply execute
  cd palacios
  git checkout --track -b devel origin/devel
The other branches are similar.


0892f8c2f90e0620c43d88694e3d986d44a376ec
[palacios.git] / palacios / src / devices / atapi.h
1 /* 
2  * This file is part of the Palacios Virtual Machine Monitor developed
3  * by the V3VEE Project with funding from the United States National 
4  * Science Foundation and the Department of Energy.  
5  *
6  * The V3VEE Project is a joint project between Northwestern University
7  * and the University of New Mexico.  You can find out more at 
8  * http://www.v3vee.org
9  *
10  * Copyright (c) 2008, Jack Lange <jarusl@cs.northwestern.edu> 
11  * Copyright (c) 2008, The V3VEE Project <http://www.v3vee.org> 
12  * All rights reserved.
13  *
14  * Author: Jack Lange <jarusl@cs.northwestern.edu>
15  *
16  * This is free software.  You are permitted to use,
17  * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
18  */
19
20 #define ATAPI_PACKET_SIZE 12
21
22 #include "atapi-types.h"
23
24
25 /* ATAPI sucks...
26  * The OS will write to the cylinder register the number of bytes it wants to read 
27  * however the device can change that value 
28  * 
29  */
30 static int atapi_update_req_len(struct ide_internal * ide, struct ide_channel * channel, uint_t xfer_len) {
31     struct ide_drive * drive = get_selected_drive(channel);
32
33     //PrintDebug("\tUpdating request length (pre=%d)\n", drive->req_len);
34
35     if (drive->req_len == 0) {
36         PrintError("ATAPI Error: request of length 0\n");
37         return -1;
38     }
39
40
41     channel->status.busy = 0;
42     channel->status.data_req = 1;
43     channel->status.error = 0;
44
45     drive->irq_flags.io_dir = 1;
46     drive->irq_flags.c_d = 0;
47
48     // make count even
49     if (drive->req_len % 2) {
50         drive->req_len -= 1;
51     }
52
53     // if the device can't return as much as the OS requested
54     // this is actually a decrement of the req_len by the amount requested by the OS
55     if (drive->req_len > xfer_len) {
56         drive->req_len = xfer_len;
57     }
58
59     //    PrintDebug("\tUpdating request length (post=%d)\n", drive->req_len);
60
61     return 0;
62 }
63
64
65
66 // This is for simple commands that don't need to sanity check the req_len
67 static void atapi_setup_cmd_resp(struct ide_internal * ide, struct ide_channel * channel, uint_t xfer_len) {
68     struct ide_drive * drive = get_selected_drive(channel);
69
70     drive->transfer_length = xfer_len;
71     drive->transfer_index = 0;
72     drive->req_len = drive->transfer_length;
73
74     drive->irq_flags.io_dir = 1;
75     drive->irq_flags.c_d = 0;
76
77     channel->status.busy = 0;
78     channel->status.data_req = 1;
79     channel->status.error = 0;
80
81     ide_raise_irq(ide, channel);
82 }
83
84 static void atapi_cmd_error(struct ide_internal * ide, struct ide_channel * channel, 
85                      atapi_sense_key_t  sense_key, atapi_add_sense_code_t asc) {
86     struct ide_drive * drive = get_selected_drive(channel);
87
88     // overload error register with ATAPI value
89     channel->error_reg.val = sense_key << 4;
90     
91     channel->status.busy = 0;
92     channel->status.ready = 1;
93     channel->status.write_fault = 0;
94     channel->status.data_req = 0;
95     channel->status.error = 1;
96   
97     drive->cd_state.sense.header = 0xf0;
98     drive->cd_state.sense.rsvd1 = 0x00;
99     drive->cd_state.sense.read_len = 0x0a;
100     drive->cd_state.sense.sense_key = sense_key;
101     drive->cd_state.sense.asc = asc;
102
103
104     drive->irq_flags.io_dir = 1;
105     drive->irq_flags.c_d = 1;
106     drive->irq_flags.rel = 0;
107
108     ide_raise_irq(ide, channel);
109 }
110
111
112 static void atapi_cmd_nop(struct ide_internal * ide, struct ide_channel * channel) {
113     struct ide_drive * drive = get_selected_drive(channel);
114
115     channel->status.busy = 0;
116     channel->status.ready = 1;
117     channel->status.data_req = 0;
118     channel->status.error = 0;
119
120     drive->irq_flags.io_dir = 1;
121     drive->irq_flags.c_d = 1;
122     drive->irq_flags.rel = 0;
123
124     ide_raise_irq(ide, channel);
125 }
126
127
128
129 static int atapi_read_chunk(struct ide_internal * ide, struct ide_channel * channel) {
130     struct ide_drive * drive = get_selected_drive(channel);
131
132     int ret = drive->ops->read(drive->data_buf, drive->current_lba * ATAPI_BLOCK_SIZE, ATAPI_BLOCK_SIZE, 
133 drive->private_data);
134     
135     if (ret == -1) {
136         PrintError("IDE: Error reading CD block (LBA=%p)\n", (void *)(addr_t)(drive->current_lba));
137         return -1;
138     }
139
140     return 0;
141 }
142
143
144 static int atapi_update_data_buf(struct ide_internal * ide, struct ide_channel * channel) {
145     struct ide_drive * drive = get_selected_drive(channel);    
146     
147     switch (drive->cd_state.atapi_cmd) {
148         case 0x28: // read(10)
149         case 0xa8: // read(12)
150
151             // Update lba address to point to next block  
152             drive->current_lba++;
153
154             // read the next block
155             return atapi_read_chunk(ide, channel);
156
157         default:
158             PrintError("Unhandled ATAPI command in update buffer %x\n", drive->cd_state.atapi_cmd);
159             return -1;
160     }
161
162     return 0;
163 }
164
165 static int atapi_read10(struct guest_info * core, 
166                         struct ide_internal * ide,
167                         struct ide_channel * channel) {
168     struct ide_drive * drive = get_selected_drive(channel);
169     struct atapi_read10_cmd * cmd = (struct atapi_read10_cmd *)(drive->data_buf);
170     uint32_t lba =  be_to_le_32(cmd->lba);
171     uint16_t xfer_len = be_to_le_16(cmd->xfer_len);
172
173     PrintDebug("READ10: XferLen=%d ; LBA=%x \n", xfer_len, lba );
174
175     /* Check if cd is ready
176      * if not: atapi_cmd_error(... ATAPI_SEN_NOT_RDY, ASC_MEDIA_NOT_PRESENT)
177      */
178     
179     if (xfer_len == 0) {
180         atapi_cmd_nop(ide, channel);
181         return 0;
182     }
183     
184     if (lba + xfer_len > drive->ops->get_capacity(drive->private_data)) {
185         PrintError("IDE: xfer len exceeded capacity (lba=%d) (xfer_len=%d) (ReadEnd=%d) (capacity=%d)\n", 
186                    lba, xfer_len, lba + xfer_len, 
187                    (uint32_t)drive->ops->get_capacity(drive->private_data));
188         atapi_cmd_error(ide, channel, ATAPI_SEN_ILL_REQ, ASC_LOG_BLK_OOR);
189         ide_raise_irq(ide, channel);
190         return 0;
191     }
192         
193     //    PrintDebug("Reading %d blocks from LBA 0x%x\n", xfer_len, lba);
194     
195     drive->current_lba = lba;
196         
197     // Update the request length value in the cylinder registers
198     drive->transfer_length = xfer_len * ATAPI_BLOCK_SIZE;
199     drive->transfer_index = 0;  
200
201     if (channel->features.dma) {
202
203         if (channel->dma_status.active == 1) {
204             if (dma_read(core, ide, channel) == -1) {
205                 PrintError("Error in DMA read for CD Read10 command\n");
206                 return -1;
207             }
208         }
209         return 0;
210     }
211
212     if (atapi_read_chunk(ide, channel) == -1) {
213         PrintError("IDE: Could not read initial chunk from CD\n");
214         return -1;
215     }
216         
217     // Length of ATAPI buffer sits in cylinder registers
218     // This is weird... The host sets this value to say what it would like to transfer, 
219     // if it is larger than the correct size, the device shrinks it to the correct size
220     if (atapi_update_req_len(ide, channel, ATAPI_BLOCK_SIZE) == -1) {
221         PrintError("Could not update initial request length\n");
222         return -1;
223     }
224     
225     ide_raise_irq(ide, channel);
226
227     return 0;
228 }
229
230
231
232 static void atapi_req_sense(struct ide_internal * ide, struct ide_channel * channel) {
233     struct ide_drive * drive = get_selected_drive(channel);
234
235     memcpy(drive->data_buf, drive->cd_state.sense.buf, sizeof(drive->cd_state.sense.buf));
236    
237     atapi_setup_cmd_resp(ide, channel, 18);
238 }
239
240
241
242 static int atapi_get_capacity(struct ide_internal * ide, struct ide_channel * channel) {
243     struct ide_drive * drive = get_selected_drive(channel);
244     struct atapi_rd_capacity_resp * resp = (struct atapi_rd_capacity_resp *)(drive->data_buf);
245     uint32_t capacity = drive->ops->get_capacity(drive->private_data);
246
247     resp->lba = le_to_be_32(capacity);
248     resp->block_len = le_to_be_32(ATAPI_BLOCK_SIZE);
249
250     atapi_setup_cmd_resp(ide, channel, sizeof(struct atapi_rd_capacity_resp));
251
252     return 0;
253 }
254
255 static int atapi_get_config(struct ide_internal * ide, struct ide_channel * channel) {
256     struct ide_drive * drive = get_selected_drive(channel);
257     struct atapi_config_cmd * cmd = (struct atapi_config_cmd *)(drive->data_buf);
258     uint16_t alloc_len = be_to_le_16(cmd->alloc_len);
259     struct atapi_config_resp * resp = (struct atapi_config_resp *)(drive->data_buf);
260     int xfer_len = 8;
261
262     memset(resp, 0, sizeof(struct atapi_config_resp));
263
264     resp->data_len = le_to_be_32(xfer_len - 4);
265
266     if (alloc_len < xfer_len) {
267         xfer_len = alloc_len;
268     }
269     
270     atapi_setup_cmd_resp(ide, channel, xfer_len);
271     
272     return 0;
273 }
274
275
276 static int atapi_read_toc(struct ide_internal * ide, struct ide_channel * channel) {
277     struct ide_drive * drive = get_selected_drive(channel);
278     struct atapi_rd_toc_cmd * cmd = (struct atapi_rd_toc_cmd *)(drive->data_buf);
279     uint16_t alloc_len = be_to_le_16(cmd->alloc_len);
280     struct atapi_rd_toc_resp * resp = (struct atapi_rd_toc_resp *)(drive->data_buf);
281
282     int xfer_len = 12;
283
284     memset(resp, 0, sizeof(struct atapi_rd_toc_resp));
285     
286     resp->data_len = le_to_be_16(10);
287     resp->first_track_num = 1;
288     resp->last_track_num = 1;
289
290     // we don't handle multi session
291     // we'll just treat it the same as single session
292     if ((cmd->format == 0) || (cmd->format == 1)) {
293         memset(&(resp->track_descs[0]), 0, 8);
294         
295         if (alloc_len < xfer_len) {
296             xfer_len = alloc_len;
297         }
298
299         atapi_setup_cmd_resp(ide, channel, xfer_len);
300     } else {
301         PrintError("Unhandled Format (%d)\n", cmd->format);
302         return -1;
303     }
304
305     return 0;
306 }
307
308
309 static int atapi_mode_sense_cur_values(struct ide_internal * ide, struct ide_channel * channel, 
310                                        struct atapi_mode_sense_cmd * sense_cmd) {
311     struct ide_drive * drive = get_selected_drive(channel);
312     struct atapi_mode_sense_hdr * hdr = (struct atapi_mode_sense_hdr *)(drive->data_buf);
313     uint_t resp_len = sizeof(struct atapi_mode_sense_hdr);
314     uint16_t alloc_len = be_to_le_16(sense_cmd->alloc_len);
315     PrintDebug("Page Code: %x\n", sense_cmd->page_code);
316     PrintDebug("Alloc len: %d\n", alloc_len);
317
318     switch (sense_cmd->page_code) {
319
320         case 0x01: {    // error recovery
321             struct atapi_error_recovery * err = NULL;
322             err = (struct atapi_error_recovery *)(drive->data_buf + 
323                                                   sizeof(struct atapi_mode_sense_hdr));
324
325
326             memcpy(err, &(drive->cd_state.err_recovery), sizeof(struct atapi_error_recovery));
327
328             resp_len += sizeof(struct atapi_error_recovery);
329
330             PrintError("mode sense (error recovery) resp_len=%d\n", resp_len);
331
332
333             hdr->mode_data_len = le_to_be_16(resp_len - 2);
334             
335             break;
336         }
337         case 0x2a: { // CDROM caps and mech. status
338
339             uint8_t * buf = drive->data_buf;
340
341
342
343             PrintError("mode sense (caps/mechs v2) resp_len=%d\n", resp_len);
344
345             *((uint16_t *)buf) = le_to_be_16(28 + 6);
346             buf[2] = 0x70;
347             buf[3] = 0;
348             buf[4] = 0;
349             buf[5] = 0;
350             buf[6] = 0;
351             buf[7] = 0;
352
353             buf[8] = 0x2a;
354             buf[9] = 0x12;
355             buf[10] = 0x00;
356             buf[11] = 0x00;
357
358             /* Claim PLAY_AUDIO capability (0x01) since some Linux
359                code checks for this to automount media. */
360             buf[12] = 0x71;
361             buf[13] = 3 << 5;
362             buf[14] = (1 << 0) | (1 << 3) | (1 << 5);
363
364             buf[6] |= 1 << 1;
365             buf[15] = 0x00;
366             *((uint16_t *)&(buf[16])) = le_to_be_16(706);
367             buf[18] = 0;
368             buf[19] = 2;
369             *((uint16_t *)&(buf[20])) = le_to_be_16(512);
370             *((uint16_t *)&(buf[22])) = le_to_be_16(706);
371             buf[24] = 0;
372             buf[25] = 0;
373             buf[26] = 0;
374             buf[27] = 0;
375
376             resp_len = 28;
377
378 #if 0
379             struct atapi_cdrom_caps * caps = NULL;
380             caps = (struct atapi_cdrom_caps *)(drive->data_buf + sizeof(struct atapi_mode_sense_hdr));
381             
382
383
384
385             memset(caps, 0, sizeof(struct atapi_cdrom_caps));
386
387             resp_len += sizeof(struct atapi_cdrom_caps);
388
389             hdr->mode_data_len = le_to_be_16(resp_len - 2);
390
391
392             PrintError("mode sense (caps/mechs v2) resp_len=%d\n", resp_len);
393
394             caps->page_code = 0x2a;
395             caps->page_len = 0x12;
396             caps->mode2_form1 = 1;
397             caps->mode2_form2 = 1;
398             caps->multisession = 1;
399             caps->isrc = 1;
400             caps->upc = 1;
401
402             /* JRL TODO: These are dynamic caps */
403             caps->lock = 1;
404             caps->lock_state = 0;
405             caps->eject = 1;
406
407             caps->lmt = 1;
408             caps->obsolete1 = le_to_be_16(0x2c2);
409             caps->num_vols_supp = le_to_be_16(2);
410
411             caps->lun_buf_size = le_to_be_16(512);
412             caps->obsolete2 = le_to_be_16(0x2c2);
413
414 #endif
415
416             break;
417         }
418         case 0x0d:
419         case 0x0e:
420         case 0x3f:
421         default:
422             PrintError("ATAPI: Mode sense Page Code not supported (%x)\n", sense_cmd->page_code);
423             atapi_cmd_error(ide, channel, ATAPI_SEN_ILL_REQ, ASC_INV_CMD_FIELD);
424             ide_raise_irq(ide, channel);
425             return 0;
426     }
427
428
429     // We do this after error checking, because its only valid if everything worked
430     //    memset(hdr, 0, sizeof(struct atapi_mode_sense_hdr));
431     // hdr->media_type_code = 0x70;
432
433     PrintDebug("resp_len=%d\n", resp_len);
434
435     drive->transfer_length = (resp_len > alloc_len) ? alloc_len : resp_len;
436     drive->transfer_index = 0;
437     atapi_update_req_len(ide, channel, drive->transfer_length);
438
439     ide_raise_irq(ide, channel);
440
441     return 0;
442 }
443
444
445 static int atapi_mode_sense(struct ide_internal * ide, struct ide_channel * channel) {
446     struct ide_drive * drive = get_selected_drive(channel);
447     struct atapi_mode_sense_cmd * sense_cmd = (struct atapi_mode_sense_cmd *)(drive->data_buf);
448
449     switch (sense_cmd->page_ctrl) {
450         case 0x00: // Current values
451             return atapi_mode_sense_cur_values(ide, channel, sense_cmd);
452         case 0x01: // Changeable values
453         case 0x02: // default values
454         case 0x03: // saved values
455         default:
456             PrintError("ATAPI: Mode sense mode not supported (%x)\n", sense_cmd->page_ctrl);
457             return -1;
458     }
459     return 0;
460 }
461
462
463
464 static int atapi_inquiry(struct ide_internal * ide, struct ide_channel * channel) {
465     struct ide_drive * drive = get_selected_drive(channel);
466     struct atapi_inquiry_cmd * inquiry_cmd = (struct atapi_inquiry_cmd *)(drive->data_buf);
467     uint16_t alloc_len = be_to_le_16(inquiry_cmd->alloc_len);
468     struct atapi_inquiry_resp * resp = (struct atapi_inquiry_resp *)(drive->data_buf);
469     int xfer_len = sizeof(struct atapi_inquiry_resp);
470     const char * vendor_id = "VTAB    ";
471     const char * product_id = "Turbo CD-ROM    ";
472     const char * product_rev = "1.0 ";
473
474     memset(resp, 0, sizeof(struct atapi_inquiry_resp));
475     
476     resp->dev_type = DEV_TYPE_CDROM;
477     resp->removable_media = 1;
478     resp->resp_data_fmt = 0x1;
479     resp->atapi_trans_ver = 0x2;
480     resp->additional_len = 31;
481
482     memcpy(resp->t10_vendor_id, vendor_id, strlen(vendor_id));
483     memcpy(resp->product_id, product_id, strlen(product_id));
484     memcpy(resp->product_rev, product_rev, strlen(product_rev));
485     
486     if (alloc_len < xfer_len) {
487         xfer_len = alloc_len;
488     }
489
490     atapi_setup_cmd_resp(ide, channel, xfer_len);
491
492     return 0;
493 }
494
495
496 static int atapi_mech_status(struct ide_internal * ide, struct ide_channel * channel) {
497     struct ide_drive * drive = get_selected_drive(channel);
498     struct atapi_mech_status_cmd * status_cmd = (struct atapi_mech_status_cmd *)(drive->data_buf);
499     uint16_t alloc_len = be_to_le_16(status_cmd->alloc_len);
500     struct atapi_mech_status_resp * resp = (struct atapi_mech_status_resp *)(drive->data_buf);
501     int xfer_len = sizeof(struct atapi_mech_status_resp);
502
503     memset(resp, 0, sizeof(struct atapi_mech_status_resp));
504
505     resp->lba = le_to_be_32(1);
506     resp->slot_table_len = le_to_be_16(0);
507     
508     if (alloc_len < xfer_len) {
509         xfer_len = alloc_len;
510     }
511
512     atapi_setup_cmd_resp(ide, channel, xfer_len);
513
514     return 0;
515 }
516
517
518 static int atapi_cmd_is_data_op(uint8_t cmd) {
519     switch (cmd) {
520         case 0x28: // read (10)
521         case 0xa8: // read (12)
522         case 0x2a: // write (10)
523         case 0xaa: // write (12)
524             return 1;
525         default:
526             return 0;
527     } 
528 }
529
530
531 static int atapi_handle_packet(struct guest_info * core, struct ide_internal * ide, struct ide_channel * channel) {
532    struct ide_drive * drive = get_selected_drive(channel);
533    uint8_t cmd = drive->data_buf[0];
534
535    PrintDebug("IDE: ATAPI Command %x\n", cmd);
536
537    drive->cd_state.atapi_cmd = cmd;
538
539    switch (cmd) {
540        case 0x00: // test unit ready
541            atapi_cmd_nop(ide, channel);
542
543            /* if drive not ready: 
544               atapi_cmd_error(... ATAPI_SEN_NOT_RDY, ASC_MEDIA_NOT_PRESENT)
545            */
546            break;
547        case 0x03: // request sense
548            PrintError("IDE: Requesting Sense (0x3)\n");
549            atapi_req_sense(ide, channel);
550            break;
551
552        case 0x1e: // lock door
553            atapi_cmd_nop(ide, channel);
554            break;
555
556        case 0x28: // read(10)
557            if (atapi_read10(core, ide, channel) == -1) {
558                PrintError("IDE: Error in ATAPI read (%x)\n", cmd);
559                return -1;
560            }
561            break;
562
563        case 0x5a: // mode sense
564            if (atapi_mode_sense(ide, channel) == -1) {
565                PrintError("IDE: Error in ATAPI mode sense (%x)\n", cmd);
566                return -1;
567            }
568            break;
569
570
571        case 0x25: // read cdrom capacity
572            if (atapi_get_capacity(ide, channel) == -1) {
573                PrintError("IDE: Error getting CDROM capacity (%x)\n", cmd);
574                return -1;
575            }
576            break;
577
578
579        case 0x43: // read TOC
580            if (atapi_read_toc(ide, channel) == -1) {
581                PrintError("IDE: Error getting CDROM TOC (%x)\n", cmd);
582                return -1;
583            }
584            break;
585
586        case 0x46: // get configuration
587            if (atapi_get_config(ide, channel) == -1) {
588                PrintError("IDE: Error getting CDROM Configuration (%x)\n", cmd);
589                return -1;
590            }
591            break;
592
593
594        case 0x4a: // Get Status/event
595        case 0x51: // read disk info
596            // no-op to keep the Linux CD-ROM driver happy
597            PrintDebug("Error: Read disk info no-op to keep the Linux CD-ROM driver happy\n");
598            atapi_cmd_error(ide, channel, ATAPI_SEN_ILL_REQ, ASC_INV_CMD_FIELD);
599            ide_raise_irq(ide, channel);
600            break;
601
602        case 0x12: // inquiry
603            if (atapi_inquiry(ide, channel) == -1) {
604                PrintError("IDE: Error in ATAPI inquiry (%x)\n", cmd);
605                return -1;
606            }
607            break;
608
609        case 0xbd: // mechanism status 
610            if (atapi_mech_status(ide, channel) == -1) {
611                PrintError("IDE: error in ATAPI Mechanism status query (%x)\n", cmd);
612                return -1;
613            }
614            break;
615
616
617        case 0xa8: // read(12)
618
619
620        case 0x1b: // start/stop drive
621
622        case 0xbe: // read cd
623
624
625
626        case 0x2b: // seek
627
628        case 0x42: // read sub-channel
629
630
631            
632        case 0x55: // mode select
633        case 0xa6: // load/unload cd
634        case 0x4b: // pause/resume
635        case 0x45: // play audio
636        case 0x47: // play audio msf
637        case 0xbc: // play cd
638        case 0xb9: // read cd msf
639        case 0x44: // read header
640        case 0xba: // scan
641        case 0xbb: // set cd speed
642        case 0x4e: // stop play/scan
643
644        default:
645            PrintError("Unhandled ATAPI command %x\n", cmd);
646            atapi_cmd_error(ide, channel, ATAPI_SEN_ILL_REQ, ASC_INV_CMD_FIELD);
647            ide_raise_irq(ide, channel);
648            return -1;
649    }
650    
651    return 0;
652 }
653
654
655 static void atapi_identify_device(struct ide_drive * drive) {
656     struct ide_drive_id * drive_id = (struct ide_drive_id *)(drive->data_buf);
657     const char* serial_number = " VT00001\0\0\0\0\0\0\0\0\0\0\0\0";
658     const char* firmware = "ALPHA1  ";
659
660     drive->transfer_length = 512;
661     drive->transfer_index = 0;
662
663
664     memset(drive_id->buf, 0, sizeof(drive_id->buf));
665
666     drive_id->fixed_drive = 1;
667     drive_id->removable_media = 1;
668
669     // Black magic...
670     drive_id->disk_speed1 = 1;
671     drive_id->disk_speed3 = 1;
672
673     drive_id->cdrom_flag = 1;
674
675     // These buffers do not contain a terminating "\0"
676     memcpy(drive_id->serial_num, serial_number, strlen(serial_number));
677     memcpy(drive_id->firmware_rev, firmware, strlen(firmware));
678     memcpy(drive_id->model_num, drive->model, 40);
679
680     // 32 bits access
681     drive_id->dword_io = 1;
682
683     // enable DMA access
684     /* Disabled until command packet DMA is fixed */
685     drive_id->dma_enable = 1;
686
687     // enable LBA access
688     drive_id->lba_enable = 1;
689     
690     drive_id->rw_multiples = 0x80ff;
691
692     // words 64-70, 54-58 valid
693     /* Disabled until command packet DMA is fixed */
694         drive_id->field_valid = 0x0007; // DMA + pkg cmd valid
695
696     // copied from CFA540A
697     /* Disabled until command packet DMA is fixed */
698      drive_id->buf[63] = 0x0103; // variable (DMA stuff)
699        
700
701     /* uncommented to disable dma(?) */
702      // drive_id->buf[64] = 0x0001; // PIO
703
704
705     drive_id->buf[65] = 0x00b4;
706     drive_id->buf[66] = 0x00b4;
707     drive_id->buf[67] = 0x012c;
708     drive_id->buf[68] = 0x00b4;
709
710     drive_id->buf[71] = 30; // faked
711     drive_id->buf[72] = 30; // faked
712
713     //    drive_id->buf[80] = 0x1e; // supports up to ATA/ATAPI-4
714     drive_id->major_rev_num = 0x0040; // supports up to ATA/ATAPI-6
715
716     /* Disabled until command packet DMA is fixed */
717     drive_id->dma_ultra = 0x2020; // Ultra_DMA_Mode_5_Selected | Ultra_DMA_Mode_5_Supported;
718 }