rendered paste body#if !ACX_DEBUG
int
acxpci_s_issue_cmd_timeo(acx_device_t * adev,
unsigned int cmd,
void *buffer, unsigned buflen, unsigned cmd_timeout)
{
#else
int
acxpci_s_issue_cmd_timeo_debug(acx_device_t * adev,
unsigned cmd,
void *buffer,
unsigned buflen,
unsigned cmd_timeout, const char *cmdstr)
{
unsigned long start = jiffies;
#endif
const char *devname;
unsigned counter;
u16 irqtype;
u16 cmd_status;
unsigned long timeout;
unsigned long flags;
FN_ENTER;
devname = wiphy_name(adev->ieee->wiphy);
if (!devname || !devname[0] || devname[4] == '%')
devname = "acx";
breakpoint();
log(L_CTL, FUNC "(cmd:%s,buflen:%u,timeout:%ums,type:0x%04X)\n",
cmdstr, buflen, cmd_timeout,
buffer ? le16_to_cpu(((acx_ie_generic_t *) buffer)->type) : -1);
breakpoint();
if (!(adev->dev_state_mask & ACX_STATE_FW_LOADED)) {
printk("%s: " FUNC "(): firmware is not loaded yet, "
"cannot execute commands!\n", devname);
goto bad;
}
breakpoint();
if ((acx_debug & L_DEBUG) && (cmd != ACX1xx_CMD_INTERROGATE)) {
printk("input buffer (len=%u):\n", buflen);
acx_dump_bytes(buffer, buflen);
}
breakpoint();
/* wait for firmware to become idle for our command submission */
timeout = HZ / 5;
counter = (timeout * 1000 / HZ) - 1; /* in ms */
timeout += jiffies;
do {
cmd_status = acxpci_read_cmd_type_status(adev);
/* Test for IDLE state */
if (!cmd_status)
break;
if (counter % 8 == 0) {
if (time_after(jiffies, timeout)) {
counter = 0;
break;
}
/* we waited 8 iterations, no luck. Sleep 8 ms */
acx_s_mwait(8);
}
} while (likely(--counter));
breakpoint();
if (!counter) {
/* the card doesn't get idle, we're in trouble */
printk("%s: " FUNC "(): cmd_status is not IDLE: 0x%04X!=0\n",
devname, cmd_status);
goto bad;
} else if (counter < 190) { /* if waited >10ms... */
log(L_CTL | L_DEBUG, FUNC "(): waited for IDLE %dms. "
"Please report\n", 199 - counter);
}
breakpoint();
/* now write the parameters of the command if needed */
if (buffer && buflen) {
/* if it's an INTERROGATE command, just pass the length
* of parameters to read, as data */
#if CMD_DISCOVERY
if (cmd == ACX1xx_CMD_INTERROGATE)
memset_io(adev->cmd_area + 4, 0xAA, buflen);
#endif
/* adev->cmd_area points to PCI device's memory, not to RAM! */
memcpy_toio(adev->cmd_area + 4, buffer,
(cmd == ACX1xx_CMD_INTERROGATE) ? 4 : buflen);
}
breakpoint();
/* now write the actual command type */
acxpci_write_cmd_type_status(adev, cmd, 0);
breakpoint();
/* execute command */
write_reg16(adev, IO_ACX_INT_TRIG, INT_TRIG_CMD);
breakpoint();
write_flush(adev);
breakpoint();
/* wait for firmware to process command */