static int ms_write_bytes()

in host/rtsx_pci_ms.c [199:265]


static int ms_write_bytes(struct realtek_pci_ms *host, u8 tpc,
		u8 cfg, u8 cnt, u8 *data, u8 *int_reg)
{
	struct rtsx_pcr *pcr = host->pcr;
	int err, i;

	dev_dbg(ms_dev(host), "%s: tpc = 0x%02x\n", __func__, tpc);

	if (!data)
		return -EINVAL;

	rtsx_pci_init_cmd(pcr);

	for (i = 0; i < cnt; i++)
		rtsx_pci_add_cmd(pcr, WRITE_REG_CMD,
				PPBUF_BASE2 + i, 0xFF, data[i]);
	if (cnt % 2)
		rtsx_pci_add_cmd(pcr, WRITE_REG_CMD,
				PPBUF_BASE2 + i, 0xFF, 0xFF);

	rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, MS_TPC, 0xFF, tpc);
	rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, MS_BYTE_CNT, 0xFF, cnt);
	rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, MS_TRANS_CFG, 0xFF, cfg);
	rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CARD_DATA_SOURCE,
			0x01, PINGPONG_BUFFER);

	rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, MS_TRANSFER,
			0xFF, MS_TRANSFER_START | MS_TM_WRITE_BYTES);
	rtsx_pci_add_cmd(pcr, CHECK_REG_CMD, MS_TRANSFER,
			MS_TRANSFER_END, MS_TRANSFER_END);
	if (int_reg)
		rtsx_pci_add_cmd(pcr, READ_REG_CMD, MS_TRANS_CFG, 0, 0);

	err = rtsx_pci_send_cmd(pcr, 5000);
	if (err < 0) {
		u8 val;

		rtsx_pci_read_register(pcr, MS_TRANS_CFG, &val);
		dev_dbg(ms_dev(host), "MS_TRANS_CFG: 0x%02x\n", val);

		if (int_reg)
			*int_reg = val & 0x0F;

		ms_print_debug_regs(host);

		ms_clear_error(host);

		if (!(tpc & 0x08)) {
			if (val & MS_CRC16_ERR)
				return -EIO;
		} else {
			if (!(val & 0x80)) {
				if (val & (MS_INT_ERR | MS_INT_CMDNK))
					return -EIO;
			}
		}

		return -ETIMEDOUT;
	}

	if (int_reg) {
		u8 *ptr = rtsx_pci_get_cmd_data(pcr) + 1;
		*int_reg = *ptr & 0x0F;
	}

	return 0;
}