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

Commit 0ea035a3 authored by Tejun Heo's avatar Tejun Heo
Browse files

[PATCH] libata-hp: implement ata_eh_detach_dev()



Implement ata_eh_detach_dev().  This function is responsible for
detaching an ATA device and offlining the associated SCSI device
atomically so that the detached device is not accessed after ATA
detach is complete.

Signed-off-by: default avatarTejun Heo <htejun@gmail.com>
parent e8e008e7
Loading
Loading
Loading
Loading
+28 −0
Original line number Original line Diff line number Diff line
@@ -666,6 +666,34 @@ void ata_eh_qc_retry(struct ata_queued_cmd *qc)
	__ata_eh_qc_complete(qc);
	__ata_eh_qc_complete(qc);
}
}


/**
 *	ata_eh_detach_dev - detach ATA device
 *	@dev: ATA device to detach
 *
 *	Detach @dev.
 *
 *	LOCKING:
 *	None.
 */
static void ata_eh_detach_dev(struct ata_device *dev)
{
	struct ata_port *ap = dev->ap;
	unsigned long flags;

	ata_dev_disable(dev);

	spin_lock_irqsave(&ap->host_set->lock, flags);

	dev->flags &= ~ATA_DFLAG_DETACH;

	if (ata_scsi_offline_dev(dev)) {
		dev->flags |= ATA_DFLAG_DETACHED;
		ap->flags |= ATA_FLAG_SCSI_HOTPLUG;
	}

	spin_unlock_irqrestore(&ap->host_set->lock, flags);
}

/**
/**
 *	ata_eh_about_to_do - about to perform eh_action
 *	ata_eh_about_to_do - about to perform eh_action
 *	@ap: target ATA port
 *	@ap: target ATA port
+24 −0
Original line number Original line Diff line number Diff line
@@ -2762,3 +2762,27 @@ void ata_scsi_scan_host(struct ata_port *ap)
		}
		}
	}
	}
}
}

/**
 *	ata_scsi_offline_dev - offline attached SCSI device
 *	@dev: ATA device to offline attached SCSI device for
 *
 *	This function is called from ata_eh_hotplug() and responsible
 *	for taking the SCSI device attached to @dev offline.  This
 *	function is called with host_set lock which protects dev->sdev
 *	against clearing.
 *
 *	LOCKING:
 *	spin_lock_irqsave(host_set lock)
 *
 *	RETURNS:
 *	1 if attached SCSI device exists, 0 otherwise.
 */
int ata_scsi_offline_dev(struct ata_device *dev)
{
	if (dev->sdev) {
		scsi_device_set_state(dev->sdev, SDEV_OFFLINE);
		return 1;
	}
	return 0;
}
+1 −0
Original line number Original line Diff line number Diff line
@@ -75,6 +75,7 @@ extern int ata_cmd_ioctl(struct scsi_device *scsidev, void __user *arg);
extern struct scsi_transport_template ata_scsi_transport_template;
extern struct scsi_transport_template ata_scsi_transport_template;


extern void ata_scsi_scan_host(struct ata_port *ap);
extern void ata_scsi_scan_host(struct ata_port *ap);
extern int ata_scsi_offline_dev(struct ata_device *dev);
extern unsigned int ata_scsiop_inq_std(struct ata_scsi_args *args, u8 *rbuf,
extern unsigned int ata_scsiop_inq_std(struct ata_scsi_args *args, u8 *rbuf,
			       unsigned int buflen);
			       unsigned int buflen);