Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 06c94400 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull SCSI fixes from James Bottomley:
 "Two basic fixes: one for the sparse problem with the blacklist flags
  and another for a hang forever in bnx2i"

* tag 'scsi-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi:
  scsi: Use 'blist_flags_t' for scsi_devinfo flags
  scsi: bnx2fc: Fix hung task messages when a cleanup response is not received during abort
parents b64f26c6 5ebde469
Loading
Loading
Loading
Loading
+32 −8
Original line number Diff line number Diff line
@@ -1084,24 +1084,35 @@ static int bnx2fc_abts_cleanup(struct bnx2fc_cmd *io_req)
{
	struct bnx2fc_rport *tgt = io_req->tgt;
	int rc = SUCCESS;
	unsigned int time_left;

	io_req->wait_for_comp = 1;
	bnx2fc_initiate_cleanup(io_req);

	spin_unlock_bh(&tgt->tgt_lock);

	wait_for_completion(&io_req->tm_done);

	/*
	 * Can't wait forever on cleanup response lest we let the SCSI error
	 * handler wait forever
	 */
	time_left = wait_for_completion_timeout(&io_req->tm_done,
						BNX2FC_FW_TIMEOUT);
	io_req->wait_for_comp = 0;
	if (!time_left)
		BNX2FC_IO_DBG(io_req, "%s(): Wait for cleanup timed out.\n",
			      __func__);

	/*
	 * release the reference taken in eh_abort to allow the
	 * target to re-login after flushing IOs
	 * Release reference held by SCSI command the cleanup completion
	 * hits the BNX2FC_CLEANUP case in bnx2fc_process_cq_compl() and
	 * thus the SCSI command is not returnedi by bnx2fc_scsi_done().
	 */
	kref_put(&io_req->refcount, bnx2fc_cmd_release);

	spin_lock_bh(&tgt->tgt_lock);
	return rc;
}

/**
 * bnx2fc_eh_abort - eh_abort_handler api to abort an outstanding
 *			SCSI command
@@ -1118,6 +1129,7 @@ int bnx2fc_eh_abort(struct scsi_cmnd *sc_cmd)
	struct fc_lport *lport;
	struct bnx2fc_rport *tgt;
	int rc;
	unsigned int time_left;

	rc = fc_block_scsi_eh(sc_cmd);
	if (rc)
@@ -1194,6 +1206,11 @@ int bnx2fc_eh_abort(struct scsi_cmnd *sc_cmd)
		if (cancel_delayed_work(&io_req->timeout_work))
			kref_put(&io_req->refcount,
				 bnx2fc_cmd_release); /* drop timer hold */
		/*
		 * We don't want to hold off the upper layer timer so simply
		 * cleanup the command and return that I/O was successfully
		 * aborted.
		 */
		rc = bnx2fc_abts_cleanup(io_req);
		/* This only occurs when an task abort was requested while ABTS
		   is in progress.  Setting the IO_CLEANUP flag will skip the
@@ -1201,7 +1218,7 @@ int bnx2fc_eh_abort(struct scsi_cmnd *sc_cmd)
		   was a result from the ABTS request rather than the CLEANUP
		   request */
		set_bit(BNX2FC_FLAG_IO_CLEANUP,	&io_req->req_flags);
		goto out;
		goto done;
	}

	/* Cancel the current timer running on this io_req */
@@ -1221,7 +1238,11 @@ int bnx2fc_eh_abort(struct scsi_cmnd *sc_cmd)
	}
	spin_unlock_bh(&tgt->tgt_lock);

	wait_for_completion(&io_req->tm_done);
	/* Wait 2 * RA_TOV + 1 to be sure timeout function hasn't fired */
	time_left = wait_for_completion_timeout(&io_req->tm_done,
	    (2 * rp->r_a_tov + 1) * HZ);
	if (time_left)
		BNX2FC_IO_DBG(io_req, "Timed out in eh_abort waiting for tm_done");

	spin_lock_bh(&tgt->tgt_lock);
	io_req->wait_for_comp = 0;
@@ -1233,8 +1254,12 @@ int bnx2fc_eh_abort(struct scsi_cmnd *sc_cmd)
		/* Let the scsi-ml try to recover this command */
		printk(KERN_ERR PFX "abort failed, xid = 0x%x\n",
		       io_req->xid);
		/*
		 * Cleanup firmware residuals before returning control back
		 * to SCSI ML.
		 */
		rc = bnx2fc_abts_cleanup(io_req);
		goto out;
		goto done;
	} else {
		/*
		 * We come here even when there was a race condition
@@ -1249,7 +1274,6 @@ int bnx2fc_eh_abort(struct scsi_cmnd *sc_cmd)
done:
	/* release the reference taken in eh_abort */
	kref_put(&io_req->refcount, bnx2fc_cmd_release);
out:
	spin_unlock_bh(&tgt->tgt_lock);
	return rc;
}
+9 −9
Original line number Diff line number Diff line
@@ -22,7 +22,7 @@ struct scsi_dev_info_list {
	struct list_head dev_info_list;
	char vendor[8];
	char model[16];
	unsigned flags;
	blist_flags_t flags;
	unsigned compatible; /* for use with scsi_static_device_list entries */
};

