Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
at v2.6.29 423 lines 11 kB view raw
1#include <linux/types.h> 2#include <linux/string.h> 3#include <linux/kernel.h> 4#include <linux/interrupt.h> 5#include <linux/ide.h> 6#include <linux/bitops.h> 7 8static const char *udma_str[] = 9 { "UDMA/16", "UDMA/25", "UDMA/33", "UDMA/44", 10 "UDMA/66", "UDMA/100", "UDMA/133", "UDMA7" }; 11static const char *mwdma_str[] = 12 { "MWDMA0", "MWDMA1", "MWDMA2" }; 13static const char *swdma_str[] = 14 { "SWDMA0", "SWDMA1", "SWDMA2" }; 15static const char *pio_str[] = 16 { "PIO0", "PIO1", "PIO2", "PIO3", "PIO4", "PIO5" }; 17 18/** 19 * ide_xfer_verbose - return IDE mode names 20 * @mode: transfer mode 21 * 22 * Returns a constant string giving the name of the mode 23 * requested. 24 */ 25 26const char *ide_xfer_verbose(u8 mode) 27{ 28 const char *s; 29 u8 i = mode & 0xf; 30 31 if (mode >= XFER_UDMA_0 && mode <= XFER_UDMA_7) 32 s = udma_str[i]; 33 else if (mode >= XFER_MW_DMA_0 && mode <= XFER_MW_DMA_2) 34 s = mwdma_str[i]; 35 else if (mode >= XFER_SW_DMA_0 && mode <= XFER_SW_DMA_2) 36 s = swdma_str[i]; 37 else if (mode >= XFER_PIO_0 && mode <= XFER_PIO_5) 38 s = pio_str[i & 0x7]; 39 else if (mode == XFER_PIO_SLOW) 40 s = "PIO SLOW"; 41 else 42 s = "XFER ERROR"; 43 44 return s; 45} 46EXPORT_SYMBOL(ide_xfer_verbose); 47 48/** 49 * ide_rate_filter - filter transfer mode 50 * @drive: IDE device 51 * @speed: desired speed 52 * 53 * Given the available transfer modes this function returns 54 * the best available speed at or below the speed requested. 55 * 56 * TODO: check device PIO capabilities 57 */ 58 59static u8 ide_rate_filter(ide_drive_t *drive, u8 speed) 60{ 61 ide_hwif_t *hwif = drive->hwif; 62 u8 mode = ide_find_dma_mode(drive, speed); 63 64 if (mode == 0) { 65 if (hwif->pio_mask) 66 mode = fls(hwif->pio_mask) - 1 + XFER_PIO_0; 67 else 68 mode = XFER_PIO_4; 69 } 70 71/* printk("%s: mode 0x%02x, speed 0x%02x\n", __func__, mode, speed); */ 72 73 return min(speed, mode); 74} 75 76/** 77 * ide_get_best_pio_mode - get PIO mode from drive 78 * @drive: drive to consider 79 * @mode_wanted: preferred mode 80 * @max_mode: highest allowed mode 81 * 82 * This routine returns the recommended PIO settings for a given drive, 83 * based on the drive->id information and the ide_pio_blacklist[]. 84 * 85 * Drive PIO mode is auto-selected if 255 is passed as mode_wanted. 86 * This is used by most chipset support modules when "auto-tuning". 87 */ 88 89u8 ide_get_best_pio_mode(ide_drive_t *drive, u8 mode_wanted, u8 max_mode) 90{ 91 u16 *id = drive->id; 92 int pio_mode = -1, overridden = 0; 93 94 if (mode_wanted != 255) 95 return min_t(u8, mode_wanted, max_mode); 96 97 if ((drive->hwif->host_flags & IDE_HFLAG_PIO_NO_BLACKLIST) == 0) 98 pio_mode = ide_scan_pio_blacklist((char *)&id[ATA_ID_PROD]); 99 100 if (pio_mode != -1) { 101 printk(KERN_INFO "%s: is on PIO blacklist\n", drive->name); 102 } else { 103 pio_mode = id[ATA_ID_OLD_PIO_MODES] >> 8; 104 if (pio_mode > 2) { /* 2 is maximum allowed tPIO value */ 105 pio_mode = 2; 106 overridden = 1; 107 } 108 109 if (id[ATA_ID_FIELD_VALID] & 2) { /* ATA2? */ 110 if (ata_id_has_iordy(id)) { 111 if (id[ATA_ID_PIO_MODES] & 7) { 112 overridden = 0; 113 if (id[ATA_ID_PIO_MODES] & 4) 114 pio_mode = 5; 115 else if (id[ATA_ID_PIO_MODES] & 2) 116 pio_mode = 4; 117 else 118 pio_mode = 3; 119 } 120 } 121 } 122 123 if (overridden) 124 printk(KERN_INFO "%s: tPIO > 2, assuming tPIO = 2\n", 125 drive->name); 126 } 127 128 if (pio_mode > max_mode) 129 pio_mode = max_mode; 130 131 return pio_mode; 132} 133EXPORT_SYMBOL_GPL(ide_get_best_pio_mode); 134 135/* req_pio == "255" for auto-tune */ 136void ide_set_pio(ide_drive_t *drive, u8 req_pio) 137{ 138 ide_hwif_t *hwif = drive->hwif; 139 const struct ide_port_ops *port_ops = hwif->port_ops; 140 u8 host_pio, pio; 141 142 if (port_ops == NULL || port_ops->set_pio_mode == NULL || 143 (hwif->host_flags & IDE_HFLAG_NO_SET_MODE)) 144 return; 145 146 BUG_ON(hwif->pio_mask == 0x00); 147 148 host_pio = fls(hwif->pio_mask) - 1; 149 150 pio = ide_get_best_pio_mode(drive, req_pio, host_pio); 151 152 /* 153 * TODO: 154 * - report device max PIO mode 155 * - check req_pio != 255 against device max PIO mode 156 */ 157 printk(KERN_DEBUG "%s: host max PIO%d wanted PIO%d%s selected PIO%d\n", 158 drive->name, host_pio, req_pio, 159 req_pio == 255 ? "(auto-tune)" : "", pio); 160 161 (void)ide_set_pio_mode(drive, XFER_PIO_0 + pio); 162} 163EXPORT_SYMBOL_GPL(ide_set_pio); 164 165/** 166 * ide_toggle_bounce - handle bounce buffering 167 * @drive: drive to update 168 * @on: on/off boolean 169 * 170 * Enable or disable bounce buffering for the device. Drives move 171 * between PIO and DMA and that changes the rules we need. 172 */ 173 174void ide_toggle_bounce(ide_drive_t *drive, int on) 175{ 176 u64 addr = BLK_BOUNCE_HIGH; /* dma64_addr_t */ 177 178 if (!PCI_DMA_BUS_IS_PHYS) { 179 addr = BLK_BOUNCE_ANY; 180 } else if (on && drive->media == ide_disk) { 181 struct device *dev = drive->hwif->dev; 182 183 if (dev && dev->dma_mask) 184 addr = *dev->dma_mask; 185 } 186 187 if (drive->queue) 188 blk_queue_bounce_limit(drive->queue, addr); 189} 190 191int ide_set_pio_mode(ide_drive_t *drive, const u8 mode) 192{ 193 ide_hwif_t *hwif = drive->hwif; 194 const struct ide_port_ops *port_ops = hwif->port_ops; 195 196 if (hwif->host_flags & IDE_HFLAG_NO_SET_MODE) 197 return 0; 198 199 if (port_ops == NULL || port_ops->set_pio_mode == NULL) 200 return -1; 201 202 /* 203 * TODO: temporary hack for some legacy host drivers that didn't 204 * set transfer mode on the device in ->set_pio_mode method... 205 */ 206 if (port_ops->set_dma_mode == NULL) { 207 port_ops->set_pio_mode(drive, mode - XFER_PIO_0); 208 return 0; 209 } 210 211 if (hwif->host_flags & IDE_HFLAG_POST_SET_MODE) { 212 if (ide_config_drive_speed(drive, mode)) 213 return -1; 214 port_ops->set_pio_mode(drive, mode - XFER_PIO_0); 215 return 0; 216 } else { 217 port_ops->set_pio_mode(drive, mode - XFER_PIO_0); 218 return ide_config_drive_speed(drive, mode); 219 } 220} 221 222int ide_set_dma_mode(ide_drive_t *drive, const u8 mode) 223{ 224 ide_hwif_t *hwif = drive->hwif; 225 const struct ide_port_ops *port_ops = hwif->port_ops; 226 227 if (hwif->host_flags & IDE_HFLAG_NO_SET_MODE) 228 return 0; 229 230 if (port_ops == NULL || port_ops->set_dma_mode == NULL) 231 return -1; 232 233 if (hwif->host_flags & IDE_HFLAG_POST_SET_MODE) { 234 if (ide_config_drive_speed(drive, mode)) 235 return -1; 236 port_ops->set_dma_mode(drive, mode); 237 return 0; 238 } else { 239 port_ops->set_dma_mode(drive, mode); 240 return ide_config_drive_speed(drive, mode); 241 } 242} 243EXPORT_SYMBOL_GPL(ide_set_dma_mode); 244 245/** 246 * ide_set_xfer_rate - set transfer rate 247 * @drive: drive to set 248 * @rate: speed to attempt to set 249 * 250 * General helper for setting the speed of an IDE device. This 251 * function knows about user enforced limits from the configuration 252 * which ->set_pio_mode/->set_dma_mode does not. 253 */ 254 255int ide_set_xfer_rate(ide_drive_t *drive, u8 rate) 256{ 257 ide_hwif_t *hwif = drive->hwif; 258 const struct ide_port_ops *port_ops = hwif->port_ops; 259 260 if (port_ops == NULL || port_ops->set_dma_mode == NULL || 261 (hwif->host_flags & IDE_HFLAG_NO_SET_MODE)) 262 return -1; 263 264 rate = ide_rate_filter(drive, rate); 265 266 BUG_ON(rate < XFER_PIO_0); 267 268 if (rate >= XFER_PIO_0 && rate <= XFER_PIO_5) 269 return ide_set_pio_mode(drive, rate); 270 271 return ide_set_dma_mode(drive, rate); 272} 273 274static void ide_dump_opcode(ide_drive_t *drive) 275{ 276 struct request *rq = drive->hwif->rq; 277 ide_task_t *task = NULL; 278 279 if (!rq) 280 return; 281 282 if (rq->cmd_type == REQ_TYPE_ATA_TASKFILE) 283 task = rq->special; 284 285 printk(KERN_ERR "ide: failed opcode was: "); 286 if (task == NULL) 287 printk(KERN_CONT "unknown\n"); 288 else 289 printk(KERN_CONT "0x%02x\n", task->tf.command); 290} 291 292u64 ide_get_lba_addr(struct ide_taskfile *tf, int lba48) 293{ 294 u32 high, low; 295 296 if (lba48) 297 high = (tf->hob_lbah << 16) | (tf->hob_lbam << 8) | 298 tf->hob_lbal; 299 else 300 high = tf->device & 0xf; 301 low = (tf->lbah << 16) | (tf->lbam << 8) | tf->lbal; 302 303 return ((u64)high << 24) | low; 304} 305EXPORT_SYMBOL_GPL(ide_get_lba_addr); 306 307static void ide_dump_sector(ide_drive_t *drive) 308{ 309 ide_task_t task; 310 struct ide_taskfile *tf = &task.tf; 311 u8 lba48 = !!(drive->dev_flags & IDE_DFLAG_LBA48); 312 313 memset(&task, 0, sizeof(task)); 314 if (lba48) 315 task.tf_flags = IDE_TFLAG_IN_LBA | IDE_TFLAG_IN_HOB_LBA | 316 IDE_TFLAG_LBA48; 317 else 318 task.tf_flags = IDE_TFLAG_IN_LBA | IDE_TFLAG_IN_DEVICE; 319 320 drive->hwif->tp_ops->tf_read(drive, &task); 321 322 if (lba48 || (tf->device & ATA_LBA)) 323 printk(KERN_CONT ", LBAsect=%llu", 324 (unsigned long long)ide_get_lba_addr(tf, lba48)); 325 else 326 printk(KERN_CONT ", CHS=%d/%d/%d", (tf->lbah << 8) + tf->lbam, 327 tf->device & 0xf, tf->lbal); 328} 329 330static void ide_dump_ata_error(ide_drive_t *drive, u8 err) 331{ 332 printk(KERN_ERR "{ "); 333 if (err & ATA_ABORTED) 334 printk(KERN_CONT "DriveStatusError "); 335 if (err & ATA_ICRC) 336 printk(KERN_CONT "%s", 337 (err & ATA_ABORTED) ? "BadCRC " : "BadSector "); 338 if (err & ATA_UNC) 339 printk(KERN_CONT "UncorrectableError "); 340 if (err & ATA_IDNF) 341 printk(KERN_CONT "SectorIdNotFound "); 342 if (err & ATA_TRK0NF) 343 printk(KERN_CONT "TrackZeroNotFound "); 344 if (err & ATA_AMNF) 345 printk(KERN_CONT "AddrMarkNotFound "); 346 printk(KERN_CONT "}"); 347 if ((err & (ATA_BBK | ATA_ABORTED)) == ATA_BBK || 348 (err & (ATA_UNC | ATA_IDNF | ATA_AMNF))) { 349 struct request *rq = drive->hwif->rq; 350 351 ide_dump_sector(drive); 352 353 if (rq) 354 printk(KERN_CONT ", sector=%llu", 355 (unsigned long long)rq->sector); 356 } 357 printk(KERN_CONT "\n"); 358} 359 360static void ide_dump_atapi_error(ide_drive_t *drive, u8 err) 361{ 362 printk(KERN_ERR "{ "); 363 if (err & ATAPI_ILI) 364 printk(KERN_CONT "IllegalLengthIndication "); 365 if (err & ATAPI_EOM) 366 printk(KERN_CONT "EndOfMedia "); 367 if (err & ATA_ABORTED) 368 printk(KERN_CONT "AbortedCommand "); 369 if (err & ATA_MCR) 370 printk(KERN_CONT "MediaChangeRequested "); 371 if (err & ATAPI_LFS) 372 printk(KERN_CONT "LastFailedSense=0x%02x ", 373 (err & ATAPI_LFS) >> 4); 374 printk(KERN_CONT "}\n"); 375} 376 377/** 378 * ide_dump_status - translate ATA/ATAPI error 379 * @drive: drive that status applies to 380 * @msg: text message to print 381 * @stat: status byte to decode 382 * 383 * Error reporting, in human readable form (luxurious, but a memory hog). 384 * Combines the drive name, message and status byte to provide a 385 * user understandable explanation of the device error. 386 */ 387 388u8 ide_dump_status(ide_drive_t *drive, const char *msg, u8 stat) 389{ 390 u8 err = 0; 391 392 printk(KERN_ERR "%s: %s: status=0x%02x { ", drive->name, msg, stat); 393 if (stat & ATA_BUSY) 394 printk(KERN_CONT "Busy "); 395 else { 396 if (stat & ATA_DRDY) 397 printk(KERN_CONT "DriveReady "); 398 if (stat & ATA_DF) 399 printk(KERN_CONT "DeviceFault "); 400 if (stat & ATA_DSC) 401 printk(KERN_CONT "SeekComplete "); 402 if (stat & ATA_DRQ) 403 printk(KERN_CONT "DataRequest "); 404 if (stat & ATA_CORR) 405 printk(KERN_CONT "CorrectedError "); 406 if (stat & ATA_IDX) 407 printk(KERN_CONT "Index "); 408 if (stat & ATA_ERR) 409 printk(KERN_CONT "Error "); 410 } 411 printk(KERN_CONT "}\n"); 412 if ((stat & (ATA_BUSY | ATA_ERR)) == ATA_ERR) { 413 err = ide_read_error(drive); 414 printk(KERN_ERR "%s: %s: error=0x%02x ", drive->name, msg, err); 415 if (drive->media == ide_disk) 416 ide_dump_ata_error(drive, err); 417 else 418 ide_dump_atapi_error(drive, err); 419 } 420 ide_dump_opcode(drive); 421 return err; 422} 423EXPORT_SYMBOL(ide_dump_status);