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.


added atapi identify and command port handler
[palacios.git] / palacios / src / devices / ramdisk.c
1 /* 
2  *
3  *   Copyright (C) 2002  MandrakeSoft S.A.
4  *
5  *     MandrakeSoft S.A.
6  *     43, rue d'Aboukir
7  *     75002 Paris - France
8  *     http://www.linux-mandrake.com/
9  *     http://www.mandrakesoft.com/
10  *
11  *   This library is free software; you can redistribute it and/or
12  *   modify it under the terms of the GNU Lesser General Public
13  *   License as published by the Free Software Foundation; either
14  *   version 2 of the License, or (at your option) any later version.
15  *
16  *   This library is distributed in the hope that it will be useful,
17  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
18  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
19  *   Lesser General Public License for more details.
20  *
21  *  You should have received a copy of the GNU Lesser General Public
22  *  License along with this library; if not, write to the Free Software
23  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
24  *
25  * Major modifications made for the V3VEE project
26  * 
27  * The V3VEE Project is a joint project between Northwestern University
28  * and the University of New Mexico.  You can find out more at 
29  * http://www.v3vee.org
30  * 
31  * Copyright (c) 2008, Zheng Cui <cuizheng@cs.unm.edu>
32  * Copyright (c) 2008, Jack Lange <jarusl@cs.northwestern.edu>
33  * Copyright (c) 2008, The V3VEE Project <http://www.v3vee.org> 
34  * All rights reserved for original changes
35  * 
36  */
37
38
39 #include <devices/ramdisk.h>
40 #include <palacios/vmm.h>
41 #include <devices/cdrom.h>
42 #include <devices/ide.h>
43 #include <devices/pci.h>
44
45 #ifndef TRACE_RAMDISK
46 #undef PrintTrace
47 #define PrintTrace(fmt, args...)
48 #endif
49
50
51 #ifndef DEBUG_RAMDISK
52 #undef PrintDebug
53 #define PrintDebug(fmt, args...)
54 #endif
55
56
57
58
59
60 /*
61  * Data type definitions
62  *
63  */
64 #define INDEX_PULSE_CYCLE 10
65
66
67
68
69 #define INTR_REASON_BIT_ERR           0x01
70 #define UNABLE_FIND_TAT_CHANNEL_ERR   0x02
71 #define DRQ_ERR                       0x03
72 #define READ_BUF_GT_512               0x04
73
74
75
76 #define PRI_DATA_PORT         0x1f0
77 #define PRI_FEATURES_PORT     0x1f1
78 #define PRI_SECT_CNT_PORT     0x1f2
79 #define PRI_SECT_ADDR1_PORT   0x1f3
80 #define PRI_SECT_ADDR2_PORT   0x1f4
81 #define PRI_SECT_ADDR3_PORT   0x1f5
82 #define PRI_DRV_SEL_PORT      0x1f6
83 #define PRI_CMD_PORT          0x1f7
84 #define PRI_CTRL_PORT         0x3f6
85 #define PRI_ADDR_REG_PORT     0x3f7
86
87 #define SEC_DATA_PORT         0x170
88 #define SEC_FEATURES_PORT     0x171
89 #define SEC_SECT_CNT_PORT     0x172
90 #define SEC_SECT_ADDR1_PORT   0x173
91 #define SEC_SECT_ADDR2_PORT   0x174
92 #define SEC_SECT_ADDR3_PORT   0x175
93 #define SEC_DRV_SEL_PORT      0x176
94 #define SEC_CMD_PORT          0x177
95 #define SEC_CTRL_PORT         0x376
96 #define SEC_ADDR_REG_PORT     0x377
97
98
99 #define PACKET_SIZE 12
100
101
102
103 static const char cdrom_str[] = "CD-ROM";
104 static const char harddisk_str[] = "HARDDISK";
105 static const char none_str[] = "NONE";
106
107
108 static inline const char * device_type_to_str(device_type_t type) {
109     switch (type) {
110         case IDE_DISK:
111             return harddisk_str;
112         case IDE_CDROM:
113             return cdrom_str;
114         case IDE_NONE:
115             return none_str;
116         default:
117             return NULL;
118     }
119 }
120
121
122 static inline void write_features(struct channel_t * channel, uchar_t value) {
123     channel->drives[0].controller.features = value;
124     channel->drives[1].controller.features = value;
125 }
126
127
128 static inline void write_sector_count(struct channel_t * channel, uchar_t value) {
129     channel->drives[0].controller.sector_count = value;
130     channel->drives[1].controller.sector_count = value;
131 }
132
133 static inline void write_sector_number(struct channel_t * channel, uchar_t value) {
134     channel->drives[0].controller.sector_no = value;
135     channel->drives[1].controller.sector_no = value;
136 }
137
138
139 static inline void write_cylinder_low(struct channel_t * channel, uchar_t value) {
140     channel->drives[0].controller.cylinder_no &= 0xff00;
141     channel->drives[0].controller.cylinder_no |= value;
142     channel->drives[1].controller.cylinder_no &= 0xff00;
143     channel->drives[1].controller.cylinder_no |= value;
144 }
145
146 static inline void write_cylinder_high(struct channel_t * channel, uchar_t value) {
147     ushort_t val2 = value;
148     val2 = val2 << 8;
149     channel->drives[0].controller.cylinder_no &= 0x00ff;
150     channel->drives[0].controller.cylinder_no |= (val2 & 0xff00);
151
152     channel->drives[1].controller.cylinder_no &= 0x00ff;
153     channel->drives[1].controller.cylinder_no |= (val2 & 0xff00);
154 }
155
156 static inline void write_head_no(struct channel_t * channel, uchar_t value) {
157     channel->drives[0].controller.head_no = value;
158     channel->drives[1].controller.head_no = value;
159 }
160
161 static inline void write_lba_mode(struct channel_t * channel, uchar_t value) {
162     channel->drives[0].controller.lba_mode = value;
163     channel->drives[1].controller.lba_mode = value;
164 }
165
166
167 static inline uint_t get_channel_no(struct ramdisk_t * ramdisk, struct channel_t * channel) {
168     return (((uchar_t *)channel - (uchar_t *)(ramdisk->channels)) / sizeof(struct channel_t));
169 }
170
171 static inline uint_t get_drive_no(struct channel_t * channel, struct drive_t * drive) {
172     return (((uchar_t *)drive - (uchar_t*)(channel->drives)) /  sizeof(struct drive_t));
173 }
174
175 static inline struct drive_t * get_selected_drive(struct channel_t * channel) {
176     return &(channel->drives[channel->drive_select]);
177 }
178
179
180 static inline int is_primary_port(struct ramdisk_t * ramdisk, ushort_t port) {
181     switch(port) 
182         {
183             case PRI_DATA_PORT:
184             case PRI_FEATURES_PORT:
185             case PRI_SECT_CNT_PORT:
186             case PRI_SECT_ADDR1_PORT:
187             case PRI_SECT_ADDR2_PORT:
188             case PRI_SECT_ADDR3_PORT:
189             case PRI_DRV_SEL_PORT:
190             case PRI_CMD_PORT:
191             case PRI_CTRL_PORT:
192                 return 1;
193             default:
194                 return 0;
195         }
196 }
197
198
199
200 static inline int is_secondary_port(struct ramdisk_t * ramdisk, ushort_t port) {
201     switch(port) 
202         {
203             case SEC_DATA_PORT:
204             case SEC_FEATURES_PORT:
205             case SEC_SECT_CNT_PORT:
206             case SEC_SECT_ADDR1_PORT:
207             case SEC_SECT_ADDR2_PORT:
208             case SEC_SECT_ADDR3_PORT:
209             case SEC_DRV_SEL_PORT:
210             case SEC_CMD_PORT:
211             case SEC_CTRL_PORT:
212                 return 1;
213             default:
214                 return 0;
215         }
216 }
217
218 static inline int num_drives_on_channel(struct channel_t * channel) {
219     if ((channel->drives[0].device_type == IDE_NONE) &&
220         (channel->drives[1].device_type == IDE_NONE)) {
221         return 0;
222     } else if ((channel->drives[0].device_type != IDE_NONE) &&
223                (channel->drives[1].device_type != IDE_NONE)) {
224         return 2;
225     } else {
226         return 1;
227     }
228 }
229
230
231
232 static inline uchar_t extract_bits(uchar_t * buf, uint_t buf_offset, uint_t bit_offset, uint_t num_bits) {
233     uchar_t val = buf[buf_offset];
234     val = val >> bit_offset;
235     val &= ((1 << num_bits) -1);
236     return val;
237 }
238
239
240 static inline uchar_t get_packet_field(struct channel_t * channel, uint_t packet_offset, uint_t bit_offset, uint_t num_bits) {
241     struct drive_t * drive = get_selected_drive(channel);
242     return extract_bits(drive->controller.buffer, packet_offset, bit_offset, num_bits);
243 }
244
245
246 static inline uchar_t get_packet_byte(struct channel_t * channel, uint_t offset) {
247     struct drive_t * drive = get_selected_drive(channel);
248     return drive->controller.buffer[offset];
249 }
250
251 static inline uint16_t get_packet_word(struct channel_t * channel, uint_t offset) {
252     struct drive_t * drive = get_selected_drive(channel);
253     uint16_t val = drive->controller.buffer[offset];
254     val = val << 8;
255     val |= drive->controller.buffer[offset + 1];
256     return val;
257 }
258
259
260 static inline uint16_t rd_read_16bit(const uint8_t* buf) {
261     return (buf[0] << 8) | buf[1];
262 }
263
264
265
266 static inline uint32_t rd_read_32bit(const uint8_t* buf) {
267     return (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | buf[3];
268 }
269
270 ////////////////////////////////////////////////////////////////////////////
271
272
273 /*
274  * ATAPI routines
275  */
276
277
278 static void rd_init_mode_sense_single(struct vm_device * dev, struct channel_t * channel, const void * src, int size);
279
280 static void rd_command_aborted(struct vm_device * dev, struct channel_t * channel, unsigned value);
281
282
283
284
285 static int handle_atapi_packet_command(struct vm_device * dev, 
286                                        struct channel_t * channel, 
287                                        ushort_t val);
288
289 static int rd_init_send_atapi_command(struct vm_device * dev, 
290                                       struct channel_t * channel, 
291                                       Bit8u command, int req_length, 
292                                       int alloc_length, bool lazy);
293
294 static void rd_ready_to_send_atapi(struct vm_device * dev, 
295                                    struct channel_t * channel);
296
297 static void rd_atapi_cmd_error(struct vm_device * dev, 
298                                struct channel_t * channel, 
299                                sense_t sense_key, asc_t asc);
300
301 static void rd_atapi_cmd_nop(struct vm_device * dev, struct channel_t * channel);
302 static void rd_identify_ATAPI_drive(struct vm_device * dev, struct channel_t * channel);
303
304
305
306 /*
307  * Interrupt handling
308  */
309 static void rd_raise_interrupt(struct vm_device * dev, struct channel_t * channel);
310 static void rd_lower_irq(struct vm_device *dev, struct channel_t * channel);
311
312
313
314 /*
315  * Helper routines
316  */
317
318
319
320 #ifdef DEBUG_RAMDISK
321 static void rd_print_state(struct ramdisk_t *ramdisk);
322 #endif
323
324
325 ////////////////////////////////////////////////////////////////////
326
327
328
329
330
331 int v3_ramdisk_register_cdrom(struct vm_device * dev, uint_t busID, uint_t driveID, struct cdrom_ops* cd, void * private_data) {
332     struct ramdisk_t * ramdisk  = (struct ramdisk_t *)(dev->private_data);
333     struct channel_t * channel = &(ramdisk->channels[busID]);
334     struct drive_t * drive = &(channel->drives[driveID]);
335     struct controller_t * controller = &(drive->controller);
336
337
338   
339     if (drive->device_type != IDE_NONE) {
340         PrintError("Device already registered at this location\n");
341         return -1;
342     }
343
344
345     channel->irq =  15;
346
347     // Make model string
348     strncpy((char*)(drive->model_no), "V3VEE Ramdisk", 40);
349
350     while (strlen((char *)(drive->model_no)) < 40) {
351         strcat ((char*)(drive->model_no), " ");
352     }
353   
354     PrintDebug("CDROM on target %d/%d\n", busID, driveID);
355   
356     drive->device_type = IDE_CDROM;
357     drive->cdrom.locked = 0;
358     drive->sense.sense_key = SENSE_NONE;
359     drive->sense.asc = 0;
360     drive->sense.ascq = 0;
361   
362     drive->private_data = private_data;
363
364     controller->sector_count = 0;
365
366     drive->cdrom.cd = cd;
367   
368     PrintDebug("\t\tCD on ata%d-%d: '%s'\n", 
369                busID, 
370                driveID, "");
371   
372     if(drive->cdrom.cd->insert_cdrom(drive->private_data)) {
373         PrintDebug("\t\tMedia present in CD-ROM drive\n");
374         drive->cdrom.ready = 1;
375         drive->cdrom.capacity = drive->cdrom.cd->capacity(drive->private_data);
376         PrintDebug("\t\tCDROM capacity is %d\n", drive->cdrom.capacity);
377     } else {                
378         PrintDebug("\t\tCould not locate CD-ROM, continuing with media not present\n");
379         drive->cdrom.ready = 0;
380     }
381   
382     return 0;
383 }
384
385
386 static Bit32u rd_init_hardware(struct ramdisk_t *ramdisk) {
387     uint_t channel_num; 
388     uint_t device;
389     struct channel_t *channels = (struct channel_t *)(&(ramdisk->channels));
390
391     PrintDebug("[rd_init_harddrive]\n");
392
393     for (channel_num = 0; channel_num < MAX_ATA_CHANNEL; channel_num++) {
394         memset((char *)(channels + channel_num), 0, sizeof(struct channel_t));
395     }
396
397     for (channel_num = 0; channel_num < MAX_ATA_CHANNEL; channel_num++){
398         struct channel_t * channel = &(channels[channel_num]);
399
400         channel->ioaddr1 = 0x0;
401         channel->ioaddr2 = 0x0;
402         channel->irq = 0;
403
404         for (device = 0; device < 2; device++){
405             struct drive_t * drive = &(channel->drives[device]);
406             struct controller_t * controller = &(drive->controller);
407
408             controller->status.busy = 0;
409             controller->status.drive_ready = 1;
410             controller->status.write_fault = 0;
411             controller->status.seek_complete = 1;
412             controller->status.drq = 0;
413             controller->status.corrected_data = 0;
414             controller->status.index_pulse = 0;
415             controller->status.index_pulse_count = 0;
416             controller->status.err = 0;
417
418             controller->error_register = 0x01; // diagnostic code: no error
419             controller->head_no = 0;
420             controller->sector_count = 1;
421             controller->sector_no = 1;
422             controller->cylinder_no = 0;
423             controller->current_command = 0x00;
424             controller->buffer_index = 0;
425
426             controller->control.reset = 0;
427             controller->control.disable_irq = 0;
428             controller->reset_in_progress = 0;
429
430             controller->sectors_per_block = 0x80;
431             controller->lba_mode = 0;
432       
433       
434             controller->features = 0;
435         
436             // If not present
437             drive->device_type = IDE_NONE;
438
439             // Make model string
440             strncpy((char*)(drive->model_no), "", 40);
441             while(strlen((char *)(drive->model_no)) < 40) {
442                 strcat ((char*)(drive->model_no), " ");
443             }
444
445         }
446     }
447
448 #ifdef DEBUG_RAMDISK
449     rd_print_state(ramdisk);
450 #endif
451     return 0;
452 }
453
454
455 /*
456   static void rd_reset_harddrive(struct ramdisk_t *ramdisk, unsigned type) {
457   return;
458   }
459
460 */
461 static void rd_close_harddrive(struct ramdisk_t *ramdisk) {
462     return;
463 }
464
465
466 ////////////////////////////////////////////////////////////////////
467
468
469
470 static int read_data_port(ushort_t port, void * dst, uint_t length, struct vm_device * dev) {
471     struct ramdisk_t * ramdisk  = (struct ramdisk_t *)(dev->private_data);
472     struct channel_t * channel = NULL;
473     struct drive_t * drive = NULL;
474     struct controller_t * controller = NULL;
475
476
477
478     if (is_primary_port(ramdisk, port)) {
479         channel = &(ramdisk->channels[0]);
480     } else if (is_secondary_port(ramdisk, port)) {
481         channel = &(ramdisk->channels[1]);
482     } else {
483         PrintError("Invalid Port: %d\n", port);
484         return -1;
485     }
486   
487     drive = get_selected_drive(channel);
488     controller = &(drive->controller);
489
490
491     PrintTrace("[read_data_handler] IO Read at 0x%x, on drive %d/%d current cmd=0x%x\n", 
492                port, 
493                get_channel_no(ramdisk, channel),
494                get_drive_no(channel, drive), 
495                controller->current_command);
496
497     switch (controller->current_command) {
498         case 0xec:    // IDENTIFY DEVICE
499         case 0xa1:
500             {
501
502
503                 controller->status.busy = 0;
504                 controller->status.drive_ready = 1;
505                 controller->status.write_fault = 0;
506                 controller->status.seek_complete = 1;
507                 controller->status.corrected_data = 0;
508                 controller->status.err = 0;
509       
510                 /*
511                   value32 = controller->buffer[index];
512                   index++;
513         
514                   if (io_len >= 2) {
515                   value32 |= (controller->buffer[index] << 8);
516                   index++;
517                   }
518         
519                   if (io_len == 4) {
520                   value32 |= (controller->buffer[index] << 16);
521                   value32 |= (controller->buffer[index+1] << 24);
522                   index += 2;
523                   }
524         
525                   controller->buffer_index = index;
526                 */
527                 /* JRL */
528                 memcpy(dst, controller->buffer + controller->buffer_index, length);
529                 controller->buffer_index += length;
530       
531                 if (controller->buffer_index >= 512) {
532                     controller->status.drq = 0;
533                 }
534       
535                 return length;
536             }
537         case 0xa0: //send packet cmd 
538             {
539                 uint_t index = controller->buffer_index;
540
541       
542                 PrintTrace("\t\tatapi.command(%02x), index(%d), cdrom.remaining_blocks(%d)\n", 
543                            drive->atapi.command, 
544                            index, 
545                            drive->cdrom.remaining_blocks);
546       
547                 // Load block if necessary
548                 if (index >= 2048) {
549         
550                     if (index > 2048) {
551                         PrintError("\t\tindex > 2048 : 0x%x\n", index);
552                         return -1;
553                     }
554         
555                     switch (drive->atapi.command) {
556                         case 0x28: // read (10)
557                         case 0xa8: // read (12)
558                             {
559     
560                                 if (!(drive->cdrom.ready)) {
561                                     PrintError("\t\tRead with CDROM not ready\n");
562                                     return -1;
563                                 } 
564             
565                                 drive->cdrom.cd->read_block(drive->private_data, controller->buffer,
566                                                             drive->cdrom.next_lba);
567                                 drive->cdrom.next_lba++;
568                                 drive->cdrom.remaining_blocks--;
569             
570             
571                                 if (!(drive->cdrom.remaining_blocks)) {
572                                     PrintDebug("\t\tLast READ block loaded {CDROM}\n");
573                                 } else {
574                                     PrintDebug("\t\tREAD block loaded (%d remaining) {CDROM}\n",
575                                                drive->cdrom.remaining_blocks);
576                                 }
577             
578                                 // one block transfered, start at beginning
579                                 index = 0;
580                                 break;
581                             }
582                         default: // no need to load a new block
583                             break;
584                     }
585                 }
586     
587
588                 /*
589                   increment = 0;
590                   value32 = controller->buffer[index + increment];
591                   increment++;
592         
593                   if (io_len >= 2) {
594                   value32 |= (controller->buffer[index + increment] << 8);
595                   increment++;
596                   }
597         
598                   if (io_len == 4) {
599                   value32 |= (controller->buffer[index + increment] << 16);
600                   value32 |= (controller->buffer[index + increment + 1] << 24);
601                   increment += 2;
602                   }
603
604                   controller->buffer_index = index + increment;
605                   controller->drq_index += increment;
606
607                 */
608                 /* JRL: CHECK THAT there is enough data in the buffer to copy.... */
609                 {      
610                     memcpy(dst, controller->buffer + index, length);
611         
612                     controller->buffer_index  = index + length;
613                     controller->drq_index += length;
614                 }
615       
616                 /* *** */
617       
618                 if (controller->drq_index >= (unsigned)drive->atapi.drq_bytes) {
619                     controller->status.drq = 0;
620                     controller->drq_index = 0;
621         
622                     drive->atapi.total_bytes_remaining -= drive->atapi.drq_bytes;
623         
624                     if (drive->atapi.total_bytes_remaining > 0) {
625                         // one or more blocks remaining (works only for single block commands)
626           
627                         PrintDebug("\t\tPACKET drq bytes read\n");
628                         controller->interrupt_reason.i_o = 1;
629                         controller->status.busy = 0;
630                         controller->status.drq = 1;
631                         controller->interrupt_reason.c_d = 0;
632           
633                         // set new byte count if last block
634                         if (drive->atapi.total_bytes_remaining < controller->byte_count) {
635                             controller->byte_count = drive->atapi.total_bytes_remaining;
636                         }
637                         drive->atapi.drq_bytes = controller->byte_count;
638           
639                         rd_raise_interrupt(dev, channel);
640                     } else {
641                         // all bytes read
642                         PrintDebug("\t\tPACKET all bytes read\n");
643           
644                         controller->interrupt_reason.i_o = 1;
645                         controller->interrupt_reason.c_d = 1;
646                         controller->status.drive_ready = 1;
647                         controller->interrupt_reason.rel = 0;
648                         controller->status.busy = 0;
649                         controller->status.drq = 0;
650                         controller->status.err = 0;
651           
652                         rd_raise_interrupt(dev, channel);
653                     }
654                 }
655                 return length;
656                 break;
657             }
658
659         default:
660             PrintError("\t\tunsupported command: %02x\n", controller->current_command);
661             break;
662     }
663
664     return -1;
665 }
666
667
668
669
670 static int write_data_port(ushort_t port, void * src, uint_t length, struct vm_device * dev) {
671     struct ramdisk_t * ramdisk  = (struct ramdisk_t *)(dev->private_data);
672     struct channel_t * channel = NULL;
673     struct drive_t * drive = NULL;
674     struct controller_t * controller = NULL;
675
676     if (is_primary_port(ramdisk, port)) {
677         channel = &(ramdisk->channels[0]);
678     } else if (is_secondary_port(ramdisk, port)) {
679         channel = &(ramdisk->channels[1]);
680     } else {
681         PrintError("Invalid Port: %d\n", port);
682         return -1;
683     }
684   
685     drive = get_selected_drive(channel);
686     controller = &(drive->controller);
687
688
689     PrintDebug("[write_data_handler] IO write at 0x%x, current_cmd = 0x%02x\n", 
690                port, controller->current_command);
691
692  
693
694     //PrintDebug("[write_data_handler]\n");
695     switch (controller->current_command) {
696         case 0x30: // WRITE SECTORS
697             PrintError("\t\tneed to implement 0x30(write sector) to port 0x%x\n", port);
698             return -1;
699     
700         case 0xa0: // PACKET
701     
702             if (handle_atapi_packet_command(dev, channel, *(ushort_t *)src) == -1) {
703                 PrintError("Error sending atapi packet command in PACKET write to data port\n");
704                 return -1;
705             }
706
707             return length;
708     
709         default:
710             PrintError("\t\tIO write(0x%x): current command is %02xh\n", 
711                        port, controller->current_command);
712
713             return -1;
714     }
715
716
717     return -1;
718 }
719
720
721
722
723
724
725
726 static int read_status_port(ushort_t port, void * dst, uint_t length, struct vm_device * dev) {
727     struct ramdisk_t * ramdisk  = (struct ramdisk_t *)(dev->private_data);
728     struct channel_t * channel = NULL;
729     struct drive_t * drive = NULL;
730     struct controller_t * controller = NULL;
731
732
733
734
735     if (is_primary_port(ramdisk, port)) {
736         channel = &(ramdisk->channels[0]);
737     } else if (is_secondary_port(ramdisk, port)) {
738         channel = &(ramdisk->channels[1]);
739     } else {
740         PrintError("Invalid Port: %d\n", port);
741         return -1;
742     }
743   
744     drive = get_selected_drive(channel);
745     controller = &(drive->controller);
746
747  
748     PrintDebug("[read_status_handler] IO read at 0x%x, on drive %d/%d\n", 
749                port, get_channel_no(ramdisk, channel), 
750                channel->drive_select);
751
752
753     if (num_drives_on_channel(channel) == 0) {
754         PrintDebug("Setting value to zero because 0 devices on channel\n");
755         // (mch) Just return zero for these registers
756         memset(dst, 0, length);
757
758     } else {
759         uchar_t val = (
760                        (controller->status.busy << 7)            |
761                        (controller->status.drive_ready << 6)     |
762                        (controller->status.write_fault << 5)     |
763                        (controller->status.seek_complete << 4)   |
764                        (controller->status.drq << 3)             |
765                        (controller->status.corrected_data << 2)  |
766                        (controller->status.index_pulse << 1)     |
767                        (controller->status.err) );
768
769
770         memcpy(dst, &val, length);
771
772         controller->status.index_pulse_count++;
773         controller->status.index_pulse = 0;
774     
775         if (controller->status.index_pulse_count >= INDEX_PULSE_CYCLE) {
776             controller->status.index_pulse = 1;
777             controller->status.index_pulse_count = 0;
778         }
779     }
780   
781     if ((port == SEC_CMD_PORT) || (port == PRI_CMD_PORT)) {
782         rd_lower_irq(dev, channel);
783     }
784   
785     PrintDebug("\t\tRead STATUS = 0x%x\n", *(uchar_t *)dst);
786
787     return length;
788   
789 }
790
791
792 static int write_cmd_port(ushort_t port, void * src, uint_t length, struct vm_device * dev) {
793     struct ramdisk_t * ramdisk  = (struct ramdisk_t *)(dev->private_data);
794     struct channel_t * channel = NULL;
795     struct drive_t * drive = NULL;
796     struct controller_t * controller = NULL;
797     uchar_t value = *(uchar_t *)src;
798
799     if (length != 1) {
800         PrintError("Invalid Command port write length: %d (port=%d)\n", length, port);
801         return -1;
802     }
803
804     if (is_primary_port(ramdisk, port)) {
805         channel = &(ramdisk->channels[0]);
806     } else if (is_secondary_port(ramdisk, port)) {
807         channel = &(ramdisk->channels[1]);
808     } else {
809         PrintError("Invalid Port: %d\n", port);
810         return -1;
811     }
812   
813     drive = get_selected_drive(channel);
814     controller = &(drive->controller);
815
816
817     PrintDebug("[write_command_handler] IO write at 0x%x, on drive %d/%d (val = 0x%x)\n", 
818                port, get_channel_no(ramdisk, channel), 
819                get_drive_no(channel, drive), 
820                value);
821
822     switch (value) {
823 #if 0
824         case 0xec: // IDENTIFY DEVICE
825             {
826
827                 if (drive->device_type == IDE_NONE) {
828                     PrintError("\t\tError: disk ata%d-%d not present, aborting\n", 
829                                get_channel_no(ramdisk, channel), 
830                                get_drive_no(channel, drive));
831                     rd_command_aborted(dev, channel, value);
832                     break;
833                 } else if (drive->device_type == IDE_CDROM) {
834                     PrintDebug("Identifying CDROM...Going to abort????\n");
835                     controller->head_no        = 0;
836                     controller->sector_count   = 1;
837                     controller->sector_no      = 1;
838                     controller->cylinder_no    = 0xeb14;
839                     rd_command_aborted(dev, channel, 0xec);
840                 } else {
841                     PrintError("\t\tError: Want to identify HDD!!\n");
842                     /*
843                       SELECTED_CONTROLLER(channel).current_command = value;
844                       SELECTED_CONTROLLER(channel).error_register = 0;
845           
846                       // See ATA/ATAPI-4, 8.12
847                       SELECTED_CONTROLLER(channel).status.busy  = 0;
848                       SELECTED_CONTROLLER(channel).status.drive_ready = 1;
849                       SELECTED_CONTROLLER(channel).status.write_fault = 0;
850                       SELECTED_CONTROLLER(channel).status.drq   = 1;
851                       SELECTED_CONTROLLER(channel).status.err   = 0;
852           
853                       SELECTED_CONTROLLER(channel).status.seek_complete = 1;
854                       SELECTED_CONTROLLER(channel).status.corrected_data = 0;
855           
856                       SELECTED_CONTROLLER(channel).buffer_index = 0;
857                       raise_interrupt(channel);
858                       identify_drive(channel);
859                     */
860                 }
861
862                 break;
863             }
864 #endif
865             // ATAPI commands
866         case 0xa1: // IDENTIFY PACKET DEVICE
867             {
868                 if (drive->device_type == IDE_CDROM) {
869                     controller->current_command = value;
870                     controller->error_register = 0;
871         
872                     controller->status.busy = 0;
873                     controller->status.drive_ready = 1;
874                     controller->status.write_fault = 0;
875                     controller->status.drq   = 1;
876                     controller->status.err   = 0;
877         
878                     controller->status.seek_complete = 1;
879                     controller->status.corrected_data = 0;
880         
881                     controller->buffer_index = 0;
882                     rd_raise_interrupt(dev, channel);
883                     rd_identify_ATAPI_drive(dev, channel);
884                 } else {
885                     PrintError("Identifying non cdrom device not supported - ata %d/%d\n", 
886                                get_channel_no(ramdisk, channel),
887                                get_drive_no(channel, drive));
888                     rd_command_aborted(dev, channel, 0xa1);
889                 }
890                 break;
891             }
892         case 0xa0: // SEND PACKET (atapi)
893             {
894                 if (drive->device_type == IDE_CDROM) {
895                     // PACKET
896         
897                     if (controller->features & (1 << 0)) {
898                         PrintError("\t\tPACKET-DMA not supported");
899                         return -1;
900                     }
901         
902                     if (controller->features & (1 << 1)) {
903                         PrintError("\t\tPACKET-overlapped not supported");
904                         return -1;
905                     }
906         
907                     // We're already ready!
908                     controller->sector_count = 1;
909                     controller->status.busy = 0;
910                     controller->status.write_fault = 0;
911
912                     // serv bit??
913                     controller->status.drq = 1;
914                     controller->status.err = 0;
915         
916                     // NOTE: no interrupt here
917                     controller->current_command = value;
918                     controller->buffer_index = 0;
919                 } else {
920                     PrintError("Sending packet to non cdrom device not supported\n");
921                     rd_command_aborted (dev, channel, 0xa0);
922                 }
923                 break;
924             }
925         default:
926             PrintError("\t\tneed translate command %2x - ata %d\%d\n", value, 
927                        get_channel_no(ramdisk, channel), 
928                        get_drive_no(channel, drive));
929             //return -1;
930             /* JRL THIS NEEDS TO CHANGE */
931             return length;
932
933     }
934     return length;
935 }
936
937
938 static int write_ctrl_port(ushort_t port, void * src, uint_t length, struct vm_device * dev) {
939     struct ramdisk_t * ramdisk  = (struct ramdisk_t *)(dev->private_data);
940     struct channel_t * channel = NULL;
941     struct drive_t * master_drive = NULL;
942     struct drive_t * slave_drive = NULL;
943     struct controller_t * controller = NULL;
944     uchar_t value = *(uchar_t *)src;
945     rd_bool prev_control_reset;
946
947     if (length != 1) {
948         PrintError("Invalid Status port read length: %d (port=%d)\n", length, port);
949         return -1;
950     }
951
952     if (is_primary_port(ramdisk, port)) {
953         channel = &(ramdisk->channels[0]);
954     } else if (is_secondary_port(ramdisk, port)) {
955         channel = &(ramdisk->channels[1]);
956     } else {
957         PrintError("Invalid Port: %d\n", port);
958         return -1;
959     }
960
961     master_drive = &(channel->drives[0]);
962     slave_drive = &(channel->drives[1]);
963
964     controller = &(get_selected_drive(channel)->controller);
965
966
967     PrintDebug("[write_control_handler] IO write at 0x%x, on drive %d/%d (val = 0x%x)\n", 
968                port, get_channel_no(ramdisk, channel), 
969                channel->drive_select, 
970                value);
971
972     // (mch) Even if device 1 was selected, a write to this register
973     // goes to device 0 (if device 1 is absent)
974   
975     prev_control_reset = controller->control.reset;
976
977
978     if (value & 0x04) {
979         PrintDebug("RESET Signaled\n");
980     }
981
982     master_drive->controller.control.reset         = value & 0x04;
983     slave_drive->controller.control.reset         = value & 0x04;
984
985     // CGS: was: SELECTED_CONTROLLER(channel).control.disable_irq    = value & 0x02;
986     master_drive->controller.control.disable_irq = value & 0x02;
987     slave_drive->controller.control.disable_irq = value & 0x02;
988   
989     PrintDebug("\t\tadpater control reg: reset controller = %d\n",
990                (unsigned) (controller->control.reset) ? 1 : 0);
991     PrintDebug("\t\tadpater control reg: disable_irq(X) = %d\n",
992                (unsigned) (controller->control.disable_irq) ? 1 : 0);
993   
994     if ((!prev_control_reset) && (controller->control.reset)) {
995         uint_t id = 0;
996
997         // transition from 0 to 1 causes all drives to reset
998         PrintDebug("\t\thard drive: RESET\n");
999     
1000         // (mch) Set BSY, drive not ready
1001         for (id = 0; id < 2; id++) {
1002             struct controller_t * ctrl = NULL;
1003
1004             if (id == 0) {
1005                 ctrl = &(master_drive->controller);
1006             } else if (id == 1) {
1007                 ctrl = &(slave_drive->controller);
1008             }
1009
1010             ctrl->status.busy           = 1;
1011             ctrl->status.drive_ready    = 0;
1012             ctrl->reset_in_progress     = 1;
1013       
1014             ctrl->status.write_fault    = 0;
1015             ctrl->status.seek_complete  = 1;
1016             ctrl->status.drq            = 0;
1017             ctrl->status.corrected_data = 0;
1018             ctrl->status.err            = 0;
1019       
1020             ctrl->error_register = 0x01; // diagnostic code: no error
1021       
1022             ctrl->current_command = 0x00;
1023             ctrl->buffer_index = 0;
1024       
1025             ctrl->sectors_per_block = 0x80;
1026             ctrl->lba_mode          = 0;
1027       
1028             ctrl->control.disable_irq = 0;
1029         }
1030
1031         rd_lower_irq(dev, channel);
1032
1033     } else if ((controller->reset_in_progress) &&
1034                (!controller->control.reset)) {
1035         uint_t id;
1036         // Clear BSY and DRDY
1037         PrintDebug("\t\tReset complete {%s}\n", device_type_to_str(get_selected_drive(channel)->device_type));
1038
1039         for (id = 0; id < 2; id++) {
1040             struct controller_t * ctrl = NULL;
1041             struct drive_t * drv = NULL;
1042
1043             if (id == 0) {
1044                 ctrl = &(master_drive->controller);
1045                 drv = master_drive;
1046             } else if (id == 1) {
1047                 ctrl = &(slave_drive->controller);
1048                 drv = slave_drive;
1049             }
1050
1051             ctrl->status.busy           = 0;
1052             ctrl->status.drive_ready    = 1;
1053             ctrl->reset_in_progress     = 0;
1054       
1055             // Device signature
1056             if (drv->device_type == IDE_DISK) {
1057                 PrintDebug("\t\tdrive %d/%d is harddrive\n", get_channel_no(ramdisk, channel), id);
1058                 ctrl->head_no        = 0;
1059                 ctrl->sector_count   = 1;
1060                 ctrl->sector_no      = 1;
1061                 ctrl->cylinder_no    = 0;
1062             } else {
1063                 ctrl->head_no        = 0;
1064                 ctrl->sector_count   = 1;
1065                 ctrl->sector_no      = 1;
1066                 ctrl->cylinder_no    = 0xeb14;
1067             }
1068         }
1069     }
1070
1071     PrintDebug("\t\ts[0].controller.control.disable_irq = %02x\n", 
1072                master_drive->controller.control.disable_irq);
1073     PrintDebug("\t\ts[1].controller.control.disable_irq = %02x\n", 
1074                slave_drive->controller.control.disable_irq);
1075     return length;
1076 }
1077
1078
1079 static int read_general_port(ushort_t port, void * dst, uint_t length, struct vm_device * dev) {
1080     struct ramdisk_t * ramdisk  = (struct ramdisk_t *)(dev->private_data);
1081     struct channel_t * channel = NULL;
1082     struct drive_t * drive = NULL;
1083     struct controller_t * controller = NULL;
1084
1085
1086     if (length != 1) {
1087         PrintError("Invalid Status port read length: %d (port=%d)\n", length, port);
1088         return -1;
1089     }
1090
1091     if (is_primary_port(ramdisk, port)) {
1092         channel = &(ramdisk->channels[0]);
1093     } else if (is_secondary_port(ramdisk, port)) {
1094         channel = &(ramdisk->channels[1]);
1095     } else {
1096         PrintError("Invalid Port: %d\n", port);
1097         return -1;
1098     }
1099   
1100     drive = get_selected_drive(channel);
1101     controller = &(drive->controller);
1102
1103
1104     PrintDebug("[read_general_handler] IO read addr at %x, on drive %d/%d, curcmd = %02x\n", 
1105                port, get_channel_no(ramdisk, channel), 
1106                channel->drive_select, 
1107                controller->current_command);
1108   
1109
1110     switch (port) {
1111         case PRI_FEATURES_PORT:
1112         case SEC_FEATURES_PORT: // hard disk error register 0x1f1
1113             {    
1114                 uchar_t val = (drive->device_type == IDE_NONE) ? 0 : controller->error_register;
1115       
1116                 controller->status.err = 0;
1117       
1118                 PrintDebug("\t\tRead FEATURES = 0x%x\n", val);
1119
1120                 *(uchar_t *)dst = val;
1121                 return length;
1122       
1123                 break;
1124             }
1125
1126         case PRI_SECT_CNT_PORT:
1127         case SEC_SECT_CNT_PORT:  // hard disk sector count / interrupt reason 0x1f2
1128             {
1129                 uchar_t val = (drive->device_type == IDE_NONE) ? 0 : controller->sector_count;
1130                 PrintDebug("\t\tRead SECTOR COUNT = 0x%x\n", val);
1131                 *(uchar_t *)dst = val;
1132                 return length;
1133
1134                 break;
1135             }
1136         case PRI_SECT_ADDR1_PORT:
1137         case SEC_SECT_ADDR1_PORT: // sector number 0x1f3
1138             { 
1139                 uchar_t val = (drive->device_type == IDE_NONE) ? 0 : controller->sector_no;
1140
1141                 PrintDebug("\t\tRead SECTOR ADDR1 = 0x%x\n", val);
1142
1143                 *(uchar_t *)dst = val;
1144                 return length;
1145
1146                 break;
1147             }
1148
1149         case PRI_SECT_ADDR2_PORT:
1150         case SEC_SECT_ADDR2_PORT:  // cylinder low 0x1f4  
1151             {
1152                 // -- WARNING : On real hardware the controller registers are shared between drives. 
1153                 // So we must respond even if the select device is not present. Some OS uses this fact 
1154                 // to detect the disks.... minix2 for example
1155                 uchar_t val = (num_drives_on_channel(channel) == 0) ? 0 : (controller->cylinder_no & 0x00ff);
1156
1157                 PrintDebug("\t\tRead SECTOR ADDR2 = 0x%x\n", val);
1158
1159                 *(uchar_t *)dst = val;
1160                 return length;
1161
1162                 break;      
1163             }
1164
1165         case PRI_SECT_ADDR3_PORT:
1166         case SEC_SECT_ADDR3_PORT: // cylinder high 0x1f5
1167             {
1168                 // -- WARNING : On real hardware the controller registers are shared between drives. 
1169                 // So we must respond even if the select device is not present. Some OS uses this fact 
1170                 // to detect the disks.... minix2 for example
1171                 uchar_t val = (num_drives_on_channel(channel) == 0) ? 0 : (controller->cylinder_no >> 8);
1172
1173                 PrintDebug("\t\tRead SECTOR ADDR3 = 0x%x\n", val);
1174
1175                 *(uchar_t *)dst = val;
1176                 return length;
1177
1178                 break;    
1179             }
1180         case PRI_DRV_SEL_PORT:
1181         case SEC_DRV_SEL_PORT:  // hard disk drive and head register 0x1f6
1182             {
1183                 // b7 Extended data field for ECC
1184                 // b6/b5: Used to be sector size.  00=256,01=512,10=1024,11=128
1185                 //   Since 512 was always used, bit 6 was taken to mean LBA mode:
1186                 //     b6 1=LBA mode, 0=CHS mode
1187                 //     b5 1
1188                 // b4: DRV
1189                 // b3..0 HD3..HD0
1190                 uchar_t val = ((1 << 7)                          |
1191                                ((controller->lba_mode > 0) << 6) |
1192                                (1 << 5)                          |            // 01b = 512 sector size
1193                                (channel->drive_select << 4)      |
1194                                (controller->head_no << 0));
1195       
1196                 PrintDebug("\t\tRead DRIVE SELECT = 0x%x\n", val);
1197                 *(uchar_t *)dst = val;
1198                 return length;
1199
1200                 break;
1201             }
1202         case PRI_ADDR_REG_PORT:
1203         case SEC_ADDR_REG_PORT: // Hard Disk Address Register 0x3f7
1204             {
1205                 // Obsolete and unsupported register.  Not driven by hard
1206                 // disk controller.  Report all 1's.  If floppy controller
1207                 // is handling this address, it will call this function
1208                 // set/clear D7 (the only bit it handles), then return
1209                 // the combined value
1210                 *(uchar_t *)dst = 0xff;
1211                 return length;
1212             }
1213
1214         default:
1215             PrintError("Invalid Port: %d\n", port);
1216             return -1;
1217     }
1218 }
1219
1220
1221
1222
1223 static int write_general_port(ushort_t port, void * src, uint_t length, struct vm_device * dev) {
1224     struct ramdisk_t * ramdisk  = (struct ramdisk_t *)(dev->private_data);
1225     struct channel_t * channel = NULL;
1226     struct drive_t * drive = NULL;
1227     struct controller_t * controller = NULL;
1228     uchar_t value = *(uchar_t *)src;
1229
1230     if (length != 1) {
1231         PrintError("Invalid Status port read length: %d (port=%d)\n", length, port);
1232         return -1;
1233     }
1234
1235     if (is_primary_port(ramdisk, port)) {
1236         channel = &(ramdisk->channels[0]);
1237     } else if (is_secondary_port(ramdisk, port)) {
1238         channel = &(ramdisk->channels[1]);
1239     } else {
1240         PrintError("Invalid Port: %d\n", port);
1241         return -1;
1242     }
1243   
1244     drive = get_selected_drive(channel);
1245     controller = &(drive->controller);
1246
1247
1248     PrintDebug("[write_general_handler] IO write to port %x (val=0x%02x), channel = %d\n", 
1249                port, value, get_channel_no(ramdisk, channel));
1250
1251     switch (port) {
1252
1253         case PRI_FEATURES_PORT:
1254         case SEC_FEATURES_PORT: // hard disk write precompensation 0x1f1
1255             {
1256                 write_features(channel, value);
1257                 break;
1258             }
1259         case PRI_SECT_CNT_PORT:
1260         case SEC_SECT_CNT_PORT: // hard disk sector count 0x1f2
1261             {
1262                 write_sector_count(channel, value);
1263                 break;
1264             }
1265         case PRI_SECT_ADDR1_PORT:
1266         case SEC_SECT_ADDR1_PORT: // hard disk sector number 0x1f3
1267             {
1268                 write_sector_number(channel, value);
1269                 break;
1270             }
1271         case PRI_SECT_ADDR2_PORT:
1272         case SEC_SECT_ADDR2_PORT: // hard disk cylinder low 0x1f4
1273             {
1274                 write_cylinder_low(channel, value);
1275                 break;
1276             }
1277         case PRI_SECT_ADDR3_PORT:
1278         case SEC_SECT_ADDR3_PORT: // hard disk cylinder high 0x1f5
1279             {
1280                 write_cylinder_high(channel, value);
1281                 break;
1282             }
1283         case PRI_DRV_SEL_PORT:
1284         case SEC_DRV_SEL_PORT: // hard disk drive and head register 0x1f6
1285             {
1286                 // b7 Extended data field for ECC
1287                 // b6/b5: Used to be sector size.  00=256,01=512,10=1024,11=128
1288                 //   Since 512 was always used, bit 6 was taken to mean LBA mode:
1289                 //     b6 1=LBA mode, 0=CHS mode
1290                 //     b5 1
1291                 // b4: DRV
1292                 // b3..0 HD3..HD0
1293
1294                 // 1x1xxxxx
1295
1296                 PrintDebug("\tDrive Select value=%x\n", value);
1297
1298                 if ((value & 0xa0) != 0xa0) { 
1299                     PrintDebug("\t\tIO write 0x%x (%02x): not 1x1xxxxxb\n", port, (unsigned) value);
1300                 }
1301       
1302                 write_head_no(channel, value & 0xf);
1303                 if ((controller->lba_mode == 0) && (((value >> 6) & 1) == 1)) {
1304                     PrintDebug("\t\tenabling LBA mode\n");
1305                 }
1306
1307                 write_lba_mode(channel, (value >> 6) & 1);
1308
1309
1310
1311                 if (drive->cdrom.cd) {
1312                     PrintDebug("\t\tSetting LBA on CDROM: %d\n", (value >> 6) & 1);
1313                     drive->cdrom.cd->set_LBA(drive->private_data, (value >> 6) & 1);
1314                 }
1315       
1316
1317                 channel->drive_select = (value >> 4) & 0x01;
1318                 drive = get_selected_drive(channel);
1319
1320                 if (drive->device_type == IDE_NONE) {
1321                     PrintError("\t\tError: device set to %d which does not exist! channel = 0x%x\n",
1322                                channel->drive_select, get_channel_no(ramdisk, channel));
1323
1324                     controller->error_register = 0x04; // aborted
1325                     controller->status.err = 1;
1326                 }
1327       
1328                 break;
1329             }
1330         default:
1331             PrintError("\t\thard drive: io write to unhandled port 0x%x  (value = %c)\n", port, value);
1332             //return -1;
1333     }
1334
1335     return length;
1336 }
1337
1338
1339  
1340
1341
1342 static void rd_raise_interrupt(struct vm_device * dev, struct channel_t * channel) {
1343     //  struct ramdisk_t * ramdisk = (struct ramdisk_t *)(dev->private_data);
1344     struct drive_t * drive = get_selected_drive(channel);
1345     struct controller_t * controller = &(drive->controller);
1346
1347     PrintDebug("[raise_interrupt] disable_irq = 0x%02x\n", controller->control.disable_irq);
1348
1349     if (!(controller->control.disable_irq)) {
1350  
1351         PrintDebug("\t\tRaising interrupt %d {%s}\n\n", channel->irq, device_type_to_str(drive->device_type));
1352
1353         v3_raise_irq(dev->vm, channel->irq);
1354     } else {
1355         PrintDebug("\t\tRaising irq but irq is disabled\n");
1356     }
1357   
1358     return;
1359 }
1360
1361 static void rd_lower_irq(struct vm_device *dev, struct channel_t * channel) {
1362     PrintDebug("[lower_irq] irq = %d\n", channel->irq);
1363     v3_lower_irq(dev->vm, channel->irq);
1364 }
1365
1366
1367
1368
1369
1370
1371
1372 //////////////////////////////////////////////////////////////////////////
1373
1374 /*
1375  * ATAPI subroutines
1376  */
1377
1378
1379
1380 int handle_atapi_packet_command(struct vm_device * dev, struct channel_t * channel, ushort_t value) {
1381     struct ramdisk_t * ramdisk  = (struct ramdisk_t *)(dev->private_data);
1382     struct drive_t * drive = get_selected_drive(channel);
1383     struct controller_t * controller = &(drive->controller);
1384
1385     if (controller->buffer_index >= PACKET_SIZE) {
1386         PrintError("ATAPI packet exceeded maximum length: buffer_index (%d) >= PACKET_SIZE\n", 
1387                    controller->buffer_index);
1388         return -1;
1389     }
1390
1391     controller->buffer[controller->buffer_index] = value;
1392     controller->buffer[controller->buffer_index + 1] = (value >> 8);
1393     controller->buffer_index += 2;
1394   
1395   
1396     /* if packet completely writtten */
1397     if (controller->buffer_index >= PACKET_SIZE) {
1398         // complete command received
1399         Bit8u atapi_command = controller->buffer[0];
1400     
1401         PrintDebug("\t\tcdrom: ATAPI command 0x%x started\n", atapi_command);
1402     
1403         switch (atapi_command) {
1404             case 0x00: // test unit ready
1405                 {
1406                     PrintDebug("Testing unit ready\n");
1407                     if (drive->cdrom.ready) {
1408                         rd_atapi_cmd_nop(dev, channel);
1409                     } else {
1410                         PrintError("CDROM not ready in test unit ready\n");
1411                         rd_atapi_cmd_error(dev, channel, SENSE_NOT_READY, ASC_MEDIUM_NOT_PRESENT);
1412                     }
1413         
1414                     rd_raise_interrupt(dev, channel);
1415         
1416                     break;
1417                 }
1418             case 0x03:  // request sense
1419                 {
1420                     int alloc_length = controller->buffer[4];
1421
1422                     if (rd_init_send_atapi_command(dev, channel, atapi_command, 18, alloc_length, false) == -1) {
1423                         PrintError("Error sending atapi command in Request Sense\n");
1424                         return -1;
1425                     }
1426         
1427                     // sense data
1428                     controller->buffer[0] = 0x70 | (1 << 7);
1429                     controller->buffer[1] = 0;
1430                     controller->buffer[2] = drive->sense.sense_key;
1431                     controller->buffer[3] = drive->sense.information.arr[0];
1432                     controller->buffer[4] = drive->sense.information.arr[1];
1433                     controller->buffer[5] = drive->sense.information.arr[2];
1434                     controller->buffer[6] = drive->sense.information.arr[3];
1435                     controller->buffer[7] = 17 - 7;
1436                     controller->buffer[8] = drive->sense.specific_inf.arr[0];
1437                     controller->buffer[9] = drive->sense.specific_inf.arr[1];
1438                     controller->buffer[10] = drive->sense.specific_inf.arr[2];
1439                     controller->buffer[11] = drive->sense.specific_inf.arr[3];
1440                     controller->buffer[12] = drive->sense.asc;
1441                     controller->buffer[13] = drive->sense.ascq;
1442                     controller->buffer[14] = drive->sense.fruc;
1443                     controller->buffer[15] = drive->sense.key_spec.arr[0];
1444                     controller->buffer[16] = drive->sense.key_spec.arr[1];
1445                     controller->buffer[17] = drive->sense.key_spec.arr[2];
1446         
1447                     rd_ready_to_send_atapi(dev, channel);
1448                     break;
1449                 }
1450             case 0x1b:  // start stop unit
1451                 {
1452                     //bx_bool Immed = (controller->buffer[1] >> 0) & 1;
1453                     rd_bool LoEj = (controller->buffer[4] >> 1) & 1;
1454                     rd_bool Start = (controller->buffer[4] >> 0) & 1;
1455
1456                     // stop the disc
1457                     if ((!LoEj) && (!Start)) { 
1458                         PrintError("FIXME: Stop disc not implemented\n");
1459
1460                         rd_atapi_cmd_nop(dev, channel);
1461                         rd_raise_interrupt(dev, channel);
1462
1463                     } else if (!LoEj && Start) { // start (spin up) the disc
1464           
1465                         drive->cdrom.cd->start_cdrom(drive->private_data);
1466           
1467                         PrintError("FIXME: ATAPI start disc not reading TOC\n");
1468                         rd_atapi_cmd_nop(dev, channel);
1469                         rd_raise_interrupt(dev, channel);
1470
1471                     } else if (LoEj && !Start) { // Eject the disc
1472                         rd_atapi_cmd_nop(dev, channel);
1473                         PrintDebug("Ejecting Disk\n");
1474                         if (drive->cdrom.ready) {
1475             
1476                             drive->cdrom.cd->eject_cdrom(drive->private_data);
1477             
1478                             drive->cdrom.ready = 0;
1479                             //bx_options.atadevice[channel][SLAVE_SELECTED(channel)].Ostatus->set(EJECTED);
1480                             //bx_gui->update_drive_status_buttons();
1481                         }
1482                         rd_raise_interrupt(dev, channel);
1483
1484                     } else { // Load the disc
1485                         // My guess is that this command only closes the tray, that's a no-op for us
1486                         rd_atapi_cmd_nop(dev, channel);
1487                         rd_raise_interrupt(dev, channel);
1488                     }
1489                     break;
1490                 }
1491             case 0xbd: // mechanism status
1492                 {
1493                     uint16_t alloc_length = rd_read_16bit(controller->buffer + 8);
1494         
1495                     if (alloc_length == 0) {
1496                         PrintError("Zero allocation length to MECHANISM STATUS not impl.\n");
1497                         return -1;
1498                     }
1499         
1500                     if (rd_init_send_atapi_command(dev, channel, atapi_command, 8, alloc_length, false) == -1) {
1501                         PrintError("Error sending atapi command in mechanism status\n");
1502                         return -1;
1503                     }
1504         
1505                     controller->buffer[0] = 0; // reserved for non changers
1506                     controller->buffer[1] = 0; // reserved for non changers
1507         
1508                     controller->buffer[2] = 0; // Current LBA (TODO!)
1509                     controller->buffer[3] = 0; // Current LBA (TODO!)
1510                     controller->buffer[4] = 0; // Current LBA (TODO!)
1511         
1512                     controller->buffer[5] = 1; // one slot
1513         
1514                     controller->buffer[6] = 0; // slot table length
1515                     controller->buffer[7] = 0; // slot table length
1516         
1517                     rd_ready_to_send_atapi(dev, channel);
1518                     break;
1519                 }
1520             case 0x5a:  // mode sense
1521                 {
1522                     uint16_t alloc_length = rd_read_16bit(controller->buffer + 7);
1523         
1524                     Bit8u PC = controller->buffer[2] >> 6;
1525                     Bit8u PageCode = controller->buffer[2] & 0x3f;
1526         
1527                     switch (PC) {
1528                         case 0x0: // current values
1529                             {
1530                                 switch (PageCode) {
1531                                     case 0x01: // error recovery
1532                                         {
1533                 
1534                                             if (rd_init_send_atapi_command(dev, channel, atapi_command, sizeof(struct error_recovery_t) + 8, alloc_length, false) == -1) {
1535                                                 PrintError("Error sending atapi command in mode sense error recovery\n");
1536                                                 return -1;
1537                                             }
1538                 
1539                                             rd_init_mode_sense_single(dev, channel, &(drive->cdrom.current.error_recovery),
1540                                                                       sizeof(struct error_recovery_t));
1541                                             rd_ready_to_send_atapi(dev, channel);
1542                                             break;
1543                                         }
1544                                     case 0x2a: // CD-ROM capabilities & mech. status
1545                                         {
1546
1547                                             if (rd_init_send_atapi_command(dev, channel, atapi_command, 28, alloc_length, false) == -1) {
1548                                                 PrintError("Error sending atapi command in CDROM caps/mech mode-sense\n");
1549                                                 return -1;
1550                                             }
1551
1552                                             rd_init_mode_sense_single(dev, channel, &(controller->buffer[8]), 28);
1553                 
1554                                             controller->buffer[8] = 0x2a;
1555                                             controller->buffer[9] = 0x12;
1556                                             controller->buffer[10] = 0x00;
1557                                             controller->buffer[11] = 0x00;
1558                                             // Multisession, Mode 2 Form 2, Mode 2 Form 1
1559                                             controller->buffer[12] = 0x70; 
1560                                             controller->buffer[13] = (3 << 5);
1561                                             controller->buffer[14] = (unsigned char) (1 |
1562                                                                                       (drive->cdrom.locked ? (1 << 1) : 0) |
1563                                                                                       (1 << 3) |
1564                                                                                       (1 << 5));
1565                                             controller->buffer[15] = 0x00;
1566                                             controller->buffer[16] = (706 >> 8) & 0xff;
1567                                             controller->buffer[17] = 706 & 0xff;
1568                                             controller->buffer[18] = 0;
1569                                             controller->buffer[19] = 2;
1570                                             controller->buffer[20] = (512 >> 8) & 0xff;
1571                                             controller->buffer[21] = 512 & 0xff;
1572                                             controller->buffer[22] = (706 >> 8) & 0xff;
1573                                             controller->buffer[23] = 706 & 0xff;
1574                                             controller->buffer[24] = 0;
1575                                             controller->buffer[25] = 0;
1576                                             controller->buffer[26] = 0;
1577                                             controller->buffer[27] = 0;
1578                                             rd_ready_to_send_atapi(dev, channel);
1579                                             break;
1580                                         }
1581                                     case 0x0d: // CD-ROM
1582                                     case 0x0e: // CD-ROM audio control
1583                                     case 0x3f: // all
1584                                         {
1585                                             PrintError("Ramdisk: cdrom: MODE SENSE (curr), code=%x not implemented yet\n",
1586                                                        PageCode);
1587                                             rd_atapi_cmd_error(dev, channel, SENSE_ILLEGAL_REQUEST,
1588                                                                ASC_INV_FIELD_IN_CMD_PACKET);
1589                                             rd_raise_interrupt(dev, channel);
1590                                             break;
1591                                         }
1592                                     default:
1593                                         {
1594                                             // not implemeted by this device
1595                                             PrintError("\t\tcdrom: MODE SENSE PC=%x, PageCode=%x, not implemented by device\n",
1596                                                        PC, PageCode);
1597                                             rd_atapi_cmd_error(dev, channel, SENSE_ILLEGAL_REQUEST,
1598                                                                ASC_INV_FIELD_IN_CMD_PACKET);
1599                                             rd_raise_interrupt(dev, channel);
1600                                             break;
1601                                         }
1602                                 }
1603                                 break;
1604                             }
1605                         case 0x1: // changeable values
1606                             {
1607                                 switch (PageCode) {
1608                                     case 0x01: // error recovery
1609                                     case 0x0d: // CD-ROM
1610                                     case 0x0e: // CD-ROM audio control
1611                                     case 0x2a: // CD-ROM capabilities & mech. status
1612                                     case 0x3f: // all
1613                                         {
1614                                             PrintError("cdrom: MODE SENSE (chg), code=%x not implemented yet\n",
1615                                                        PageCode);
1616                                             rd_atapi_cmd_error(dev, channel, SENSE_ILLEGAL_REQUEST,
1617                                                                ASC_INV_FIELD_IN_CMD_PACKET);
1618                                             rd_raise_interrupt(dev, channel);
1619                                             break;
1620                                         }
1621                                     default:
1622                                         {
1623                                             // not implemeted by this device
1624                                             PrintError("Changeable values of mode sense not supported by cdrom\n");
1625                                             PrintDebug("\t\tcdrom: MODE SENSE PC=%x, PageCode=%x, not implemented by device\n",
1626                                                        PC, PageCode);
1627                                             rd_atapi_cmd_error(dev, channel, SENSE_ILLEGAL_REQUEST,
1628                                                                ASC_INV_FIELD_IN_CMD_PACKET);
1629                                             rd_raise_interrupt(dev, channel);
1630                                             break;
1631                                         }
1632                                 }
1633                                 break;
1634                             }
1635                         case 0x2: // default values
1636                             {
1637                                 switch (PageCode) {
1638                                     case 0x01: // error recovery
1639                                     case 0x0d: // CD-ROM
1640                                     case 0x0e: // CD-ROM audio control
1641                                     case 0x2a: // CD-ROM capabilities & mech. status
1642                                     case 0x3f: // all
1643                                         PrintError("Default values of mode sense not supported by cdrom\n");
1644                                         PrintDebug("cdrom: MODE SENSE (dflt), code=%x\n",
1645                                                    PageCode);
1646                                         return -1;
1647               
1648                                     default:
1649                                         {
1650                                             PrintError("Default values of mode sense not implemented in cdrom\n");
1651                                             // not implemeted by this device
1652                                             PrintDebug("cdrom: MODE SENSE PC=%x, PageCode=%x, not implemented by device\n",
1653                                                        PC, PageCode);
1654                                             rd_atapi_cmd_error(dev, channel, SENSE_ILLEGAL_REQUEST,
1655                                                                ASC_INV_FIELD_IN_CMD_PACKET);
1656                                             rd_raise_interrupt(dev, channel);
1657                                             break;
1658                                         }
1659                                 }
1660                                 break;
1661                             }
1662                         case 0x3: // saved values not implemented
1663                             {
1664                                 PrintError("\t\tSaved values not implemented in mode sense\n");
1665                                 rd_atapi_cmd_error(dev, channel, SENSE_ILLEGAL_REQUEST, ASC_SAVING_PARAMETERS_NOT_SUPPORTED);
1666                                 rd_raise_interrupt(dev, channel);
1667                                 break;
1668                             }
1669                         default:
1670                             {
1671                                 PrintError("Unsupported Mode sense value\n");
1672                                 return -1;
1673                                 break;
1674                             }
1675                     }
1676                     break;
1677                 }
1678             case 0x12: // inquiry
1679                 { 
1680                     uint8_t alloc_length = controller->buffer[4];
1681         
1682                     if (rd_init_send_atapi_command(dev, channel, atapi_command, 36, alloc_length, false) == -1) {
1683                         PrintError("Error sending atapi command in inquiry\n");
1684                         return -1;
1685                     }
1686         
1687                     controller->buffer[0] = 0x05; // CD-ROM
1688                     controller->buffer[1] = 0x80; // Removable
1689                     controller->buffer[2] = 0x00; // ISO, ECMA, ANSI version
1690                     controller->buffer[3] = 0x21; // ATAPI-2, as specified
1691                     controller->buffer[4] = 31; // additional length (total 36)
1692                     controller->buffer[5] = 0x00; // reserved
1693                     controller->buffer[6] = 0x00; // reserved
1694                     controller->buffer[7] = 0x00; // reserved
1695         
1696                     // Vendor ID
1697                     const char* vendor_id = "VTAB    ";
1698                     int i;
1699                     for (i = 0; i < 8; i++) {
1700                         controller->buffer[8+i] = vendor_id[i];
1701                     }
1702
1703                     // Product ID
1704                     const char* product_id = "Turbo CD-ROM    ";
1705                     for (i = 0; i < 16; i++) {
1706                         controller->buffer[16+i] = product_id[i];
1707                     }
1708
1709                     // Product Revision level
1710                     const char* rev_level = "1.0 ";     
1711                     for (i = 0; i < 4; i++) {
1712                         controller->buffer[32 + i] = rev_level[i];
1713                     }
1714
1715                     rd_ready_to_send_atapi(dev, channel);
1716                     break;
1717                 }
1718             case 0x25:  // read cd-rom capacity
1719                 {
1720                     // no allocation length???
1721                     if (rd_init_send_atapi_command(dev, channel, atapi_command, 8, 8, false) == -1) {
1722                         PrintError("Error sending atapi command in read cdrom capacity\n");
1723                         return -1;
1724                     }
1725         
1726                     if (drive->cdrom.ready) {
1727                         uint32_t capacity = drive->cdrom.capacity;
1728
1729                         PrintDebug("\t\tCapacity is %d sectors (%d bytes)\n", capacity, capacity * 2048);
1730
1731                         controller->buffer[0] = (capacity >> 24) & 0xff;
1732                         controller->buffer[1] = (capacity >> 16) & 0xff;
1733                         controller->buffer[2] = (capacity >> 8) & 0xff;
1734                         controller->buffer[3] = (capacity >> 0) & 0xff;
1735                         controller->buffer[4] = (2048 >> 24) & 0xff;
1736                         controller->buffer[5] = (2048 >> 16) & 0xff;
1737                         controller->buffer[6] = (2048 >> 8) & 0xff;
1738                         controller->buffer[7] = (2048 >> 0) & 0xff;
1739
1740                         rd_ready_to_send_atapi(dev, channel);
1741                     } else {
1742                         PrintError("CDROM not ready in read cdrom capacity\n");
1743                         rd_atapi_cmd_error(dev, channel, SENSE_NOT_READY, ASC_MEDIUM_NOT_PRESENT);
1744                         rd_raise_interrupt(dev, channel);
1745                     }
1746                     break;
1747                 }
1748       
1749       
1750             case 0xbe:  // read cd
1751                 {
1752                     if (drive->cdrom.ready) {
1753                         PrintError("Read CD with CD present not implemented\n");
1754                         rd_atapi_cmd_error(dev, channel, SENSE_ILLEGAL_REQUEST, ASC_INV_FIELD_IN_CMD_PACKET);
1755                         rd_raise_interrupt(dev, channel);
1756                     } else {
1757                         PrintError("Drive not ready in read cd with CD present\n");
1758                         rd_atapi_cmd_error(dev, channel, SENSE_NOT_READY, ASC_MEDIUM_NOT_PRESENT);
1759                         rd_raise_interrupt(dev, channel);
1760                     }
1761                     break;
1762                 }
1763             case 0x43: // read toc
1764                 { 
1765                     if (drive->cdrom.ready) {
1766                         int toc_length = 0;  
1767                         bool msf = (controller->buffer[1] >> 1) & 1;
1768                         uint8_t starting_track = controller->buffer[6];
1769           
1770                         uint16_t alloc_length = rd_read_16bit(controller->buffer + 7);
1771           
1772                         uint8_t format = (controller->buffer[9] >> 6);
1773                         int i;
1774
1775                         PrintDebug("Reading CDROM TOC: Format=%d (byte count=%d) (toc length:%d)\n", 
1776                                    format, controller->byte_count, toc_length);
1777
1778                         switch (format) {
1779                             case 0:
1780                                 if (!(drive->cdrom.cd->read_toc(drive->private_data, controller->buffer,
1781                                                                 &toc_length, msf, starting_track))) {
1782                                     PrintError("CDROM: Reading Table of Contents Failed\n");
1783                                     rd_atapi_cmd_error(dev, channel, SENSE_ILLEGAL_REQUEST,
1784                                                        ASC_INV_FIELD_IN_CMD_PACKET);
1785                                     rd_raise_interrupt(dev, channel);
1786                                     break;
1787                                 }
1788
1789               
1790                                 if (rd_init_send_atapi_command(dev, channel, atapi_command, toc_length, alloc_length, false) == -1) {
1791                                     PrintError("Failed to init send atapi command in read toc (fmt=%d)\n", format);
1792                                     return -1;
1793                                 }
1794
1795                                 rd_ready_to_send_atapi(dev, channel);    
1796
1797                                 break;
1798
1799                             case 1:
1800                                 // multi session stuff. we ignore this and emulate a single session only
1801
1802                                 if (rd_init_send_atapi_command(dev, channel, atapi_command, 12, alloc_length, false) == -1) {
1803                                     PrintError("Failed to init send atapi command in read toc (fmt=%d)\n", format);
1804                                     return -1;
1805                                 }
1806             
1807                                 controller->buffer[0] = 0;
1808                                 controller->buffer[1] = 0x0a;
1809                                 controller->buffer[2] = 1;
1810                                 controller->buffer[3] = 1;
1811
1812                                 for (i = 0; i < 8; i++) {
1813                                     controller->buffer[4 + i] = 0;
1814                                 }
1815
1816                                 rd_ready_to_send_atapi(dev, channel);
1817                                 break;
1818             
1819                             case 2:
1820                             default:
1821                                 PrintError("(READ TOC) Format %d not supported\n", format);
1822                                 return -1;
1823                         }
1824                     } else {
1825                         PrintError("CDROM not ready in read toc\n");
1826                         rd_atapi_cmd_error(dev, channel, SENSE_NOT_READY, ASC_MEDIUM_NOT_PRESENT);
1827                         rd_raise_interrupt(dev, channel);
1828                     }
1829                     break;
1830                 }
1831             case 0x28: // read (10)
1832             case 0xa8: // read (12)
1833                 { 
1834         
1835                     uint32_t transfer_length;
1836                     if (atapi_command == 0x28) {
1837                         transfer_length = rd_read_16bit(controller->buffer + 7);
1838                     } else {
1839                         transfer_length = rd_read_32bit(controller->buffer + 6);
1840                     }
1841
1842                     uint32_t lba = rd_read_32bit(controller->buffer + 2);
1843         
1844                     if (!(drive->cdrom.ready)) {
1845                         PrintError("CDROM Error: Not Ready (ATA%d/%d)\n", 
1846                                    get_channel_no(ramdisk, channel), get_drive_no(channel, drive));
1847                         rd_atapi_cmd_error(dev, channel, SENSE_NOT_READY, ASC_MEDIUM_NOT_PRESENT);
1848                         rd_raise_interrupt(dev, channel);
1849                         break;
1850                     }
1851         
1852                     if (transfer_length == 0) {
1853                         PrintError("READ(%d) with transfer length 0, ok\n", 
1854                                    (atapi_command == 0x28) ? 10 : 12);
1855                         rd_atapi_cmd_nop(dev, channel);
1856                         rd_raise_interrupt(dev, channel);
1857                         break;
1858                     }
1859         
1860                     if (lba + transfer_length > drive->cdrom.capacity) {
1861                         PrintError("CDROM Error: Capacity exceeded [capacity=%d] (ATA%d/%d)\n",
1862                                    drive->cdrom.capacity,
1863                                    get_channel_no(ramdisk, channel), get_drive_no(channel, drive));
1864                         rd_atapi_cmd_error(dev, channel, SENSE_ILLEGAL_REQUEST, ASC_LOGICAL_BLOCK_OOR);
1865                         rd_raise_interrupt(dev, channel);
1866                         break;
1867                     }
1868         
1869                     PrintDebug("\t\tcdrom: READ (%d) LBA=%d LEN=%d\n", 
1870                                (atapi_command == 0x28) ? 10 : 12, 
1871                                lba, transfer_length);
1872         
1873                     // handle command
1874                     if (rd_init_send_atapi_command(dev, channel, atapi_command, transfer_length * 2048,
1875                                                    transfer_length * 2048, true) == -1) {
1876                         PrintError("CDROM Error: Atapi command send error\n");
1877                         return -1;
1878                     }
1879
1880                     drive->cdrom.remaining_blocks = transfer_length;
1881                     drive->cdrom.next_lba = lba;
1882                     rd_ready_to_send_atapi(dev, channel);
1883                     break;
1884                 }
1885             case 0x2b:  // seek
1886                 {
1887                     uint32_t lba = rd_read_32bit(controller->buffer + 2);
1888
1889                     if (!(drive->cdrom.ready)) {
1890                         PrintError("CDROM not ready in seek\n");
1891                         rd_atapi_cmd_error(dev, channel, SENSE_NOT_READY, ASC_MEDIUM_NOT_PRESENT);
1892                         rd_raise_interrupt(dev, channel);
1893                         break;
1894                     }
1895         
1896                     if (lba > drive->cdrom.capacity) {
1897                         PrintError("LBA is greater than CDROM capacity in seek\n");
1898                         rd_atapi_cmd_error(dev, channel, SENSE_ILLEGAL_REQUEST, ASC_LOGICAL_BLOCK_OOR);
1899                         rd_raise_interrupt(dev, channel);
1900                         break;
1901                     }
1902         
1903                     PrintError("\t\tcdrom: SEEK (ignored)\n");
1904
1905                     rd_atapi_cmd_nop(dev, channel);
1906                     rd_raise_interrupt(dev, channel);
1907
1908                     break;
1909                 }
1910             case 0x1e:  // prevent/allow medium removal
1911                 {
1912
1913                     if (drive->cdrom.ready) {
1914                         drive->cdrom.locked = controller->buffer[4] & 1;
1915                         rd_atapi_cmd_nop(dev, channel);
1916                     } else {
1917                         PrintError("CD not ready in prevent/allow medium removal\n");
1918                         rd_atapi_cmd_error(dev, channel, SENSE_NOT_READY, ASC_MEDIUM_NOT_PRESENT);
1919                     }
1920
1921                     rd_raise_interrupt(dev, channel);
1922
1923                     break;
1924                 }
1925             case 0x42:  // read sub-channel
1926                 {
1927                     //bool msf = get_packet_field(channel, 1, 1, 1);
1928                     bool sub_q = get_packet_field(channel, 2, 6, 1);
1929                     //uint8_t data_format = get_packet_byte(channel, 3);
1930                     //uint8_t track_number = get_packet_byte(channel, 6);
1931                     uint16_t alloc_length = get_packet_word(channel, 7);
1932         
1933
1934                     /*
1935                       UNUSED(msf);
1936                       UNUSED(data_format);
1937                       UNUSED(track_number);
1938                     */
1939                     if (!(drive->cdrom.ready)) {
1940                         PrintError("CDROM not ready in read sub-channel\n");
1941                         rd_atapi_cmd_error(dev, channel, SENSE_NOT_READY, ASC_MEDIUM_NOT_PRESENT);
1942                         rd_raise_interrupt(dev, channel);
1943                     } else {
1944                         controller->buffer[0] = 0;
1945                         controller->buffer[1] = 0; // audio not supported
1946                         controller->buffer[2] = 0;
1947                         controller->buffer[3] = 0;
1948           
1949                         int ret_len = 4; // header size
1950           
1951                         if (sub_q) { // !sub_q == header only
1952                             PrintError("Read sub-channel with SubQ not implemented\n");
1953                             rd_atapi_cmd_error(dev, channel, SENSE_ILLEGAL_REQUEST,
1954                                                ASC_INV_FIELD_IN_CMD_PACKET);
1955                             rd_raise_interrupt(dev, channel);
1956                         }
1957           
1958                         if (rd_init_send_atapi_command(dev, channel, atapi_command, ret_len, alloc_length, false) == -1) {
1959                             PrintError("Error sending atapi command in read sub-channel\n");
1960                             return -1;
1961                         }
1962                         rd_ready_to_send_atapi(dev, channel);
1963                     }
1964                     break;
1965                 }
1966             case 0x51:  // read disc info
1967                 {
1968                     // no-op to keep the Linux CD-ROM driver happy
1969                     PrintError("Error: Read disk info no-op to keep the Linux CD-ROM driver happy\n");
1970                     rd_atapi_cmd_error(dev, channel, SENSE_ILLEGAL_REQUEST, ASC_INV_FIELD_IN_CMD_PACKET);
1971                     rd_raise_interrupt(dev, channel);
1972                     break;
1973                 }
1974             case 0x55: // mode select
1975             case 0xa6: // load/unload cd
1976             case 0x4b: // pause/resume
1977             case 0x45: // play audio
1978             case 0x47: // play audio msf
1979             case 0xbc: // play cd
1980             case 0xb9: // read cd msf
1981             case 0x44: // read header
1982             case 0xba: // scan
1983             case 0xbb: // set cd speed
1984             case 0x4e: // stop play/scan
1985             case 0x46: // ???
1986             case 0x4a: // ???
1987                 PrintError("ATAPI command 0x%x not implemented yet\n",
1988                            atapi_command);
1989                 rd_atapi_cmd_error(dev, channel, SENSE_ILLEGAL_REQUEST, ASC_INV_FIELD_IN_CMD_PACKET);
1990                 rd_raise_interrupt(dev, channel);
1991                 break;
1992             default:
1993                 PrintError("Unknown ATAPI command 0x%x (%d)\n",
1994                            atapi_command, atapi_command);
1995                 // We'd better signal the error if the user chose to continue
1996                 rd_atapi_cmd_error(dev, channel, SENSE_ILLEGAL_REQUEST, ASC_INV_FIELD_IN_CMD_PACKET);
1997                 rd_raise_interrupt(dev, channel);
1998                 break;
1999         }
2000     }
2001        
2002               
2003     return 0;
2004 }
2005
2006
2007
2008
2009 int rd_init_send_atapi_command(struct vm_device * dev, struct channel_t * channel, Bit8u command, int req_length, int alloc_length, bool lazy)
2010 {
2011     struct drive_t * drive = &(channel->drives[channel->drive_select]);
2012     struct controller_t * controller = &(drive->controller);
2013
2014     // controller->byte_count is a union of controller->cylinder_no;
2015     // lazy is used to force a data read in the buffer at the next read.
2016   
2017     PrintDebug("[rd_init_send_atapi_cmd]\n");
2018
2019     if (controller->byte_count == 0xffff) {
2020         controller->byte_count = 0xfffe;
2021     }
2022
2023     if ((controller->byte_count & 1) && 
2024         !(alloc_length <= controller->byte_count)) {
2025       
2026         PrintDebug("\t\tOdd byte count (0x%04x) to ATAPI command 0x%02x, using 0x%x\n", 
2027                    controller->byte_count, 
2028                    command, 
2029                    controller->byte_count - 1);
2030     
2031         controller->byte_count -= 1;
2032     }
2033   
2034     if (controller->byte_count == 0) {
2035         PrintError("\t\tATAPI command with zero byte count\n");
2036         return -1;
2037     }
2038
2039     if (alloc_length < 0) {
2040         PrintError("\t\tAllocation length < 0\n");
2041         return -1;
2042     }
2043
2044     if (alloc_length == 0) {
2045         alloc_length = controller->byte_count;
2046     }
2047   
2048     controller->interrupt_reason.i_o = 1;
2049     controller->interrupt_reason.c_d = 0;
2050     controller->status.busy = 0;
2051     controller->status.drq = 1;
2052     controller->status.err = 0;
2053   
2054     // no bytes transfered yet
2055     if (lazy) {
2056         controller->buffer_index = 2048;
2057     } else {
2058         controller->buffer_index = 0;
2059     }
2060
2061     controller->drq_index = 0;
2062   
2063     if (controller->byte_count > req_length) {
2064         controller->byte_count = req_length;
2065     }
2066
2067     if (controller->byte_count > alloc_length) {
2068         controller->byte_count = alloc_length;
2069     }  
2070
2071     drive->atapi.command = command;
2072     drive->atapi.drq_bytes = controller->byte_count;
2073     drive->atapi.total_bytes_remaining = (req_length < alloc_length) ? req_length : alloc_length;
2074   
2075     // if (lazy) {
2076     // // bias drq_bytes and total_bytes_remaining
2077     // SELECTED_DRIVE(channel).atapi.drq_bytes += 2048;
2078     // SELECTED_DRIVE(channel).atapi.total_bytes_remaining += 2048;
2079     // }
2080
2081     return 0;
2082 }
2083
2084
2085
2086 void rd_ready_to_send_atapi(struct vm_device * dev, struct channel_t * channel) {
2087     PrintDebug("[rd_ready_to_send_atapi]\n");
2088   
2089     rd_raise_interrupt(dev, channel);
2090 }
2091
2092
2093
2094
2095
2096 void rd_atapi_cmd_error(struct vm_device * dev, struct channel_t * channel, sense_t sense_key, asc_t asc)
2097 {
2098     struct drive_t * drive = &(channel->drives[channel->drive_select]);
2099     struct controller_t * controller = &(drive->controller);
2100
2101
2102     struct ramdisk_t *ramdisk = (struct ramdisk_t *)(dev->private_data);
2103     PrintError("[rd_atapi_cmd_error]\n");
2104     PrintError("Error: atapi_cmd_error channel=%02x key=%02x asc=%02x\n", 
2105                get_channel_no(ramdisk, channel), sense_key, asc);
2106   
2107
2108     controller->error_register = sense_key << 4;
2109     controller->interrupt_reason.i_o = 1;
2110     controller->interrupt_reason.c_d = 1;
2111     controller->interrupt_reason.rel = 0;
2112     controller->status.busy = 0;
2113     controller->status.drive_ready = 1;
2114     controller->status.write_fault = 0;
2115     controller->status.drq = 0;
2116     controller->status.err = 1;
2117   
2118     drive->sense.sense_key = sense_key;
2119     drive->sense.asc = asc;
2120     drive->sense.ascq = 0;
2121 }
2122
2123
2124
2125 void rd_atapi_cmd_nop(struct vm_device * dev, struct channel_t * channel)
2126 {
2127     struct drive_t * drive = &(channel->drives[channel->drive_select]);
2128     struct controller_t * controller = &(drive->controller);
2129
2130     PrintDebug("[rd_atapi_cmd_nop]\n");
2131     controller->interrupt_reason.i_o = 1;
2132     controller->interrupt_reason.c_d = 1;
2133     controller->interrupt_reason.rel = 0;
2134     controller->status.busy = 0;
2135     controller->status.drive_ready = 1;
2136     controller->status.drq = 0;
2137     controller->status.err = 0;
2138 }
2139
2140
2141
2142
2143 void rd_identify_ATAPI_drive(struct vm_device * dev, struct channel_t * channel)
2144 {
2145     struct drive_t * drive = &(channel->drives[channel->drive_select]);
2146     struct controller_t * controller = &(drive->controller);
2147
2148
2149     uint_t i;
2150     const char* serial_number = " VT00001\0\0\0\0\0\0\0\0\0\0\0\0";
2151     const char* firmware = "ALPHA1  ";
2152
2153     drive->id_drive[0] = (2 << 14) | (5 << 8) | (1 << 7) | (2 << 5) | (0 << 0); // Removable CDROM, 50us response, 12 byte packets
2154
2155     for (i = 1; i <= 9; i++) {
2156         drive->id_drive[i] = 0;
2157     }
2158
2159     for (i = 0; i < 10; i++) {
2160         drive->id_drive[10 + i] = ((serial_number[i * 2] << 8) |
2161                                    (serial_number[(i * 2) + 1]));
2162     }
2163
2164     for (i = 20; i <= 22; i++) {
2165         drive->id_drive[i] = 0;
2166     }
2167
2168     for (i = 0; i < strlen(firmware) / 2; i++) {
2169         drive->id_drive[23 + i] = ((firmware[i * 2] << 8) |
2170                                    (firmware[(i * 2) + 1]));
2171     }
2172     V3_ASSERT((23 + i) == 27);
2173   
2174     for (i = 0; i < strlen((char *)(drive->model_no)) / 2; i++) {
2175         drive->id_drive[27 + i] = ((drive->model_no[i * 2] << 8) |
2176                                    (drive->model_no[(i * 2) + 1]));
2177     }
2178
2179     V3_ASSERT((27 + i) == 47);
2180
2181     drive->id_drive[47] = 0;
2182     drive->id_drive[48] = 1; // 32 bits access
2183
2184     drive->id_drive[49] = (1 << 9); // LBA supported
2185
2186     drive->id_drive[50] = 0;
2187     drive->id_drive[51] = 0;
2188     drive->id_drive[52] = 0;
2189
2190     drive->id_drive[53] = 3; // words 64-70, 54-58 valid
2191
2192     for (i = 54; i <= 62; i++) {
2193         drive->id_drive[i] = 0;
2194     }
2195
2196     // copied from CFA540A
2197     drive->id_drive[63] = 0x0103; // variable (DMA stuff)
2198     drive->id_drive[64] = 0x0001; // PIO
2199     drive->id_drive[65] = 0x00b4;
2200     drive->id_drive[66] = 0x00b4;
2201     drive->id_drive[67] = 0x012c;
2202     drive->id_drive[68] = 0x00b4;
2203
2204     drive->id_drive[69] = 0;
2205     drive->id_drive[70] = 0;
2206     drive->id_drive[71] = 30; // faked
2207     drive->id_drive[72] = 30; // faked
2208     drive->id_drive[73] = 0;
2209     drive->id_drive[74] = 0;
2210
2211     drive->id_drive[75] = 0;
2212
2213     for (i = 76; i <= 79; i++) {
2214         drive->id_drive[i] = 0;
2215     }
2216
2217     drive->id_drive[80] = 0x1e; // supports up to ATA/ATAPI-4
2218     drive->id_drive[81] = 0;
2219     drive->id_drive[82] = 0;
2220     drive->id_drive[83] = 0;
2221     drive->id_drive[84] = 0;
2222     drive->id_drive[85] = 0;
2223     drive->id_drive[86] = 0;
2224     drive->id_drive[87] = 0;
2225     drive->id_drive[88] = 0;
2226
2227     for (i = 89; i <= 126; i++) {
2228         drive->id_drive[i] = 0;
2229     }
2230
2231     drive->id_drive[127] = 0;
2232     drive->id_drive[128] = 0;
2233
2234     for (i = 129; i <= 159; i++) {
2235         drive->id_drive[i] = 0;
2236     }
2237
2238     for (i = 160; i <= 255; i++) {
2239         drive->id_drive[i] = 0;
2240     }
2241
2242
2243
2244     return;
2245 }
2246
2247
2248
2249
2250
2251
2252
2253 static 
2254 void rd_init_mode_sense_single(struct vm_device * dev, 
2255                                struct channel_t * channel, const void* src, int size)
2256 {
2257     struct drive_t * drive = &(channel->drives[channel->drive_select]);
2258     struct controller_t * controller = &(drive->controller);
2259
2260     PrintDebug("[rd_init_mode_sense_single]\n");
2261
2262     // Header
2263     controller->buffer[0] = (size + 6) >> 8;
2264     controller->buffer[1] = (size + 6) & 0xff;
2265     controller->buffer[2] = 0x70; // no media present
2266     controller->buffer[3] = 0; // reserved
2267     controller->buffer[4] = 0; // reserved
2268     controller->buffer[5] = 0; // reserved
2269     controller->buffer[6] = 0; // reserved
2270     controller->buffer[7] = 0; // reserved
2271   
2272     // Data
2273     memcpy(controller->buffer + 8, src, size);
2274 }
2275
2276
2277
2278 static void rd_command_aborted(struct vm_device * dev, 
2279                                struct channel_t * channel, unsigned value) {
2280     struct drive_t * drive = &(channel->drives[channel->drive_select]);
2281     struct controller_t * controller = &(drive->controller);
2282
2283     PrintError("[rd_command_aborted]\n");
2284     PrintError("\t\taborting on command 0x%02x {%s}\n", value, device_type_to_str(drive->device_type));
2285
2286     controller->current_command = 0;
2287     controller->status.busy = 0;
2288     controller->status.drive_ready = 1;
2289     controller->status.err = 1;
2290     controller->error_register = 0x04; // command ABORTED
2291     controller->status.drq = 0;
2292     controller->status.seek_complete = 0;
2293     controller->status.corrected_data = 0;
2294     controller->buffer_index = 0;
2295
2296     rd_raise_interrupt(dev, channel);
2297 }
2298
2299
2300 /*    
2301 static void init_pci(struct ramdisk_t * ramdisk) {
2302 struct v3_pci_bar bars[6];
2303     struct pci_device * pci_dev;
2304     int i;
2305     
2306     for (i = 0; i < 6; i++) {
2307         bars[i].type = PCI_BAR_NONE;
2308         bars[i].mem_hook = 0;
2309         bars[i].num_pages = 0;
2310         bars[i].bar_update = NULL;
2311     }
2312
2313     bars[4].type = PCI_BAR_MEM32;
2314     bars[4].mem_hook = 0;
2315     bars[4].num_pages = 1;
2316     bars[4].bar_update = NULL;
2317
2318     pci_dev = v3_pci_register_device(ramdisk->pci, PCI_STD_DEVICE, 0, "IDE", -1, bars, NULL, NULL, NULL, NULL);
2319
2320
2321     pci_dev->config_header.vendor_id = 0x8086;
2322     pci_dev->config_header.device_id = 0x2421;
2323
2324
2325 }
2326     */
2327 static int ramdisk_init_device(struct vm_device *dev) {
2328     struct ramdisk_t *ramdisk= (struct ramdisk_t *)dev->private_data;
2329
2330     PrintDebug("Initializing Ramdisk\n");
2331
2332
2333     rd_init_hardware(ramdisk);
2334
2335
2336     v3_dev_hook_io(dev, PRI_CTRL_PORT, 
2337                    &read_status_port, &write_ctrl_port);
2338
2339     v3_dev_hook_io(dev, PRI_DATA_PORT, 
2340                    &read_data_port, &write_data_port);
2341     v3_dev_hook_io(dev, PRI_FEATURES_PORT, 
2342                    &read_general_port, &write_general_port);
2343     v3_dev_hook_io(dev, PRI_SECT_CNT_PORT, 
2344                    &read_general_port, &write_general_port);
2345     v3_dev_hook_io(dev, PRI_SECT_ADDR1_PORT, 
2346                    &read_general_port, &write_general_port);
2347     v3_dev_hook_io(dev, PRI_SECT_ADDR2_PORT, 
2348                    &read_general_port, &write_general_port);
2349     v3_dev_hook_io(dev, PRI_SECT_ADDR3_PORT, 
2350                    &read_general_port, &write_general_port);
2351     v3_dev_hook_io(dev, PRI_DRV_SEL_PORT, 
2352                    &read_general_port, &write_general_port);
2353     v3_dev_hook_io(dev, PRI_CMD_PORT, 
2354                    &read_status_port, &write_cmd_port);
2355
2356
2357     v3_dev_hook_io(dev, SEC_CTRL_PORT, 
2358                    &read_status_port, &write_ctrl_port);
2359
2360     v3_dev_hook_io(dev, SEC_DATA_PORT, 
2361                    &read_data_port, &write_data_port);
2362     v3_dev_hook_io(dev, SEC_FEATURES_PORT, 
2363                    &read_general_port, &write_general_port);
2364     v3_dev_hook_io(dev, SEC_SECT_CNT_PORT, 
2365                    &read_general_port, &write_general_port);
2366     v3_dev_hook_io(dev, SEC_SECT_ADDR1_PORT, 
2367                    &read_general_port, &write_general_port);
2368     v3_dev_hook_io(dev, SEC_SECT_ADDR2_PORT, 
2369                    &read_general_port, &write_general_port);
2370     v3_dev_hook_io(dev, SEC_SECT_ADDR3_PORT, 
2371                    &read_general_port, &write_general_port);
2372     v3_dev_hook_io(dev, SEC_DRV_SEL_PORT, 
2373                    &read_general_port, &write_general_port);
2374     v3_dev_hook_io(dev, SEC_CMD_PORT, 
2375                    &read_status_port, &write_cmd_port);
2376   
2377   
2378
2379     v3_dev_hook_io(dev, SEC_ADDR_REG_PORT, 
2380                    &read_general_port, &write_general_port);
2381
2382     v3_dev_hook_io(dev, PRI_ADDR_REG_PORT, 
2383                    &read_general_port, &write_general_port);
2384
2385
2386
2387
2388
2389     return 0;
2390
2391 }
2392
2393
2394 static int ramdisk_deinit_device(struct vm_device *dev) {
2395     struct ramdisk_t *ramdisk = (struct ramdisk_t *)(dev->private_data);
2396     rd_close_harddrive(ramdisk);
2397     return 0;
2398 }
2399
2400 static struct vm_device_ops dev_ops = {
2401     .init = ramdisk_init_device,
2402     .deinit = ramdisk_deinit_device,
2403     .reset = NULL,
2404     .start = NULL,
2405     .stop = NULL,
2406 };
2407
2408
2409
2410
2411 struct vm_device * v3_create_ramdisk(struct vm_device * pci)
2412 {
2413
2414     struct ramdisk_t *ramdisk;
2415     ramdisk = (struct ramdisk_t *)V3_Malloc(sizeof(struct ramdisk_t));  
2416     V3_ASSERT(ramdisk != NULL);  
2417
2418     //    ramdisk->pci = pci;
2419
2420     PrintDebug("[create_ramdisk]\n");
2421
2422     struct vm_device * device = v3_create_device("RAMDISK", &dev_ops, ramdisk);
2423
2424     
2425
2426     return device;
2427 }
2428
2429
2430
2431
2432 #ifdef DEBUG_RAMDISK
2433
2434 static void rd_print_state(struct ramdisk_t * ramdisk) {
2435     uchar_t channel; 
2436     uchar_t device;
2437     struct channel_t * channels = (struct channel_t *)(&(ramdisk->channels));
2438
2439     /*
2440       for (channel = 0; channel < MAX_ATA_CHANNEL; channel++) {
2441       memset((char *)(channels + channel), 0, sizeof(struct channel_t));
2442       }
2443     */
2444     PrintDebug("sizeof(*channels) = %d\n", sizeof(*channels));
2445     PrintDebug("sizeof(channles->drives[0].controller) = %d\n", sizeof((channels->drives[0].controller)));
2446     PrintDebug("sizeof(channles->drives[0].cdrom) = %d\n", sizeof((channels->drives[0].cdrom)));
2447     PrintDebug("sizeof(channles->drives[0].sense) = %d\n", sizeof((channels->drives[0].sense)));
2448     PrintDebug("sizeof(channles->drives[0].atapi) = %d\n", sizeof((channels->drives[0].atapi)));
2449
2450
2451     PrintDebug("sizeof(channles->drives[0].controller.status) = %d\n", 
2452                sizeof((channels->drives[0].controller.status)));
2453     PrintDebug("sizeof(channles->drives[0].controller.sector_count) = %d\n", 
2454                sizeof((channels->drives[0].controller.sector_count)));
2455     PrintDebug("sizeof(channles->drives[0].controller.interrupt_reason) = %d\n", 
2456                sizeof((channels->drives[0].controller.interrupt_reason)));
2457
2458     PrintDebug("sizeof(channles->drives[0].controller.cylinder_no) = %d\n", 
2459                sizeof((channels->drives[0].controller.cylinder_no)));
2460     PrintDebug("sizeof(channles->drives[0].controller.byte_count) = %d\n", 
2461                sizeof((channels->drives[0].controller.byte_count)));
2462
2463
2464     PrintDebug("sizeof(channles->drives[0].controller.control) = %d\n", 
2465                sizeof((channels->drives[0].controller.control)));
2466
2467
2468     for (channel = 0; channel < MAX_ATA_CHANNEL; channel++){
2469   
2470         for (device = 0; device < 2; device++){
2471                   
2472             // Initialize controller state, even if device is not present
2473             PrintDebug("channels[%d].drives[%d].controller.status.busy = %d\n",
2474                        channel, device, 
2475                        channels[channel].drives[device].controller.status.busy);
2476             PrintDebug("channels[%d].drives[%d].controller.status.drive_ready = %d\n", 
2477                        channel, device, 
2478                        channels[channel].drives[device].controller.status.drive_ready);
2479             PrintDebug("channels[%d].drives[%d].controller.status.write_fault = %d\n", 
2480                        channel, device, 
2481                        channels[channel].drives[device].controller.status.write_fault);
2482             PrintDebug("channels[%d].drives[%d].controller.status.seek_complete = %d\n", 
2483                        channel, device, 
2484                        channels[channel].drives[device].controller.status.seek_complete);
2485             PrintDebug("channels[%d].drives[%d].controller.status.drq = %d\n", 
2486                        channel, device, 
2487                        channels[channel].drives[device].controller.status.drq);
2488             PrintDebug("channels[%d].drives[%d].controller.status.corrected_data = %d\n", 
2489                        channel, device, 
2490                        channels[channel].drives[device].controller.status.corrected_data);
2491             PrintDebug("channels[%d].drives[%d].controller.status.index_pulse = %d\n", 
2492                        channel, device, 
2493                        channels[channel].drives[device].controller.status.index_pulse);
2494             PrintDebug("channels[%d].drives[%d].controller.status.index_pulse_count = %d\n", 
2495                        channel, device, 
2496                        channels[channel].drives[device].controller.status.index_pulse_count);
2497             PrintDebug("channels[%d].drives[%d].controller.status.err = %d\n", 
2498                        channel, device, 
2499                        channels[channel].drives[device].controller.status.err);
2500
2501
2502             PrintDebug("channels[%d].drives[%d].controller.error_register = %d\n", 
2503                        channel, device, 
2504                        channels[channel].drives[device].controller.error_register);
2505             PrintDebug("channels[%d].drives[%d].controller.head_no = %d\n", 
2506                        channel, device, 
2507                        channels[channel].drives[device].controller.head_no);
2508             PrintDebug("channels[%d].drives[%d].controller.sector_count = %d\n", 
2509                        channel, device, 
2510                        channels[channel].drives[device].controller.sector_count);
2511             PrintDebug("channels[%d].drives[%d].controller.sector_no = %d\n", 
2512                        channel, device, 
2513                        channels[channel].drives[device].controller.sector_no);
2514             PrintDebug("channels[%d].drives[%d].controller.cylinder_no = %d\n", 
2515                        channel, device, 
2516                        channels[channel].drives[device].controller.cylinder_no);
2517             PrintDebug("channels[%d].drives[%d].controller.current_command = %02x\n", 
2518                        channel, device, 
2519                        channels[channel].drives[device].controller.current_command);
2520             PrintDebug("channels[%d].drives[%d].controller.buffer_index = %d\n", 
2521                        channel, device, 
2522                        channels[channel].drives[device].controller.buffer_index);
2523
2524
2525             PrintDebug("channels[%d].drives[%d].controller.control.reset = %d\n", 
2526                        channel, device, 
2527                        channels[channel].drives[device].controller.control.reset);
2528             PrintDebug("channels[%d].drives[%d].controller.control.disable_irq = %d\n", 
2529                        channel, device, 
2530                        channels[channel].drives[device].controller.control.disable_irq);
2531
2532
2533             PrintDebug("channels[%d].drives[%d].controller.reset_in_progress = %d\n", 
2534                        channel, device, 
2535                        channels[channel].drives[device].controller.reset_in_progress);
2536             PrintDebug("channels[%d].drives[%d].controller.sectors_per_block = %02x\n", 
2537                        channel, device, 
2538                        channels[channel].drives[device].controller.sectors_per_block); 
2539             PrintDebug("channels[%d].drives[%d].controller.lba_mode = %d\n", 
2540                        channel, device, 
2541                        channels[channel].drives[device].controller.lba_mode); 
2542             PrintDebug("channels[%d].drives[%d].controller.features = %d\n", 
2543                        channel, device, 
2544                        channels[channel].drives[device].controller.features); 
2545
2546
2547             PrintDebug("channels[%d].drives[%d].model_no = %s\n", 
2548                        channel, device, 
2549                        channels[channel].drives[device].model_no); 
2550             PrintDebug("channels[%d].drives[%d].device_type = %d\n", 
2551                        channel, device, 
2552                        channels[channel].drives[device].device_type); 
2553             PrintDebug("channels[%d].drives[%d].cdrom.locked = %d\n", 
2554                        channel, device, 
2555                        channels[channel].drives[device].cdrom.locked); 
2556             PrintDebug("channels[%d].drives[%d].sense.sense_key = %d\n", 
2557                        channel, device, 
2558                        channels[channel].drives[device].sense.sense_key); 
2559             PrintDebug("channels[%d].drives[%d].sense.asc = %d\n", 
2560                        channel, device, 
2561                        channels[channel].drives[device].sense.asc); 
2562             PrintDebug("channels[%d].drives[%d].sense.ascq = %d\n", 
2563                        channel, device, 
2564                        channels[channel].drives[device].sense.ascq); 
2565
2566
2567
2568             PrintDebug("channels[%d].drives[%d].controller.interrupt_reason.c_d = %02x\n", 
2569                        channel, device, 
2570                        channels[channel].drives[device].controller.interrupt_reason.c_d);
2571
2572             PrintDebug("channels[%d].drives[%d].controller.interrupt_reason.i_o = %02x\n", 
2573                        channel, device, 
2574                        channels[channel].drives[device].controller.interrupt_reason.i_o);
2575
2576             PrintDebug("channels[%d].drives[%d].controller.interrupt_reason.rel = %02x\n", 
2577                        channel, device, 
2578                        channels[channel].drives[device].controller.interrupt_reason.rel);
2579
2580             PrintDebug("channels[%d].drives[%d].controller.interrupt_reason.tag = %02x\n", 
2581                        channel, device, 
2582                        channels[channel].drives[device].controller.interrupt_reason.tag);
2583
2584             PrintDebug("channels[%d].drives[%d].cdrom.ready = %d\n", 
2585                        channel, device, 
2586                        channels[channel].drives[device].cdrom.ready);
2587       
2588         }  //for device
2589     }  //for channel
2590   
2591     return;
2592 }
2593
2594
2595 #endif