This source file includes following definitions.
- HT_CONFIG
- HT_TIMING
- ht6560b_dev_select
- try_to_init_ht6560b
- ht_pio2timings
- ht_set_prefetch
- ht6560b_set_pio_mode
- ht6560b_init_dev
- ht6560b_init
   1 
   2 
   3 
   4 
   5 
   6 
   7 
   8 
   9 
  10 
  11 
  12 
  13 
  14 
  15 
  16 #define DRV_NAME        "ht6560b"
  17 #define HT6560B_VERSION "v0.08"
  18 
  19 #include <linux/module.h>
  20 #include <linux/types.h>
  21 #include <linux/kernel.h>
  22 #include <linux/delay.h>
  23 #include <linux/timer.h>
  24 #include <linux/mm.h>
  25 #include <linux/ioport.h>
  26 #include <linux/blkdev.h>
  27 #include <linux/ide.h>
  28 #include <linux/init.h>
  29 
  30 #include <asm/io.h>
  31 
  32   
  33 
  34 
  35 
  36 
  37 
  38 
  39 
  40 
  41 
  42 
  43 
  44 
  45 
  46 #define HT_CONFIG_PORT    0x3e6
  47 
  48 static inline u8 HT_CONFIG(ide_drive_t *drive)
  49 {
  50         return ((unsigned long)ide_get_drivedata(drive) & 0xff00) >> 8;
  51 }
  52 
  53 
  54 
  55 
  56 #define HT_CONFIG_DEFAULT 0x1c 
  57  
  58 #define HT_SECONDARY_IF   0x01
  59 #define HT_PREFETCH_MODE  0x20
  60 
  61 
  62 
  63 
  64 
  65 
  66 
  67 
  68 
  69 
  70 
  71 
  72 
  73 
  74 
  75 
  76 
  77 
  78 
  79 
  80 
  81 
  82 
  83 
  84 
  85 
  86 
  87 
  88 
  89 
  90 
  91 
  92 
  93 
  94 
  95 
  96 
  97 
  98 static inline u8 HT_TIMING(ide_drive_t *drive)
  99 {
 100         return (unsigned long)ide_get_drivedata(drive) & 0x00ff;
 101 }
 102 
 103 #define HT_TIMING_DEFAULT 0xff
 104 
 105 
 106 
 107 
 108 
 109 
 110 
 111 
 112 
 113 
 114 
 115 static void ht6560b_dev_select(ide_drive_t *drive)
 116 {
 117         ide_hwif_t *hwif = drive->hwif;
 118         unsigned long flags;
 119         static u8 current_select = 0;
 120         static u8 current_timing = 0;
 121         u8 select, timing;
 122         
 123         local_irq_save(flags);
 124 
 125         select = HT_CONFIG(drive);
 126         timing = HT_TIMING(drive);
 127 
 128         
 129 
 130 
 131 
 132         if (drive->media != ide_disk ||
 133             (drive->dev_flags & IDE_DFLAG_PRESENT) == 0)
 134                 select |= HT_PREFETCH_MODE;
 135 
 136         if (select != current_select || timing != current_timing) {
 137                 current_select = select;
 138                 current_timing = timing;
 139                 (void)inb(HT_CONFIG_PORT);
 140                 (void)inb(HT_CONFIG_PORT);
 141                 (void)inb(HT_CONFIG_PORT);
 142                 (void)inb(HT_CONFIG_PORT);
 143                 outb(select, HT_CONFIG_PORT);
 144                 
 145 
 146 
 147                 outb(timing, hwif->io_ports.device_addr);
 148                 (void)inb(hwif->io_ports.status_addr);
 149 #ifdef DEBUG
 150                 printk("ht6560b: %s: select=%#x timing=%#x\n",
 151                         drive->name, select, timing);
 152 #endif
 153         }
 154         local_irq_restore(flags);
 155 
 156         outb(drive->select | ATA_DEVICE_OBS, hwif->io_ports.device_addr);
 157 }
 158 
 159 
 160 
 161 
 162 static int __init try_to_init_ht6560b(void)
 163 {
 164         u8 orig_value;
 165         int i;
 166         
 167         
 168         if ((orig_value = inb(HT_CONFIG_PORT)) == 0xff)
 169                 return 0;
 170         
 171         for (i=3;i>0;i--) {
 172                 outb(0x00, HT_CONFIG_PORT);
 173                 if (!( (~inb(HT_CONFIG_PORT)) & 0x3f )) {
 174                         outb(orig_value, HT_CONFIG_PORT);
 175                         return 0;
 176                 }
 177         }
 178         outb(0x00, HT_CONFIG_PORT);
 179         if ((~inb(HT_CONFIG_PORT))& 0x3f) {
 180                 outb(orig_value, HT_CONFIG_PORT);
 181                 return 0;
 182         }
 183         
 184 
 185 
 186         outb(HT_CONFIG_DEFAULT, HT_CONFIG_PORT);
 187         outb(HT_TIMING_DEFAULT, 0x1f6); 
 188         (void)inb(0x1f7);               
 189 
 190         printk("ht6560b " HT6560B_VERSION
 191                ": chipset detected and initialized"
 192 #ifdef DEBUG
 193                " with debug enabled"
 194 #endif
 195                "\n"
 196                 );
 197         return 1;
 198 }
 199 
 200 static u8 ht_pio2timings(ide_drive_t *drive, const u8 pio)
 201 {
 202         int active_time, recovery_time;
 203         int active_cycles, recovery_cycles;
 204         int bus_speed = ide_vlb_clk ? ide_vlb_clk : 50;
 205 
 206         if (pio) {
 207                 unsigned int cycle_time;
 208                 struct ide_timing *t = ide_timing_find_mode(XFER_PIO_0 + pio);
 209 
 210                 cycle_time = ide_pio_cycle_time(drive, pio);
 211 
 212                 
 213 
 214 
 215 
 216 
 217                 active_time = t->active;
 218                 recovery_time = cycle_time - active_time - t->setup;
 219                 
 220 
 221 
 222                 active_cycles   = (active_time   * bus_speed + 999) / 1000;
 223                 recovery_cycles = (recovery_time * bus_speed + 999) / 1000;
 224                 
 225 
 226 
 227                 if (active_cycles   < 2)  active_cycles   = 2;
 228                 if (recovery_cycles < 2)  recovery_cycles = 2;
 229                 if (active_cycles   > 15) active_cycles   = 15;
 230                 if (recovery_cycles > 15) recovery_cycles = 0;  
 231                 
 232 #ifdef DEBUG
 233                 printk("ht6560b: drive %s setting pio=%d recovery=%d (%dns) active=%d (%dns)\n", drive->name, pio, recovery_cycles, recovery_time, active_cycles, active_time);
 234 #endif
 235                 
 236                 return (u8)((recovery_cycles << 4) | active_cycles);
 237         } else {
 238                 
 239 #ifdef DEBUG
 240                 printk("ht6560b: drive %s setting pio=0\n", drive->name);
 241 #endif
 242                 
 243                 return HT_TIMING_DEFAULT;    
 244         }
 245 }
 246 
 247 static DEFINE_SPINLOCK(ht6560b_lock);
 248 
 249 
 250 
 251 
 252 static void ht_set_prefetch(ide_drive_t *drive, u8 state)
 253 {
 254         unsigned long flags, config;
 255         int t = HT_PREFETCH_MODE << 8;
 256 
 257         spin_lock_irqsave(&ht6560b_lock, flags);
 258 
 259         config = (unsigned long)ide_get_drivedata(drive);
 260 
 261         
 262 
 263 
 264         if (state) {
 265                 config |= t;   
 266                 drive->dev_flags |= IDE_DFLAG_NO_UNMASK;
 267                 drive->dev_flags &= ~IDE_DFLAG_UNMASK;
 268         } else {
 269                 config &= ~t;  
 270                 drive->dev_flags &= ~IDE_DFLAG_NO_UNMASK;
 271         }
 272 
 273         ide_set_drivedata(drive, (void *)config);
 274 
 275         spin_unlock_irqrestore(&ht6560b_lock, flags);
 276 
 277 #ifdef DEBUG
 278         printk("ht6560b: drive %s prefetch mode %sabled\n", drive->name, (state ? "en" : "dis"));
 279 #endif
 280 }
 281 
 282 static void ht6560b_set_pio_mode(ide_hwif_t *hwif, ide_drive_t *drive)
 283 {
 284         unsigned long flags, config;
 285         const u8 pio = drive->pio_mode - XFER_PIO_0;
 286         u8 timing;
 287         
 288         switch (pio) {
 289         case 8:         
 290         case 9:         
 291                 ht_set_prefetch(drive, pio & 1);
 292                 return;
 293         }
 294 
 295         timing = ht_pio2timings(drive, pio);
 296 
 297         spin_lock_irqsave(&ht6560b_lock, flags);
 298         config = (unsigned long)ide_get_drivedata(drive);
 299         config &= 0xff00;
 300         config |= timing;
 301         ide_set_drivedata(drive, (void *)config);
 302         spin_unlock_irqrestore(&ht6560b_lock, flags);
 303 
 304 #ifdef DEBUG
 305         printk("ht6560b: drive %s tuned to pio mode %#x timing=%#x\n", drive->name, pio, timing);
 306 #endif
 307 }
 308 
 309 static void __init ht6560b_init_dev(ide_drive_t *drive)
 310 {
 311         ide_hwif_t *hwif = drive->hwif;
 312         
 313         int t = (HT_CONFIG_DEFAULT << 8) | HT_TIMING_DEFAULT;
 314 
 315         if (hwif->channel)
 316                 t |= (HT_SECONDARY_IF << 8);
 317 
 318         ide_set_drivedata(drive, (void *)t);
 319 }
 320 
 321 static bool probe_ht6560b;
 322 
 323 module_param_named(probe, probe_ht6560b, bool, 0);
 324 MODULE_PARM_DESC(probe, "probe for HT6560B chipset");
 325 
 326 static const struct ide_tp_ops ht6560b_tp_ops = {
 327         .exec_command           = ide_exec_command,
 328         .read_status            = ide_read_status,
 329         .read_altstatus         = ide_read_altstatus,
 330         .write_devctl           = ide_write_devctl,
 331 
 332         .dev_select             = ht6560b_dev_select,
 333         .tf_load                = ide_tf_load,
 334         .tf_read                = ide_tf_read,
 335 
 336         .input_data             = ide_input_data,
 337         .output_data            = ide_output_data,
 338 };
 339 
 340 static const struct ide_port_ops ht6560b_port_ops = {
 341         .init_dev               = ht6560b_init_dev,
 342         .set_pio_mode           = ht6560b_set_pio_mode,
 343 };
 344 
 345 static const struct ide_port_info ht6560b_port_info __initconst = {
 346         .name                   = DRV_NAME,
 347         .chipset                = ide_ht6560b,
 348         .tp_ops                 = &ht6560b_tp_ops,
 349         .port_ops               = &ht6560b_port_ops,
 350         .host_flags             = IDE_HFLAG_SERIALIZE | 
 351                                   IDE_HFLAG_NO_DMA |
 352                                   IDE_HFLAG_ABUSE_PREFETCH,
 353         .pio_mask               = ATA_PIO4,
 354 };
 355 
 356 static int __init ht6560b_init(void)
 357 {
 358         if (probe_ht6560b == 0)
 359                 return -ENODEV;
 360 
 361         if (!request_region(HT_CONFIG_PORT, 1, DRV_NAME)) {
 362                 printk(KERN_NOTICE "%s: HT_CONFIG_PORT not found\n",
 363                         __func__);
 364                 return -ENODEV;
 365         }
 366 
 367         if (!try_to_init_ht6560b()) {
 368                 printk(KERN_NOTICE "%s: HBA not found\n", __func__);
 369                 goto release_region;
 370         }
 371 
 372         return ide_legacy_device_add(&ht6560b_port_info, 0);
 373 
 374 release_region:
 375         release_region(HT_CONFIG_PORT, 1);
 376         return -ENODEV;
 377 }
 378 
 379 module_init(ht6560b_init);
 380 
 381 MODULE_AUTHOR("See Local File");
 382 MODULE_DESCRIPTION("HT-6560B EIDE-controller support");
 383 MODULE_LICENSE("GPL");