Re: [PATCH]qla4xxx:Add support for Async Message PDUs

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Tue, 2008-04-22 at 11:20 -0500, Mike Christie wrote:
> David C Somayajulu wrote:
> > +int qla4xxx_conn_close_sess_logout(struct scsi_qla_host * ha,
> > +	   uint16_t fw_ddb_index, uint16_t connection_id, uint16_t option)
> > +{
> > +	uint32_t mbox_cmd[MBOX_REG_COUNT];
> > +	uint32_t mbox_sts[MBOX_REG_COUNT];
> > +
> > +	memset(&mbox_cmd, 0, sizeof(mbox_cmd));
> > +	memset(&mbox_sts, 0, sizeof(mbox_sts));
> > +
> > +	mbox_cmd[0] = MBOX_CMD_CONN_CLOSE_SESS_LOGOUT;
> > +	mbox_cmd[1] = fw_ddb_index;
> > +	mbox_cmd[2] = connection_id;
> > +	mbox_cmd[3] = LOGOUT_OPTION_RESET;
> > +
> > +	if (qla4xxx_mailbox_command(ha, MBOX_REG_COUNT, 2, &mbox_cmd[0],
> > +		&mbox_sts[0]) != QLA_SUCCESS) {
> > +		DEBUG2(printk("scsi%ld: %s: MBOX_CMD_CONN_CLOSE_SESS_LOGOUT "
> > +			      "option %04x failed sts %04X %04X",
> > +			      ha->host_no, __func__,
> > +			      option, mbox_sts[0], mbox_sts[1]));
> > +		if (mbox_sts[0] == 0x4005)
> > +			DEBUG2(printk("%s reason %04X\n", __func__,
> > +				      mbox_sts[1]));
> > +	}
> > +	return QLA_SUCCESS;
> 
> 
> Does this logout function logout a session and stop it from being logged 
> back in, or does it logout the session then the firmware tries to log 
> back in?
Once the session is logged out, it stays in that state till the user
initiates a login. The firmware does not automatically try to login
again.
> 
> 
> > +/*
> > + * qla4xxx_async_iocbs - processes ASYNC PDU IOCBS, if they are greater in
> > + * length than 48 bytes (i.e., more than just the iscsi header). Used for
> > + * unsolicited pdus received from target.
> > + */
> > +static void qla4xxx_async_iocbs(struct scsi_qla_host *ha,
> > +		struct async_msg_pdu_iocb *amsg_pdu_iocb)
> > +{
> > +	struct iscsi_hdr *hdr;
> > +	struct async_pdu_iocb *apdu;
> > +	uint32_t len;
> > +	void *buf_addr;
> > +	dma_addr_t buf_addr_dma;
> > +	uint32_t offset;
> > +	struct passthru0 *pthru0_iocb;
> > +	struct scsi_sense_hdr sshdr;
> > +	struct ddb_entry *ddb_entry = NULL;
> > +	uint8_t using_prealloc = 1;
> > +	uint8_t async_event_type;
> > +
> > +	apdu = (struct async_pdu_iocb *)amsg_pdu_iocb->iocb;
> > +	hdr = (struct iscsi_hdr *)apdu->iscsi_pdu_hdr;
> > +	len = hdr->hlength + hdr->dlength[2] +
> > +		(hdr->dlength[1]<<8) + (hdr->dlength[0]<<16);
> > +
> > +	offset = sizeof (struct passthru0) + sizeof (struct passthru_status);
> > +	if (len <= (PAGE_SIZE - offset)) {
> > +		buf_addr_dma = ha->gen_req_rsp_iocb_dma + offset;
> > +		buf_addr = (uint8_t *)ha->gen_req_rsp_iocb + offset;
> > +	} else {
> > +		using_prealloc = 0;
> > +		buf_addr = dma_alloc_coherent(&ha->pdev->dev, len,
> > +                                        &buf_addr_dma, GFP_KERNEL);
> > +		if (!buf_addr) {
> > +			dev_info(&ha->pdev->dev,
> > +				"%s: dma_alloc_coherent failed\n", __func__);
> > +			return;
> > +		}
> > +	}
> > +	/* Create the pass-thru0 iocb */
> > +	pthru0_iocb = ha->gen_req_rsp_iocb;
> > +	memset(pthru0_iocb, 0, offset);
> > +
> > +	pthru0_iocb->hdr.entryType = ET_PASSTHRU0;
> > +	pthru0_iocb->controlFlags =
> > +		cpu_to_le16(PT_FLAG_ISCSI_PDU | PT_FLAG_WAIT_4_RESPONSE);
> > +	pthru0_iocb->timeout = cpu_to_le16(PT_DEFAULT_TIMEOUT);
> > +	pthru0_iocb->inDataSeg64.base.addrHigh =
> > +		cpu_to_le32(MSDW(buf_addr_dma));
> > +	pthru0_iocb->inDataSeg64.base.addrLow =
> > +		cpu_to_le32(LSDW(buf_addr_dma));
> > +	pthru0_iocb->inDataSeg64.count = cpu_to_le32(len);
> > +
> > +	if (qla4xxx_issue_iocb(ha, sizeof(struct passthru0),
> > +		ha->gen_req_rsp_iocb_dma) != QLA_SUCCESS) {
> > +		dev_info(&ha->pdev->dev,
> > +			"%s: qla4xxx_issue_iocb failed\n", __func__);
> > +		goto exit_async_pdu_iocb;
> > +	}
> > + 
> > +	async_event_type = ((struct iscsi_async *)hdr)->async_event;
> > +	ddb_entry = ha->fw_ddb_index_map[apdu->target_id];
> > +
> > +	if (ddb_entry == NULL)
> > +		goto exit_async_pdu_iocb;
> > +
> > +	switch (async_event_type) {
> > +	case ISCSI_ASYNC_MSG_SCSI_EVENT:
> > +		if (!scsi_normalize_sense((uint8_t *)buf_addr, len, &sshdr)) {
> > +			dev_info(&ha->pdev->dev,
> > +				"%s: scsi_normalize_sense failed\n", __func__);
> > +			break;
> > +		}
> > +		if (sshdr.asc == 0x3f && sshdr.ascq == 0x0e) {
> > +			scsi_scan_target(&ddb_entry->sess->dev, 0,
> > +				ddb_entry->sess->target_id, SCAN_WILD_CARD, 0);
> >
> 
> I do not think you can call scsi_scan_target from your dpc thread. If 
> there was a problem that the the dpc thread needed to recover the 
> session or host for it would not be able to because the scsi_scan_target 
> call would be blocked on the recovery of that host or session.
> 
> You need to modify scsi_transport_iscsi.c:session->scan_work related 
> code to be able to be called from _iscsi_unblock_session and from some 
> new function that just checks the state and scans the session.
O.K. Mike I will look into this.
--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [SCSI Target Devel]     [Linux SCSI Target Infrastructure]     [Kernel Newbies]     [IDE]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux ATA RAID]     [Linux IIO]     [Samba]     [Device Mapper]
  Powered by Linux