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
- short blurb on using SCSI support as a module.
scsi_mid_low_api.txt
- info on API between SCSI layer and low level drivers
scsi_eh.txt
- info on SCSI midlayer error handling infrastructure
st.txt
- info on scsi tape driver
sym53c500_cs.txt
......
This diff is collapsed.
......@@ -123,6 +123,7 @@ static int verify_command(struct file *file, unsigned char *cmd)
safe_for_read(READ_12),
safe_for_read(READ_16),
safe_for_read(READ_BUFFER),
safe_for_read(READ_DEFECT_DATA),
safe_for_read(READ_LONG),
safe_for_read(INQUIRY),
safe_for_read(MODE_SENSE),
......
......@@ -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)
{
struct sbp2scsi_host_info *hi = scsi_id->hi;
struct scsi_device *sdev;
int error;
SBP2_DEBUG("sbp2_start_device");
......@@ -939,10 +939,10 @@ static int sbp2_start_device(struct scsi_id_instance_data *scsi_id)
sbp2_max_speed_and_size(scsi_id);
/* Add this device to the scsi layer now */
sdev = scsi_add_device(scsi_id->scsi_host, 0, scsi_id->ud->id, 0);
if (IS_ERR(sdev)) {
error = scsi_add_device(scsi_id->scsi_host, 0, scsi_id->ud->id, 0);
if (error) {
SBP2_ERR("scsi_add_device failed");
return PTR_ERR(sdev);
return error;
}
return 0;
......
......@@ -59,6 +59,7 @@
Fix 'handled=1' ISR usage, remove bogus IRQ check.
Remove un-needed eh_abort handler.
Add support for embedded firmware error strings.
2.26.02.003 - Correctly handle single sgl's with use_sg=1.
*/
#include <linux/module.h>
......@@ -81,7 +82,7 @@
#include "3w-9xxx.h"
/* 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 unsigned int twa_device_extension_count;
static int twa_major = -1;
......@@ -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) {
command_packet->sg_list[0].address = tw_dev->generic_buffer_phys[request_id];
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 {
buffaddr = twa_map_scsi_single_data(tw_dev, request_id);
if (buffaddr == 0)
......@@ -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 == 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].length = TW_MIN_SGL_LENGTH;
} else {
......@@ -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 */
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_buffer) && (tw_dev->srb[request_id]->request_bufflen < TW_MIN_SGL_LENGTH)) {
if (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,
tw_dev->generic_buffer_virt[request_id],
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() */
/* This function tells the controller to shut down */
......
......@@ -235,6 +235,13 @@ config SCSI_ISCSI_ATTRS
each attached iSCSI device to sysfs, say Y.
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
menu "SCSI low-level drivers"
......
......@@ -31,6 +31,7 @@ obj-$(CONFIG_RAID_ATTRS) += raid_class.o
obj-$(CONFIG_SCSI_SPI_ATTRS) += scsi_transport_spi.o
obj-$(CONFIG_SCSI_FC_ATTRS) += scsi_transport_fc.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_A3000_SCSI) += a3000.o wd33c93.o
......
......@@ -966,21 +966,21 @@ static void
lpfc_get_host_fabric_name (struct Scsi_Host *shost)
{
struct lpfc_hba *phba = (struct lpfc_hba*)shost->hostdata[0];
u64 nodename;
u64 node_name;
spin_lock_irq(shost->host_lock);
if ((phba->fc_flag & FC_FABRIC) ||
((phba->fc_topology == TOPOLOGY_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
/* 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);
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)
{
struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
struct lpfc_hba *phba = (struct lpfc_hba *) shost->hostdata[0];
uint64_t node_name = 0;
u64 node_name = 0;
struct lpfc_nodelist *ndlp = NULL;
spin_lock_irq(shost->host_lock);
/* Search the mapped list for this target ID */
list_for_each_entry(ndlp, &phba->fc_nlpmap_list, nlp_listp) {
if (starget->id == ndlp->nlp_sid) {
memcpy(&node_name, &ndlp->nlp_nodename,
sizeof(struct lpfc_name));
node_name = wwn_to_u64(ndlp->nlp_nodename.wwn);
break;
}
}
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
......@@ -1125,21 +1124,20 @@ lpfc_get_starget_port_name(struct scsi_target *starget)
{
struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
struct lpfc_hba *phba = (struct lpfc_hba *) shost->hostdata[0];
uint64_t port_name = 0;
u64 port_name = 0;
struct lpfc_nodelist *ndlp = NULL;
spin_lock_irq(shost->host_lock);
/* Search the mapped list for this target ID */
list_for_each_entry(ndlp, &phba->fc_nlpmap_list, nlp_listp) {
if (starget->id == ndlp->nlp_sid) {
memcpy(&port_name, &ndlp->nlp_portname,
sizeof(struct lpfc_name));
port_name = wwn_to_u64(ndlp->nlp_portname.wwn);
break;
}
}
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
......
......@@ -1017,13 +1017,10 @@ lpfc_register_remote_port(struct lpfc_hba * phba,
struct fc_rport *rport;
struct lpfc_rport_data *rdata;
struct fc_rport_identifiers rport_ids;
uint64_t wwn;
/* Remote port has reappeared. Re-register w/ FC transport */
memcpy(&wwn, &ndlp->nlp_nodename, sizeof(uint64_t));
rport_ids.node_name = be64_to_cpu(wwn);
memcpy(&wwn, &ndlp->nlp_portname, sizeof(uint64_t));
rport_ids.port_name = be64_to_cpu(wwn);
rport_ids.node_name = wwn_to_u64(ndlp->nlp_nodename.wwn);
rport_ids.port_name = wwn_to_u64(ndlp->nlp_portname.wwn);
rport_ids.port_id = ndlp->nlp_DID;
rport_ids.roles = FC_RPORT_ROLE_UNKNOWN;
if (ndlp->nlp_type & NLP_FCP_TARGET)
......
......@@ -262,6 +262,8 @@ struct lpfc_sli_ct_request {
#define FF_FRAME_SIZE 2048
struct lpfc_name {
union {
struct {
#ifdef __BIG_ENDIAN_BITFIELD
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 */
......@@ -278,6 +280,9 @@ struct lpfc_name {
#define NAME_CCITT_GR_TYPE 0xE
uint8_t IEEEextLsb; /* FC Word 0, bit 16:23, IEEE extended Lsb */
uint8_t IEEE[6]; /* FC IEEE address */
};
uint8_t wwn[8];
};
};
struct csp {
......
......@@ -1333,7 +1333,6 @@ lpfc_pci_probe_one(struct pci_dev *pdev, const struct pci_device_id *pid)
unsigned long bar0map_len, bar2map_len;
int error = -ENODEV, retval;
int i;
u64 wwname;
if (pci_enable_device(pdev))
goto out;
......@@ -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()
*/
memcpy(&wwname, &phba->fc_nodename, sizeof(u64));
fc_host_node_name(host) = be64_to_cpu(wwname);
memcpy(&wwname, &phba->fc_portname, sizeof(u64));
fc_host_port_name(host) = be64_to_cpu(wwname);
fc_host_node_name(host) = wwn_to_u64(phba->fc_nodename.wwn);
fc_host_port_name(host) = wwn_to_u64(phba->fc_portname.wwn);
fc_host_supported_classes(host) = FC_COS_CLASS3;
memset(fc_host_supported_fc4s(host), 0,
......
......@@ -360,16 +360,16 @@ qla2x00_get_starget_node_name(struct scsi_target *starget)
struct Scsi_Host *host = dev_to_shost(starget->dev.parent);
scsi_qla_host_t *ha = to_qla_host(host);
fc_port_t *fcport;
uint64_t node_name = 0;
u64 node_name = 0;
list_for_each_entry(fcport, &ha->fcports, list) {
if (starget->id == fcport->os_target_id) {
node_name = *(uint64_t *)fcport->node_name;
node_name = wwn_to_u64(fcport->node_name);
break;
}
}
fc_starget_node_name(starget) = be64_to_cpu(node_name);
fc_starget_node_name(starget) = node_name;
}
static void
......@@ -378,16 +378,16 @@ qla2x00_get_starget_port_name(struct scsi_target *starget)
struct Scsi_Host *host = dev_to_shost(starget->dev.parent);
scsi_qla_host_t *ha = to_qla_host(host);
fc_port_t *fcport;
uint64_t port_name = 0;
u64 port_name = 0;
list_for_each_entry(fcport, &ha->fcports, list) {
if (starget->id == fcport->os_target_id) {
port_name = *(uint64_t *)fcport->port_name;
port_name = wwn_to_u64(fcport->port_name);
break;
}
}
fc_starget_port_name(starget) = be64_to_cpu(port_name);
fc_starget_port_name(starget) = port_name;
}
static void
......@@ -460,9 +460,7 @@ struct fc_function_template qla2xxx_transport_functions = {
void
qla2x00_init_host_attr(scsi_qla_host_t *ha)
{
fc_host_node_name(ha->host) =
be64_to_cpu(*(uint64_t *)ha->init_cb->node_name);
fc_host_port_name(ha->host) =
be64_to_cpu(*(uint64_t *)ha->init_cb->port_name);
fc_host_node_name(ha->host) = wwn_to_u64(ha->init_cb->node_name);
fc_host_port_name(ha->host) = wwn_to_u64(ha->init_cb->port_name);
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)
return;
}
rport_ids.node_name = be64_to_cpu(*(uint64_t *)fcport->node_name);
rport_ids.port_name = be64_to_cpu(*(uint64_t *)fcport->port_name);
rport_ids.node_name = wwn_to_u64(fcport->node_name);
rport_ids.port_name = wwn_to_u64(fcport->port_name);
rport_ids.port_id = fcport->d_id.b.domain << 16 |
fcport->d_id.b.area << 8 | fcport->d_id.b.al_pa;
rport_ids.roles = FC_RPORT_ROLE_UNKNOWN;
......
This diff is collapsed.
......@@ -124,6 +124,7 @@ extern void scsi_sysfs_unregister(void);
extern void scsi_sysfs_device_initialize(struct scsi_device *);
extern int scsi_sysfs_target_initialize(struct scsi_device *);
extern struct scsi_transport_template blank_transport_template;
extern void __scsi_remove_device(struct scsi_device *);
extern struct bus_type scsi_bus_type;
......
......@@ -870,8 +870,12 @@ static int scsi_probe_and_add_lun(struct scsi_target *starget,
out_free_sdev:
if (res == SCSI_SCAN_LUN_PRESENT) {
if (sdevp) {
scsi_device_get(sdev);
if (scsi_device_get(sdev) == 0) {
*sdevp = sdev;
} else {
__scsi_remove_device(sdev);
res = SCSI_SCAN_NO_RESPONSE;
}
}
} else {
if (sdev->host->hostt->slave_destroy)
......@@ -1260,6 +1264,19 @@ struct scsi_device *__scsi_add_device(struct Scsi_Host *shost, uint channel,
}
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)
{
struct scsi_driver *drv;
......@@ -1276,26 +1293,7 @@ void scsi_rescan_device(struct device *dev)
}
EXPORT_SYMBOL(scsi_rescan_device);
/**
* 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,
static 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);
......@@ -1310,9 +1308,7 @@ void scsi_scan_target(struct device *parent, unsigned int channel,
*/
return;
starget = scsi_alloc_target(parent, channel, id);
if (!starget)
return;
......@@ -1358,6 +1354,33 @@ void scsi_scan_target(struct device *parent, unsigned int channel,
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);
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;
else
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
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,
......@@ -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 *sdev;
struct scsi_device *sdev = NULL;
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);
if (!starget)
return NULL;
goto out;
sdev = scsi_alloc_sdev(starget, 0, NULL);
if (sdev) {
......@@ -1497,6 +1525,8 @@ struct scsi_device *scsi_get_host_dev(struct Scsi_Host *shost)
sdev->borken = 0;
}
put_device(&starget->dev);
out:
up(&shost->scan_mutex);
return sdev;
}
EXPORT_SYMBOL(scsi_get_host_dev);
......
......@@ -653,7 +653,7 @@ int scsi_sysfs_add_sdev(struct scsi_device *sdev)
error = attr_add(&sdev->sdev_gendev,
sdev->host->hostt->sdev_attrs[i]);
if (error) {
scsi_remove_device(sdev);
__scsi_remove_device(sdev);
goto out;
}
}
......@@ -667,7 +667,7 @@ int scsi_sysfs_add_sdev(struct scsi_device *sdev)
scsi_sysfs_sdev_attrs[i]);
error = device_create_file(&sdev->sdev_gendev, attr);
if (error) {
scsi_remove_device(sdev);
__scsi_remove_device(sdev);
goto out;
}
}
......@@ -687,17 +687,10 @@ int scsi_sysfs_add_sdev(struct scsi_device *sdev)
return error;
}
/**
* scsi_remove_device - unregister a device from the scsi bus
* @sdev: scsi_device to unregister
**/
void scsi_remove_device(struct scsi_device *sdev)
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)
goto out;
return;
class_device_unregister(&sdev->sdev_classdev);
device_del(&sdev->sdev_gendev);
......@@ -706,8 +699,17 @@ void scsi_remove_device(struct scsi_device *sdev)
sdev->host->hostt->slave_destroy(sdev);
transport_unregister_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);
......
This diff is collapsed.
......@@ -61,7 +61,7 @@ static int sg_version_num = 30533; /* 2 digits for each component */
#ifdef CONFIG_SCSI_PROC_FS
#include <linux/proc_fs.h>
static char *sg_version_date = "20050901";
static char *sg_version_date = "20050908";
static int sg_proc_init(void);
static void sg_proc_cleanup(void);
......@@ -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 */
sfp->mmap_called = 1;
}
vma->vm_flags |= (VM_RESERVED | VM_IO);
vma->vm_flags |= VM_RESERVED;
vma->vm_private_data = sfp;
vma->vm_ops = &sg_mmap_vm_ops;
return 0;
......
......@@ -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 *,
uint, uint, uint, void *hostdata);
#define scsi_add_device(host, channel, target, lun) \
__scsi_add_device(host, channel, target, lun, NULL)
extern int scsi_add_device(struct Scsi_Host *host, uint channel,
uint target, uint lun);
extern void scsi_remove_device(struct scsi_device *);
extern int scsi_device_cancel(struct scsi_device *, int);
......
......@@ -439,4 +439,12 @@ int fc_remote_port_block(struct fc_rport *rport);
void fc_remote_port_unblock(struct fc_rport *rport);
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 */
#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