コード例 #1
0
ファイル: arcmsr_attr.c プロジェクト: 020gzh/linux
static ssize_t arcmsr_sysfs_iop_message_read(struct file *filp,
					     struct kobject *kobj,
					     struct bin_attribute *bin,
					     char *buf, loff_t off,
					     size_t count)
{
	struct device *dev = container_of(kobj,struct device,kobj);
	struct Scsi_Host *host = class_to_shost(dev);
	struct AdapterControlBlock *acb = (struct AdapterControlBlock *) host->hostdata;
	uint8_t *ptmpQbuffer;
	int32_t allxfer_len = 0;
	unsigned long flags;

	if (!capable(CAP_SYS_ADMIN))
		return -EACCES;

	/* do message unit read. */
	ptmpQbuffer = (uint8_t *)buf;
	spin_lock_irqsave(&acb->rqbuffer_lock, flags);
	if (acb->rqbuf_getIndex != acb->rqbuf_putIndex) {
		unsigned int tail = acb->rqbuf_getIndex;
		unsigned int head = acb->rqbuf_putIndex;
		unsigned int cnt_to_end = CIRC_CNT_TO_END(head, tail, ARCMSR_MAX_QBUFFER);

		allxfer_len = CIRC_CNT(head, tail, ARCMSR_MAX_QBUFFER);
		if (allxfer_len > ARCMSR_API_DATA_BUFLEN)
			allxfer_len = ARCMSR_API_DATA_BUFLEN;

		if (allxfer_len <= cnt_to_end)
			memcpy(ptmpQbuffer, acb->rqbuffer + tail, allxfer_len);
		else {
			memcpy(ptmpQbuffer, acb->rqbuffer + tail, cnt_to_end);
			memcpy(ptmpQbuffer + cnt_to_end, acb->rqbuffer, allxfer_len - cnt_to_end);
		}
		acb->rqbuf_getIndex = (acb->rqbuf_getIndex + allxfer_len) % ARCMSR_MAX_QBUFFER;
	}
	if (acb->acb_flags & ACB_F_IOPDATA_OVERFLOW) {
		struct QBUFFER __iomem *prbuffer;
		acb->acb_flags &= ~ACB_F_IOPDATA_OVERFLOW;
		prbuffer = arcmsr_get_iop_rqbuffer(acb);
		if (arcmsr_Read_iop_rqbuffer_data(acb, prbuffer) == 0)
			acb->acb_flags |= ACB_F_IOPDATA_OVERFLOW;
	}
	spin_unlock_irqrestore(&acb->rqbuffer_lock, flags);
	return allxfer_len;
}
コード例 #2
0
ファイル: arcmsr_attr.c プロジェクト: CSCLOG/beaglebone
static ssize_t arcmsr_sysfs_iop_message_read(struct file *filp,
					     struct kobject *kobj,
					     struct bin_attribute *bin,
					     char *buf, loff_t off,
					     size_t count)
{
	struct device *dev = container_of(kobj,struct device,kobj);
	struct Scsi_Host *host = class_to_shost(dev);
	struct AdapterControlBlock *acb = (struct AdapterControlBlock *) host->hostdata;
	uint8_t *pQbuffer,*ptmpQbuffer;
	int32_t allxfer_len = 0;

	if (!capable(CAP_SYS_ADMIN))
		return -EACCES;

	/* do message unit read. */
	ptmpQbuffer = (uint8_t *)buf;
	while ((acb->rqbuf_firstindex != acb->rqbuf_lastindex)
		&& (allxfer_len < 1031)) {
		pQbuffer = &acb->rqbuffer[acb->rqbuf_firstindex];
		memcpy(ptmpQbuffer, pQbuffer, 1);
		acb->rqbuf_firstindex++;
		acb->rqbuf_firstindex %= ARCMSR_MAX_QBUFFER;
		ptmpQbuffer++;
		allxfer_len++;
	}
	if (acb->acb_flags & ACB_F_IOPDATA_OVERFLOW) {
		struct QBUFFER __iomem *prbuffer;
		uint8_t __iomem *iop_data;
		int32_t iop_len;

		acb->acb_flags &= ~ACB_F_IOPDATA_OVERFLOW;
		prbuffer = arcmsr_get_iop_rqbuffer(acb);
		iop_data = prbuffer->data;
		iop_len = readl(&prbuffer->data_len);
		while (iop_len > 0) {
			acb->rqbuffer[acb->rqbuf_lastindex] = readb(iop_data);
			acb->rqbuf_lastindex++;
			acb->rqbuf_lastindex %= ARCMSR_MAX_QBUFFER;
			iop_data++;
			iop_len--;
		}
		arcmsr_iop_message_read(acb);
	}
	return (allxfer_len);
}