📄 libata-core.c
字号:
WARN_ON(!(len & 1)); ata_id_string(id, s, ofs, len - 1); p = s + strnlen(s, len - 1); while (p > s && p[-1] == ' ') p--; *p = '\0';}static u64 ata_id_n_sectors(const u16 *id){ if (ata_id_has_lba(id)) { if (ata_id_has_lba48(id)) return ata_id_u64(id, 100); else return ata_id_u32(id, 60); } else { if (ata_id_current_chs_valid(id)) return ata_id_u32(id, 57); else return id[1] * id[3] * id[6]; }}static u64 ata_tf_to_lba48(struct ata_taskfile *tf){ u64 sectors = 0; sectors |= ((u64)(tf->hob_lbah & 0xff)) << 40; sectors |= ((u64)(tf->hob_lbam & 0xff)) << 32; sectors |= (tf->hob_lbal & 0xff) << 24; sectors |= (tf->lbah & 0xff) << 16; sectors |= (tf->lbam & 0xff) << 8; sectors |= (tf->lbal & 0xff); return ++sectors;}static u64 ata_tf_to_lba(struct ata_taskfile *tf){ u64 sectors = 0; sectors |= (tf->device & 0x0f) << 24; sectors |= (tf->lbah & 0xff) << 16; sectors |= (tf->lbam & 0xff) << 8; sectors |= (tf->lbal & 0xff); return ++sectors;}/** * ata_read_native_max_address - Read native max address * @dev: target device * @max_sectors: out parameter for the result native max address * * Perform an LBA48 or LBA28 native size query upon the device in * question. * * RETURNS: * 0 on success, -EACCES if command is aborted by the drive. * -EIO on other errors. */static int ata_read_native_max_address(struct ata_device *dev, u64 *max_sectors){ unsigned int err_mask; struct ata_taskfile tf; int lba48 = ata_id_has_lba48(dev->id); ata_tf_init(dev, &tf); /* always clear all address registers */ tf.flags |= ATA_TFLAG_DEVICE | ATA_TFLAG_ISADDR; if (lba48) { tf.command = ATA_CMD_READ_NATIVE_MAX_EXT; tf.flags |= ATA_TFLAG_LBA48; } else tf.command = ATA_CMD_READ_NATIVE_MAX; tf.protocol |= ATA_PROT_NODATA; tf.device |= ATA_LBA; err_mask = ata_exec_internal(dev, &tf, NULL, DMA_NONE, NULL, 0, 0); if (err_mask) { ata_dev_printk(dev, KERN_WARNING, "failed to read native " "max address (err_mask=0x%x)\n", err_mask); if (err_mask == AC_ERR_DEV && (tf.feature & ATA_ABORTED)) return -EACCES; return -EIO; } if (lba48) *max_sectors = ata_tf_to_lba48(&tf); else *max_sectors = ata_tf_to_lba(&tf); if (dev->horkage & ATA_HORKAGE_HPA_SIZE) (*max_sectors)--; return 0;}/** * ata_set_max_sectors - Set max sectors * @dev: target device * @new_sectors: new max sectors value to set for the device * * Set max sectors of @dev to @new_sectors. * * RETURNS: * 0 on success, -EACCES if command is aborted or denied (due to * previous non-volatile SET_MAX) by the drive. -EIO on other * errors. */static int ata_set_max_sectors(struct ata_device *dev, u64 new_sectors){ unsigned int err_mask; struct ata_taskfile tf; int lba48 = ata_id_has_lba48(dev->id); new_sectors--; ata_tf_init(dev, &tf); tf.flags |= ATA_TFLAG_DEVICE | ATA_TFLAG_ISADDR; if (lba48) { tf.command = ATA_CMD_SET_MAX_EXT; tf.flags |= ATA_TFLAG_LBA48; tf.hob_lbal = (new_sectors >> 24) & 0xff; tf.hob_lbam = (new_sectors >> 32) & 0xff; tf.hob_lbah = (new_sectors >> 40) & 0xff; } else { tf.command = ATA_CMD_SET_MAX; tf.device |= (new_sectors >> 24) & 0xf; } tf.protocol |= ATA_PROT_NODATA; tf.device |= ATA_LBA; tf.lbal = (new_sectors >> 0) & 0xff; tf.lbam = (new_sectors >> 8) & 0xff; tf.lbah = (new_sectors >> 16) & 0xff; err_mask = ata_exec_internal(dev, &tf, NULL, DMA_NONE, NULL, 0, 0); if (err_mask) { ata_dev_printk(dev, KERN_WARNING, "failed to set " "max address (err_mask=0x%x)\n", err_mask); if (err_mask == AC_ERR_DEV && (tf.feature & (ATA_ABORTED | ATA_IDNF))) return -EACCES; return -EIO; } return 0;}/** * ata_hpa_resize - Resize a device with an HPA set * @dev: Device to resize * * Read the size of an LBA28 or LBA48 disk with HPA features and resize * it if required to the full size of the media. The caller must check * the drive has the HPA feature set enabled. * * RETURNS: * 0 on success, -errno on failure. */static int ata_hpa_resize(struct ata_device *dev){ struct ata_eh_context *ehc = &dev->link->eh_context; int print_info = ehc->i.flags & ATA_EHI_PRINTINFO; u64 sectors = ata_id_n_sectors(dev->id); u64 native_sectors; int rc; /* do we need to do it? */ if (dev->class != ATA_DEV_ATA || !ata_id_has_lba(dev->id) || !ata_id_hpa_enabled(dev->id) || (dev->horkage & ATA_HORKAGE_BROKEN_HPA)) return 0; /* read native max address */ rc = ata_read_native_max_address(dev, &native_sectors); if (rc) { /* If HPA isn't going to be unlocked, skip HPA * resizing from the next try. */ if (!ata_ignore_hpa) { ata_dev_printk(dev, KERN_WARNING, "HPA support seems " "broken, will skip HPA handling\n"); dev->horkage |= ATA_HORKAGE_BROKEN_HPA; /* we can continue if device aborted the command */ if (rc == -EACCES) rc = 0; } return rc; } /* nothing to do? */ if (native_sectors <= sectors || !ata_ignore_hpa) { if (!print_info || native_sectors == sectors) return 0; if (native_sectors > sectors) ata_dev_printk(dev, KERN_INFO, "HPA detected: current %llu, native %llu\n", (unsigned long long)sectors, (unsigned long long)native_sectors); else if (native_sectors < sectors) ata_dev_printk(dev, KERN_WARNING, "native sectors (%llu) is smaller than " "sectors (%llu)\n", (unsigned long long)native_sectors, (unsigned long long)sectors); return 0; } /* let's unlock HPA */ rc = ata_set_max_sectors(dev, native_sectors); if (rc == -EACCES) { /* if device aborted the command, skip HPA resizing */ ata_dev_printk(dev, KERN_WARNING, "device aborted resize " "(%llu -> %llu), skipping HPA handling\n", (unsigned long long)sectors, (unsigned long long)native_sectors); dev->horkage |= ATA_HORKAGE_BROKEN_HPA; return 0; } else if (rc) return rc; /* re-read IDENTIFY data */ rc = ata_dev_reread_id(dev, 0); if (rc) { ata_dev_printk(dev, KERN_ERR, "failed to re-read IDENTIFY " "data after HPA resizing\n"); return rc; } if (print_info) { u64 new_sectors = ata_id_n_sectors(dev->id); ata_dev_printk(dev, KERN_INFO, "HPA unlocked: %llu -> %llu, native %llu\n", (unsigned long long)sectors, (unsigned long long)new_sectors, (unsigned long long)native_sectors); } return 0;}/** * ata_id_to_dma_mode - Identify DMA mode from id block * @dev: device to identify * @unknown: mode to assume if we cannot tell * * Set up the timing values for the device based upon the identify * reported values for the DMA mode. This function is used by drivers * which rely upon firmware configured modes, but wish to report the * mode correctly when possible. * * In addition we emit similarly formatted messages to the default * ata_dev_set_mode handler, in order to provide consistency of * presentation. */void ata_id_to_dma_mode(struct ata_device *dev, u8 unknown){ unsigned int mask; u8 mode; /* Pack the DMA modes */ mask = ((dev->id[63] >> 8) << ATA_SHIFT_MWDMA) & ATA_MASK_MWDMA; if (dev->id[53] & 0x04) mask |= ((dev->id[88] >> 8) << ATA_SHIFT_UDMA) & ATA_MASK_UDMA; /* Select the mode in use */ mode = ata_xfer_mask2mode(mask); if (mode != 0) { ata_dev_printk(dev, KERN_INFO, "configured for %s\n", ata_mode_string(mask)); } else { /* SWDMA perhaps ? */ mode = unknown; ata_dev_printk(dev, KERN_INFO, "configured for DMA\n"); } /* Configure the device reporting */ dev->xfer_mode = mode; dev->xfer_shift = ata_xfer_mode2shift(mode);}/** * ata_noop_dev_select - Select device 0/1 on ATA bus * @ap: ATA channel to manipulate * @device: ATA device (numbered from zero) to select * * This function performs no actual function. * * May be used as the dev_select() entry in ata_port_operations. * * LOCKING: * caller. */void ata_noop_dev_select(struct ata_port *ap, unsigned int device){}/** * ata_std_dev_select - Select device 0/1 on ATA bus * @ap: ATA channel to manipulate * @device: ATA device (numbered from zero) to select * * Use the method defined in the ATA specification to * make either device 0, or device 1, active on the * ATA channel. Works with both PIO and MMIO. * * May be used as the dev_select() entry in ata_port_operations. * * LOCKING: * caller. */void ata_std_dev_select(struct ata_port *ap, unsigned int device){ u8 tmp; if (device == 0) tmp = ATA_DEVICE_OBS; else tmp = ATA_DEVICE_OBS | ATA_DEV1; iowrite8(tmp, ap->ioaddr.device_addr); ata_pause(ap); /* needed; also flushes, for mmio */}/** * ata_dev_select - Select device 0/1 on ATA bus * @ap: ATA channel to manipulate * @device: ATA device (numbered from zero) to select * @wait: non-zero to wait for Status register BSY bit to clear * @can_sleep: non-zero if context allows sleeping * * Use the method defined in the ATA specification to * make either device 0, or device 1, active on the * ATA channel. * * This is a high-level version of ata_std_dev_select(), * which additionally provides the services of inserting * the proper pauses and status polling, where needed. * * LOCKING: * caller. */void ata_dev_select(struct ata_port *ap, unsigned int device, unsigned int wait, unsigned int can_sleep){ if (ata_msg_probe(ap)) ata_port_printk(ap, KERN_INFO, "ata_dev_select: ENTER, " "device %u, wait %u\n", device, wait); if (wait) ata_wait_idle(ap); ap->ops->dev_select(ap, device); if (wait) { if (can_sleep && ap->link.device[device].class == ATA_DEV_ATAPI) msleep(150); ata_wait_idle(ap); }}/** * ata_dump_id - IDENTIFY DEVICE info debugging output * @id: IDENTIFY DEVICE page to dump * * Dump selected 16-bit words from the given IDENTIFY DEVICE * page. * * LOCKING: * caller. */static inline void ata_dump_id(const u16 *id){ DPRINTK("49==0x%04x " "53==0x%04x " "63==0x%04x " "64==0x%04x " "75==0x%04x \n", id[49], id[53], id[63], id[64], id[75]); DPRINTK("80==0x%04x " "81==0x%04x " "82==0x%04x " "83==0x%04x " "84==0x%04x \n", id[80], id[81], id[82], id[83], id[84]); DPRINTK("88==0x%04x " "93==0x%04x\n", id[88], id[93]);}/** * ata_id_xfermask - Compute xfermask from the given IDENTIFY data * @id: IDENTIFY data to compute xfer mask from * * Compute the xfermask for this device. This is not as trivial * as it seems if we must consider early devices correctly. * * FIXME: pre IDE drive timing (do we care ?). * * LOCKING: * None. * * RETURNS: * Computed xfermask */static unsigned int ata_id_xfermask(const u16 *id){ unsigned int pio_mask, mwdma_mask, udma_mask; /* Usual case. Word 53 indicates word 64 is valid */ if (id[ATA_ID_FIELD_VALID] & (1 << 1)) { pio_mask = id[ATA_ID_PIO_MODES] & 0x03; pio_mask <<= 3; pio_mask |= 0x7; } else { /* If word 64 isn't valid then Word 51 high byte holds * the PIO timing number for the maximum. Turn it into * a mask. */ u8 mode = (id[ATA_ID_OLD_PIO_MODES] >> 8) & 0xFF; if (mode < 5) /* Valid PIO range */ pio_mask = (2 << mode) - 1; else pio_mask = 1; /* But wait.. there's more. Design your standards by * committee and you too can get a free iordy field to * process. However its the speeds not the modes that * are supported... Note drivers using the timing API * will get this right anyway */ } mwdma_mask = id[ATA_ID_MWDMA_MODES] & 0x07; if (ata_id_is_cfa(id)) { /* * Process compact flash extended modes */ int pio = id[163] & 0x7; int dma = (id[163] >> 3) & 7; if (pio) pio_mask |= (1 << 5); if (pio > 1) pio_mask |= (1 << 6); if (dma) mwdma_mask |= (1 << 3); if (dma > 1) mwdma_mask |= (1 << 4); } udma_mask = 0; if (id[ATA_ID_FIELD_VALID] & (1 << 2)) udma_mask = id[ATA_ID_UDMA_MODES] & 0xff; return ata_pack_xfermask(pio_mask, mwdma_mask, udma_mask);}/** * ata_port_queue_task - Queue port_task * @ap: The ata_port to queue port_task for * @fn: workqueue function to be scheduled * @data: data for @fn to use * @delay: delay time for workqueue function * * Schedule @fn(@data) for execution after @delay jiffies using * port_task. There is one port_task per port and it's the * user(low level driver)'s responsibility to make sure that only * one task is active at any given time. * * libata core layer takes care of synchronization between * port_task and EH. ata_port_queue_task() may be ignored for EH * synchronization. * * LOCKING: * Inherited from caller. */void ata_port_queue_task(struct ata_port *ap, work_func_t fn, void *data, unsigned long delay){ PREPARE_DELAYED_WORK(&ap->port_task, fn); ap->port_task_data = data; /* may fail if ata_port_flush_task() in progress */ queue_delayed_work(ata_wq, &ap->port_task, delay);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -