Re: [PATCH UPDATED] ahci: add "em_buffer" attribute for AHCI hosts

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hello,

> Add "em_buffer" attribute for SATA AHCI hosts to enable user access
> AHCI EM (enclosure management) buffer in user space if the host
> support EM.
> 
> AHCI driver should support SGPIO EM message. However the SATA/AHCI
> spec does no define the SGPIO message format filled in EM
> buffer. Different HW vendors may have different definitions. The
> mainly purpose of "em_buffer" attribute is to solve this issue by
> allowing HW vendors to provide user space SGPIO drivers and tools.

Yeap, the only way to deal with the SGPIO case seems to be to provide
a way for userland to directly generate and consume messages.

> @@ -931,18 +937,20 @@ static ssize_t ahci_transmit_led_message(struct ata_port *ap, u32 state,
>  		return -EBUSY;
>  	}
>  
> -	/*
> -	 * create message header - this is all zero except for
> -	 * the message size, which is 4 bytes.
> -	 */
> -	message[0] |= (4 << 8);
> +	if (ahci_em_messages & 0x01) {
> +		/*
> +		 * create message header - this is all zero except for
> +		 * the message size, which is 4 bytes.
> +		 */
> +		message[0] |= (4 << 8);

This isn't your fault but there can be multiple ahci controllers on
the system and controlling EM capability via a module parameter
doesn't really work.  There needs to be some mechanism to configure
this automatically.

> +static ssize_t ahci_em_buffer_store(struct ata_port *ap,
> +				    const char *buf, size_t size)
> +{
> +	struct ahci_host_priv *hpriv = ap->host->private_data;
> +	void __iomem *mmio = hpriv->mmio;
> +	void __iomem *em_mmio = mmio + hpriv->em_loc;
> +	struct ahci_em_buf_msg *msg = (struct ahci_em_buf_msg *)buf;
> +	u32 em_ctl;
> +	unsigned long flags;
> +	int i, tmp;
> +
> +	/* check message validity */
> +	tmp = sizeof(struct ahci_em_buf_msg);
> +	if (size % 4 || size < tmp || size > tmp + msg->len * 4 ||
> +			msg->start + msg->len > hpriv->em_buf_sz / 4) {
> +		return -EINVAL;
> +	}

Please don't share data structure directly with userland this way.
The action of storing can indicate TM.  I don't think RST needs to be
exported to userland verbatim.  @start is unnecessary if the whole
message is written always and @len can be determined from the write
size.  IOW, simply writing the raw message should be enough.

Also, isn't it also necessary to implement 'read'?

> +static ssize_t
> +ata_scsi_em_buffer_store(struct device *dev, struct device_attribute *attr,
> +	const char *buf, size_t count)
> +{
> +	struct Scsi_Host *shost = class_to_shost(dev);
> +	struct ata_port *ap = ata_shost_to_port(shost);
> +
> +	if (ap->ops->em_buffer_store && (ap->flags & ATA_FLAG_EM))
> +		return ap->ops->em_buffer_store(ap, buf, count);
> +	return -EINVAL;
> +}
> +DEVICE_ATTR(em_buffer, S_IWUSR, NULL, ata_scsi_em_buffer_store);
> +EXPORT_SYMBOL_GPL(dev_attr_em_buffer);

Let's just put it in libahci.c for now and move it to common part if
anything else ever requires SGPIO EM.

Thanks.

--
tejun
--
To unsubscribe from this list: send the line "unsubscribe linux-ide" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Linux Filesystems]     [Linux SCSI]     [Linux RAID]     [Git]     [Kernel Newbies]     [Linux Newbie]     [Security]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Samba]     [Device Mapper]

  Powered by Linux