Commit 35d91f75 authored by Linus Torvalds's avatar Linus Torvalds

Merge master.kernel.org:/pub/scm/linux/kernel/git/jejb/scsi-for-linus-2.6

parents 9401c705 70c83e11
...@@ -60,6 +60,8 @@ scsi.txt ...@@ -60,6 +60,8 @@ scsi.txt
- short blurb on using SCSI support as a module. - short blurb on using SCSI support as a module.
scsi_mid_low_api.txt scsi_mid_low_api.txt
- info on API between SCSI layer and low level drivers - info on API between SCSI layer and low level drivers
scsi_eh.txt
- info on SCSI midlayer error handling infrastructure
st.txt st.txt
- info on scsi tape driver - info on scsi tape driver
sym53c500_cs.txt sym53c500_cs.txt
......
This diff is collapsed.
...@@ -123,6 +123,7 @@ static int verify_command(struct file *file, unsigned char *cmd) ...@@ -123,6 +123,7 @@ static int verify_command(struct file *file, unsigned char *cmd)
safe_for_read(READ_12), safe_for_read(READ_12),
safe_for_read(READ_16), safe_for_read(READ_16),
safe_for_read(READ_BUFFER), safe_for_read(READ_BUFFER),
safe_for_read(READ_DEFECT_DATA),
safe_for_read(READ_LONG), safe_for_read(READ_LONG),
safe_for_read(INQUIRY), safe_for_read(INQUIRY),
safe_for_read(MODE_SENSE), safe_for_read(MODE_SENSE),
......
...@@ -790,7 +790,7 @@ static void sbp2_host_reset(struct hpsb_host *host) ...@@ -790,7 +790,7 @@ static void sbp2_host_reset(struct hpsb_host *host)
static int sbp2_start_device(struct scsi_id_instance_data *scsi_id) static int sbp2_start_device(struct scsi_id_instance_data *scsi_id)
{ {
struct sbp2scsi_host_info *hi = scsi_id->hi; struct sbp2scsi_host_info *hi = scsi_id->hi;
struct scsi_device *sdev; int error;
SBP2_DEBUG("sbp2_start_device"); SBP2_DEBUG("sbp2_start_device");
...@@ -939,10 +939,10 @@ static int sbp2_start_device(struct scsi_id_instance_data *scsi_id) ...@@ -939,10 +939,10 @@ static int sbp2_start_device(struct scsi_id_instance_data *scsi_id)
sbp2_max_speed_and_size(scsi_id); sbp2_max_speed_and_size(scsi_id);
/* Add this device to the scsi layer now */ /* Add this device to the scsi layer now */
sdev = scsi_add_device(scsi_id->scsi_host, 0, scsi_id->ud->id, 0); error = scsi_add_device(scsi_id->scsi_host, 0, scsi_id->ud->id, 0);
if (IS_ERR(sdev)) { if (error) {
SBP2_ERR("scsi_add_device failed"); SBP2_ERR("scsi_add_device failed");
return PTR_ERR(sdev); return error;
} }
return 0; return 0;
......
...@@ -59,6 +59,7 @@ ...@@ -59,6 +59,7 @@
Fix 'handled=1' ISR usage, remove bogus IRQ check. Fix 'handled=1' ISR usage, remove bogus IRQ check.
Remove un-needed eh_abort handler. Remove un-needed eh_abort handler.
Add support for embedded firmware error strings. Add support for embedded firmware error strings.
2.26.02.003 - Correctly handle single sgl's with use_sg=1.
*/ */
#include <linux/module.h> #include <linux/module.h>
...@@ -81,7 +82,7 @@ ...@@ -81,7 +82,7 @@
#include "3w-9xxx.h" #include "3w-9xxx.h"
/* Globals */ /* Globals */
#define TW_DRIVER_VERSION "2.26.02.002" #define TW_DRIVER_VERSION "2.26.02.003"
static TW_Device_Extension *twa_device_extension_list[TW_MAX_SLOT]; static TW_Device_Extension *twa_device_extension_list[TW_MAX_SLOT];
static unsigned int twa_device_extension_count; static unsigned int twa_device_extension_count;
static int twa_major = -1; static int twa_major = -1;
...@@ -1805,6 +1806,8 @@ static int twa_scsiop_execute_scsi(TW_Device_Extension *tw_dev, int request_id, ...@@ -1805,6 +1806,8 @@ static int twa_scsiop_execute_scsi(TW_Device_Extension *tw_dev, int request_id,
if (tw_dev->srb[request_id]->request_bufflen < TW_MIN_SGL_LENGTH) { if (tw_dev->srb[request_id]->request_bufflen < TW_MIN_SGL_LENGTH) {
command_packet->sg_list[0].address = tw_dev->generic_buffer_phys[request_id]; command_packet->sg_list[0].address = tw_dev->generic_buffer_phys[request_id];
command_packet->sg_list[0].length = TW_MIN_SGL_LENGTH; command_packet->sg_list[0].length = TW_MIN_SGL_LENGTH;
if (tw_dev->srb[request_id]->sc_data_direction == DMA_TO_DEVICE || tw_dev->srb[request_id]->sc_data_direction == DMA_BIDIRECTIONAL)
memcpy(tw_dev->generic_buffer_virt[request_id], tw_dev->srb[request_id]->request_buffer, tw_dev->srb[request_id]->request_bufflen);
} else { } else {
buffaddr = twa_map_scsi_single_data(tw_dev, request_id); buffaddr = twa_map_scsi_single_data(tw_dev, request_id);
if (buffaddr == 0) if (buffaddr == 0)
...@@ -1823,6 +1826,12 @@ static int twa_scsiop_execute_scsi(TW_Device_Extension *tw_dev, int request_id, ...@@ -1823,6 +1826,12 @@ static int twa_scsiop_execute_scsi(TW_Device_Extension *tw_dev, int request_id,
if (tw_dev->srb[request_id]->use_sg > 0) { if (tw_dev->srb[request_id]->use_sg > 0) {
if ((tw_dev->srb[request_id]->use_sg == 1) && (tw_dev->srb[request_id]->request_bufflen < TW_MIN_SGL_LENGTH)) { if ((tw_dev->srb[request_id]->use_sg == 1) && (tw_dev->srb[request_id]->request_bufflen < TW_MIN_SGL_LENGTH)) {
if (tw_dev->srb[request_id]->sc_data_direction == DMA_TO_DEVICE || tw_dev->srb[request_id]->sc_data_direction == DMA_BIDIRECTIONAL) {
struct scatterlist *sg = (struct scatterlist *)tw_dev->srb[request_id]->request_buffer;
char *buf = kmap_atomic(sg->page, KM_IRQ0) + sg->offset;
memcpy(tw_dev->generic_buffer_virt[request_id], buf, sg->length);
kunmap_atomic(buf - sg->offset, KM_IRQ0);
}
command_packet->sg_list[0].address = tw_dev->generic_buffer_phys[request_id]; command_packet->sg_list[0].address = tw_dev->generic_buffer_phys[request_id];
command_packet->sg_list[0].length = TW_MIN_SGL_LENGTH; command_packet->sg_list[0].length = TW_MIN_SGL_LENGTH;
} else { } else {
...@@ -1888,12 +1897,21 @@ static int twa_scsiop_execute_scsi(TW_Device_Extension *tw_dev, int request_id, ...@@ -1888,12 +1897,21 @@ static int twa_scsiop_execute_scsi(TW_Device_Extension *tw_dev, int request_id,
/* This function completes an execute scsi operation */ /* This function completes an execute scsi operation */
static void twa_scsiop_execute_scsi_complete(TW_Device_Extension *tw_dev, int request_id) static void twa_scsiop_execute_scsi_complete(TW_Device_Extension *tw_dev, int request_id)
{ {
/* Copy the response if too small */ if (tw_dev->srb[request_id]->request_bufflen < TW_MIN_SGL_LENGTH &&
if ((tw_dev->srb[request_id]->request_buffer) && (tw_dev->srb[request_id]->request_bufflen < TW_MIN_SGL_LENGTH)) { (tw_dev->srb[request_id]->sc_data_direction == DMA_FROM_DEVICE ||
tw_dev->srb[request_id]->sc_data_direction == DMA_BIDIRECTIONAL)) {
if (tw_dev->srb[request_id]->use_sg == 0) {
memcpy(tw_dev->srb[request_id]->request_buffer, memcpy(tw_dev->srb[request_id]->request_buffer,
tw_dev->generic_buffer_virt[request_id], tw_dev->generic_buffer_virt[request_id],
tw_dev->srb[request_id]->request_bufflen); tw_dev->srb[request_id]->request_bufflen);
} }
if (tw_dev->srb[request_id]->use_sg == 1) {
struct scatterlist *sg = (struct scatterlist *)tw_dev->srb[request_id]->request_buffer;
char *buf = kmap_atomic(sg->page, KM_IRQ0) + sg->offset;
memcpy(buf, tw_dev->generic_buffer_virt[request_id], sg->length);
kunmap_atomic(buf - sg->offset, KM_IRQ0);
}
}
} /* End twa_scsiop_execute_scsi_complete() */ } /* End twa_scsiop_execute_scsi_complete() */
/* This function tells the controller to shut down */ /* This function tells the controller to shut down */
......
...@@ -235,6 +235,13 @@ config SCSI_ISCSI_ATTRS ...@@ -235,6 +235,13 @@ config SCSI_ISCSI_ATTRS
each attached iSCSI device to sysfs, say Y. each attached iSCSI device to sysfs, say Y.
Otherwise, say N. Otherwise, say N.
config SCSI_SAS_ATTRS
tristate "SAS Transport Attributes"
depends on SCSI
help
If you wish to export transport-specific information about
each attached SAS device to sysfs, say Y.
endmenu endmenu
menu "SCSI low-level drivers" menu "SCSI low-level drivers"
......
...@@ -31,6 +31,7 @@ obj-$(CONFIG_RAID_ATTRS) += raid_class.o ...@@ -31,6 +31,7 @@ obj-$(CONFIG_RAID_ATTRS) += raid_class.o
obj-$(CONFIG_SCSI_SPI_ATTRS) += scsi_transport_spi.o obj-$(CONFIG_SCSI_SPI_ATTRS) += scsi_transport_spi.o
obj-$(CONFIG_SCSI_FC_ATTRS) += scsi_transport_fc.o obj-$(CONFIG_SCSI_FC_ATTRS) += scsi_transport_fc.o
obj-$(CONFIG_SCSI_ISCSI_ATTRS) += scsi_transport_iscsi.o obj-$(CONFIG_SCSI_ISCSI_ATTRS) += scsi_transport_iscsi.o
obj-$(CONFIG_SCSI_SAS_ATTRS) += scsi_transport_sas.o
obj-$(CONFIG_SCSI_AMIGA7XX) += amiga7xx.o 53c7xx.o obj-$(CONFIG_SCSI_AMIGA7XX) += amiga7xx.o 53c7xx.o
obj-$(CONFIG_A3000_SCSI) += a3000.o wd33c93.o obj-$(CONFIG_A3000_SCSI) += a3000.o wd33c93.o
......
...@@ -966,21 +966,21 @@ static void ...@@ -966,21 +966,21 @@ static void
lpfc_get_host_fabric_name (struct Scsi_Host *shost) lpfc_get_host_fabric_name (struct Scsi_Host *shost)
{ {
struct lpfc_hba *phba = (struct lpfc_hba*)shost->hostdata[0]; struct lpfc_hba *phba = (struct lpfc_hba*)shost->hostdata[0];
u64 nodename; u64 node_name;
spin_lock_irq(shost->host_lock); spin_lock_irq(shost->host_lock);
if ((phba->fc_flag & FC_FABRIC) || if ((phba->fc_flag & FC_FABRIC) ||
((phba->fc_topology == TOPOLOGY_LOOP) && ((phba->fc_topology == TOPOLOGY_LOOP) &&
(phba->fc_flag & FC_PUBLIC_LOOP))) (phba->fc_flag & FC_PUBLIC_LOOP)))
memcpy(&nodename, &phba->fc_fabparam.nodeName, sizeof(u64)); node_name = wwn_to_u64(phba->fc_fabparam.nodeName.wwn);
else else
/* fabric is local port if there is no F/FL_Port */ /* fabric is local port if there is no F/FL_Port */
memcpy(&nodename, &phba->fc_nodename, sizeof(u64)); node_name = wwn_to_u64(phba->fc_nodename.wwn);
spin_unlock_irq(shost->host_lock); spin_unlock_irq(shost->host_lock);
fc_host_fabric_name(shost) = be64_to_cpu(nodename); fc_host_fabric_name(shost) = node_name;
} }
...@@ -1103,21 +1103,20 @@ lpfc_get_starget_node_name(struct scsi_target *starget) ...@@ -1103,21 +1103,20 @@ lpfc_get_starget_node_name(struct scsi_target *starget)
{ {
struct Scsi_Host *shost = dev_to_shost(starget->dev.parent); struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
struct lpfc_hba *phba = (struct lpfc_hba *) shost->hostdata[0]; struct lpfc_hba *phba = (struct lpfc_hba *) shost->hostdata[0];
uint64_t node_name = 0; u64 node_name = 0;
struct lpfc_nodelist *ndlp = NULL; struct lpfc_nodelist *ndlp = NULL;
spin_lock_irq(shost->host_lock); spin_lock_irq(shost->host_lock);
/* Search the mapped list for this target ID */ /* Search the mapped list for this target ID */
list_for_each_entry(ndlp, &phba->fc_nlpmap_list, nlp_listp) { list_for_each_entry(ndlp, &phba->fc_nlpmap_list, nlp_listp) {
if (starget->id == ndlp->nlp_sid) { if (starget->id == ndlp->nlp_sid) {
memcpy(&node_name, &ndlp->nlp_nodename, node_name = wwn_to_u64(ndlp->nlp_nodename.wwn);
sizeof(struct lpfc_name));
break; break;
} }
} }
spin_unlock_irq(shost->host_lock); spin_unlock_irq(shost->host_lock);
fc_starget_node_name(starget) = be64_to_cpu(node_name); fc_starget_node_name(starget) = node_name;
} }
static void static void
...@@ -1125,21 +1124,20 @@ lpfc_get_starget_port_name(struct scsi_target *starget) ...@@ -1125,21 +1124,20 @@ lpfc_get_starget_port_name(struct scsi_target *starget)
{ {
struct Scsi_Host *shost = dev_to_shost(starget->dev.parent); struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
struct lpfc_hba *phba = (struct lpfc_hba *) shost->hostdata[0]; struct lpfc_hba *phba = (struct lpfc_hba *) shost->hostdata[0];
uint64_t port_name = 0; u64 port_name = 0;
struct lpfc_nodelist *ndlp = NULL; struct lpfc_nodelist *ndlp = NULL;
spin_lock_irq(shost->host_lock); spin_lock_irq(shost->host_lock);
/* Search the mapped list for this target ID */ /* Search the mapped list for this target ID */
list_for_each_entry(ndlp, &phba->fc_nlpmap_list, nlp_listp) { list_for_each_entry(ndlp, &phba->fc_nlpmap_list, nlp_listp) {
if (starget->id == ndlp->nlp_sid) { if (starget->id == ndlp->nlp_sid) {
memcpy(&port_name, &ndlp->nlp_portname, port_name = wwn_to_u64(ndlp->nlp_portname.wwn);
sizeof(struct lpfc_name));
break; break;
} }
} }
spin_unlock_irq(shost->host_lock); spin_unlock_irq(shost->host_lock);
fc_starget_port_name(starget) = be64_to_cpu(port_name); fc_starget_port_name(starget) = port_name;
} }
static void static void
......
...@@ -1017,13 +1017,10 @@ lpfc_register_remote_port(struct lpfc_hba * phba, ...@@ -1017,13 +1017,10 @@ lpfc_register_remote_port(struct lpfc_hba * phba,
struct fc_rport *rport; struct fc_rport *rport;
struct lpfc_rport_data *rdata; struct lpfc_rport_data *rdata;
struct fc_rport_identifiers rport_ids; struct fc_rport_identifiers rport_ids;
uint64_t wwn;
/* Remote port has reappeared. Re-register w/ FC transport */ /* Remote port has reappeared. Re-register w/ FC transport */
memcpy(&wwn, &ndlp->nlp_nodename, sizeof(uint64_t)); rport_ids.node_name = wwn_to_u64(ndlp->nlp_nodename.wwn);
rport_ids.node_name = be64_to_cpu(wwn); rport_ids.port_name = wwn_to_u64(ndlp->nlp_portname.wwn);
memcpy(&wwn, &ndlp->nlp_portname, sizeof(uint64_t));
rport_ids.port_name = be64_to_cpu(wwn);
rport_ids.port_id = ndlp->nlp_DID; rport_ids.port_id = ndlp->nlp_DID;
rport_ids.roles = FC_RPORT_ROLE_UNKNOWN; rport_ids.roles = FC_RPORT_ROLE_UNKNOWN;
if (ndlp->nlp_type & NLP_FCP_TARGET) if (ndlp->nlp_type & NLP_FCP_TARGET)
......
...@@ -262,6 +262,8 @@ struct lpfc_sli_ct_request { ...@@ -262,6 +262,8 @@ struct lpfc_sli_ct_request {
#define FF_FRAME_SIZE 2048 #define FF_FRAME_SIZE 2048
struct lpfc_name { struct lpfc_name {
union {
struct {
#ifdef __BIG_ENDIAN_BITFIELD #ifdef __BIG_ENDIAN_BITFIELD
uint8_t nameType:4; /* FC Word 0, bit 28:31 */ uint8_t nameType:4; /* FC Word 0, bit 28:31 */
uint8_t IEEEextMsn:4; /* FC Word 0, bit 24:27, bit 8:11 of IEEE ext */ uint8_t IEEEextMsn:4; /* FC Word 0, bit 24:27, bit 8:11 of IEEE ext */
...@@ -278,6 +280,9 @@ struct lpfc_name { ...@@ -278,6 +280,9 @@ struct lpfc_name {
#define NAME_CCITT_GR_TYPE 0xE #define NAME_CCITT_GR_TYPE 0xE
uint8_t IEEEextLsb; /* FC Word 0, bit 16:23, IEEE extended Lsb */ uint8_t IEEEextLsb; /* FC Word 0, bit 16:23, IEEE extended Lsb */
uint8_t IEEE[6]; /* FC IEEE address */ uint8_t IEEE[6]; /* FC IEEE address */
};
uint8_t wwn[8];
};
}; };
struct csp { struct csp {
......
...@@ -1333,7 +1333,6 @@ lpfc_pci_probe_one(struct pci_dev *pdev, const struct pci_device_id *pid) ...@@ -1333,7 +1333,6 @@ lpfc_pci_probe_one(struct pci_dev *pdev, const struct pci_device_id *pid)
unsigned long bar0map_len, bar2map_len; unsigned long bar0map_len, bar2map_len;
int error = -ENODEV, retval; int error = -ENODEV, retval;
int i; int i;
u64 wwname;
if (pci_enable_device(pdev)) if (pci_enable_device(pdev))
goto out; goto out;
...@@ -1524,10 +1523,8 @@ lpfc_pci_probe_one(struct pci_dev *pdev, const struct pci_device_id *pid) ...@@ -1524,10 +1523,8 @@ lpfc_pci_probe_one(struct pci_dev *pdev, const struct pci_device_id *pid)
* Must done after lpfc_sli_hba_setup() * Must done after lpfc_sli_hba_setup()
*/ */
memcpy(&wwname, &phba->fc_nodename, sizeof(u64)); fc_host_node_name(host) = wwn_to_u64(phba->fc_nodename.wwn);
fc_host_node_name(host) = be64_to_cpu(wwname); fc_host_port_name(host) = wwn_to_u64(phba->fc_portname.wwn);
memcpy(&wwname, &phba->fc_portname, sizeof(u64));
fc_host_port_name(host) = be64_to_cpu(wwname);
fc_host_supported_classes(host) = FC_COS_CLASS3; fc_host_supported_classes(host) = FC_COS_CLASS3;
memset(fc_host_supported_fc4s(host), 0, memset(fc_host_supported_fc4s(host), 0,
......
...@@ -360,16 +360,16 @@ qla2x00_get_starget_node_name(struct scsi_target *starget) ...@@ -360,16 +360,16 @@ qla2x00_get_starget_node_name(struct scsi_target *starget)
struct Scsi_Host *host = dev_to_shost(starget->dev.parent); struct Scsi_Host *host = dev_to_shost(starget->dev.parent);
scsi_qla_host_t *ha = to_qla_host(host); scsi_qla_host_t *ha = to_qla_host(host);
fc_port_t *fcport; fc_port_t *fcport;
uint64_t node_name = 0; u64 node_name = 0;
list_for_each_entry(fcport, &ha->fcports, list) { list_for_each_entry(fcport, &ha->fcports, list) {
if (starget->id == fcport->os_target_id) { if (starget->id == fcport->os_target_id) {
node_name = *(uint64_t *)fcport->node_name; node_name = wwn_to_u64(fcport->node_name);
break; break;
} }
} }
fc_starget_node_name(starget) = be64_to_cpu(node_name); fc_starget_node_name(starget) = node_name;
} }
static void static void
...@@ -378,16 +378,16 @@ qla2x00_get_starget_port_name(struct scsi_target *starget) ...@@ -378,16 +378,16 @@ qla2x00_get_starget_port_name(struct scsi_target *starget)
struct Scsi_Host *host = dev_to_shost(starget->dev.parent); struct Scsi_Host *host = dev_to_shost(starget->dev.parent);
scsi_qla_host_t *ha = to_qla_host(host); scsi_qla_host_t *ha = to_qla_host(host);
fc_port_t *fcport; fc_port_t *fcport;
uint64_t port_name = 0; u64 port_name = 0;
list_for_each_entry(fcport, &ha->fcports, list) { list_for_each_entry(fcport, &ha->fcports, list) {
if (starget->id == fcport->os_target_id) { if (starget->id == fcport->os_target_id) {
port_name = *(uint64_t *)fcport->port_name; port_name = wwn_to_u64(fcport->port_name);
break; break;
} }
} }
fc_starget_port_name(starget) = be64_to_cpu(port_name); fc_starget_port_name(starget) = port_name;
} }
static void static void
...@@ -460,9 +460,7 @@ struct fc_function_template qla2xxx_transport_functions = { ...@@ -460,9 +460,7 @@ struct fc_function_template qla2xxx_transport_functions = {
void void
qla2x00_init_host_attr(scsi_qla_host_t *ha) qla2x00_init_host_attr(scsi_qla_host_t *ha)
{ {
fc_host_node_name(ha->host) = fc_host_node_name(ha->host) = wwn_to_u64(ha->init_cb->node_name);
be64_to_cpu(*(uint64_t *)ha->init_cb->node_name); fc_host_port_name(ha->host) = wwn_to_u64(ha->init_cb->port_name);
fc_host_port_name(ha->host) =
be64_to_cpu(*(uint64_t *)ha->init_cb->port_name);
fc_host_supported_classes(ha->host) = FC_COS_CLASS3; fc_host_supported_classes(ha->host) = FC_COS_CLASS3;
} }
...@@ -2066,8 +2066,8 @@ qla2x00_reg_remote_port(scsi_qla_host_t *ha, fc_port_t *fcport) ...@@ -2066,8 +2066,8 @@ qla2x00_reg_remote_port(scsi_qla_host_t *ha, fc_port_t *fcport)
return; return;
} }
rport_ids.node_name = be64_to_cpu(*(uint64_t *)fcport->node_name); rport_ids.node_name = wwn_to_u64(fcport->node_name);
rport_ids.port_name = be64_to_cpu(*(uint64_t *)fcport->port_name); rport_ids.port_name = wwn_to_u64(fcport->port_name);
rport_ids.port_id = fcport->d_id.b.domain << 16 | rport_ids.port_id = fcport->d_id.b.domain << 16 |
fcport->d_id.b.area << 8 | fcport->d_id.b.al_pa; fcport->d_id.b.area << 8 | fcport->d_id.b.al_pa;
rport_ids.roles = FC_RPORT_ROLE_UNKNOWN; rport_ids.roles = FC_RPORT_ROLE_UNKNOWN;
......
This diff is collapsed.
...@@ -124,6 +124,7 @@ extern void scsi_sysfs_unregister(void); ...@@ -124,6 +124,7 @@ extern void scsi_sysfs_unregister(void);
extern void scsi_sysfs_device_initialize(struct scsi_device *); extern void scsi_sysfs_device_initialize(struct scsi_device *);
extern int scsi_sysfs_target_initialize(struct scsi_device *); extern int scsi_sysfs_target_initialize(struct scsi_device *);
extern struct scsi_transport_template blank_transport_template; extern struct scsi_transport_template blank_transport_template;
extern void __scsi_remove_device(struct scsi_device *);
extern struct bus_type scsi_bus_type; extern struct bus_type scsi_bus_type;
......
...@@ -870,8 +870,12 @@ static int scsi_probe_and_add_lun(struct scsi_target *starget, ...@@ -870,8 +870,12 @@ static int scsi_probe_and_add_lun(struct scsi_target *starget,
out_free_sdev: out_free_sdev:
if (res == SCSI_SCAN_LUN_PRESENT) { if (res == SCSI_SCAN_LUN_PRESENT) {
if (sdevp) { if (sdevp) {
scsi_device_get(sdev); if (scsi_device_get(sdev) == 0) {
*sdevp = sdev; *sdevp = sdev;
} else {
__scsi_remove_device(sdev);
res = SCSI_SCAN_NO_RESPONSE;
}
} }
} else { } else {
if (sdev->host->hostt->slave_destroy) if (sdev->host->hostt->slave_destroy)
...@@ -1260,6 +1264,19 @@ struct scsi_device *__scsi_add_device(struct Scsi_Host *shost, uint channel, ...@@ -1260,6 +1264,19 @@ struct scsi_device *__scsi_add_device(struct Scsi_Host *shost, uint channel,
} }
EXPORT_SYMBOL(__scsi_add_device); EXPORT_SYMBOL(__scsi_add_device);
int scsi_add_device(struct Scsi_Host *host, uint channel,
uint target, uint lun)
{
struct scsi_device *sdev =
__scsi_add_device(host, channel, target, lun, NULL);
if (IS_ERR(sdev))
return PTR_ERR(sdev);
scsi_device_put(sdev);
return 0;
}
EXPORT_SYMBOL(scsi_add_device);
void scsi_rescan_device(struct device *dev) void scsi_rescan_device(struct device *dev)
{ {
struct scsi_driver *drv; struct scsi_driver *drv;
...@@ -1276,26 +1293,7 @@ void scsi_rescan_device(struct device *dev) ...@@ -1276,26 +1293,7 @@ void scsi_rescan_device(struct device *dev)
} }
EXPORT_SYMBOL(scsi_rescan_device); EXPORT_SYMBOL(scsi_rescan_device);
/** static void __scsi_scan_target(struct device *parent, unsigned int channel,
* scsi_scan_target - scan a target id, possibly including all LUNs on the
* target.
* @sdevsca: Scsi_Device handle for scanning
* @shost: host to scan
* @channel: channel to scan
* @id: target id to scan
*
* Description:
* Scan the target id on @shost, @channel, and @id. Scan at least LUN
* 0, and possibly all LUNs on the target id.
*
* Use the pre-allocated @sdevscan as a handle for the scanning. This
* function sets sdevscan->host, sdevscan->id and sdevscan->lun; the
* scanning functions modify sdevscan->lun.
*
* First try a REPORT LUN scan, if that does not scan the target, do a
* sequential scan of LUNs on the target id.
**/
void scsi_scan_target(struct device *parent, unsigned int channel,
unsigned int id, unsigned int lun, int rescan) unsigned int id, unsigned int lun, int rescan)
{ {
struct Scsi_Host *shost = dev_to_shost(parent); struct Scsi_Host *shost = dev_to_shost(parent);
...@@ -1310,9 +1308,7 @@ void scsi_scan_target(struct device *parent, unsigned int channel, ...@@ -1310,9 +1308,7 @@ void scsi_scan_target(struct device *parent, unsigned int channel,
*/ */
return; return;
starget = scsi_alloc_target(parent, channel, id); starget = scsi_alloc_target(parent, channel, id);
if (!starget) if (!starget)
return; return;
...@@ -1358,6 +1354,33 @@ void scsi_scan_target(struct device *parent, unsigned int channel, ...@@ -1358,6 +1354,33 @@ void scsi_scan_target(struct device *parent, unsigned int channel,
put_device(&starget->dev); put_device(&starget->dev);
} }
/**
* scsi_scan_target - scan a target id, possibly including all LUNs on the
* target.
* @parent: host to scan
* @channel: channel to scan
* @id: target id to scan
* @lun: Specific LUN to scan or SCAN_WILD_CARD
* @rescan: passed to LUN scanning routines
*
* Description:
* Scan the target id on @parent, @channel, and @id. Scan at least LUN 0,
* and possibly all LUNs on the target id.
*
* First try a REPORT LUN scan, if that does not scan the target, do a
* sequential scan of LUNs on the target id.
**/
void scsi_scan_target(struct device *parent, unsigned int channel,
unsigned int id, unsigned int lun, int rescan)
{
struct Scsi_Host *shost = dev_to_shost(parent);
down(&shost->scan_mutex);
if (scsi_host_scan_allowed(shost))
__scsi_scan_target(parent, channel, id, lun, rescan);
up(&shost->scan_mutex);
}
EXPORT_SYMBOL(scsi_scan_target); EXPORT_SYMBOL(scsi_scan_target);
static void scsi_scan_channel(struct Scsi_Host *shost, unsigned int channel, static void scsi_scan_channel(struct Scsi_Host *shost, unsigned int channel,
...@@ -1383,10 +1406,12 @@ static void scsi_scan_channel(struct Scsi_Host *shost, unsigned int channel, ...@@ -1383,10 +1406,12 @@ static void scsi_scan_channel(struct Scsi_Host *shost, unsigned int channel,
order_id = shost->max_id - id - 1; order_id = shost->max_id - id - 1;
else else
order_id = id; order_id = id;
scsi_scan_target(&shost->shost_gendev, channel, order_id, lun, rescan); __scsi_scan_target(&shost->shost_gendev, channel,
order_id, lun, rescan);
} }
else else
scsi_scan_target(&shost->shost_gendev, channel, id, lun, rescan); __scsi_scan_target(&shost->shost_gendev, channel,
id, lun, rescan);
} }
int scsi_scan_host_selected(struct Scsi_Host *shost, unsigned int channel, int scsi_scan_host_selected(struct Scsi_Host *shost, unsigned int channel,
...@@ -1484,12 +1509,15 @@ void scsi_forget_host(struct Scsi_Host *shost) ...@@ -1484,12 +1509,15 @@ void scsi_forget_host(struct Scsi_Host *shost)
*/ */
struct scsi_device *scsi_get_host_dev(struct Scsi_Host *shost) struct scsi_device *scsi_get_host_dev(struct Scsi_Host *shost)
{ {
struct scsi_device *sdev; struct scsi_device *sdev = NULL;
struct scsi_target *starget; struct scsi_target *starget;
down(&shost->scan_mutex);
if (!scsi_host_scan_allowed(shost))
goto out;
starget = scsi_alloc_target(&shost->shost_gendev, 0, shost->this_id); starget = scsi_alloc_target(&shost->shost_gendev, 0, shost->this_id);
if (!starget) if (!starget)
return NULL; goto out;
sdev = scsi_alloc_sdev(starget, 0, NULL); sdev = scsi_alloc_sdev(starget, 0, NULL);
if (sdev) { if (sdev) {
...@@ -1497,6 +1525,8 @@ struct scsi_device *scsi_get_host_dev(struct Scsi_Host *shost) ...@@ -1497,6 +1525,8 @@ struct scsi_device *scsi_get_host_dev(struct Scsi_Host *shost)
sdev->borken = 0; sdev->borken = 0;
} }
put_device(&starget->dev); put_device(&starget->dev);
out:
up(&shost->scan_mutex);
return sdev; return sdev;
} }
EXPORT_SYMBOL(scsi_get_host_dev); EXPORT_SYMBOL(scsi_get_host_dev);
......
...@@ -653,7 +653,7 @@ int scsi_sysfs_add_sdev(struct scsi_device *sdev) ...@@ -653,7 +653,7 @@ int scsi_sysfs_add_sdev(struct scsi_device *sdev)
error = attr_add(&sdev->sdev_gendev, error = attr_add(&sdev->sdev_gendev,
sdev->host->hostt->sdev_attrs[i]); sdev->host->hostt->sdev_attrs[i]);
if (error) { if (error) {
scsi_remove_device(sdev); __scsi_remove_device(sdev);
goto out; goto out;
} }
} }
...@@ -667,7 +667,7 @@ int scsi_sysfs_add_sdev(struct scsi_device *sdev) ...@@ -667,7 +667,7 @@ int scsi_sysfs_add_sdev(struct scsi_device *sdev)
scsi_sysfs_sdev_attrs[i]); scsi_sysfs_sdev_attrs[i]);
error = device_create_file(&sdev->sdev_gendev, attr); error = device_create_file(&sdev->sdev_gendev, attr);
if (error) { if (error) {
scsi_remove_device(sdev); __scsi_remove_device(sdev);
goto out; goto out;
} }
} }
...@@ -687,17 +687,10 @@ int scsi_sysfs_add_sdev(struct scsi_device *sdev) ...@@ -687,17 +687,10 @@ int scsi_sysfs_add_sdev(struct scsi_device *sdev)
return error; return error;
} }
/** void __scsi_remove_device(struct scsi_device *sdev)
* scsi_remove_device - unregister a device from the scsi bus
* @sdev: scsi_device to unregister
**/
void scsi_remove_device(struct scsi_device *sdev)
{ {
struct Scsi_Host *shost = sdev->host;
down(&shost->scan_mutex);
if (scsi_device_set_state(sdev, SDEV_CANCEL) != 0) if (scsi_device_set_state(sdev, SDEV_CANCEL) != 0)
goto out; return;
class_device_unregister(&sdev->sdev_classdev); class_device_unregister(&sdev->sdev_classdev);
device_del(&sdev->sdev_gendev); device_del(&sdev->sdev_gendev);
...@@ -706,8 +699,17 @@ void scsi_remove_device(struct scsi_device *sdev) ...@@ -706,8 +699,17 @@ void scsi_remove_device(struct scsi_device *sdev)
sdev->host->hostt->slave_destroy(sdev); sdev->host->hostt->slave_destroy(sdev);
transport_unregister_device(&sdev->sdev_gendev); transport_unregister_device(&sdev->sdev_gendev);
put_device(&sdev->sdev_gendev); put_device(&sdev->sdev_gendev);
out: }
up(&shost->scan_mutex);
/**
* scsi_remove_device - unregister a device from the scsi bus
* @sdev: scsi_device to unregister
**/
void scsi_remove_device(struct scsi_device *sdev)
{
down(&sdev->host->scan_mutex);
__scsi_remove_device(sdev);
up(&sdev->host->scan_mutex);
} }
EXPORT_SYMBOL(scsi_remove_device); EXPORT_SYMBOL(scsi_remove_device);
......
This diff is collapsed.
...@@ -61,7 +61,7 @@ static int sg_version_num = 30533; /* 2 digits for each component */ ...@@ -61,7 +61,7 @@ static int sg_version_num = 30533; /* 2 digits for each component */
#ifdef CONFIG_SCSI_PROC_FS #ifdef CONFIG_SCSI_PROC_FS
#include <linux/proc_fs.h> #include <linux/proc_fs.h>
static char *sg_version_date = "20050901"; static char *sg_version_date = "20050908";
static int sg_proc_init(void); static int sg_proc_init(void);
static void sg_proc_cleanup(void); static void sg_proc_cleanup(void);
...@@ -1299,7 +1299,7 @@ sg_mmap(struct file *filp, struct vm_area_struct *vma) ...@@ -1299,7 +1299,7 @@ sg_mmap(struct file *filp, struct vm_area_struct *vma)
sg_rb_correct4mmap(rsv_schp, 1); /* do only once per fd lifetime */ sg_rb_correct4mmap(rsv_schp, 1); /* do only once per fd lifetime */
sfp->mmap_called = 1; sfp->mmap_called = 1;
} }
vma->vm_flags |= (VM_RESERVED | VM_IO); vma->vm_flags |= VM_RESERVED;
vma->vm_private_data = sfp; vma->vm_private_data = sfp;
vma->vm_ops = &sg_mmap_vm_ops; vma->vm_ops = &sg_mmap_vm_ops;
return 0; return 0;
......
...@@ -178,8 +178,8 @@ static inline struct scsi_target *scsi_target(struct scsi_device *sdev) ...@@ -178,8 +178,8 @@ static inline struct scsi_target *scsi_target(struct scsi_device *sdev)
extern struct scsi_device *__scsi_add_device(struct Scsi_Host *, extern struct scsi_device *__scsi_add_device(struct Scsi_Host *,
uint, uint, uint, void *hostdata); uint, uint, uint, void *hostdata);
#define scsi_add_device(host, channel, target, lun) \ extern int scsi_add_device(struct Scsi_Host *host, uint channel,
__scsi_add_device(host, channel, target, lun, NULL) uint target, uint lun);
extern void scsi_remove_device(struct scsi_device *); extern void scsi_remove_device(struct scsi_device *);
extern int scsi_device_cancel(struct scsi_device *, int); extern int scsi_device_cancel(struct scsi_device *, int);
......
...@@ -439,4 +439,12 @@ int fc_remote_port_block(struct fc_rport *rport); ...@@ -439,4 +439,12 @@ int fc_remote_port_block(struct fc_rport *rport);
void fc_remote_port_unblock(struct fc_rport *rport); void fc_remote_port_unblock(struct fc_rport *rport);
int scsi_is_fc_rport(const struct device *); int scsi_is_fc_rport(const struct device *);
static inline u64 wwn_to_u64(u8 *wwn)
{
return (u64)wwn[0] << 56 | (u64)wwn[1] << 48 |
(u64)wwn[2] << 40 | (u64)wwn[3] << 32 |
(u64)wwn[4] << 24 | (u64)wwn[5] << 16 |
(u64)wwn[6] << 8 | (u64)wwn[7];
}
#endif /* SCSI_TRANSPORT_FC_H */ #endif /* SCSI_TRANSPORT_FC_H */
#ifndef SCSI_TRANSPORT_SAS_H
#define SCSI_TRANSPORT_SAS_H
#include <linux/transport_class.h>
#include <linux/types.h>
struct scsi_transport_template;
struct sas_rphy;
enum sas_device_type {
SAS_PHY_UNUSED,
SAS_END_DEVICE,
SAS_EDGE_EXPANDER_DEVICE,
SAS_FANOUT_EXPANDER_DEVICE,
};
enum sas_protocol {
SAS_PROTOCOL_SATA = 0x01,
SAS_PROTOCOL_SMP = 0x02,
SAS_PROTOCOL_STP = 0x04,
SAS_PROTOCOL_SSP = 0x08,
};
enum sas_linkrate {
SAS_LINK_RATE_UNKNOWN,
SAS_PHY_DISABLED,
SAS_LINK_RATE_FAILED,
SAS_SATA_SPINUP_HOLD,
SAS_SATA_PORT_SELECTOR,
SAS_LINK_RATE_1_5_GBPS,
SAS_LINK_RATE_3_0_GBPS,
SAS_LINK_VIRTUAL,
};
struct sas_identify {
enum sas_device_type device_type;
enum sas_protocol initiator_port_protocols;
enum sas_protocol target_port_protocols;
u64 sas_address;
u8 phy_identifier;
};
/* The functions by which the transport class and the driver communicate */
struct sas_function_template {
};
struct sas_phy {
struct device dev;
int number;
struct sas_identify identify;
enum sas_linkrate negotiated_linkrate;
enum sas_linkrate minimum_linkrate_hw;
enum sas_linkrate minimum_linkrate;
enum sas_linkrate maximum_linkrate_hw;
enum sas_linkrate maximum_linkrate;
u8 port_identifier;
struct sas_rphy *rphy;
};
#define dev_to_phy(d) \
container_of((d), struct sas_phy, dev)
#define transport_class_to_phy(cdev) \
dev_to_phy((cdev)->dev)
#define phy_to_shost(phy) \
dev_to_shost((phy)->dev.parent)
struct sas_rphy {
struct device dev;
struct sas_identify identify;
struct list_head list;
u32 scsi_target_id;
};
#define dev_to_rphy(d) \
container_of((d), struct sas_rphy, dev)
#define transport_class_to_rphy(cdev) \
dev_to_rphy((cdev)->dev)
#define rphy_to_shost(rphy) \
dev_to_shost((rphy)->dev.parent)
extern void sas_remove_host(struct Scsi_Host *);
extern struct sas_phy *sas_phy_alloc(struct device *, int);
extern void sas_phy_free(struct sas_phy *);
extern int sas_phy_add(struct sas_phy *);
extern void sas_phy_delete(struct sas_phy *);
extern int scsi_is_sas_phy(const struct device *);
extern struct sas_rphy *sas_rphy_alloc(struct sas_phy *);
void sas_rphy_free(struct sas_rphy *);
extern int sas_rphy_add(struct sas_rphy *);
extern void sas_rphy_delete(struct sas_rphy *);
extern int scsi_is_sas_rphy(const struct device *);
extern struct scsi_transport_template *
sas_attach_transport(struct sas_function_template *);
extern void sas_release_transport(struct scsi_transport_template *);
#endif /* SCSI_TRANSPORT_SAS_H */
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