⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 libata-core.c

📁 linux 内核源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
		dev->flags |= ATA_DFLAG_NCQ;	}	if (hdepth >= ddepth)		snprintf(desc, desc_sz, "NCQ (depth %d)", ddepth);	else		snprintf(desc, desc_sz, "NCQ (depth %d/%d)", hdepth, ddepth);}/** *	ata_dev_configure - Configure the specified ATA/ATAPI device *	@dev: Target device to configure * *	Configure @dev according to @dev->id.  Generic and low-level *	driver specific fixups are also applied. * *	LOCKING: *	Kernel thread context (may sleep) * *	RETURNS: *	0 on success, -errno otherwise */int ata_dev_configure(struct ata_device *dev){	struct ata_port *ap = dev->link->ap;	struct ata_eh_context *ehc = &dev->link->eh_context;	int print_info = ehc->i.flags & ATA_EHI_PRINTINFO;	const u16 *id = dev->id;	unsigned int xfer_mask;	char revbuf[7];		/* XYZ-99\0 */	char fwrevbuf[ATA_ID_FW_REV_LEN+1];	char modelbuf[ATA_ID_PROD_LEN+1];	int rc;	if (!ata_dev_enabled(dev) && ata_msg_info(ap)) {		ata_dev_printk(dev, KERN_INFO, "%s: ENTER/EXIT -- nodev\n",			       __FUNCTION__);		return 0;	}	if (ata_msg_probe(ap))		ata_dev_printk(dev, KERN_DEBUG, "%s: ENTER\n", __FUNCTION__);	/* set horkage */	dev->horkage |= ata_dev_blacklisted(dev);	/* let ACPI work its magic */	rc = ata_acpi_on_devcfg(dev);	if (rc)		return rc;	/* massage HPA, do it early as it might change IDENTIFY data */	rc = ata_hpa_resize(dev);	if (rc)		return rc;	/* print device capabilities */	if (ata_msg_probe(ap))		ata_dev_printk(dev, KERN_DEBUG,			       "%s: cfg 49:%04x 82:%04x 83:%04x 84:%04x "			       "85:%04x 86:%04x 87:%04x 88:%04x\n",			       __FUNCTION__,			       id[49], id[82], id[83], id[84],			       id[85], id[86], id[87], id[88]);	/* initialize to-be-configured parameters */	dev->flags &= ~ATA_DFLAG_CFG_MASK;	dev->max_sectors = 0;	dev->cdb_len = 0;	dev->n_sectors = 0;	dev->cylinders = 0;	dev->heads = 0;	dev->sectors = 0;	/*	 * common ATA, ATAPI feature tests	 */	/* find max transfer mode; for printk only */	xfer_mask = ata_id_xfermask(id);	if (ata_msg_probe(ap))		ata_dump_id(id);	/* SCSI only uses 4-char revisions, dump full 8 chars from ATA */	ata_id_c_string(dev->id, fwrevbuf, ATA_ID_FW_REV,			sizeof(fwrevbuf));	ata_id_c_string(dev->id, modelbuf, ATA_ID_PROD,			sizeof(modelbuf));	/* ATA-specific feature tests */	if (dev->class == ATA_DEV_ATA) {		if (ata_id_is_cfa(id)) {			if (id[162] & 1) /* CPRM may make this media unusable */				ata_dev_printk(dev, KERN_WARNING,					       "supports DRM functions and may "					       "not be fully accessable.\n");			snprintf(revbuf, 7, "CFA");		} else			snprintf(revbuf, 7, "ATA-%d", ata_id_major_version(id));		dev->n_sectors = ata_id_n_sectors(id);		if (dev->id[59] & 0x100)			dev->multi_count = dev->id[59] & 0xff;		if (ata_id_has_lba(id)) {			const char *lba_desc;			char ncq_desc[20];			lba_desc = "LBA";			dev->flags |= ATA_DFLAG_LBA;			if (ata_id_has_lba48(id)) {				dev->flags |= ATA_DFLAG_LBA48;				lba_desc = "LBA48";				if (dev->n_sectors >= (1UL << 28) &&				    ata_id_has_flush_ext(id))					dev->flags |= ATA_DFLAG_FLUSH_EXT;			}			/* config NCQ */			ata_dev_config_ncq(dev, ncq_desc, sizeof(ncq_desc));			/* print device info to dmesg */			if (ata_msg_drv(ap) && print_info) {				ata_dev_printk(dev, KERN_INFO,					"%s: %s, %s, max %s\n",					revbuf, modelbuf, fwrevbuf,					ata_mode_string(xfer_mask));				ata_dev_printk(dev, KERN_INFO,					"%Lu sectors, multi %u: %s %s\n",					(unsigned long long)dev->n_sectors,					dev->multi_count, lba_desc, ncq_desc);			}		} else {			/* CHS */			/* Default translation */			dev->cylinders	= id[1];			dev->heads	= id[3];			dev->sectors	= id[6];			if (ata_id_current_chs_valid(id)) {				/* Current CHS translation is valid. */				dev->cylinders = id[54];				dev->heads     = id[55];				dev->sectors   = id[56];			}			/* print device info to dmesg */			if (ata_msg_drv(ap) && print_info) {				ata_dev_printk(dev, KERN_INFO,					"%s: %s, %s, max %s\n",					revbuf,	modelbuf, fwrevbuf,					ata_mode_string(xfer_mask));				ata_dev_printk(dev, KERN_INFO,					"%Lu sectors, multi %u, CHS %u/%u/%u\n",					(unsigned long long)dev->n_sectors,					dev->multi_count, dev->cylinders,					dev->heads, dev->sectors);			}		}		dev->cdb_len = 16;	}	/* ATAPI-specific feature tests */	else if (dev->class == ATA_DEV_ATAPI) {		const char *cdb_intr_string = "";		const char *atapi_an_string = "";		u32 sntf;		rc = atapi_cdb_len(id);		if ((rc < 12) || (rc > ATAPI_CDB_LEN)) {			if (ata_msg_warn(ap))				ata_dev_printk(dev, KERN_WARNING,					       "unsupported CDB len\n");			rc = -EINVAL;			goto err_out_nosup;		}		dev->cdb_len = (unsigned int) rc;		/* Enable ATAPI AN if both the host and device have		 * the support.  If PMP is attached, SNTF is required		 * to enable ATAPI AN to discern between PHY status		 * changed notifications and ATAPI ANs.		 */		if ((ap->flags & ATA_FLAG_AN) && ata_id_has_atapi_AN(id) &&		    (!ap->nr_pmp_links ||		     sata_scr_read(&ap->link, SCR_NOTIFICATION, &sntf) == 0)) {			unsigned int err_mask;			/* issue SET feature command to turn this on */			err_mask = ata_dev_set_feature(dev,					SETFEATURES_SATA_ENABLE, SATA_AN);			if (err_mask)				ata_dev_printk(dev, KERN_ERR,					"failed to enable ATAPI AN "					"(err_mask=0x%x)\n", err_mask);			else {				dev->flags |= ATA_DFLAG_AN;				atapi_an_string = ", ATAPI AN";			}		}		if (ata_id_cdb_intr(dev->id)) {			dev->flags |= ATA_DFLAG_CDB_INTR;			cdb_intr_string = ", CDB intr";		}		/* print device info to dmesg */		if (ata_msg_drv(ap) && print_info)			ata_dev_printk(dev, KERN_INFO,				       "ATAPI: %s, %s, max %s%s%s\n",				       modelbuf, fwrevbuf,				       ata_mode_string(xfer_mask),				       cdb_intr_string, atapi_an_string);	}	/* determine max_sectors */	dev->max_sectors = ATA_MAX_SECTORS;	if (dev->flags & ATA_DFLAG_LBA48)		dev->max_sectors = ATA_MAX_SECTORS_LBA48;	if (!(dev->horkage & ATA_HORKAGE_IPM)) {		if (ata_id_has_hipm(dev->id))			dev->flags |= ATA_DFLAG_HIPM;		if (ata_id_has_dipm(dev->id))			dev->flags |= ATA_DFLAG_DIPM;	}	if (dev->horkage & ATA_HORKAGE_DIAGNOSTIC) {		/* Let the user know. We don't want to disallow opens for		   rescue purposes, or in case the vendor is just a blithering		   idiot */		if (print_info) {			ata_dev_printk(dev, KERN_WARNING,"Drive reports diagnostics failure. This may indicate a drive\n");			ata_dev_printk(dev, KERN_WARNING,"fault or invalid emulation. Contact drive vendor for information.\n");		}	}	/* limit bridge transfers to udma5, 200 sectors */	if (ata_dev_knobble(dev)) {		if (ata_msg_drv(ap) && print_info)			ata_dev_printk(dev, KERN_INFO,				       "applying bridge limits\n");		dev->udma_mask &= ATA_UDMA5;		dev->max_sectors = ATA_MAX_SECTORS;	}	if ((dev->class == ATA_DEV_ATAPI) &&	    (atapi_command_packet_set(id) == TYPE_TAPE)) {		dev->max_sectors = ATA_MAX_SECTORS_TAPE;		dev->horkage |= ATA_HORKAGE_STUCK_ERR;	}	if (dev->horkage & ATA_HORKAGE_MAX_SEC_128)		dev->max_sectors = min_t(unsigned int, ATA_MAX_SECTORS_128,					 dev->max_sectors);	if (ata_dev_blacklisted(dev) & ATA_HORKAGE_IPM) {		dev->horkage |= ATA_HORKAGE_IPM;		/* reset link pm_policy for this port to no pm */		ap->pm_policy = MAX_PERFORMANCE;	}	if (ap->ops->dev_config)		ap->ops->dev_config(dev);	if (ata_msg_probe(ap))		ata_dev_printk(dev, KERN_DEBUG, "%s: EXIT, drv_stat = 0x%x\n",			__FUNCTION__, ata_chk_status(ap));	return 0;err_out_nosup:	if (ata_msg_probe(ap))		ata_dev_printk(dev, KERN_DEBUG,			       "%s: EXIT, err\n", __FUNCTION__);	return rc;}/** *	ata_cable_40wire	-	return 40 wire cable type *	@ap: port * *	Helper method for drivers which want to hardwire 40 wire cable *	detection. */int ata_cable_40wire(struct ata_port *ap){	return ATA_CBL_PATA40;}/** *	ata_cable_80wire	-	return 80 wire cable type *	@ap: port * *	Helper method for drivers which want to hardwire 80 wire cable *	detection. */int ata_cable_80wire(struct ata_port *ap){	return ATA_CBL_PATA80;}/** *	ata_cable_unknown	-	return unknown PATA cable. *	@ap: port * *	Helper method for drivers which have no PATA cable detection. */int ata_cable_unknown(struct ata_port *ap){	return ATA_CBL_PATA_UNK;}/** *	ata_cable_sata	-	return SATA cable type *	@ap: port * *	Helper method for drivers which have SATA cables */int ata_cable_sata(struct ata_port *ap){	return ATA_CBL_SATA;}/** *	ata_bus_probe - Reset and probe ATA bus *	@ap: Bus to probe * *	Master ATA bus probing function.  Initiates a hardware-dependent *	bus reset, then attempts to identify any devices found on *	the bus. * *	LOCKING: *	PCI/etc. bus probe sem. * *	RETURNS: *	Zero on success, negative errno otherwise. */int ata_bus_probe(struct ata_port *ap){	unsigned int classes[ATA_MAX_DEVICES];	int tries[ATA_MAX_DEVICES];	int rc;	struct ata_device *dev;	ata_port_probe(ap);	ata_link_for_each_dev(dev, &ap->link)		tries[dev->devno] = ATA_PROBE_MAX_TRIES; retry:	ata_link_for_each_dev(dev, &ap->link) {		/* If we issue an SRST then an ATA drive (not ATAPI)		 * may change configuration and be in PIO0 timing. If		 * we do a hard reset (or are coming from power on)		 * this is true for ATA or ATAPI. Until we've set a		 * suitable controller mode we should not touch the		 * bus as we may be talking too fast.		 */		dev->pio_mode = XFER_PIO_0;		/* If the controller has a pio mode setup function		 * then use it to set the chipset to rights. Don't		 * touch the DMA setup as that will be dealt with when		 * configuring devices.		 */		if (ap->ops->set_piomode)			ap->ops->set_piomode(ap, dev);	}	/* reset and determine device classes */	ap->ops->phy_reset(ap);	ata_link_for_each_dev(dev, &ap->link) {		if (!(ap->flags & ATA_FLAG_DISABLED) &&		    dev->class != ATA_DEV_UNKNOWN)			classes[dev->devno] = dev->class;		else			classes[dev->devno] = ATA_DEV_NONE;		dev->class = ATA_DEV_UNKNOWN;	}	ata_port_probe(ap);	/* read IDENTIFY page and configure devices. We have to do the identify	   specific sequence bass-ackwards so that PDIAG- is released by	   the slave device */	ata_link_for_each_dev(dev, &ap->link) {		if (tries[dev->devno])			dev->class = classes[dev->devno];		if (!ata_dev_enabled(dev))			continue;		rc = ata_dev_read_id(dev, &dev->class, ATA_READID_POSTRESET,				     dev->id);		if (rc)			goto fail;	}	/* Now ask for the cable type as PDIAG- should have been released */	if (ap->ops->cable_detect)		ap->cbl = ap->ops->cable_detect(ap);	/* We may have SATA bridge glue hiding here irrespective of the	   reported cable types and sensed types */	ata_link_for_each_dev(dev, &ap->link) {		if (!ata_dev_enabled(dev))			continue;		/* SATA drives indicate we have a bridge. We don't know which		   end of the link the bridge is which is a problem */		if (ata_id_is_sata(dev->id))			ap->cbl = ATA_CBL_SATA;	}	/* After the identify sequence we can now set up the devices. We do	   this in the normal order so that the user doesn't get confused */	ata_link_for_each_dev(dev, &ap->link) {		if (!ata_dev_enabled(dev))			continue;		ap->link.eh_context.i.flags |= ATA_EHI_PRINTINFO;		rc = ata_dev_configure(dev);		ap->link.eh_context.i.flags &= ~ATA_EHI_PRINTINFO;		if (rc)			goto fail;	}	/* configure transfer mode */	rc = ata_set_mode(&ap->link, &dev);	if (rc)		goto fail;	ata_link_for_each_dev(dev, &ap->link)		if (ata_dev_enabled(dev))			return 0;	/* no device present, disable port */	ata_port_disable(ap);	return -ENODEV; fail:	tries[dev->devno]--;	switch (rc) {	case -EINVAL:		/* eeek, something went very wrong, give up */		tries[dev->devno] = 0;		break;	case -ENODEV:		/* give it just one more chance */		tries[dev->devno] = min(tries[dev->devno], 1);	case -EIO:		if (tries[dev->devno] == 1) {			/* This is the last chance, better to slow			 * down than lose it.			 */			sata_down_spd_limit(&ap->link);			ata_down_xfermask_limit(dev, ATA_DNXFER_PIO);		}	}	if (!tries[dev->devno])		ata_dev_disable(dev);	goto retry;}/** *	ata_port_probe - Mark port as enabled *	@ap: Port for which we indicate enablement * *	Modify @ap data structure such that the system *	thinks that the entire port is enabled. * *	LOCKING: host lock, or some other form of *	serialization. */void ata_port_probe(struct ata_port *ap){	ap->flags &= ~ATA_FLAG_DISABLED;}/** *	sata_print_link_status - Print SATA link status *	@link: SATA link to printk link status about * *	This function prints link speed and status of a SATA link. * *	LOCKING: *	None. */void sata_print_link_status(struct ata_link *link){	u32 sstatus, scontrol, tmp;	if (sata_sc

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -