
Dear Dirk,
In message 0e4604dcfff89a1bd2b7f144a5b3ceae@gdsys.cc you wrote:
sorry for the delay, I had to clean some other things on my ToDoList.
Ditto :-(
void fpga_set_reg(u32 fpga, u16 *reg, off_t regoff, u16 data) { if (fpga) return mclink_send(fpga - 1, regoff, data);
return out_le16(reg, data); }
...
#define FPGA_SET_REG(ix,fld,val) \ fpga_set_reg((ix), \ &fpga_ptr->fld, \ offsetof(struct ihs_fpga, fld), \ val)
...
FPGA_SET_REG(0, mc_tx_address, addr); FPGA_SET_REG(0, mc_tx_data, data); FPGA_SET_REG(0, mc_tx_cmd, (slave & 0x03) << 14);
This works nicely for our memory mapped FPGA. But how about the other FPGAs? I don't have a fpga_ptr for them. Setting it NULL would make FPGA_SET_REG dereference a NULL pointer.
No, it does not.
In your setup you have a single memory mapped FPGA, addressed by the globally visible pointer fpga_ptr.
When accessing this memory mapped FPGA (index is zero), then this pointer gets used, which is OK.
For the other devices (index is not zero), then the pointer is ignored, and only the offset is used.
In case you had more memory mapped devices (not only index 0; say, something like index < N) you can still use this, and pass any (properly aligned) pointer for the non-memory mapped case. Note that the pointer will NOT be dereferenced - only the address of field "fld" will be calculated (and even this only in theory, because this code will not be executed for the non-memory mapped case).
Certainly I might call fpga_set_reg(1, NULL, offsetof(struct ihs_fpga, mc_tx_address), addr); but that would not be generic any more.
You don't call fpga_set_reg() any more, you just use the FPGA_SET_REG() macro described above.
Do you have any idea how to solve this?
I think this needs no new solution, because it shoul just work :-)
Best regards,
Wolfgang Denk