Home | History | Annotate | Line # | Download | only in ppc
hw_ide.c revision 1.1.1.1.8.1
      1 /*  This file is part of the program psim.
      2 
      3     Copyright (C) 1996, Andrew Cagney <cagney (at) highland.com.au>
      4 
      5     This program is free software; you can redistribute it and/or modify
      6     it under the terms of the GNU General Public License as published by
      7     the Free Software Foundation; either version 3 of the License, or
      8     (at your option) any later version.
      9 
     10     This program is distributed in the hope that it will be useful,
     11     but WITHOUT ANY WARRANTY; without even the implied warranty of
     12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     13     GNU General Public License for more details.
     14 
     15     You should have received a copy of the GNU General Public License
     16     along with this program; if not, see <http://www.gnu.org/licenses/>.
     17 
     18     */
     19 
     20 
     21 #ifndef _HW_IDE_C_
     22 #define _HW_IDE_C_
     23 
     24 #include "device_table.h"
     25 
     26 
     27 
     28 /* DEVICE
     29 
     30 
     31    ide - Integrated Disk Electronics
     32 
     33 
     34    DESCRIPTION
     35 
     36 
     37    This device models the primary/secondary <<ide>> controller
     38    described in the [CHRPIO] document.
     39 
     40    The controller has separate independant interrupt outputs for each
     41    <<ide>> bus.
     42 
     43 
     44    PROPERTIES
     45 
     46 
     47    reg = ...  (required)
     48 
     49    The <<reg>> property is described in the document [CHRPIO].
     50 
     51 
     52    ready-delay = <integer>  (optional)
     53 
     54    If present, this specifies the time that the <<ide>> device takes
     55    to complete an I/O operation.
     56 
     57 
     58    disk@?/ide-byte-count = <integer>  (optional)
     59 
     60    disk@?/ide-sector-count = <integer>  (optional)
     61 
     62    disk@?/ide-head-count = <integer>  (optional)
     63 
     64    The <<ide>> device checks each child (disk device) node to see if
     65    it has the above properties.  If present, these values will be used
     66    to compute the <<LBA>> address in <<CHS>> addressing mode.
     67 
     68 
     69    EXAMPLES
     70 
     71 
     72    Enable tracing:
     73 
     74    |  -t ide-device \
     75 
     76 
     77    Attach the <<ide>> device to the <<pci>> bus at slot one.  Specify
     78    legacy I/O addresses:
     79 
     80    |  -o '/phb/ide@1/assigned-addresses \
     81    |        ni0,0,10,1f0 8 \
     82    |        ni0,0,14,3f8 8 \
     83    |        ni0,0,18,170 8 \
     84    |        ni0,0,1c,378 8 \
     85    |        ni0,0,20,200 8' \
     86    |  -o '/phb@0x80000000/ide@1/reg \
     87    |        1 0 \
     88    |        i0,0,10,0 8 \
     89    |        i0,0,18,0 8 \
     90    |        i0,0,14,6 1 \
     91    |        i0,0,1c,6 1 \
     92    |        i0,0,20,0 8' \
     93 
     94    Note: the fouth and fifth reg entries specify that the register is
     95    at an offset into the address specified by the base register
     96    (<<assigned-addresses>>); Apart from restrictions placed by the
     97    <<pci>> specification, no restrictions are placed on the number of
     98    base registers specified by the <<assigned-addresses>> property.
     99 
    100    Attach a <<disk>> to the primary and a <<cdrom>> to the secondary
    101    <<ide>> controller.
    102 
    103    |  -o '/phb@0x80000000/ide@1/disk@0/file "zero' \
    104    |  -o '/phb@0x80000000/ide@1/cdrom@2/file "/dev/cdrom"' \
    105 
    106    Connect the two interrupt outputs (a and b) to a <<glue>> device to
    107    allow testing of the interrupt port. In a real simulation they
    108    would be wired to the interrupt controller.
    109 
    110    |  -o '/phb@0x80000000/glue@2/reg 2 0 ni0,0,0,0 8' \
    111    |  -o '/phb@0x80000000/ide@1 > a 0 /phb@0x80000000/glue@2' \
    112    |  -o '/phb@0x80000000/ide@1 > b 1 /phb@0x80000000/glue@2'
    113 
    114 
    115    BUGS
    116 
    117 
    118    While the DMA registers are present, DMA support has not yet been
    119    implemented.
    120 
    121    The number of supported commands is very limited.
    122 
    123    The standards documents appear to be vague on how to specify the
    124    <<unit-address>> of disk devices devices being attached to the
    125    <<ide>> controller.  I've chosen to use integers with devices zero
    126    and one going to the primary controller while two and three are
    127    connected to the secondary controller.
    128 
    129 
    130    REFERENCES
    131 
    132 
    133    [CHRPIO] PowerPC(tm) Microprocessor Common Hardware Reference
    134    Platform: I/O Device Reference.  http://chrp.apple.com/???.
    135 
    136    [SCHMIDT] The SCSI Bus and IDE Interface - Protocols, Applications
    137    and Programming.  Friedhelm Schmidt (translated by Michael
    138    Schultz).  ISBN 0-201-42284-0.  Addison-Wesley Publishing Company.
    139 
    140 
    141    */
    142 
    143 
    144 
    145 typedef enum _io_direction {
    146   is_read,
    147   is_write,
    148 } io_direction;
    149 
    150 
    151 enum {
    152   nr_ide_controllers = 2,
    153   nr_ide_drives_per_controller = 2,
    154   nr_fifo_entries = 8192,
    155 };
    156 
    157 enum {
    158   /* command register block - read */
    159   ide_data_reg,
    160   ide_error_reg, /*ide_feature_reg*/
    161   ide_sector_count_reg,
    162   ide_sector_number_reg,
    163   ide_cylinder_reg0,
    164   ide_cylinder_reg1,
    165   ide_drive_head_reg,
    166   ide_status_reg, /*ide_command_reg*/
    167   /* command register block - write */
    168   ide_feature_reg, /*ide_error_reg*/
    169   ide_command_reg, /*ide_status_reg*/
    170   /* control register block - read */
    171   ide_alternate_status_reg, /*ide_control_reg*/
    172   ide_control_reg, /*ide_alternate_status_reg*/
    173   /* dma register block */
    174   ide_dma_command_reg,
    175   ide_dma_unused_1_reg,
    176   ide_dma_status_reg,
    177   ide_dma_unused_3_reg,
    178   ide_dma_prd_table_address_reg0,
    179   ide_dma_prd_table_address_reg1,
    180   ide_dma_prd_table_address_reg2,
    181   ide_dma_prd_table_address_reg3,
    182   nr_ide_registers,
    183 };
    184 
    185 
    186 typedef enum _ide_states {
    187   idle_state,
    188   busy_loaded_state,
    189   busy_drained_state,
    190   busy_dma_state,
    191   busy_command_state,
    192   loading_state,
    193   draining_state,
    194 } ide_states;
    195 
    196 static const char *
    197 ide_state_name(ide_states state)
    198 {
    199   switch (state) {
    200   case idle_state: return "idle";
    201   case busy_loaded_state: return "busy_loaded_state";
    202   case busy_drained_state: return "busy_drained_state";
    203   case busy_dma_state: return "busy_dma_state";
    204   case busy_command_state: return "busy_command_state";
    205   case loading_state: return "loading_state";
    206   case draining_state: return "draining_state";
    207   default: return "illegal-state";
    208   }
    209 }
    210 
    211 typedef struct _ide_geometry {
    212   int head;
    213   int sector;
    214   int byte;
    215 } ide_geometry;
    216 
    217 typedef struct _ide_drive {
    218   int nr;
    219   device *device;
    220   ide_geometry geometry;
    221   ide_geometry default_geometry;
    222 } ide_drive;
    223 
    224 typedef struct _ide_controller {
    225   int nr;
    226   ide_states state;
    227   unsigned8 reg[nr_ide_registers];
    228   unsigned8 fifo[nr_fifo_entries];
    229   int fifo_pos;
    230   int fifo_size;
    231   ide_drive *current_drive;
    232   int current_byte;
    233   int current_transfer;
    234   ide_drive drive[nr_ide_drives_per_controller];
    235   device *me;
    236   event_entry_tag event_tag;
    237   int is_interrupting;
    238   signed64 ready_delay;
    239 } ide_controller;
    240 
    241 
    242 
    243 static void
    244 set_interrupt(device *me,
    245 	      ide_controller *controller)
    246 {
    247   if ((controller->reg[ide_control_reg] & 0x2) == 0) {
    248     DTRACE(ide, ("controller %d - interrupt set\n", controller->nr));
    249     device_interrupt_event(me, controller->nr, 1, NULL, 0);
    250     controller->is_interrupting = 1;
    251   }
    252 }
    253 
    254 
    255 static void
    256 clear_interrupt(device *me,
    257 		ide_controller *controller)
    258 {
    259   if (controller->is_interrupting) {
    260     DTRACE(ide, ("controller %d - interrupt clear\n", controller->nr));
    261     device_interrupt_event(me, controller->nr, 0, NULL, 0);
    262     controller->is_interrupting = 0;
    263   }
    264 }
    265 
    266 
    267 static void
    268 do_event(void *data)
    269 {
    270   ide_controller *controller = data;
    271   device *me = controller->me;
    272   controller->event_tag = 0;
    273   switch (controller->state) {
    274   case busy_loaded_state:
    275   case busy_drained_state:
    276     if (controller->current_transfer > 0) {
    277       controller->state = (controller->state == busy_loaded_state
    278 			   ? loading_state : draining_state);
    279     }
    280     else {
    281       controller->state = idle_state;
    282     }
    283     set_interrupt(me, controller);
    284     break;
    285   default:
    286     device_error(me, "controller %d - unexpected event", controller->nr);
    287     break;
    288   }
    289 }
    290 
    291 
    292 static void
    293 schedule_ready_event(device *me,
    294 		     ide_controller *controller)
    295 {
    296   if (controller->event_tag != 0)
    297     device_error(me, "controller %d - attempting to schedule multiple events",
    298 		 controller->nr);
    299   controller->event_tag =
    300     device_event_queue_schedule(me, controller->ready_delay,
    301 				do_event, controller);
    302 }
    303 
    304 
    305 static void
    306 do_fifo_read(device *me,
    307 	     ide_controller *controller,
    308 	     void *dest,
    309 	     int nr_bytes)
    310 {
    311   if (controller->state != draining_state)
    312     device_error(me, "controller %d - reading fifo when not ready (%s)",
    313 		 controller->nr,
    314 		 ide_state_name(controller->state));
    315   if (controller->fifo_pos + nr_bytes > controller->fifo_size)
    316     device_error(me, "controller %d - fifo underflow", controller->nr);
    317   if (nr_bytes > 0) {
    318     memcpy(dest, &controller->fifo[controller->fifo_pos], nr_bytes);
    319     controller->fifo_pos += nr_bytes;
    320   }
    321   if (controller->fifo_pos == controller->fifo_size) {
    322     controller->current_transfer -= 1;
    323     if (controller->current_transfer > 0
    324 	&& controller->current_drive != NULL) {
    325       DTRACE(ide, ("controller %d:%d - reading %d byte block at 0x%x\n",
    326 		   controller->nr,
    327 		   controller->current_drive->nr,
    328 		   controller->fifo_size,
    329 		   controller->current_byte));
    330       if (device_io_read_buffer(controller->current_drive->device,
    331 				controller->fifo,
    332 				0, controller->current_byte,
    333 				controller->fifo_size,
    334 				NULL, 0)
    335 	  != controller->fifo_size)
    336 	device_error(me, "controller %d - disk %s io read error",
    337 		     controller->nr,
    338 		     device_path(controller->current_drive->device));
    339     }
    340     controller->state = busy_drained_state;
    341     controller->fifo_pos = 0;
    342     controller->current_byte += controller->fifo_size;
    343     schedule_ready_event(me, controller);
    344   }
    345 }
    346 
    347 
    348 static void
    349 do_fifo_write(device *me,
    350 	      ide_controller *controller,
    351 	      const void *source,
    352 	      int nr_bytes)
    353 {
    354   if (controller->state != loading_state)
    355     device_error(me, "controller %d - writing fifo when not ready (%s)",
    356 		 controller->nr,
    357 		 ide_state_name(controller->state));
    358   if (controller->fifo_pos + nr_bytes > controller->fifo_size)
    359     device_error(me, "controller %d - fifo overflow", controller->nr);
    360   if (nr_bytes > 0) {
    361     memcpy(&controller->fifo[controller->fifo_pos], source, nr_bytes);
    362     controller->fifo_pos += nr_bytes;
    363   }
    364   if (controller->fifo_pos == controller->fifo_size) {
    365     if (controller->current_transfer > 0
    366 	&& controller->current_drive != NULL) {
    367       DTRACE(ide, ("controller %d:%d - writing %d byte block at 0x%x\n",
    368 		   controller->nr,
    369 		   controller->current_drive->nr,
    370 		   controller->fifo_size,
    371 		   controller->current_byte));
    372       if (device_io_write_buffer(controller->current_drive->device,
    373 				 controller->fifo,
    374 				 0, controller->current_byte,
    375 				 controller->fifo_size,
    376 				 NULL, 0)
    377 	  != controller->fifo_size)
    378 	device_error(me, "controller %d - disk %s io write error",
    379 		     controller->nr,
    380 		     device_path(controller->current_drive->device));
    381     }
    382     controller->current_transfer -= 1;
    383     controller->fifo_pos = 0;
    384     controller->current_byte += controller->fifo_size;
    385     controller->state = busy_loaded_state;
    386     schedule_ready_event(me, controller);
    387   }
    388 }
    389 
    390 
    391 static void
    392 setup_fifo(device *me,
    393 	   ide_controller *controller,
    394 	   int is_simple,
    395 	   int is_with_disk,
    396 	   io_direction direction)
    397 {
    398   /* find the disk */
    399   if (is_with_disk) {
    400     int drive_nr = (controller->reg[ide_drive_head_reg] & 0x10) != 0;
    401     controller->current_drive = &controller->drive[drive_nr];
    402   }
    403   else {
    404     controller->current_drive = NULL;
    405   }
    406 
    407   /* number of transfers */
    408   if (is_simple)
    409     controller->current_transfer = 1;
    410   else {
    411     int sector_count = controller->reg[ide_sector_count_reg];
    412     if (sector_count == 0)
    413       controller->current_transfer = 256;
    414     else
    415       controller->current_transfer = sector_count;
    416   }
    417 
    418   /* the transfer size */
    419   if (controller->current_drive == NULL)
    420     controller->fifo_size = 512;
    421   else
    422     controller->fifo_size = controller->current_drive->geometry.byte;
    423 
    424   /* empty the fifo */
    425   controller->fifo_pos = 0;
    426 
    427   /* the starting address */
    428   if (controller->current_drive == NULL)
    429     controller->current_byte = 0;
    430   else if (controller->reg[ide_drive_head_reg] & 0x40) {
    431     /* LBA addressing mode */
    432     controller->current_byte = controller->fifo_size
    433       * (((controller->reg[ide_drive_head_reg] & 0xf) << 24)
    434 	 | (controller->reg[ide_cylinder_reg1] << 16)
    435 	 | (controller->reg[ide_cylinder_reg0] << 8)
    436 	 | (controller->reg[ide_sector_number_reg]));
    437   }
    438   else if (controller->current_drive->geometry.head != 0
    439 	   && controller->current_drive->geometry.sector != 0) {
    440     /* CHS addressing mode */
    441     int head_nr = controller->reg[ide_drive_head_reg] & 0xf;
    442     int cylinder_nr = ((controller->reg[ide_cylinder_reg1] << 8)
    443 		    | controller->reg[ide_cylinder_reg0]);
    444     int sector_nr = controller->reg[ide_sector_number_reg];
    445     controller->current_byte = controller->fifo_size
    446       * ((cylinder_nr * controller->current_drive->geometry.head + head_nr)
    447 	 * controller->current_drive->geometry.sector + sector_nr - 1);
    448   }
    449   else
    450     device_error(me, "controller %d:%d - CHS addressing disabled",
    451 		 controller->nr, controller->current_drive->nr);
    452   DTRACE(ide, ("controller %ld:%ld - transfer (%s) %ld blocks of %ld bytes from 0x%lx\n",
    453 	       (long)controller->nr,
    454 	       controller->current_drive == NULL ? -1L : (long)controller->current_drive->nr,
    455 	       direction == is_read ? "read" : "write",
    456 	       (long)controller->current_transfer,
    457 	       (long)controller->fifo_size,
    458 	       (unsigned long)controller->current_byte));
    459   switch (direction) {
    460   case is_read:
    461     /* force a primeing read */
    462     controller->current_transfer += 1;
    463     controller->state = draining_state;
    464     controller->fifo_pos = controller->fifo_size;
    465     do_fifo_read(me, controller, NULL, 0);
    466     break;
    467   case is_write:
    468     controller->state = loading_state;
    469     break;
    470   }
    471 }
    472 
    473 
    474 static void
    475 do_command(device *me,
    476 	   ide_controller *controller,
    477 	   int command)
    478 {
    479   if (controller->state != idle_state)
    480     device_error(me, "controller %d - command when not idle", controller->nr);
    481   switch (command) {
    482   case 0x20: case 0x21: /* read-sectors */
    483     setup_fifo(me, controller, 0/*is_simple*/, 1/*is_with_disk*/, is_read);
    484     break;
    485   case 0x30: case 0x31: /* write */
    486     setup_fifo(me, controller, 0/*is_simple*/, 1/*is_with_disk*/, is_write);
    487     break;
    488   }
    489 }
    490 
    491 static unsigned8
    492 get_status(device *me,
    493 	   ide_controller *controller)
    494 {
    495   switch (controller->state) {
    496   case loading_state:
    497   case draining_state:
    498     return 0x08; /* data req */
    499   case busy_loaded_state:
    500   case busy_drained_state:
    501     return 0x80; /* busy */
    502   case idle_state:
    503     return 0x40; /* drive ready */
    504   default:
    505     device_error(me, "internal error");
    506     return 0;
    507   }
    508 }
    509 
    510 
    511 /* The address presented to the IDE controler is decoded and then
    512    mapped onto a controller:reg pair */
    513 
    514 enum {
    515   nr_address_blocks = 6,
    516 };
    517 
    518 typedef struct _address_block {
    519   int space;
    520   unsigned_word base_addr;
    521   unsigned_word bound_addr;
    522   int controller;
    523   int base_reg;
    524 } address_block;
    525 
    526 typedef struct _address_decoder {
    527   address_block block[nr_address_blocks];
    528 } address_decoder;
    529 
    530 static void
    531 decode_address(device *me,
    532 	       address_decoder *decoder,
    533 	       int space,
    534 	       unsigned_word address,
    535 	       int *controller,
    536 	       int *reg,
    537 	       io_direction direction)
    538 {
    539   int i;
    540   for (i = 0; i < nr_address_blocks; i++) {
    541     if (space == decoder->block[i].space
    542 	&& address >= decoder->block[i].base_addr
    543 	&& address <= decoder->block[i].bound_addr) {
    544       *controller = decoder->block[i].controller;
    545       *reg = (address
    546 	      - decoder->block[i].base_addr
    547 	      + decoder->block[i].base_reg);
    548       if (direction == is_write) {
    549 	switch (*reg) {
    550 	case ide_error_reg: *reg = ide_feature_reg; break;
    551 	case ide_status_reg: *reg = ide_command_reg; break;
    552 	case ide_alternate_status_reg: *reg = ide_control_reg; break;
    553 	default: break;
    554 	}
    555       }
    556       return;
    557     }
    558   }
    559   device_error(me, "address %d:0x%lx invalid",
    560 	       space, (unsigned long)address);
    561 }
    562 
    563 
    564 static void
    565 build_address_decoder(device *me,
    566 		      address_decoder *decoder)
    567 {
    568   int reg;
    569   for (reg = 1; reg < 6; reg++) {
    570     reg_property_spec unit;
    571     int space;
    572     unsigned_word address;
    573     unsigned size;
    574     /* find and decode the reg property */
    575     if (!device_find_reg_array_property(me, "reg", reg, &unit))
    576       device_error(me, "missing or invalid reg entry %d", reg);
    577     device_address_to_attach_address(device_parent(me), &unit.address,
    578 				     &space, &address, me);
    579     device_size_to_attach_size(device_parent(me), &unit.size, &size, me);
    580     /* insert it into the address decoder */
    581     switch (reg) {
    582     case 1:
    583     case 2:
    584       /* command register block */
    585       if (size != 8)
    586 	device_error(me, "reg entry %d must have a size of 8", reg);
    587       decoder->block[reg-1].space = space;
    588       decoder->block[reg-1].base_addr = address;
    589       decoder->block[reg-1].bound_addr = address + size - 1;
    590       decoder->block[reg-1].controller = (reg + 1) % nr_ide_controllers;
    591       decoder->block[reg-1].base_reg = ide_data_reg;
    592       DTRACE(ide, ("controller %d command register block at %d:0x%lx..0x%lx\n",
    593 		   decoder->block[reg-1].controller,
    594 		   decoder->block[reg-1].space,
    595 		   (unsigned long)decoder->block[reg-1].base_addr,
    596 		   (unsigned long)decoder->block[reg-1].bound_addr));
    597       break;
    598     case 3:
    599     case 4:
    600       /* control register block */
    601       if (size != 1)
    602 	device_error(me, "reg entry %d must have a size of 1", reg);
    603       decoder->block[reg-1].space = space;
    604       decoder->block[reg-1].base_addr = address;
    605       decoder->block[reg-1].bound_addr = address + size - 1;
    606       decoder->block[reg-1].controller = (reg + 1) % nr_ide_controllers;
    607       decoder->block[reg-1].base_reg = ide_alternate_status_reg;
    608       DTRACE(ide, ("controller %d control register block at %d:0x%lx..0x%lx\n",
    609 		   decoder->block[reg-1].controller,
    610 		   decoder->block[reg-1].space,
    611 		   (unsigned long)decoder->block[reg-1].base_addr,
    612 		   (unsigned long)decoder->block[reg-1].bound_addr));
    613       break;
    614     case 5:
    615       /* dma register block */
    616       if (size != 8)
    617 	device_error(me, "reg entry %d must have a size of 8", reg);
    618       decoder->block[reg-1].space = space;
    619       decoder->block[reg-1].base_addr = address;
    620       decoder->block[reg-1].bound_addr = address + 4 - 1;
    621       decoder->block[reg-1].base_reg = ide_dma_command_reg;
    622       decoder->block[reg-1].controller = 0;
    623       DTRACE(ide, ("controller %d dma register block at %d:0x%lx..0x%lx\n",
    624 		   decoder->block[reg-1].controller,
    625 		   decoder->block[reg-1].space,
    626 		   (unsigned long)decoder->block[reg-1].base_addr,
    627 		   (unsigned long)decoder->block[reg-1].bound_addr));
    628       decoder->block[reg].space = space;
    629       decoder->block[reg].base_addr = address + 4;
    630       decoder->block[reg].bound_addr = address + 8 - 1;
    631       decoder->block[reg].controller = 1;
    632       decoder->block[reg].base_reg = ide_dma_command_reg;
    633       DTRACE(ide, ("controller %d dma register block at %d:0x%lx..0x%lx\n",
    634 		   decoder->block[reg].controller,
    635 		   decoder->block[reg-1].space,
    636 		   (unsigned long)decoder->block[reg].base_addr,
    637 		   (unsigned long)decoder->block[reg].bound_addr));
    638       break;
    639     default:
    640       device_error(me, "internal error - bad switch");
    641       break;
    642     }
    643   }
    644 }
    645 
    646 
    647 
    648 typedef struct _hw_ide_device {
    649   ide_controller controller[nr_ide_controllers];
    650   address_decoder decoder;
    651 } hw_ide_device;
    652 
    653 
    654 static void
    655 hw_ide_init_address(device *me)
    656 {
    657   hw_ide_device *ide = device_data(me);
    658   int controller;
    659   int drive;
    660 
    661   /* zero some things */
    662   for (controller = 0; controller < nr_ide_controllers; controller++) {
    663     memset(&ide->controller[controller], 0, sizeof(ide_controller));
    664     for (drive = 0; drive < nr_ide_drives_per_controller; drive++) {
    665       ide->controller[controller].drive[drive].nr = drive;
    666     }
    667     ide->controller[controller].me = me;
    668     if (device_find_property(me, "ready-delay") != NULL)
    669       ide->controller[controller].ready_delay =
    670 	device_find_integer_property(me, "ready-delay");
    671   }
    672 
    673   /* attach this device to its parent */
    674   generic_device_init_address(me);
    675 
    676   /* determine our own address map */
    677   build_address_decoder(me, &ide->decoder);
    678 
    679 }
    680 
    681 
    682 static void
    683 hw_ide_attach_address(device *me,
    684 		      attach_type type,
    685 		      int space,
    686 		      unsigned_word addr,
    687 		      unsigned nr_bytes,
    688 		      access_type access,
    689 		      device *client) /*callback/default*/
    690 {
    691   hw_ide_device *ide = (hw_ide_device*)device_data(me);
    692   int controller_nr = addr / nr_ide_drives_per_controller;
    693   int drive_nr = addr % nr_ide_drives_per_controller;
    694   ide_controller *controller;
    695   ide_drive *drive;
    696   if (controller_nr >= nr_ide_controllers)
    697     device_error(me, "no controller for disk %s",
    698 		 device_path(client));
    699 
    700   controller = &ide->controller[controller_nr];
    701   drive = &controller->drive[drive_nr];
    702   drive->device = client;
    703   if (device_find_property(client, "ide-byte-count") != NULL)
    704     drive->geometry.byte = device_find_integer_property(client, "ide-byte-count");
    705   else
    706     drive->geometry.byte = 512;
    707   if (device_find_property(client, "ide-sector-count") != NULL)
    708     drive->geometry.sector = device_find_integer_property(client, "ide-sector-count");
    709   if (device_find_property(client, "ide-head-count") != NULL)
    710     drive->geometry.head = device_find_integer_property(client, "ide-head-count");
    711   drive->default_geometry = drive->geometry;
    712   DTRACE(ide, ("controller %d:%d %s byte-count %d, sector-count %d, head-count %d\n",
    713 	       controller_nr,
    714 	       drive->nr,
    715 	       device_path(client),
    716 	       drive->geometry.byte,
    717 	       drive->geometry.sector,
    718 	       drive->geometry.head));
    719 }
    720 
    721 
    722 static unsigned
    723 hw_ide_io_read_buffer(device *me,
    724 		      void *dest,
    725 		      int space,
    726 		      unsigned_word addr,
    727 		      unsigned nr_bytes,
    728 		      cpu *processor,
    729 		      unsigned_word cia)
    730 {
    731   hw_ide_device *ide = (hw_ide_device *)device_data(me);
    732   int control_nr;
    733   int reg;
    734   ide_controller *controller;
    735 
    736   /* find the interface */
    737   decode_address(me, &ide->decoder, space, addr, &control_nr, &reg, is_read);
    738   controller = & ide->controller[control_nr];
    739 
    740   /* process the transfer */
    741   memset(dest, 0, nr_bytes);
    742   switch (reg) {
    743   case ide_data_reg:
    744     do_fifo_read(me, controller, dest, nr_bytes);
    745     break;
    746   case ide_status_reg:
    747     *(unsigned8*)dest = get_status(me, controller);
    748     clear_interrupt(me, controller);
    749     break;
    750   case ide_alternate_status_reg:
    751     *(unsigned8*)dest = get_status(me, controller);
    752     break;
    753   case ide_error_reg:
    754   case ide_sector_count_reg:
    755   case ide_sector_number_reg:
    756   case ide_cylinder_reg0:
    757   case ide_cylinder_reg1:
    758   case ide_drive_head_reg:
    759   case ide_control_reg:
    760   case ide_dma_command_reg:
    761   case ide_dma_status_reg:
    762   case ide_dma_prd_table_address_reg0:
    763   case ide_dma_prd_table_address_reg1:
    764   case ide_dma_prd_table_address_reg2:
    765   case ide_dma_prd_table_address_reg3:
    766     *(unsigned8*)dest = controller->reg[reg];
    767     break;
    768   default:
    769     device_error(me, "bus-error at address 0x%lx", addr);
    770     break;
    771   }
    772   return nr_bytes;
    773 }
    774 
    775 
    776 static unsigned
    777 hw_ide_io_write_buffer(device *me,
    778 		       const void *source,
    779 		       int space,
    780 		       unsigned_word addr,
    781 		       unsigned nr_bytes,
    782 		       cpu *processor,
    783 		       unsigned_word cia)
    784 {
    785   hw_ide_device *ide = (hw_ide_device *)device_data(me);
    786   int control_nr;
    787   int reg;
    788   ide_controller *controller;
    789 
    790   /* find the interface */
    791   decode_address(me, &ide->decoder, space, addr, &control_nr, &reg, is_write);
    792   controller = &ide->controller[control_nr];
    793 
    794   /* process the access */
    795   switch (reg) {
    796   case ide_data_reg:
    797     do_fifo_write(me, controller, source, nr_bytes);
    798     break;
    799   case ide_command_reg:
    800     do_command(me, controller, *(unsigned8*)source);
    801     break;
    802   case ide_control_reg:
    803     controller->reg[reg] = *(unsigned8*)source;
    804     /* possibly cancel interrupts */
    805     if ((controller->reg[reg] & 0x02) == 0x02)
    806       clear_interrupt(me, controller);
    807     break;
    808   case ide_feature_reg:
    809   case ide_sector_count_reg:
    810   case ide_sector_number_reg:
    811   case ide_cylinder_reg0:
    812   case ide_cylinder_reg1:
    813   case ide_drive_head_reg:
    814   case ide_dma_command_reg:
    815   case ide_dma_status_reg:
    816   case ide_dma_prd_table_address_reg0:
    817   case ide_dma_prd_table_address_reg1:
    818   case ide_dma_prd_table_address_reg2:
    819   case ide_dma_prd_table_address_reg3:
    820     controller->reg[reg] = *(unsigned8*)source;
    821     break;
    822   default:
    823     device_error(me, "bus-error at 0x%lx", addr);
    824     break;
    825   }
    826   return nr_bytes;
    827 }
    828 
    829 
    830 static const device_interrupt_port_descriptor hw_ide_interrupt_ports[] = {
    831   { "a", 0, 0 },
    832   { "b", 1, 0 },
    833   { "c", 2, 0 },
    834   { "d", 3, 0 },
    835   { NULL }
    836 };
    837 
    838 
    839 
    840 static device_callbacks const hw_ide_callbacks = {
    841   { hw_ide_init_address, },
    842   { hw_ide_attach_address, }, /* attach */
    843   { hw_ide_io_read_buffer, hw_ide_io_write_buffer, },
    844   { NULL, }, /* DMA */
    845   { NULL, NULL, hw_ide_interrupt_ports }, /* interrupt */
    846   { generic_device_unit_decode,
    847     generic_device_unit_encode,
    848     generic_device_address_to_attach_address,
    849     generic_device_size_to_attach_size },
    850 };
    851 
    852 
    853 static void *
    854 hw_ide_create(const char *name,
    855 	      const device_unit *unit_address,
    856 	      const char *args)
    857 {
    858   hw_ide_device *ide = ZALLOC(hw_ide_device);
    859   return ide;
    860 }
    861 
    862 
    863 const device_descriptor hw_ide_device_descriptor[] = {
    864   { "ide", hw_ide_create, &hw_ide_callbacks },
    865   { NULL, },
    866 };
    867 
    868 #endif /* _HW_IDE_ */
    869