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?