Commit 29cd195e authored by Linus Torvalds's avatar Linus Torvalds

Merge git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi-rc-fixes-2.6

* git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi-rc-fixes-2.6:
  [SCSI] fix check of PQ and PDT bits for WLUNs
  [SCSI] make scsi_check_sense HARDWARE_ERROR return ADD_TO_MLQUEUE on retry
  [SCSI] scsi_dh: make check_sense return ADD_TO_MLQUEUE
  [SCSI] zfcp: Remove duplicated unlikely() macros.
  [SCSI] zfcp: channel cannot be detached due to refcount imbalance
  [SCSI] zfcp: Fix reference counter for remote ports
  [SCSI] zfcp: Simplify ccw notify handler
  [SCSI] zfcp: Correctly query end flag in gpn_ft response
  [SCSI] zfcp: Fix request queue locking
  [SCSI] sd: select CRC_T10DIF only when necessary
parents c529b7e2 01b291bd
...@@ -152,10 +152,8 @@ static int zfcp_ccw_set_offline(struct ccw_device *ccw_device) ...@@ -152,10 +152,8 @@ static int zfcp_ccw_set_offline(struct ccw_device *ccw_device)
*/ */
static int zfcp_ccw_notify(struct ccw_device *ccw_device, int event) static int zfcp_ccw_notify(struct ccw_device *ccw_device, int event)
{ {
struct zfcp_adapter *adapter; struct zfcp_adapter *adapter = dev_get_drvdata(&ccw_device->dev);
down(&zfcp_data.config_sema);
adapter = dev_get_drvdata(&ccw_device->dev);
switch (event) { switch (event) {
case CIO_GONE: case CIO_GONE:
dev_warn(&adapter->ccw_device->dev, "device gone\n"); dev_warn(&adapter->ccw_device->dev, "device gone\n");
...@@ -174,8 +172,6 @@ static int zfcp_ccw_notify(struct ccw_device *ccw_device, int event) ...@@ -174,8 +172,6 @@ static int zfcp_ccw_notify(struct ccw_device *ccw_device, int event)
89, NULL); 89, NULL);
break; break;
} }
zfcp_erp_wait(adapter);
up(&zfcp_data.config_sema);
return 1; return 1;
} }
......
...@@ -39,18 +39,6 @@ struct zfcp_gpn_ft { ...@@ -39,18 +39,6 @@ struct zfcp_gpn_ft {
struct scatterlist sg_resp[ZFCP_GPN_FT_BUFFERS]; struct scatterlist sg_resp[ZFCP_GPN_FT_BUFFERS];
}; };
static struct zfcp_port *zfcp_get_port_by_did(struct zfcp_adapter *adapter,
u32 d_id)
{
struct zfcp_port *port;
list_for_each_entry(port, &adapter->port_list_head, list)
if ((port->d_id == d_id) &&
!atomic_test_mask(ZFCP_STATUS_COMMON_REMOVE, &port->status))
return port;
return NULL;
}
static void _zfcp_fc_incoming_rscn(struct zfcp_fsf_req *fsf_req, u32 range, static void _zfcp_fc_incoming_rscn(struct zfcp_fsf_req *fsf_req, u32 range,
struct fcp_rscn_element *elem) struct fcp_rscn_element *elem)
{ {
...@@ -341,11 +329,12 @@ void zfcp_test_link(struct zfcp_port *port) ...@@ -341,11 +329,12 @@ void zfcp_test_link(struct zfcp_port *port)
zfcp_port_get(port); zfcp_port_get(port);
retval = zfcp_fc_adisc(port); retval = zfcp_fc_adisc(port);
if (retval == 0 || retval == -EBUSY) if (retval == 0)
return; return;
/* send of ADISC was not possible */ /* send of ADISC was not possible */
zfcp_port_put(port); zfcp_port_put(port);
if (retval != -EBUSY)
zfcp_erp_port_forced_reopen(port, 0, 65, NULL); zfcp_erp_port_forced_reopen(port, 0, 65, NULL);
} }
...@@ -363,7 +352,6 @@ static int zfcp_scan_get_nameserver(struct zfcp_adapter *adapter) ...@@ -363,7 +352,6 @@ static int zfcp_scan_get_nameserver(struct zfcp_adapter *adapter)
if (ret) if (ret)
return ret; return ret;
zfcp_erp_wait(adapter); zfcp_erp_wait(adapter);
zfcp_port_put(adapter->nameserver_port);
} }
return !atomic_test_mask(ZFCP_STATUS_COMMON_UNBLOCKED, return !atomic_test_mask(ZFCP_STATUS_COMMON_UNBLOCKED,
&adapter->nameserver_port->status); &adapter->nameserver_port->status);
...@@ -475,7 +463,7 @@ static int zfcp_scan_eval_gpn_ft(struct zfcp_gpn_ft *gpn_ft) ...@@ -475,7 +463,7 @@ static int zfcp_scan_eval_gpn_ft(struct zfcp_gpn_ft *gpn_ft)
struct zfcp_adapter *adapter = ct->port->adapter; struct zfcp_adapter *adapter = ct->port->adapter;
struct zfcp_port *port, *tmp; struct zfcp_port *port, *tmp;
u32 d_id; u32 d_id;
int ret = 0, x; int ret = 0, x, last = 0;
if (ct->status) if (ct->status)
return -EIO; return -EIO;
...@@ -492,19 +480,24 @@ static int zfcp_scan_eval_gpn_ft(struct zfcp_gpn_ft *gpn_ft) ...@@ -492,19 +480,24 @@ static int zfcp_scan_eval_gpn_ft(struct zfcp_gpn_ft *gpn_ft)
down(&zfcp_data.config_sema); down(&zfcp_data.config_sema);
/* first entry is the header */ /* first entry is the header */
for (x = 1; x < ZFCP_GPN_FT_MAX_ENTRIES; x++) { for (x = 1; x < ZFCP_GPN_FT_MAX_ENTRIES && !last; x++) {
if (x % (ZFCP_GPN_FT_ENTRIES + 1)) if (x % (ZFCP_GPN_FT_ENTRIES + 1))
acc++; acc++;
else else
acc = sg_virt(++sg); acc = sg_virt(++sg);
last = acc->control & 0x80;
d_id = acc->port_id[0] << 16 | acc->port_id[1] << 8 | d_id = acc->port_id[0] << 16 | acc->port_id[1] << 8 |
acc->port_id[2]; acc->port_id[2];
/* skip the adapter's port and known remote ports */ /* skip the adapter's port and known remote ports */
if (acc->wwpn == fc_host_port_name(adapter->scsi_host) || if (acc->wwpn == fc_host_port_name(adapter->scsi_host))
zfcp_get_port_by_did(adapter, d_id)) continue;
port = zfcp_get_port_by_wwpn(adapter, acc->wwpn);
if (port) {
zfcp_port_get(port);
continue; continue;
}
port = zfcp_port_enqueue(adapter, acc->wwpn, port = zfcp_port_enqueue(adapter, acc->wwpn,
ZFCP_STATUS_PORT_DID_DID | ZFCP_STATUS_PORT_DID_DID |
...@@ -513,8 +506,6 @@ static int zfcp_scan_eval_gpn_ft(struct zfcp_gpn_ft *gpn_ft) ...@@ -513,8 +506,6 @@ static int zfcp_scan_eval_gpn_ft(struct zfcp_gpn_ft *gpn_ft)
ret = PTR_ERR(port); ret = PTR_ERR(port);
else else
zfcp_erp_port_reopen(port, 0, 149, NULL); zfcp_erp_port_reopen(port, 0, 149, NULL);
if (acc->control & 0x80) /* last entry */
break;
} }
zfcp_erp_wait(adapter); zfcp_erp_wait(adapter);
......
This diff is collapsed.
...@@ -423,9 +423,9 @@ void zfcp_qdio_close(struct zfcp_adapter *adapter) ...@@ -423,9 +423,9 @@ void zfcp_qdio_close(struct zfcp_adapter *adapter)
/* clear QDIOUP flag, thus do_QDIO is not called during qdio_shutdown */ /* clear QDIOUP flag, thus do_QDIO is not called during qdio_shutdown */
req_q = &adapter->req_q; req_q = &adapter->req_q;
spin_lock(&req_q->lock); spin_lock_bh(&req_q->lock);
atomic_clear_mask(ZFCP_STATUS_ADAPTER_QDIOUP, &adapter->status); atomic_clear_mask(ZFCP_STATUS_ADAPTER_QDIOUP, &adapter->status);
spin_unlock(&req_q->lock); spin_unlock_bh(&req_q->lock);
qdio_shutdown(adapter->ccw_device, QDIO_FLAG_CLEANUP_USING_CLEAR); qdio_shutdown(adapter->ccw_device, QDIO_FLAG_CLEANUP_USING_CLEAR);
......
...@@ -63,7 +63,7 @@ comment "SCSI support type (disk, tape, CD-ROM)" ...@@ -63,7 +63,7 @@ comment "SCSI support type (disk, tape, CD-ROM)"
config BLK_DEV_SD config BLK_DEV_SD
tristate "SCSI disk support" tristate "SCSI disk support"
depends on SCSI depends on SCSI
select CRC_T10DIF select CRC_T10DIF if BLK_DEV_INTEGRITY
---help--- ---help---
If you want to use SCSI hard disks, Fibre Channel disks, If you want to use SCSI hard disks, Fibre Channel disks,
Serial ATA (SATA) or Parallel ATA (PATA) hard disks, Serial ATA (SATA) or Parallel ATA (PATA) hard disks,
......
...@@ -425,7 +425,7 @@ static int alua_check_sense(struct scsi_device *sdev, ...@@ -425,7 +425,7 @@ static int alua_check_sense(struct scsi_device *sdev,
/* /*
* LUN Not Accessible - ALUA state transition * LUN Not Accessible - ALUA state transition
*/ */
return NEEDS_RETRY; return ADD_TO_MLQUEUE;
if (sense_hdr->asc == 0x04 && sense_hdr->ascq == 0x0b) if (sense_hdr->asc == 0x04 && sense_hdr->ascq == 0x0b)
/* /*
* LUN Not Accessible -- Target port in standby state * LUN Not Accessible -- Target port in standby state
...@@ -447,18 +447,18 @@ static int alua_check_sense(struct scsi_device *sdev, ...@@ -447,18 +447,18 @@ static int alua_check_sense(struct scsi_device *sdev,
/* /*
* Power On, Reset, or Bus Device Reset, just retry. * Power On, Reset, or Bus Device Reset, just retry.
*/ */
return NEEDS_RETRY; return ADD_TO_MLQUEUE;
if (sense_hdr->asc == 0x2a && sense_hdr->ascq == 0x06) { if (sense_hdr->asc == 0x2a && sense_hdr->ascq == 0x06) {
/* /*
* ALUA state changed * ALUA state changed
*/ */
return NEEDS_RETRY; return ADD_TO_MLQUEUE;
} }
if (sense_hdr->asc == 0x2a && sense_hdr->ascq == 0x07) { if (sense_hdr->asc == 0x2a && sense_hdr->ascq == 0x07) {
/* /*
* Implicit ALUA state transition failed * Implicit ALUA state transition failed
*/ */
return NEEDS_RETRY; return ADD_TO_MLQUEUE;
} }
break; break;
} }
...@@ -490,7 +490,7 @@ static int alua_stpg(struct scsi_device *sdev, int state, ...@@ -490,7 +490,7 @@ static int alua_stpg(struct scsi_device *sdev, int state,
if (!err) if (!err)
return SCSI_DH_IO; return SCSI_DH_IO;
err = alua_check_sense(sdev, &sense_hdr); err = alua_check_sense(sdev, &sense_hdr);
if (retry > 0 && err == NEEDS_RETRY) { if (retry > 0 && err == ADD_TO_MLQUEUE) {
retry--; retry--;
goto retry; goto retry;
} }
...@@ -535,7 +535,7 @@ static int alua_rtpg(struct scsi_device *sdev, struct alua_dh_data *h) ...@@ -535,7 +535,7 @@ static int alua_rtpg(struct scsi_device *sdev, struct alua_dh_data *h)
return SCSI_DH_IO; return SCSI_DH_IO;
err = alua_check_sense(sdev, &sense_hdr); err = alua_check_sense(sdev, &sense_hdr);
if (err == NEEDS_RETRY) if (err == ADD_TO_MLQUEUE)
goto retry; goto retry;
sdev_printk(KERN_INFO, sdev, sdev_printk(KERN_INFO, sdev,
"%s: rtpg sense code %02x/%02x/%02x\n", "%s: rtpg sense code %02x/%02x/%02x\n",
......
...@@ -439,7 +439,7 @@ static int clariion_check_sense(struct scsi_device *sdev, ...@@ -439,7 +439,7 @@ static int clariion_check_sense(struct scsi_device *sdev,
* Unit Attention Code. This is the first IO * Unit Attention Code. This is the first IO
* to the new path, so just retry. * to the new path, so just retry.
*/ */
return NEEDS_RETRY; return ADD_TO_MLQUEUE;
break; break;
} }
...@@ -514,7 +514,7 @@ static int clariion_send_inquiry(struct scsi_device *sdev, ...@@ -514,7 +514,7 @@ static int clariion_send_inquiry(struct scsi_device *sdev,
return SCSI_DH_IO; return SCSI_DH_IO;
err = clariion_check_sense(sdev, &sshdr); err = clariion_check_sense(sdev, &sshdr);
if (retry > 0 && err == NEEDS_RETRY) { if (retry > 0 && err == ADD_TO_MLQUEUE) {
retry--; retry--;
goto retry; goto retry;
} }
......
...@@ -551,7 +551,7 @@ static int rdac_check_sense(struct scsi_device *sdev, ...@@ -551,7 +551,7 @@ static int rdac_check_sense(struct scsi_device *sdev,
* *
* Just retry and wait. * Just retry and wait.
*/ */
return NEEDS_RETRY; return ADD_TO_MLQUEUE;
break; break;
case ILLEGAL_REQUEST: case ILLEGAL_REQUEST:
if (sense_hdr->asc == 0x94 && sense_hdr->ascq == 0x01) { if (sense_hdr->asc == 0x94 && sense_hdr->ascq == 0x01) {
...@@ -568,7 +568,7 @@ static int rdac_check_sense(struct scsi_device *sdev, ...@@ -568,7 +568,7 @@ static int rdac_check_sense(struct scsi_device *sdev,
/* /*
* Power On, Reset, or Bus Device Reset, just retry. * Power On, Reset, or Bus Device Reset, just retry.
*/ */
return NEEDS_RETRY; return ADD_TO_MLQUEUE;
break; break;
} }
/* success just means we do not care what scsi-ml does */ /* success just means we do not care what scsi-ml does */
......
...@@ -391,7 +391,7 @@ static int scsi_check_sense(struct scsi_cmnd *scmd) ...@@ -391,7 +391,7 @@ static int scsi_check_sense(struct scsi_cmnd *scmd)
case HARDWARE_ERROR: case HARDWARE_ERROR:
if (scmd->device->retry_hwerror) if (scmd->device->retry_hwerror)
return NEEDS_RETRY; return ADD_TO_MLQUEUE;
else else
return SUCCESS; return SUCCESS;
......
...@@ -1080,7 +1080,8 @@ static int scsi_probe_and_add_lun(struct scsi_target *starget, ...@@ -1080,7 +1080,8 @@ static int scsi_probe_and_add_lun(struct scsi_target *starget,
* PDT=1Fh none (no FDD connected to the requested logical unit) * PDT=1Fh none (no FDD connected to the requested logical unit)
*/ */
if (((result[0] >> 5) == 1 || starget->pdt_1f_for_no_lun) && if (((result[0] >> 5) == 1 || starget->pdt_1f_for_no_lun) &&
(result[0] & 0x1f) == 0x1f) { (result[0] & 0x1f) == 0x1f &&
!scsi_is_wlun(lun)) {
SCSI_LOG_SCAN_BUS(3, printk(KERN_INFO SCSI_LOG_SCAN_BUS(3, printk(KERN_INFO
"scsi scan: peripheral device type" "scsi scan: peripheral device type"
" of 31, no device added\n")); " of 31, no device added\n"));
......
...@@ -308,6 +308,20 @@ struct scsi_lun { ...@@ -308,6 +308,20 @@ struct scsi_lun {
__u8 scsi_lun[8]; __u8 scsi_lun[8];
}; };
/*
* The Well Known LUNS (SAM-3) in our int representation of a LUN
*/
#define SCSI_W_LUN_BASE 0xc100
#define SCSI_W_LUN_REPORT_LUNS (SCSI_W_LUN_BASE + 1)
#define SCSI_W_LUN_ACCESS_CONTROL (SCSI_W_LUN_BASE + 2)
#define SCSI_W_LUN_TARGET_LOG_PAGE (SCSI_W_LUN_BASE + 3)
static inline int scsi_is_wlun(unsigned int lun)
{
return (lun & 0xff00) == SCSI_W_LUN_BASE;
}
/* /*
* MESSAGE CODES * MESSAGE CODES
*/ */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment