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