The caller of ql_icmd() should hold the host lock (from the head comments of ql_icmd() shown below). But, the lock is not acquired in function qlogicfas408_queuecommand(). All of these code is in file drivers/scsi/qlogicfas408.c /* * Initiate scsi command - queueing handler * caller must hold host lock */ static void ql_icmd(struct scsi_cmnd *cmd) { struct qlogicfas408_priv *priv = get_priv_by_cmd(cmd); int qbase = priv->qbase; int int_type = priv->int_type; unsigned int i; priv->qabort = 0; REG0; /* clearing of interrupts and the fifo is needed */ ... ------------------------------------------------------ int qlogicfas408_queuecommand(struct scsi_cmnd *cmd, void (*done) (struct scsi_cmnd *)) { struct qlogicfas408_priv *priv = get_priv_by_cmd(cmd); if (scmd_id(cmd) == priv->qinitid) { cmd->result = DID_BAD_TARGET << 16; done(cmd); return 0; } cmd->scsi_done = done; /* wait for the last command's interrupt to finish */ while (priv->qlcmd != NULL) { barrier(); cpu_relax(); } ql_icmd(cmd); return 0; }
We do hold the lock in generic scsi code when call queuecommand. in scsi_dispatch_cmd: ... spin_lock_irqsave(host->host_lock, flags); scsi_cmd_get_serial(host, cmd); if (unlikely(host->shost_state == SHOST_DEL)) { cmd->result = (DID_NO_CONNECT << 16); scsi_done(cmd); } else { rtn = host->hostt->queuecommand(cmd, scsi_done); } spin_unlock_irqrestore(host->host_lock, flags); ... scsi_send)eh_command: ... spin_lock_irqsave(shost->host_lock, flags); scsi_log_send(scmd); shost->hostt->queuecommand(scmd, scsi_eh_done); spin_unlock_irqrestore(shost->host_lock, flags); ... So it looks like we are good.