@@ -35,7 +35,7 @@ struct scsi_dev_info_list_table {


static const char spaces[] = "                "; /* 16 of them */
static unsigned scsi_default_dev_flags;
static blist_flags_t scsi_default_dev_flags;
static LIST_HEAD(scsi_dev_info_list);
static char scsi_dev_flags[256];

@@ -52,7 +52,7 @@ static struct {
	char *vendor;
	char *model;
	char *revision;	/* revision known to be bad, unused */
	unsigned flags;
	blist_flags_t flags;
} scsi_static_device_list[] __initdata = {
	/*
	 * The following devices are known not to tolerate a lun != 0 scan
@@ -335,7 +335,7 @@ static void scsi_strcpy_devinfo(char *name, char *to, size_t to_length,
 * Returns: 0 OK, -error on failure.
 **/
static int scsi_dev_info_list_add(int compatible, char *vendor, char *model,
			    char *strflags, int flags)
			    char *strflags, blist_flags_t flags)
{
	return scsi_dev_info_list_add_keyed(compatible, vendor, model,
					    strflags, flags,
@@ -361,7 +361,7 @@ static int scsi_dev_info_list_add(int compatible, char *vendor, char *model,
 * Returns: 0 OK, -error on failure.
 **/
int scsi_dev_info_list_add_keyed(int compatible, char *vendor, char *model,
				 char *strflags, int flags, int key)
				 char *strflags, blist_flags_t flags, int key)
{
	struct scsi_dev_info_list *devinfo;
	struct scsi_dev_info_list_table *devinfo_table =
@@ -571,7 +571,7 @@ static int scsi_dev_info_list_add_str(char *dev_list)
 *     matching flags value, else return the host or global default
 *     settings.  Called during scan time.
 **/
int scsi_get_device_flags(struct scsi_device *sdev,
blist_flags_t scsi_get_device_flags(struct scsi_device *sdev,
				    const unsigned char *vendor,
				    const unsigned char *model)
{
@@ -593,7 +593,7 @@ int scsi_get_device_flags(struct scsi_device *sdev,
 *     flags value, else return the host or global default settings.
 *     Called during scan time.
 **/
int scsi_get_device_flags_keyed(struct scsi_device *sdev,
blist_flags_t scsi_get_device_flags_keyed(struct scsi_device *sdev,
				const unsigned char *vendor,
				const unsigned char *model,
				int key)
+8 −7
Original line number Diff line number Diff line
@@ -50,15 +50,16 @@ enum {
	SCSI_DEVINFO_SPI,
};

extern int scsi_get_device_flags(struct scsi_device *sdev,
extern blist_flags_t scsi_get_device_flags(struct scsi_device *sdev,
					   const unsigned char *vendor,
					   const unsigned char *model);
extern int scsi_get_device_flags_keyed(struct scsi_device *sdev,
extern blist_flags_t scsi_get_device_flags_keyed(struct scsi_device *sdev,
						 const unsigned char *vendor,
				       const unsigned char *model, int key);
						 const unsigned char *model,
						 int key);
extern int scsi_dev_info_list_add_keyed(int compatible, char *vendor,
					char *model, char *strflags,
					int flags, int key);
					blist_flags_t flags, int key);
extern int scsi_dev_info_list_del_keyed(char *vendor, char *model, int key);
extern int scsi_dev_info_add_list(int key, const char *name);
extern int scsi_dev_info_remove_list(int key);
+1 −1
Original line number Diff line number Diff line
@@ -566,7 +566,7 @@ EXPORT_SYMBOL(scsi_sanitize_inquiry_string);
 *     are copied to the scsi_device any flags value is stored in *@bflags.
 **/
static int scsi_probe_lun(struct scsi_device *sdev, unsigned char *inq_result,
			  int result_len, int *bflags)
			  int result_len, blist_flags_t *bflags)
{
	unsigned char scsi_cmd[MAX_COMMAND_SIZE];
	int first_inquiry_len, try_inquiry_len, next_inquiry_len;
+3 −1
Original line number Diff line number Diff line
@@ -15,6 +15,8 @@ struct scsi_cmnd;
struct scsi_lun;
struct scsi_sense_hdr;

typedef unsigned int __bitwise blist_flags_t;

struct scsi_mode_data {
	__u32	length;
	__u16	block_descriptor_length;
@@ -141,7 +143,7 @@ struct scsi_device {
	unsigned char current_tag;	/* current tag */
	struct scsi_target      *sdev_target;   /* used only for single_lun */

	unsigned int	sdev_bflags; /* black/white flags as also found in
	blist_flags_t		sdev_bflags; /* black/white flags as also found in
				 * scsi_devinfo.[hc]. For now used only to
				 * pass settings from slave_alloc to scsi
				 * core. */
Loading