On Thu, May 14, 2020 at 4:09 PM Jeffrey Hugo <jhugo@xxxxxxxxxxxxxx> wrote: > > +struct dbc_req { /* everything must be little endian encoded */ Instead of the comment, I suppose you want to use __le16 and __le32 types and let sparse check that you got it right. > + u16 req_id; > + u8 seq_id; > + u8 cmd; > + u32 resv; > + u64 src_addr; > + u64 dest_addr; > + u32 len; > + u32 resv2; > + u64 db_addr; /* doorbell address */ > + u8 db_len; /* not a raw value, special encoding */ > + u8 resv3; > + u16 resv4; > + u32 db_data; > + u32 sem_cmd0; > + u32 sem_cmd1; > + u32 sem_cmd2; > + u32 sem_cmd3; > +} __packed; All members are naturally aligned, so better drop the __packed annotation get better code, unless the structure itself is at an unaligned offset in memory. > +struct dbc_rsp { /* everything must be little endian encoded */ > + u16 req_id; > + u16 status; > +} __packed; Same here. > + init_completion(&mem->xfer_done); > + list_add_tail(&mem->list, &dbc->xfer_list); > + tail = (tail + mem->nents) % dbc->nelem; > + __raw_writel(cpu_to_le32(tail), dbc->dbc_base + REQTP_OFF); What is this __raw accessor for? This generally results in non-portable code that should be replaced with writel() or something specific to the bus on the architecture you deal with. > + spin_lock_irqsave(&qdev->dbc[exec->dbc_id].xfer_lock, flags); > + req_id = qdev->dbc[exec->dbc_id].next_req_id++; > + queued = mem->queued; > + mem->queued = true; > + spin_unlock_irqrestore(&qdev->dbc[exec->dbc_id].xfer_lock, flags); No need for 'irqsave' locks when you know that interrupts are enabled. > + head = le32_to_cpu(__raw_readl(dbc->dbc_base + RSPHP_OFF)); > + tail = le32_to_cpu(__raw_readl(dbc->dbc_base + RSPTP_OFF)); More __raw accessors to replace. > + case QAIC_IOCTL_MEM_NR: > + if (_IOC_DIR(cmd) != (_IOC_READ | _IOC_WRITE) || > + _IOC_SIZE(cmd) != sizeof(struct qaic_mem_req)) { > + ret = -EINVAL; > + break; This looks like a very verbose way to check 'cmd' against a known constant. Why not use 'switch (cmd)' like all other drivers? Arnd