aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi')
-rw-r--r--drivers/scsi/Kconfig8
-rw-r--r--drivers/scsi/aacraid/aacraid.h6
-rw-r--r--drivers/scsi/aacraid/linit.c3
-rw-r--r--drivers/scsi/ahci.c1
-rw-r--r--drivers/scsi/aic7xxx/aic7xxx_osm.c24
-rw-r--r--drivers/scsi/arm/Kconfig2
-rw-r--r--drivers/scsi/ata_piix.c2
-rw-r--r--drivers/scsi/dc395x.c48
-rw-r--r--drivers/scsi/dpt_i2o.c9
-rw-r--r--drivers/scsi/ibmvscsi/srp.h2
-rw-r--r--drivers/scsi/ips.c8
-rw-r--r--drivers/scsi/ips.h39
-rw-r--r--drivers/scsi/libata-core.c25
-rw-r--r--drivers/scsi/libata-scsi.c1
-rw-r--r--drivers/scsi/libata.h2
-rw-r--r--drivers/scsi/sata_promise.c2
-rw-r--r--drivers/scsi/sata_sx4.c2
-rw-r--r--drivers/scsi/scsi_lib.c148
-rw-r--r--drivers/scsi/scsi_scan.c128
-rw-r--r--drivers/scsi/scsi_transport_fc.c19
-rw-r--r--drivers/scsi/sg.c13
-rw-r--r--drivers/scsi/st.c8
22 files changed, 275 insertions, 225 deletions
diff --git a/drivers/scsi/Kconfig b/drivers/scsi/Kconfig
index 96df148..12c208f 100644
--- a/drivers/scsi/Kconfig
+++ b/drivers/scsi/Kconfig
@@ -424,7 +424,7 @@ config SCSI_IN2000
source "drivers/scsi/megaraid/Kconfig.megaraid"
config SCSI_SATA
- bool "Serial ATA (SATA) support"
+ tristate "Serial ATA (SATA) support"
depends on SCSI
help
This driver family supports Serial ATA host controllers
@@ -1696,7 +1696,7 @@ config TT_DMA_EMUL
config MAC_SCSI
bool "Macintosh NCR5380 SCSI"
- depends on MAC && SCSI
+ depends on MAC && SCSI=y
help
This is the NCR 5380 SCSI controller included on most of the 68030
based Macintoshes. If you have one of these say Y and read the
@@ -1717,7 +1717,7 @@ config SCSI_MAC_ESP
config MVME147_SCSI
bool "WD33C93 SCSI driver for MVME147"
- depends on MVME147 && SCSI
+ depends on MVME147 && SCSI=y
help
Support for the on-board SCSI controller on the Motorola MVME147
single-board computer.
@@ -1758,7 +1758,7 @@ config SUN3_SCSI
config SUN3X_ESP
bool "Sun3x ESP SCSI"
- depends on SUN3X && SCSI
+ depends on SUN3X && SCSI=y
help
The ESP was an on-board SCSI controller used on Sun 3/80
machines. Say Y here to compile in support for it.
diff --git a/drivers/scsi/aacraid/aacraid.h b/drivers/scsi/aacraid/aacraid.h
index bc91e7c..e405281 100644
--- a/drivers/scsi/aacraid/aacraid.h
+++ b/drivers/scsi/aacraid/aacraid.h
@@ -15,11 +15,7 @@
#define AAC_MAX_LUN (8)
#define AAC_MAX_HOSTPHYSMEMPAGES (0xfffff)
-/*
- * max_sectors is an unsigned short, otherwise limit is 0x100000000 / 512
- * Linux has starvation problems if we permit larger than 4MB I/O ...
- */
-#define AAC_MAX_32BIT_SGBCOUNT ((unsigned short)8192)
+#define AAC_MAX_32BIT_SGBCOUNT ((unsigned short)512)
/*
* These macros convert from physical channels to virtual channels
diff --git a/drivers/scsi/aacraid/linit.c b/drivers/scsi/aacraid/linit.c
index 2bd5942..4ff29d7 100644
--- a/drivers/scsi/aacraid/linit.c
+++ b/drivers/scsi/aacraid/linit.c
@@ -391,7 +391,8 @@ static int aac_slave_configure(struct scsi_device *sdev)
else
scsi_adjust_queue_depth(sdev, 0, 1);
- if (host->max_sectors < AAC_MAX_32BIT_SGBCOUNT)
+ if (!(((struct aac_dev *)host->hostdata)->adapter_info.options
+ & AAC_OPT_NEW_COMM))
blk_queue_max_segment_size(sdev->request_queue, 65536);
return 0;
diff --git a/drivers/scsi/ahci.c b/drivers/scsi/ahci.c
index c562369..e3b9692 100644
--- a/drivers/scsi/ahci.c
+++ b/drivers/scsi/ahci.c
@@ -1105,6 +1105,7 @@ MODULE_AUTHOR("Jeff Garzik");
MODULE_DESCRIPTION("AHCI SATA low-level driver");
MODULE_LICENSE("GPL");
MODULE_DEVICE_TABLE(pci, ahci_pci_tbl);
+MODULE_VERSION(DRV_VERSION);
module_init(ahci_init);
module_exit(ahci_exit);
diff --git a/drivers/scsi/aic7xxx/aic7xxx_osm.c b/drivers/scsi/aic7xxx/aic7xxx_osm.c
index 2243484..5417388 100644
--- a/drivers/scsi/aic7xxx/aic7xxx_osm.c
+++ b/drivers/scsi/aic7xxx/aic7xxx_osm.c
@@ -1266,14 +1266,12 @@ ahc_platform_set_tags(struct ahc_softc *ahc, struct ahc_devinfo *devinfo,
}
switch ((dev->flags & (AHC_DEV_Q_BASIC|AHC_DEV_Q_TAGGED))) {
case AHC_DEV_Q_BASIC:
- scsi_adjust_queue_depth(sdev,
- MSG_SIMPLE_TASK,
- dev->openings + dev->active);
+ scsi_set_tag_type(sdev, MSG_SIMPLE_TAG);
+ scsi_activate_tcq(sdev, dev->openings + dev->active);
break;
case AHC_DEV_Q_TAGGED:
- scsi_adjust_queue_depth(sdev,
- MSG_ORDERED_TASK,
- dev->openings + dev->active);
+ scsi_set_tag_type(sdev, MSG_ORDERED_TAG);
+ scsi_activate_tcq(sdev, dev->openings + dev->active);
break;
default:
/*
@@ -1282,9 +1280,7 @@ ahc_platform_set_tags(struct ahc_softc *ahc, struct ahc_devinfo *devinfo,
* serially on the controller/device. This should
* remove some latency.
*/
- scsi_adjust_queue_depth(sdev,
- /*NON-TAGGED*/0,
- /*queue depth*/2);
+ scsi_deactivate_tcq(sdev, 2);
break;
}
}
@@ -1637,9 +1633,9 @@ ahc_send_async(struct ahc_softc *ahc, char channel,
spi_period(starget) = tinfo->curr.period;
spi_width(starget) = tinfo->curr.width;
spi_offset(starget) = tinfo->curr.offset;
- spi_dt(starget) = tinfo->curr.ppr_options & MSG_EXT_PPR_DT_REQ;
- spi_qas(starget) = tinfo->curr.ppr_options & MSG_EXT_PPR_QAS_REQ;
- spi_iu(starget) = tinfo->curr.ppr_options & MSG_EXT_PPR_IU_REQ;
+ spi_dt(starget) = tinfo->curr.ppr_options & MSG_EXT_PPR_DT_REQ ? 1 : 0;
+ spi_qas(starget) = tinfo->curr.ppr_options & MSG_EXT_PPR_QAS_REQ ? 1 : 0;
+ spi_iu(starget) = tinfo->curr.ppr_options & MSG_EXT_PPR_IU_REQ ? 1 : 0;
spi_display_xfer_agreement(starget);
break;
}
@@ -2429,12 +2425,14 @@ static void ahc_linux_set_dt(struct scsi_target *starget, int dt)
unsigned int ppr_options = tinfo->goal.ppr_options
& ~MSG_EXT_PPR_DT_REQ;
unsigned int period = tinfo->goal.period;
+ unsigned int width = tinfo->goal.width;
unsigned long flags;
struct ahc_syncrate *syncrate;
if (dt) {
- period = 9; /* 12.5ns is the only period valid for DT */
ppr_options |= MSG_EXT_PPR_DT_REQ;
+ if (!width)
+ ahc_linux_set_width(starget, 1);
} else if (period == 9)
period = 10; /* if resetting DT, period must be >= 25ns */
diff --git a/drivers/scsi/arm/Kconfig b/drivers/scsi/arm/Kconfig
index 54b3286..13f2304 100644
--- a/drivers/scsi/arm/Kconfig
+++ b/drivers/scsi/arm/Kconfig
@@ -3,7 +3,7 @@
#
config SCSI_ACORNSCSI_3
tristate "Acorn SCSI card (aka30) support"
- depends on ARCH_ACORN && SCSI
+ depends on ARCH_ACORN && SCSI && BROKEN
help
This enables support for the Acorn SCSI card (aka30). If you have an
Acorn system with one of these, say Y. If unsure, say N.
diff --git a/drivers/scsi/ata_piix.c b/drivers/scsi/ata_piix.c
index a2cfade..d96ebf9 100644
--- a/drivers/scsi/ata_piix.c
+++ b/drivers/scsi/ata_piix.c
@@ -32,7 +32,7 @@
#include <linux/libata.h>
#define DRV_NAME "ata_piix"
-#define DRV_VERSION "1.03"
+#define DRV_VERSION "1.04"
enum {
PIIX_IOCFG = 0x54, /* IDE I/O configuration register */
diff --git a/drivers/scsi/dc395x.c b/drivers/scsi/dc395x.c
index 929170d..600ba12 100644
--- a/drivers/scsi/dc395x.c
+++ b/drivers/scsi/dc395x.c
@@ -183,7 +183,7 @@
* cross a page boundy.
*/
#define SEGMENTX_LEN (sizeof(struct SGentry)*DC395x_MAX_SG_LISTENTRY)
-#define VIRTX_LEN (sizeof(void *) * DC395x_MAX_SG_LISTENTRY)
+
struct SGentry {
u32 address; /* bus! address */
@@ -235,7 +235,6 @@ struct ScsiReqBlk {
u8 sg_count; /* No of HW sg entries for this request */
u8 sg_index; /* Index of HW sg entry for this request */
u32 total_xfer_length; /* Total number of bytes remaining to be transfered */
- void **virt_map;
unsigned char *virt_addr; /* Virtual address of current transfer position */
/*
@@ -1022,14 +1021,14 @@ static void build_srb(struct scsi_cmnd *cmd, struct DeviceCtlBlk *dcb,
reqlen, cmd->request_buffer, cmd->use_sg,
srb->sg_count);
+ srb->virt_addr = page_address(sl->page);
for (i = 0; i < srb->sg_count; i++) {
- u32 seglen = (u32)sg_dma_len(sl + i);
- sgp[i].address = (u32)sg_dma_address(sl + i);
+ u32 busaddr = (u32)sg_dma_address(&sl[i]);
+ u32 seglen = (u32)sl[i].length;
+ sgp[i].address = busaddr;
sgp[i].length = seglen;
srb->total_xfer_length += seglen;
- srb->virt_map[i] = kmap(sl[i].page);
}
- srb->virt_addr = srb->virt_map[0];
sgp += srb->sg_count - 1;
/*
@@ -1976,7 +1975,6 @@ static void sg_update_list(struct ScsiReqBlk *srb, u32 left)
int segment = cmd->use_sg;
u32 xferred = srb->total_xfer_length - left; /* bytes transfered */
struct SGentry *psge = srb->segment_x + srb->sg_index;
- void **virt = srb->virt_map;
dprintkdbg(DBG_0,
"sg_update_list: Transfered %i of %i bytes, %i remain\n",
@@ -2016,16 +2014,16 @@ static void sg_update_list(struct ScsiReqBlk *srb, u32 left)
/* We have to walk the scatterlist to find it */
sg = (struct scatterlist *)cmd->request_buffer;
- idx = 0;
while (segment--) {
unsigned long mask =
~((unsigned long)sg->length - 1) & PAGE_MASK;
if ((sg_dma_address(sg) & mask) == (psge->address & mask)) {
- srb->virt_addr = virt[idx] + (psge->address & ~PAGE_MASK);
+ srb->virt_addr = (page_address(sg->page)
+ + psge->address -
+ (psge->address & PAGE_MASK));
return;
}
++sg;
- ++idx;
}
dprintkl(KERN_ERR, "sg_update_list: sg_to_virt failed\n");
@@ -2151,7 +2149,7 @@ static void data_out_phase0(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb,
DC395x_read32(acb, TRM_S1040_DMA_CXCNT));
}
/*
- * calculate all the residue data that not yet transfered
+ * calculate all the residue data that not yet tranfered
* SCSI transfer counter + left in SCSI FIFO data
*
* .....TRM_S1040_SCSI_COUNTER (24bits)
@@ -3269,7 +3267,6 @@ static void pci_unmap_srb(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb)
struct scsi_cmnd *cmd = srb->cmd;
enum dma_data_direction dir = cmd->sc_data_direction;
if (cmd->use_sg && dir != PCI_DMA_NONE) {
- int i;
/* unmap DC395x SG list */
dprintkdbg(DBG_SG, "pci_unmap_srb: list=%08x(%05x)\n",
srb->sg_bus_addr, SEGMENTX_LEN);
@@ -3279,8 +3276,6 @@ static void pci_unmap_srb(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb)
dprintkdbg(DBG_SG, "pci_unmap_srb: segs=%i buffer=%p\n",
cmd->use_sg, cmd->request_buffer);
/* unmap the sg segments */
- for (i = 0; i < srb->sg_count; i++)
- kunmap(virt_to_page(srb->virt_map[i]));
pci_unmap_sg(acb->dev,
(struct scatterlist *)cmd->request_buffer,
cmd->use_sg, dir);
@@ -3327,7 +3322,7 @@ static void srb_done(struct AdapterCtlBlk *acb, struct DeviceCtlBlk *dcb,
if (cmd->use_sg) {
struct scatterlist* sg = (struct scatterlist *)cmd->request_buffer;
- ptr = (struct ScsiInqData *)(srb->virt_map[0] + sg->offset);
+ ptr = (struct ScsiInqData *)(page_address(sg->page) + sg->offset);
} else {
ptr = (struct ScsiInqData *)(cmd->request_buffer);
}
@@ -4262,9 +4257,8 @@ static void adapter_sg_tables_free(struct AdapterCtlBlk *acb)
const unsigned srbs_per_page = PAGE_SIZE/SEGMENTX_LEN;
for (i = 0; i < DC395x_MAX_SRB_CNT; i += srbs_per_page)
- kfree(acb->srb_array[i].segment_x);
-
- vfree(acb->srb_array[0].virt_map);
+ if (acb->srb_array[i].segment_x)
+ kfree(acb->srb_array[i].segment_x);
}
@@ -4280,12 +4274,9 @@ static int __devinit adapter_sg_tables_alloc(struct AdapterCtlBlk *acb)
int srb_idx = 0;
unsigned i = 0;
struct SGentry *ptr;
- void **virt_array;
- for (i = 0; i < DC395x_MAX_SRB_CNT; i++) {
+ for (i = 0; i < DC395x_MAX_SRB_CNT; i++)
acb->srb_array[i].segment_x = NULL;
- acb->srb_array[i].virt_map = NULL;
- }
dprintkdbg(DBG_1, "Allocate %i pages for SG tables\n", pages);
while (pages--) {
@@ -4306,19 +4297,6 @@ static int __devinit adapter_sg_tables_alloc(struct AdapterCtlBlk *acb)
ptr + (i * DC395x_MAX_SG_LISTENTRY);
else
dprintkl(KERN_DEBUG, "No space for tmsrb SG table reserved?!\n");
-
- virt_array = vmalloc((DC395x_MAX_SRB_CNT + 1) * DC395x_MAX_SG_LISTENTRY * sizeof(void*));
-
- if (!virt_array) {
- adapter_sg_tables_free(acb);
- return 1;
- }
-
- for (i = 0; i < DC395x_MAX_SRB_CNT + 1; i++) {
- acb->srb_array[i].virt_map = virt_array;
- virt_array += DC395x_MAX_SG_LISTENTRY;
- }
-
return 0;
}
diff --git a/drivers/scsi/dpt_i2o.c b/drivers/scsi/dpt_i2o.c
index e237052..7235f94 100644
--- a/drivers/scsi/dpt_i2o.c
+++ b/drivers/scsi/dpt_i2o.c
@@ -907,9 +907,13 @@ static int adpt_install_hba(struct scsi_host_template* sht, struct pci_dev* pDev
raptorFlag = TRUE;
}
-
+ if (pci_request_regions(pDev, "dpt_i2o")) {
+ PERROR("dpti: adpt_config_hba: pci request region failed\n");
+ return -EINVAL;
+ }
base_addr_virt = ioremap(base_addr0_phys,hba_map0_area_size);
if (!base_addr_virt) {
+ pci_release_regions(pDev);
PERROR("dpti: adpt_config_hba: io remap failed\n");
return -EINVAL;
}
@@ -919,6 +923,7 @@ static int adpt_install_hba(struct scsi_host_template* sht, struct pci_dev* pDev
if (!msg_addr_virt) {
PERROR("dpti: adpt_config_hba: io remap failed on BAR1\n");
iounmap(base_addr_virt);
+ pci_release_regions(pDev);
return -EINVAL;
}
} else {
@@ -932,6 +937,7 @@ static int adpt_install_hba(struct scsi_host_template* sht, struct pci_dev* pDev
iounmap(msg_addr_virt);
}
iounmap(base_addr_virt);
+ pci_release_regions(pDev);
return -ENOMEM;
}
memset(pHba, 0, sizeof(adpt_hba));
@@ -1027,6 +1033,7 @@ static void adpt_i2o_delete_hba(adpt_hba* pHba)
up(&adpt_configuration_lock);
iounmap(pHba->base_addr_virt);
+ pci_release_regions(pHba->pDev);
if(pHba->msg_addr_virt != pHba->base_addr_virt){
iounmap(pHba->msg_addr_virt);
}
diff --git a/drivers/scsi/ibmvscsi/srp.h b/drivers/scsi/ibmvscsi/srp.h
index 2ae5154..7d8e4c4 100644
--- a/drivers/scsi/ibmvscsi/srp.h
+++ b/drivers/scsi/ibmvscsi/srp.h
@@ -35,7 +35,7 @@
enum srp_types {
SRP_LOGIN_REQ_TYPE = 0x00,
SRP_LOGIN_RSP_TYPE = 0xC0,
- SRP_LOGIN_REJ_TYPE = 0x80,
+ SRP_LOGIN_REJ_TYPE = 0xC2,
SRP_I_LOGOUT_TYPE = 0x03,
SRP_T_LOGOUT_TYPE = 0x80,
SRP_TSK_MGMT_TYPE = 0x01,
diff --git a/drivers/scsi/ips.c b/drivers/scsi/ips.c
index 6dfcb4f..4cdd891 100644
--- a/drivers/scsi/ips.c
+++ b/drivers/scsi/ips.c
@@ -133,10 +133,12 @@
/* 6.10.00 - Remove 1G Addressing Limitations */
/* 6.11.xx - Get VersionInfo buffer off the stack ! DDTS 60401 */
/* 6.11.xx - Make Logical Drive Info structure safe for DMA DDTS 60639 */
-/* 7.10.xx - Add highmem_io flag in SCSI Templete for 2.4 kernels */
+/* 7.10.18 - Add highmem_io flag in SCSI Templete for 2.4 kernels */
/* - Fix path/name for scsi_hosts.h include for 2.6 kernels */
/* - Fix sort order of 7k */
/* - Remove 3 unused "inline" functions */
+/* 7.12.xx - Use STATIC functions whereever possible */
+/* - Clean up deprecated MODULE_PARM calls */
/*****************************************************************************/
/*
@@ -207,8 +209,8 @@ module_param(ips, charp, 0);
/*
* DRIVER_VER
*/
-#define IPS_VERSION_HIGH "7.10"
-#define IPS_VERSION_LOW ".18 "
+#define IPS_VERSION_HIGH "7.12"
+#define IPS_VERSION_LOW ".02 "
#if !defined(__i386__) && !defined(__ia64__) && !defined(__x86_64__)
#warning "This driver has only been tested on the x86/ia64/x86_64 platforms"
diff --git a/drivers/scsi/ips.h b/drivers/scsi/ips.h
index 480e06f..505e967 100644
--- a/drivers/scsi/ips.h
+++ b/drivers/scsi/ips.h
@@ -87,15 +87,14 @@
#define scsi_set_pci_device(sh,dev) (0)
#endif
- #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
-
- #ifndef irqreturn_t
- typedef void irqreturn_t;
- #endif
-
+ #ifndef IRQ_NONE
+ typedef void irqreturn_t;
#define IRQ_NONE
#define IRQ_HANDLED
#define IRQ_RETVAL(x)
+ #endif
+
+ #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
#define IPS_REGISTER_HOSTS(SHT) scsi_register_module(MODULE_SCSI_HA,SHT)
#define IPS_UNREGISTER_HOSTS(SHT) scsi_unregister_module(MODULE_SCSI_HA,SHT)
#define IPS_ADD_HOST(shost,device)
@@ -123,6 +122,10 @@
#ifndef min
#define min(x,y) ((x) < (y) ? x : y)
#endif
+
+ #ifndef __iomem /* For clean compiles in earlier kernels without __iomem annotations */
+ #define __iomem
+ #endif
#define pci_dma_hi32(a) ((a >> 16) >> 16)
#define pci_dma_lo32(a) (a & 0xffffffff)
@@ -1206,13 +1209,13 @@ typedef struct {
#define IPS_VER_MAJOR 7
#define IPS_VER_MAJOR_STRING "7"
-#define IPS_VER_MINOR 10
-#define IPS_VER_MINOR_STRING "10"
-#define IPS_VER_BUILD 18
-#define IPS_VER_BUILD_STRING "18"
-#define IPS_VER_STRING "7.10.18"
+#define IPS_VER_MINOR 12
+#define IPS_VER_MINOR_STRING "12"
+#define IPS_VER_BUILD 02
+#define IPS_VER_BUILD_STRING "02"
+#define IPS_VER_STRING "7.12.02"
#define IPS_RELEASE_ID 0x00020000
-#define IPS_BUILD_IDENT 731
+#define IPS_BUILD_IDENT 761
#define IPS_LEGALCOPYRIGHT_STRING "(C) Copyright IBM Corp. 1994, 2002. All Rights Reserved."
#define IPS_ADAPTECCOPYRIGHT_STRING "(c) Copyright Adaptec, Inc. 2002 to 2004. All Rights Reserved."
#define IPS_DELLCOPYRIGHT_STRING "(c) Copyright Dell 2004. All Rights Reserved."
@@ -1223,12 +1226,12 @@ typedef struct {
#define IPS_VER_SERVERAID2 "2.88.13"
#define IPS_VER_NAVAJO "2.88.13"
#define IPS_VER_SERVERAID3 "6.10.24"
-#define IPS_VER_SERVERAID4H "7.10.11"
-#define IPS_VER_SERVERAID4MLx "7.10.18"
-#define IPS_VER_SARASOTA "7.10.18"
-#define IPS_VER_MARCO "7.10.18"
-#define IPS_VER_SEBRING "7.10.18"
-#define IPS_VER_KEYWEST "7.10.18"
+#define IPS_VER_SERVERAID4H "7.12.02"
+#define IPS_VER_SERVERAID4MLx "7.12.02"
+#define IPS_VER_SARASOTA "7.12.02"
+#define IPS_VER_MARCO "7.12.02"
+#define IPS_VER_SEBRING "7.12.02"
+#define IPS_VER_KEYWEST "7.12.02"
/* Compatability IDs for various adapters */
#define IPS_COMPAT_UNKNOWN ""
diff --git a/drivers/scsi/libata-core.c b/drivers/scsi/libata-core.c
index 73b1f72..f4e7dcb 100644
--- a/drivers/scsi/libata-core.c
+++ b/drivers/scsi/libata-core.c
@@ -2268,19 +2268,6 @@ void ata_qc_prep(struct ata_queued_cmd *qc)
* spin_lock_irqsave(host_set lock)
*/
-
-
-/**
- * ata_sg_init_one - Prepare a one-entry scatter-gather list.
- * @qc: Queued command
- * @buf: transfer buffer
- * @buflen: length of buf
- *
- * Builds a single-entry scatter-gather list to initiate a
- * transfer utilizing the specified buffer.
- *
- * LOCKING:
- */
void ata_sg_init_one(struct ata_queued_cmd *qc, void *buf, unsigned int buflen)
{
struct scatterlist *sg;
@@ -2312,18 +2299,6 @@ void ata_sg_init_one(struct ata_queued_cmd *qc, void *buf, unsigned int buflen)
* spin_lock_irqsave(host_set lock)
*/
-
-/**
- * ata_sg_init - Assign a scatter gather list to a queued command
- * @qc: Queued command
- * @sg: Scatter-gather list
- * @n_elem: length of sg list
- *
- * Attaches a scatter-gather list to a queued command.
- *
- * LOCKING:
- */
-
void ata_sg_init(struct ata_queued_cmd *qc, struct scatterlist *sg,
unsigned int n_elem)
{
diff --git a/drivers/scsi/libata-scsi.c b/drivers/scsi/libata-scsi.c
index 794fb55..6a75ec2 100644
--- a/drivers/scsi/libata-scsi.c
+++ b/drivers/scsi/libata-scsi.c
@@ -385,6 +385,7 @@ int ata_scsi_error(struct Scsi_Host *host)
* appropriate place
*/
host->host_failed--;
+ INIT_LIST_HEAD(&host->eh_cmd_q);
DPRINTK("EXIT\n");
return 0;
diff --git a/drivers/scsi/libata.h b/drivers/scsi/libata.h
index d90430b..3e7f484 100644
--- a/drivers/scsi/libata.h
+++ b/drivers/scsi/libata.h
@@ -26,7 +26,7 @@
#define __LIBATA_H__
#define DRV_NAME "libata"
-#define DRV_VERSION "1.11" /* must be exactly four chars */
+#define DRV_VERSION "1.12" /* must be exactly four chars */
struct ata_scsi_args {
u16 *id;
diff --git a/drivers/scsi/sata_promise.c b/drivers/scsi/sata_promise.c
index 5c1d441..919fb31 100644
--- a/drivers/scsi/sata_promise.c
+++ b/drivers/scsi/sata_promise.c
@@ -40,7 +40,7 @@
#include "sata_promise.h"
#define DRV_NAME "sata_promise"
-#define DRV_VERSION "1.01"
+#define DRV_VERSION "1.02"
enum {
diff --git a/drivers/scsi/sata_sx4.c b/drivers/scsi/sata_sx4.c
index 140cea0..efd7d7a 100644
--- a/drivers/scsi/sata_sx4.c
+++ b/drivers/scsi/sata_sx4.c
@@ -468,7 +468,7 @@ static void pdc20621_dma_prep(struct ata_queued_cmd *qc)
for (i = 0; i < last; i++) {
buf[idx++] = cpu_to_le32(sg_dma_address(&sg[i]));
buf[idx++] = cpu_to_le32(sg_dma_len(&sg[i]));
- total_len += sg[i].length;
+ total_len += sg_dma_len(&sg[i]);
}
buf[idx - 1] |= cpu_to_le32(ATA_PRD_EOT);
sgt_len = idx * 4;
diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c
index 060010b..278e0c9 100644
--- a/drivers/scsi/scsi_lib.c
+++ b/drivers/scsi/scsi_lib.c
@@ -232,23 +232,6 @@ void scsi_do_req(struct scsi_request *sreq, const void *cmnd,
}
EXPORT_SYMBOL(scsi_do_req);
-static void scsi_wait_done(struct scsi_cmnd *cmd)
-{
- struct request *req = cmd->request;
- struct request_queue *q = cmd->device->request_queue;
- unsigned long flags;
-
- req->rq_status = RQ_SCSI_DONE; /* Busy, but indicate request done */
-
- spin_lock_irqsave(q->queue_lock, flags);
- if (blk_rq_tagged(req))
- blk_queue_end_tag(q, req);
- spin_unlock_irqrestore(q->queue_lock, flags);
-
- if (req->waiting)
- complete(req->waiting);
-}
-
/* This is the end routine we get to if a command was never attached
* to the request. Simply complete the request without changing
* rq_status; this will cause a DRIVER_ERROR. */
@@ -263,21 +246,90 @@ void scsi_wait_req(struct scsi_request *sreq, const void *cmnd, void *buffer,
unsigned bufflen, int timeout, int retries)
{
DECLARE_COMPLETION(wait);
-
- sreq->sr_request->waiting = &wait;
- sreq->sr_request->rq_status = RQ_SCSI_BUSY;
- sreq->sr_request->end_io = scsi_wait_req_end_io;
- scsi_do_req(sreq, cmnd, buffer, bufflen, scsi_wait_done,
- timeout, retries);
+ int write = (sreq->sr_data_direction == DMA_TO_DEVICE);
+ struct request *req;
+
+ req = blk_get_request(sreq->sr_device->request_queue, write,
+ __GFP_WAIT);
+ if (bufflen && blk_rq_map_kern(sreq->sr_device->request_queue, req,
+ buffer, bufflen, __GFP_WAIT)) {
+ sreq->sr_result = DRIVER_ERROR << 24;
+ blk_put_request(req);
+ return;
+ }
+
+ req->flags |= REQ_NOMERGE;
+ req->waiting = &wait;
+ req->end_io = scsi_wait_req_end_io;
+ req->cmd_len = COMMAND_SIZE(((u8 *)cmnd)[0]);
+ req->sense = sreq->sr_sense_buffer;
+ req->sense_len = 0;
+ memcpy(req->cmd, cmnd, req->cmd_len);
+ req->timeout = timeout;
+ req->flags |= REQ_BLOCK_PC;
+ req->rq_disk = NULL;
+ blk_insert_request(sreq->sr_device->request_queue, req,
+ sreq->sr_data_direction == DMA_TO_DEVICE, NULL);
wait_for_completion(&wait);
sreq->sr_request->waiting = NULL;
- if (sreq->sr_request->rq_status != RQ_SCSI_DONE)
+ sreq->sr_result = req->errors;
+ if (req->errors)
sreq->sr_result |= (DRIVER_ERROR << 24);
- __scsi_release_request(sreq);
+ blk_put_request(req);
}
+
EXPORT_SYMBOL(scsi_wait_req);
+/**
+ * scsi_execute_req - insert request and wait for the result
+ * @sdev: scsi device
+ * @cmd: scsi command
+ * @data_direction: data direction
+ * @buffer: data buffer
+ * @bufflen: len of buffer
+ * @sense: optional sense buffer
+ * @timeout: request timeout in seconds
+ * @retries: number of times to retry request
+ *
+ * scsi_execute_req returns the req->errors value which is the
+ * the scsi_cmnd result field.
+ **/
+int scsi_execute_req(struct scsi_device *sdev, unsigned char *cmd,
+ int data_direction, void *buffer, unsigned bufflen,
+ unsigned char *sense, int timeout, int retries)
+{
+ struct request *req;
+ int write = (data_direction == DMA_TO_DEVICE);
+ int ret = DRIVER_ERROR << 24;
+
+ req = blk_get_request(sdev->request_queue, write, __GFP_WAIT);
+
+ if (bufflen && blk_rq_map_kern(sdev->request_queue, req,
+ buffer, bufflen, __GFP_WAIT))
+ goto out;
+
+ req->cmd_len = COMMAND_SIZE(cmd[0]);
+ memcpy(req->cmd, cmd, req->cmd_len);
+ req->sense = sense;
+ req->sense_len = 0;
+ req->timeout = timeout;
+ req->flags |= REQ_BLOCK_PC | REQ_SPECIAL;
+
+ /*
+ * head injection *required* here otherwise quiesce won't work
+ */
+ blk_execute_rq(req->q, NULL, req, 1);
+
+ ret = req->errors;
+ out:
+ blk_put_request(req);
+
+ return ret;
+}
+
+EXPORT_SYMBOL(scsi_execute_req);
+
/*
* Function: scsi_init_cmd_errh()
*
@@ -878,11 +930,12 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes,
return;
}
if (result) {
- printk(KERN_INFO "SCSI error : <%d %d %d %d> return code "
- "= 0x%x\n", cmd->device->host->host_no,
- cmd->device->channel,
- cmd->device->id,
- cmd->device->lun, result);
+ if (!(req->flags & REQ_SPECIAL))
+ printk(KERN_INFO "SCSI error : <%d %d %d %d> return code "
+ "= 0x%x\n", cmd->device->host->host_no,
+ cmd->device->channel,
+ cmd->device->id,
+ cmd->device->lun, result);
if (driver_byte(result) & DRIVER_SENSE)
scsi_print_sense("", cmd);
@@ -1020,6 +1073,12 @@ static int scsi_issue_flush_fn(request_queue_t *q, struct gendisk *disk,
return -EOPNOTSUPP;
}
+static void scsi_generic_done(struct scsi_cmnd *cmd)
+{
+ BUG_ON(!blk_pc_request(cmd->request));
+ scsi_io_completion(cmd, cmd->result == 0 ? cmd->bufflen : 0, 0);
+}
+
static int scsi_prep_fn(struct request_queue *q, struct request *req)
{
struct scsi_device *sdev = q->queuedata;
@@ -1061,7 +1120,7 @@ static int scsi_prep_fn(struct request_queue *q, struct request *req)
* these two cases differently. We differentiate by looking
* at request->cmd, as this tells us the real story.
*/
- if (req->flags & REQ_SPECIAL) {
+ if (req->flags & REQ_SPECIAL && req->special) {
struct scsi_request *sreq = req->special;
if (sreq->sr_magic == SCSI_REQ_MAGIC) {
@@ -1073,7 +1132,7 @@ static int scsi_prep_fn(struct request_queue *q, struct request *req)
cmd = req->special;
} else if (req->flags & (REQ_CMD | REQ_BLOCK_PC)) {
- if(unlikely(specials_only)) {
+ if(unlikely(specials_only) && !(req->flags & REQ_SPECIAL)) {
if(specials_only == SDEV_QUIESCE ||
specials_only == SDEV_BLOCK)
return BLKPREP_DEFER;
@@ -1142,11 +1201,26 @@ static int scsi_prep_fn(struct request_queue *q, struct request *req)
/*
* Initialize the actual SCSI command for this request.
*/
- drv = *(struct scsi_driver **)req->rq_disk->private_data;
- if (unlikely(!drv->init_command(cmd))) {
- scsi_release_buffers(cmd);
- scsi_put_command(cmd);
- return BLKPREP_KILL;
+ if (req->rq_disk) {
+ drv = *(struct scsi_driver **)req->rq_disk->private_data;
+ if (unlikely(!drv->init_command(cmd))) {
+ scsi_release_buffers(cmd);
+ scsi_put_command(cmd);
+ return BLKPREP_KILL;
+ }
+ } else {
+ memcpy(cmd->cmnd, req->cmd, sizeof(cmd->cmnd));
+ if (rq_data_dir(req) == WRITE)
+ cmd->sc_data_direction = DMA_TO_DEVICE;
+ else if (req->data_len)
+ cmd->sc_data_direction = DMA_FROM_DEVICE;
+ else
+ cmd->sc_data_direction = DMA_NONE;
+
+ cmd->transfersize = req->data_len;
+ cmd->allowed = 3;
+ cmd->timeout_per_command = req->timeout;
+ cmd->done = scsi_generic_done;
}
}
diff --git a/drivers/scsi/scsi_scan.c b/drivers/scsi/scsi_scan.c
index 076cbe3..0048bea 100644
--- a/drivers/scsi/scsi_scan.c
+++ b/drivers/scsi/scsi_scan.c
@@ -111,15 +111,14 @@ MODULE_PARM_DESC(inq_timeout,
/**
* scsi_unlock_floptical - unlock device via a special MODE SENSE command
- * @sreq: used to send the command
+ * @sdev: scsi device to send command to
* @result: area to store the result of the MODE SENSE
*
* Description:
- * Send a vendor specific MODE SENSE (not a MODE SELECT) command using
- * @sreq to unlock a device, storing the (unused) results into result.
+ * Send a vendor specific MODE SENSE (not a MODE SELECT) command.
* Called for BLIST_KEY devices.
**/
-static void scsi_unlock_floptical(struct scsi_request *sreq,
+static void scsi_unlock_floptical(struct scsi_device *sdev,
unsigned char *result)
{
unsigned char scsi_cmd[MAX_COMMAND_SIZE];
@@ -129,11 +128,10 @@ static void scsi_unlock_floptical(struct scsi_request *sreq,
scsi_cmd[1] = 0;
scsi_cmd[2] = 0x2e;
scsi_cmd[3] = 0;
- scsi_cmd[4] = 0x2a; /* size */
+ scsi_cmd[4] = 0x2a; /* size */
scsi_cmd[5] = 0;
- sreq->sr_cmd_len = 0;
- sreq->sr_data_direction = DMA_FROM_DEVICE;
- scsi_wait_req(sreq, scsi_cmd, result, 0x2a /* size */, SCSI_TIMEOUT, 3);
+ scsi_execute_req(sdev, scsi_cmd, DMA_FROM_DEVICE, result, 0x2a, NULL,
+ SCSI_TIMEOUT, 3);
}
/**
@@ -336,9 +334,23 @@ static struct scsi_target *scsi_alloc_target(struct device *parent,
unsigned long flags;
const int size = sizeof(struct scsi_target)
+ shost->transportt->target_size;
- struct scsi_target *starget = kmalloc(size, GFP_ATOMIC);
+ struct scsi_target *starget;
struct scsi_target *found_target;
+ /*
+ * Obtain the real parent from the transport. The transport
+ * is allowed to fail (no error) if there is nothing at that
+ * target id.
+ */
+ if (shost->transportt->target_parent) {
+ spin_lock_irqsave(shost->host_lock, flags);
+ parent = shost->transportt->target_parent(shost, channel, id);
+ spin_unlock_irqrestore(shost->host_lock, flags);
+ if (!parent)
+ return NULL;
+ }
+
+ starget = kmalloc(size, GFP_KERNEL);
if (!starget) {
printk(KERN_ERR "%s: allocation failure\n", __FUNCTION__);
return NULL;
@@ -419,26 +431,26 @@ void scsi_target_reap(struct scsi_target *starget)
/**
* scsi_probe_lun - probe a single LUN using a SCSI INQUIRY
- * @sreq: used to send the INQUIRY
+ * @sdev: scsi_device to probe
* @inq_result: area to store the INQUIRY result
+ * @result_len: len of inq_result
* @bflags: store any bflags found here
*
* Description:
- * Probe the lun associated with @sreq using a standard SCSI INQUIRY;
+ * Probe the lun associated with @req using a standard SCSI INQUIRY;
*
- * If the INQUIRY is successful, sreq->sr_result is zero and: the
+ * If the INQUIRY is successful, zero is returned and the
* INQUIRY data is in @inq_result; the scsi_level and INQUIRY length
- * are copied to the Scsi_Device at @sreq->sr_device (sdev);
- * any flags value is stored in *@bflags.
+ * are copied to the Scsi_Device any flags value is stored in *@bflags.
**/
-static void scsi_probe_lun(struct scsi_request *sreq, char *inq_result,
- int *bflags)
+static int scsi_probe_lun(struct scsi_device *sdev, char *inq_result,
+ int result_len, int *bflags)
{
- struct scsi_device *sdev = sreq->sr_device; /* a bit ugly */
+ char sense[SCSI_SENSE_BUFFERSIZE];
unsigned char scsi_cmd[MAX_COMMAND_SIZE];
int first_inquiry_len, try_inquiry_len, next_inquiry_len;
int response_len = 0;
- int pass, count;
+ int pass, count, result;
struct scsi_sense_hdr sshdr;
*bflags = 0;
@@ -461,28 +473,28 @@ static void scsi_probe_lun(struct scsi_request *sreq, char *inq_result,
memset(scsi_cmd, 0, 6);
scsi_cmd[0] = INQUIRY;
scsi_cmd[4] = (unsigned char) try_inquiry_len;
- sreq->sr_cmd_len = 0;
- sreq->sr_data_direction = DMA_FROM_DEVICE;
+ memset(sense, 0, sizeof(sense));
memset(inq_result, 0, try_inquiry_len);
- scsi_wait_req(sreq, (void *) scsi_cmd, (void *) inq_result,
- try_inquiry_len,
- HZ/2 + HZ*scsi_inq_timeout, 3);
+
+ result = scsi_execute_req(sdev, scsi_cmd, DMA_FROM_DEVICE,
+ inq_result, try_inquiry_len, sense,
+ HZ / 2 + HZ * scsi_inq_timeout, 3);
SCSI_LOG_SCAN_BUS(3, printk(KERN_INFO "scsi scan: INQUIRY %s "
"with code 0x%x\n",
- sreq->sr_result ? "failed" : "successful",
- sreq->sr_result));
+ result ? "failed" : "successful", result));
- if (sreq->sr_result) {
+ if (result) {
/*
* not-ready to ready transition [asc/ascq=0x28/0x0]
* or power-on, reset [asc/ascq=0x29/0x0], continue.
* INQUIRY should not yield UNIT_ATTENTION
* but many buggy devices do so anyway.
*/
- if ((driver_byte(sreq->sr_result) & DRIVER_SENSE) &&
- scsi_request_normalize_sense(sreq, &sshdr)) {
+ if ((driver_byte(result) & DRIVER_SENSE) &&
+ scsi_normalize_sense(sense, sizeof(sense),
+ &sshdr)) {
if ((sshdr.sense_key == UNIT_ATTENTION) &&
((sshdr.asc == 0x28) ||
(sshdr.asc == 0x29)) &&
@@ -493,7 +505,7 @@ static void scsi_probe_lun(struct scsi_request *sreq, char *inq_result,
break;
}
- if (sreq->sr_result == 0) {
+ if (result == 0) {
response_len = (unsigned char) inq_result[4] + 5;
if (response_len > 255)
response_len = first_inquiry_len; /* sanity */
@@ -542,8 +554,8 @@ static void scsi_probe_lun(struct scsi_request *sreq, char *inq_result,
/* If the last transfer attempt got an error, assume the
* peripheral doesn't exist or is dead. */
- if (sreq->sr_result)
- return;
+ if (result)
+ return -EIO;
/* Don't report any more data than the device says is valid */
sdev->inquiry_len = min(try_inquiry_len, response_len);
@@ -579,7 +591,7 @@ static void scsi_probe_lun(struct scsi_request *sreq, char *inq_result,
(sdev->scsi_level == 1 && (inq_result[3] & 0x0f) == 1))
sdev->scsi_level++;
- return;
+ return 0;
}
/**
@@ -786,9 +798,8 @@ static int scsi_probe_and_add_lun(struct scsi_target *starget,
void *hostdata)
{
struct scsi_device *sdev;
- struct scsi_request *sreq;
unsigned char *result;
- int bflags, res = SCSI_SCAN_NO_RESPONSE;
+ int bflags, res = SCSI_SCAN_NO_RESPONSE, result_len = 256;
struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
/*
@@ -817,16 +828,13 @@ static int scsi_probe_and_add_lun(struct scsi_target *starget,
sdev = scsi_alloc_sdev(starget, lun, hostdata);
if (!sdev)
goto out;
- sreq = scsi_allocate_request(sdev, GFP_ATOMIC);
- if (!sreq)
- goto out_free_sdev;
- result = kmalloc(256, GFP_ATOMIC |
+
+ result = kmalloc(result_len, GFP_ATOMIC |
((shost->unchecked_isa_dma) ? __GFP_DMA : 0));
if (!result)
- goto out_free_sreq;
+ goto out_free_sdev;
- scsi_probe_lun(sreq, result, &bflags);
- if (sreq->sr_result)
+ if (scsi_probe_lun(sdev, result, result_len, &bflags))
goto out_free_result;
/*
@@ -854,7 +862,7 @@ static int scsi_probe_and_add_lun(struct scsi_target *starget,
if (res == SCSI_SCAN_LUN_PRESENT) {
if (bflags & BLIST_KEY) {
sdev->lockable = 0;
- scsi_unlock_floptical(sreq, result);
+ scsi_unlock_floptical(sdev, result);
}
if (bflagsp)
*bflagsp = bflags;
@@ -862,8 +870,6 @@ static int scsi_probe_and_add_lun(struct scsi_target *starget,
out_free_result:
kfree(result);
- out_free_sreq:
- scsi_release_request(sreq);
out_free_sdev:
if (res == SCSI_SCAN_LUN_PRESENT) {
if (sdevp) {
@@ -1051,13 +1057,14 @@ static int scsi_report_lun_scan(struct scsi_device *sdev, int bflags,
int rescan)
{
char devname[64];
+ char sense[SCSI_SENSE_BUFFERSIZE];
unsigned char scsi_cmd[MAX_COMMAND_SIZE];
unsigned int length;
unsigned int lun;
unsigned int num_luns;
unsigned int retries;
+ int result;
struct scsi_lun *lunp, *lun_data;
- struct scsi_request *sreq;
u8 *data;
struct scsi_sense_hdr sshdr;
struct scsi_target *starget = scsi_target(sdev);
@@ -1075,10 +1082,6 @@ static int scsi_report_lun_scan(struct scsi_device *sdev, int bflags,
if (bflags & BLIST_NOLUN)
return 0;
- sreq = scsi_allocate_request(sdev, GFP_ATOMIC);
- if (!sreq)
- goto out;
-
sprintf(devname, "host %d channel %d id %d",
sdev->host->host_no, sdev->channel, sdev->id);
@@ -1096,7 +1099,7 @@ static int scsi_report_lun_scan(struct scsi_device *sdev, int bflags,
lun_data = kmalloc(length, GFP_ATOMIC |
(sdev->host->unchecked_isa_dma ? __GFP_DMA : 0));
if (!lun_data)
- goto out_release_request;
+ goto out;
scsi_cmd[0] = REPORT_LUNS;
@@ -1115,8 +1118,6 @@ static int scsi_report_lun_scan(struct scsi_device *sdev, int bflags,
scsi_cmd[10] = 0; /* reserved */
scsi_cmd[11] = 0; /* control */
- sreq->sr_cmd_len = 0;
- sreq->sr_data_direction = DMA_FROM_DEVICE;
/*
* We can get a UNIT ATTENTION, for example a power on/reset, so
@@ -1132,29 +1133,30 @@ static int scsi_report_lun_scan(struct scsi_device *sdev, int bflags,
SCSI_LOG_SCAN_BUS(3, printk (KERN_INFO "scsi scan: Sending"
" REPORT LUNS to %s (try %d)\n", devname,
retries));
- scsi_wait_req(sreq, scsi_cmd, lun_data, length,
- SCSI_TIMEOUT + 4*HZ, 3);
+
+ memset(sense, 0, sizeof(sense));
+ result = scsi_execute_req(sdev, scsi_cmd, DMA_FROM_DEVICE,
+ lun_data, length, sense,
+ SCSI_TIMEOUT + 4 * HZ, 3);
+
SCSI_LOG_SCAN_BUS(3, printk (KERN_INFO "scsi scan: REPORT LUNS"
- " %s (try %d) result 0x%x\n", sreq->sr_result
- ? "failed" : "successful", retries,
- sreq->sr_result));
- if (sreq->sr_result == 0)
+ " %s (try %d) result 0x%x\n", result
+ ? "failed" : "successful", retries, result));
+ if (result == 0)
break;
- else if (scsi_request_normalize_sense(sreq, &sshdr)) {
+ else if (scsi_normalize_sense(sense, sizeof(sense), &sshdr)) {
if (sshdr.sense_key != UNIT_ATTENTION)
break;
}
}
- if (sreq->sr_result) {
+ if (result) {
/*
* The device probably does not support a REPORT LUN command
*/
kfree(lun_data);
- scsi_release_request(sreq);
return 1;
}
- scsi_release_request(sreq);
/*
* Get the length from the first four bytes of lun_data.
@@ -1228,8 +1230,6 @@ static int scsi_report_lun_scan(struct scsi_device *sdev, int bflags,
kfree(lun_data);
return 0;
- out_release_request:
- scsi_release_request(sreq);
out:
/*
* We are out of memory, don't try scanning any further.
diff --git a/drivers/scsi/scsi_transport_fc.c b/drivers/scsi/scsi_transport_fc.c
index 96243c7..2cab556 100644
--- a/drivers/scsi/scsi_transport_fc.c
+++ b/drivers/scsi/scsi_transport_fc.c
@@ -1024,6 +1024,23 @@ static int fc_rport_match(struct attribute_container *cont,
return &i->rport_attr_cont.ac == cont;
}
+
+/*
+ * Must be called with shost->host_lock held
+ */
+static struct device *fc_target_parent(struct Scsi_Host *shost,
+ int channel, uint id)
+{
+ struct fc_rport *rport;
+
+ list_for_each_entry(rport, &fc_host_rports(shost), peers)
+ if ((rport->channel == channel) &&
+ (rport->scsi_target_id == id))
+ return &rport->dev;
+
+ return NULL;
+}
+
struct scsi_transport_template *
fc_attach_transport(struct fc_function_template *ft)
{
@@ -1059,6 +1076,8 @@ fc_attach_transport(struct fc_function_template *ft)
/* Transport uses the shost workq for scsi scanning */
i->t.create_work_queue = 1;
+
+ i->t.target_parent = fc_target_parent;
/*
* Setup SCSI Target Attributes.
diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c
index 14fb179..052d55c 100644
--- a/drivers/scsi/sg.c
+++ b/drivers/scsi/sg.c
@@ -2970,23 +2970,22 @@ static void * dev_seq_start(struct seq_file *s, loff_t *pos)
{
struct sg_proc_deviter * it = kmalloc(sizeof(*it), GFP_KERNEL);
+ s->private = it;
if (! it)
return NULL;
+
if (NULL == sg_dev_arr)
- goto err1;
+ return NULL;
it->index = *pos;
it->max = sg_last_dev();
if (it->index >= it->max)
- goto err1;
+ return NULL;
return it;
-err1:
- kfree(it);
- return NULL;
}
static void * dev_seq_next(struct seq_file *s, void *v, loff_t *pos)
{
- struct sg_proc_deviter * it = (struct sg_proc_deviter *) v;
+ struct sg_proc_deviter * it = s->private;
*pos = ++it->index;
return (it->index < it->max) ? it : NULL;
@@ -2994,7 +2993,7 @@ static void * dev_seq_next(struct seq_file *s, void *v, loff_t *pos)
static void dev_seq_stop(struct seq_file *s, void *v)
{
- kfree (v);
+ kfree(s->private);
}
static int sg_proc_open_dev(struct inode *inode, struct file *file)
diff --git a/drivers/scsi/st.c b/drivers/scsi/st.c
index 47a5698..9aadf2f 100644
--- a/drivers/scsi/st.c
+++ b/drivers/scsi/st.c
@@ -4241,12 +4241,10 @@ static int __init init_st(void)
do_create_driverfs_files();
return 0;
}
- if (st_sysfs_class)
- class_destroy(st_sysfs_class);
unregister_chrdev_region(MKDEV(SCSI_TAPE_MAJOR, 0),
-
ST_MAX_TAPE_ENTRIES);
}
+ class_destroy(st_sysfs_class);
printk(KERN_ERR "Unable to get major %d for SCSI tapes\n", SCSI_TAPE_MAJOR);
return 1;
@@ -4254,13 +4252,11 @@ static int __init init_st(void)
static void __exit exit_st(void)
{
- if (st_sysfs_class)
- class_destroy(st_sysfs_class);
- st_sysfs_class = NULL;
do_remove_driverfs_files();
scsi_unregister_driver(&st_template.gendrv);
unregister_chrdev_region(MKDEV(SCSI_TAPE_MAJOR, 0),
ST_MAX_TAPE_ENTRIES);
+ class_destroy(st_sysfs_class);
kfree(scsi_tapes);
printk(KERN_INFO "st: Unloaded.\n");
}