Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 72fa4b74 authored by Tejun Heo's avatar Tejun Heo
Browse files

[PATCH] libata-hp-prep: make some ata_device fields persistent



Lifetimes of some fields span over device plugging/unplugging.  This
patch moves such persistent fields to the top of ata_device and
separate them with ATA_DEVICE_CLEAR_OFFSET.  Fields above the offset
are initialized once during host initializatino while all other fields
are cleared before hotplugging.  Currently ->ap, devno and part of
flags are persistent.

Note that flags is partially cleared while holding host_set lock.
This is to synchronize with later warm plug implementation which will
record hotplug request in dev->flags.

Signed-off-by: default avatarTejun Heo <htejun@gmail.com>
parent 3ef3b43d
Loading
Loading
Loading
Loading
+12 −2
Original line number Original line Diff line number Diff line
@@ -5153,9 +5153,18 @@ static void ata_host_remove(struct ata_port *ap, unsigned int do_unregister)
void ata_dev_init(struct ata_device *dev)
void ata_dev_init(struct ata_device *dev)
{
{
	struct ata_port *ap = dev->ap;
	struct ata_port *ap = dev->ap;
	unsigned long flags;

	/* High bits of dev->flags are used to record warm plug
	 * requests which occur asynchronously.  Synchronize using
	 * host_set lock.
	 */
	spin_lock_irqsave(&ap->host_set->lock, flags);
	dev->flags &= ~ATA_DFLAG_INIT_MASK;
	spin_unlock_irqrestore(&ap->host_set->lock, flags);


	memset((void *)dev, 0, sizeof(*dev));
	memset((void *)dev + ATA_DEVICE_CLEAR_OFFSET, 0,
	dev->devno = dev - ap->device;
	       sizeof(*dev) - ATA_DEVICE_CLEAR_OFFSET);
	dev->pio_mask = UINT_MAX;
	dev->pio_mask = UINT_MAX;
	dev->mwdma_mask = UINT_MAX;
	dev->mwdma_mask = UINT_MAX;
	dev->udma_mask = UINT_MAX;
	dev->udma_mask = UINT_MAX;
@@ -5218,6 +5227,7 @@ static void ata_host_init(struct ata_port *ap, struct Scsi_Host *host,
	for (i = 0; i < ATA_MAX_DEVICES; i++) {
	for (i = 0; i < ATA_MAX_DEVICES; i++) {
		struct ata_device *dev = &ap->device[i];
		struct ata_device *dev = &ap->device[i];
		dev->ap = ap;
		dev->ap = ap;
		dev->devno = i;
		ata_dev_init(dev);
		ata_dev_init(dev);
	}
	}


+9 −2
Original line number Original line Diff line number Diff line
@@ -130,6 +130,7 @@ enum {
	ATA_DFLAG_CFG_MASK	= (1 << 8) - 1,
	ATA_DFLAG_CFG_MASK	= (1 << 8) - 1,


	ATA_DFLAG_PIO		= (1 << 8), /* device currently in PIO mode */
	ATA_DFLAG_PIO		= (1 << 8), /* device currently in PIO mode */
	ATA_DFLAG_INIT_MASK	= (1 << 16) - 1,


	ATA_DFLAG_DETACH	= (1 << 16),
	ATA_DFLAG_DETACH	= (1 << 16),
	ATA_DFLAG_DETACHED	= (1 << 17),
	ATA_DFLAG_DETACHED	= (1 << 17),
@@ -410,10 +411,11 @@ struct ata_ering {


struct ata_device {
struct ata_device {
	struct ata_port		*ap;
	struct ata_port		*ap;
	u64			n_sectors;	/* size of device, if ATA */
	unsigned int		devno;		/* 0 or 1 */
	unsigned long		flags;		/* ATA_DFLAG_xxx */
	unsigned long		flags;		/* ATA_DFLAG_xxx */
	/* n_sector is used as CLEAR_OFFSET, read comment above CLEAR_OFFSET */
	u64			n_sectors;	/* size of device, if ATA */
	unsigned int		class;		/* ATA_DEV_xxx */
	unsigned int		class;		/* ATA_DEV_xxx */
	unsigned int		devno;		/* 0 or 1 */
	u16			id[ATA_ID_WORDS]; /* IDENTIFY xxx DEVICE data */
	u16			id[ATA_ID_WORDS]; /* IDENTIFY xxx DEVICE data */
	u8			pio_mode;
	u8			pio_mode;
	u8			dma_mode;
	u8			dma_mode;
@@ -439,6 +441,11 @@ struct ata_device {
	struct ata_ering	ering;
	struct ata_ering	ering;
};
};


/* Offset into struct ata_device.  Fields above it are maintained
 * acress device init.  Fields below are zeroed.
 */
#define ATA_DEVICE_CLEAR_OFFSET		offsetof(struct ata_device, n_sectors)

struct ata_eh_info {
struct ata_eh_info {
	struct ata_device	*dev;		/* offending device */
	struct ata_device	*dev;		/* offending device */
	u32			serror;		/* SError from LLDD */
	u32			serror;		/* SError from LLDD */