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; }
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); }