in net/ctcm_mpc.c [1649:1800]
static void mpc_action_side_xid(fsm_instance *fsm, void *arg, int side)
{
struct channel *ch = arg;
int rc = 0;
int gotlock = 0;
unsigned long saveflags = 0; /* avoids compiler warning with
spin_unlock_irqrestore */
CTCM_PR_DEBUG("Enter %s: cp=%i ch=0x%p id=%s\n",
__func__, smp_processor_id(), ch, ch->id);
if (ctcm_checkalloc_buffer(ch))
goto done;
/*
* skb data-buffer referencing:
*/
ch->trans_skb->data = ch->trans_skb_data;
skb_reset_tail_pointer(ch->trans_skb);
ch->trans_skb->len = 0;
/* result of the previous 3 statements is NOT always
* already set after ctcm_checkalloc_buffer
* because of possible reuse of the trans_skb
*/
memset(ch->trans_skb->data, 0, 16);
ch->rcvd_xid_th = (struct th_header *)ch->trans_skb_data;
/* check is main purpose here: */
skb_put(ch->trans_skb, TH_HEADER_LENGTH);
ch->rcvd_xid = (struct xid2 *)skb_tail_pointer(ch->trans_skb);
/* check is main purpose here: */
skb_put(ch->trans_skb, XID2_LENGTH);
ch->rcvd_xid_id = skb_tail_pointer(ch->trans_skb);
/* cleanup back to startpoint */
ch->trans_skb->data = ch->trans_skb_data;
skb_reset_tail_pointer(ch->trans_skb);
ch->trans_skb->len = 0;
/* non-checking rewrite of above skb data-buffer referencing: */
/*
memset(ch->trans_skb->data, 0, 16);
ch->rcvd_xid_th = (struct th_header *)ch->trans_skb_data;
ch->rcvd_xid = (struct xid2 *)(ch->trans_skb_data + TH_HEADER_LENGTH);
ch->rcvd_xid_id = ch->trans_skb_data + TH_HEADER_LENGTH + XID2_LENGTH;
*/
ch->ccw[8].flags = CCW_FLAG_SLI | CCW_FLAG_CC;
ch->ccw[8].count = 0;
ch->ccw[8].cda = 0x00;
if (!(ch->xid_th && ch->xid && ch->xid_id))
CTCM_DBF_TEXT_(MPC_TRACE, CTC_DBF_INFO,
"%s(%s): xid_th=%p, xid=%p, xid_id=%p",
CTCM_FUNTAIL, ch->id, ch->xid_th, ch->xid, ch->xid_id);
if (side == XSIDE) {
/* mpc_action_xside_xid */
if (ch->xid_th == NULL)
goto done;
ch->ccw[9].cmd_code = CCW_CMD_WRITE;
ch->ccw[9].flags = CCW_FLAG_SLI | CCW_FLAG_CC;
ch->ccw[9].count = TH_HEADER_LENGTH;
ch->ccw[9].cda = virt_to_phys(ch->xid_th);
if (ch->xid == NULL)
goto done;
ch->ccw[10].cmd_code = CCW_CMD_WRITE;
ch->ccw[10].flags = CCW_FLAG_SLI | CCW_FLAG_CC;
ch->ccw[10].count = XID2_LENGTH;
ch->ccw[10].cda = virt_to_phys(ch->xid);
ch->ccw[11].cmd_code = CCW_CMD_READ;
ch->ccw[11].flags = CCW_FLAG_SLI | CCW_FLAG_CC;
ch->ccw[11].count = TH_HEADER_LENGTH;
ch->ccw[11].cda = virt_to_phys(ch->rcvd_xid_th);
ch->ccw[12].cmd_code = CCW_CMD_READ;
ch->ccw[12].flags = CCW_FLAG_SLI | CCW_FLAG_CC;
ch->ccw[12].count = XID2_LENGTH;
ch->ccw[12].cda = virt_to_phys(ch->rcvd_xid);
ch->ccw[13].cmd_code = CCW_CMD_READ;
ch->ccw[13].cda = virt_to_phys(ch->rcvd_xid_id);
} else { /* side == YSIDE : mpc_action_yside_xid */
ch->ccw[9].cmd_code = CCW_CMD_READ;
ch->ccw[9].flags = CCW_FLAG_SLI | CCW_FLAG_CC;
ch->ccw[9].count = TH_HEADER_LENGTH;
ch->ccw[9].cda = virt_to_phys(ch->rcvd_xid_th);
ch->ccw[10].cmd_code = CCW_CMD_READ;
ch->ccw[10].flags = CCW_FLAG_SLI | CCW_FLAG_CC;
ch->ccw[10].count = XID2_LENGTH;
ch->ccw[10].cda = virt_to_phys(ch->rcvd_xid);
if (ch->xid_th == NULL)
goto done;
ch->ccw[11].cmd_code = CCW_CMD_WRITE;
ch->ccw[11].flags = CCW_FLAG_SLI | CCW_FLAG_CC;
ch->ccw[11].count = TH_HEADER_LENGTH;
ch->ccw[11].cda = virt_to_phys(ch->xid_th);
if (ch->xid == NULL)
goto done;
ch->ccw[12].cmd_code = CCW_CMD_WRITE;
ch->ccw[12].flags = CCW_FLAG_SLI | CCW_FLAG_CC;
ch->ccw[12].count = XID2_LENGTH;
ch->ccw[12].cda = virt_to_phys(ch->xid);
if (ch->xid_id == NULL)
goto done;
ch->ccw[13].cmd_code = CCW_CMD_WRITE;
ch->ccw[13].cda = virt_to_phys(ch->xid_id);
}
ch->ccw[13].flags = CCW_FLAG_SLI | CCW_FLAG_CC;
ch->ccw[13].count = 4;
ch->ccw[14].cmd_code = CCW_CMD_NOOP;
ch->ccw[14].flags = CCW_FLAG_SLI;
ch->ccw[14].count = 0;
ch->ccw[14].cda = 0;
CTCM_CCW_DUMP((char *)&ch->ccw[8], sizeof(struct ccw1) * 7);
CTCM_D3_DUMP((char *)ch->xid_th, TH_HEADER_LENGTH);
CTCM_D3_DUMP((char *)ch->xid, XID2_LENGTH);
CTCM_D3_DUMP((char *)ch->xid_id, 4);
if (!in_hardirq()) {
/* Such conditional locking is a known problem for
* sparse because its static undeterministic.
* Warnings should be ignored here. */
spin_lock_irqsave(get_ccwdev_lock(ch->cdev), saveflags);
gotlock = 1;
}
fsm_addtimer(&ch->timer, 5000 , CTC_EVENT_TIMER, ch);
rc = ccw_device_start(ch->cdev, &ch->ccw[8], 0, 0xff, 0);
if (gotlock) /* see remark above about conditional locking */
spin_unlock_irqrestore(get_ccwdev_lock(ch->cdev), saveflags);
if (rc != 0) {
ctcm_ccw_check_rc(ch, rc,
(side == XSIDE) ? "x-side XID" : "y-side XID");
}
done:
CTCM_PR_DEBUG("Exit %s: ch=0x%p id=%s\n",
__func__, ch, ch->id);
return;
}