/* Description: allocate a struct scsi_cmd from host's slab, recycling from the host's free_list if necessary.  */
struct scsi_cmnd* __scsi_get_command(struct Scsi_Host *shost, gfp_t gfp_mask)
/* Description: allocate a struct scsi_cmd from host's slab, recycling from the host's free_list if necessary.  */
struct scsi_cmnd* __scsi_get_command(struct Scsi_Host *shost, gfp_t gfp_mask)
{
	struct scsi_cmnd *cmd = scsi_host_alloc_command(shost, gfp_mask);
	if (unlikely(!cmd)) {
		unsigned long flags;
		spin_lock_irqsave(&shost->free_list_lock, flags);
		if (likely(!list_empty(&shost->free_list))) {
			cmd = list_entry(shost->free_list.next,
					 struct scsi_cmnd, list);
			list_del_init(&cmd->list);
		}
		spin_unlock_irqrestore(&shost->free_list_lock, flags);
		if (cmd) {
			void *buf, *prot;
			buf = cmd->sense_buffer;
			prot = cmd->prot_sdb;
			memset(cmd, 0, sizeof(*cmd));
			cmd->sense_buffer = buf;
			cmd->prot_sdb = prot;
		}
	}
	return cmd;
}