diff --git a/[refs] b/[refs]
index 405862d9a783..72002a2827b8 100644
--- a/[refs]
+++ b/[refs]
@@ -1,2 +1,2 @@
---
-refs/heads/master: f389e9fcecdec4c4cb890ad28ea30a87a579ec3e
+refs/heads/master: aca7f96600b170e470b3056aba0ed8d7df8d330d
diff --git a/trunk/Documentation/DocBook/kernel-api.tmpl b/trunk/Documentation/DocBook/kernel-api.tmpl
index 77436d735013..aa38cc5692a0 100644
--- a/trunk/Documentation/DocBook/kernel-api.tmpl
+++ b/trunk/Documentation/DocBook/kernel-api.tmpl
@@ -419,13 +419,7 @@ X!Edrivers/pnp/system.c
Block Devices
-!Eblock/blk-core.c
-!Eblock/blk-map.c
-!Iblock/blk-sysfs.c
-!Eblock/blk-settings.c
-!Eblock/blk-exec.c
-!Eblock/blk-barrier.c
-!Eblock/blk-tag.c
+!Eblock/ll_rw_blk.c
diff --git a/trunk/arch/ia64/hp/sim/simscsi.c b/trunk/arch/ia64/hp/sim/simscsi.c
index 7661bb065fa5..6ef9b5219930 100644
--- a/trunk/arch/ia64/hp/sim/simscsi.c
+++ b/trunk/arch/ia64/hp/sim/simscsi.c
@@ -360,6 +360,7 @@ static struct scsi_host_template driver_template = {
.max_sectors = 1024,
.cmd_per_lun = SIMSCSI_REQ_QUEUE_LEN,
.use_clustering = DISABLE_CLUSTERING,
+ .use_sg_chaining = ENABLE_SG_CHAINING,
};
static int __init
diff --git a/trunk/block/bsg.c b/trunk/block/bsg.c
index 8917c5174dc2..69b0a9d33306 100644
--- a/trunk/block/bsg.c
+++ b/trunk/block/bsg.c
@@ -279,7 +279,6 @@ bsg_map_hdr(struct bsg_device *bd, struct sg_io_v4 *hdr)
goto out;
}
rq->next_rq = next_rq;
- next_rq->cmd_type = rq->cmd_type;
dxferp = (void*)(unsigned long)hdr->din_xferp;
ret = blk_rq_map_user(q, next_rq, dxferp, hdr->din_xfer_len);
diff --git a/trunk/drivers/base/class.c b/trunk/drivers/base/class.c
index 412fd9a05573..59cf35894cfc 100644
--- a/trunk/drivers/base/class.c
+++ b/trunk/drivers/base/class.c
@@ -863,7 +863,7 @@ EXPORT_SYMBOL_GPL(class_for_each_device);
* The callback should return 0 if the device doesn't match and non-zero
* if it does. If the callback returns non-zero, this function will
* return to the caller and not iterate over any more devices.
- *
+
* Note, you will need to drop the reference with put_device() after use.
*
* We hold class->sem in this function, so it can not be
diff --git a/trunk/drivers/infiniband/ulp/srp/ib_srp.c b/trunk/drivers/infiniband/ulp/srp/ib_srp.c
index 195ce7c12319..f2d2c7e2c76b 100644
--- a/trunk/drivers/infiniband/ulp/srp/ib_srp.c
+++ b/trunk/drivers/infiniband/ulp/srp/ib_srp.c
@@ -1571,6 +1571,7 @@ static struct scsi_host_template srp_template = {
.this_id = -1,
.cmd_per_lun = SRP_SQ_SIZE,
.use_clustering = ENABLE_CLUSTERING,
+ .use_sg_chaining = ENABLE_SG_CHAINING,
.shost_attrs = srp_host_attrs
};
diff --git a/trunk/drivers/kvm/x86_emulate.c b/trunk/drivers/kvm/x86_emulate.c
index bd46de6bf891..84af9cc737fa 100644
--- a/trunk/drivers/kvm/x86_emulate.c
+++ b/trunk/drivers/kvm/x86_emulate.c
@@ -1380,6 +1380,12 @@ x86_emulate_memop(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops)
u16 size;
unsigned long address;
+ case 0: /* vmcall */
+ if (modrm_mod != 3 || modrm_rm != 1)
+ goto cannot_emulate;
+
+ /* nop */
+ break;
case 2: /* lgdt */
rc = read_descriptor(ctxt, ops, src.ptr,
&size, &address, op_bytes);
@@ -1387,12 +1393,17 @@ x86_emulate_memop(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops)
goto done;
realmode_lgdt(ctxt->vcpu, size, address);
break;
- case 3: /* lidt */
- rc = read_descriptor(ctxt, ops, src.ptr,
- &size, &address, op_bytes);
- if (rc)
- goto done;
- realmode_lidt(ctxt->vcpu, size, address);
+ case 3: /* lidt/vmmcall */
+ if (modrm_mod == 3 && modrm_rm == 1) {
+ /* nop */
+ } else {
+ rc = read_descriptor(ctxt, ops, src.ptr,
+ &size, &address,
+ op_bytes);
+ if (rc)
+ goto done;
+ realmode_lidt(ctxt->vcpu, size, address);
+ }
break;
case 4: /* smsw */
if (modrm_mod != 3)
diff --git a/trunk/drivers/s390/scsi/zfcp_fsf.c b/trunk/drivers/s390/scsi/zfcp_fsf.c
index 0dff05840ee2..e45f85f7c7ed 100644
--- a/trunk/drivers/s390/scsi/zfcp_fsf.c
+++ b/trunk/drivers/s390/scsi/zfcp_fsf.c
@@ -4224,10 +4224,10 @@ zfcp_fsf_send_fcp_command_task_handler(struct zfcp_fsf_req *fsf_req)
ZFCP_LOG_TRACE("%i bytes sense data provided by FCP\n",
fcp_rsp_iu->fcp_sns_len);
- memcpy(scpnt->sense_buffer,
+ memcpy(&scpnt->sense_buffer,
zfcp_get_fcp_sns_info_ptr(fcp_rsp_iu), sns_len);
ZFCP_HEX_DUMP(ZFCP_LOG_LEVEL_TRACE,
- (void *)scpnt->sense_buffer, sns_len);
+ (void *) &scpnt->sense_buffer, sns_len);
}
/* check for overrun */
diff --git a/trunk/drivers/scsi/3w-9xxx.c b/trunk/drivers/scsi/3w-9xxx.c
index b4912d1cee2a..1c244832c6c8 100644
--- a/trunk/drivers/scsi/3w-9xxx.c
+++ b/trunk/drivers/scsi/3w-9xxx.c
@@ -1990,6 +1990,7 @@ static struct scsi_host_template driver_template = {
.max_sectors = TW_MAX_SECTORS,
.cmd_per_lun = TW_MAX_CMDS_PER_LUN,
.use_clustering = ENABLE_CLUSTERING,
+ .use_sg_chaining = ENABLE_SG_CHAINING,
.shost_attrs = twa_host_attrs,
.emulated = 1
};
diff --git a/trunk/drivers/scsi/3w-xxxx.c b/trunk/drivers/scsi/3w-xxxx.c
index d09532162217..59716ebeb10c 100644
--- a/trunk/drivers/scsi/3w-xxxx.c
+++ b/trunk/drivers/scsi/3w-xxxx.c
@@ -2261,6 +2261,7 @@ static struct scsi_host_template driver_template = {
.max_sectors = TW_MAX_SECTORS,
.cmd_per_lun = TW_MAX_CMDS_PER_LUN,
.use_clustering = ENABLE_CLUSTERING,
+ .use_sg_chaining = ENABLE_SG_CHAINING,
.shost_attrs = tw_host_attrs,
.emulated = 1
};
diff --git a/trunk/drivers/scsi/BusLogic.c b/trunk/drivers/scsi/BusLogic.c
index 4d3ebb1af490..ead47c143ce0 100644
--- a/trunk/drivers/scsi/BusLogic.c
+++ b/trunk/drivers/scsi/BusLogic.c
@@ -3575,6 +3575,7 @@ static struct scsi_host_template Bus_Logic_template = {
.unchecked_isa_dma = 1,
.max_sectors = 128,
.use_clustering = ENABLE_CLUSTERING,
+ .use_sg_chaining = ENABLE_SG_CHAINING,
};
/*
diff --git a/trunk/drivers/scsi/Kconfig b/trunk/drivers/scsi/Kconfig
index 14fc7f39e83e..3e161cd66463 100644
--- a/trunk/drivers/scsi/Kconfig
+++ b/trunk/drivers/scsi/Kconfig
@@ -345,7 +345,7 @@ config ISCSI_TCP
config SGIWD93_SCSI
tristate "SGI WD93C93 SCSI Driver"
- depends on SGI_HAS_WD93 && SCSI
+ depends on SGI_IP22 && SCSI
help
If you have a Western Digital WD93 SCSI controller on
an SGI MIPS system, say Y. Otherwise, say N.
diff --git a/trunk/drivers/scsi/NCR53c406a.c b/trunk/drivers/scsi/NCR53c406a.c
index 6961f78742ae..137d065db3da 100644
--- a/trunk/drivers/scsi/NCR53c406a.c
+++ b/trunk/drivers/scsi/NCR53c406a.c
@@ -1065,6 +1065,7 @@ static struct scsi_host_template driver_template =
.cmd_per_lun = 1 /* commands per lun */,
.unchecked_isa_dma = 1 /* unchecked_isa_dma */,
.use_clustering = ENABLE_CLUSTERING,
+ .use_sg_chaining = ENABLE_SG_CHAINING,
};
#include "scsi_module.c"
diff --git a/trunk/drivers/scsi/a100u2w.c b/trunk/drivers/scsi/a100u2w.c
index f608d4a1d6da..d3a6d15fb77a 100644
--- a/trunk/drivers/scsi/a100u2w.c
+++ b/trunk/drivers/scsi/a100u2w.c
@@ -1071,6 +1071,7 @@ static struct scsi_host_template inia100_template = {
.sg_tablesize = SG_ALL,
.cmd_per_lun = 1,
.use_clustering = ENABLE_CLUSTERING,
+ .use_sg_chaining = ENABLE_SG_CHAINING,
};
static int __devinit inia100_probe_one(struct pci_dev *pdev,
diff --git a/trunk/drivers/scsi/aacraid/commctrl.c b/trunk/drivers/scsi/aacraid/commctrl.c
index f8afa358b6b6..851a7e599c50 100644
--- a/trunk/drivers/scsi/aacraid/commctrl.c
+++ b/trunk/drivers/scsi/aacraid/commctrl.c
@@ -243,6 +243,7 @@ static int next_getadapter_fib(struct aac_dev * dev, void __user *arg)
* Search the list of AdapterFibContext addresses on the adapter
* to be sure this is a valid address
*/
+ spin_lock_irqsave(&dev->fib_lock, flags);
entry = dev->fib_list.next;
fibctx = NULL;
@@ -251,24 +252,25 @@ static int next_getadapter_fib(struct aac_dev * dev, void __user *arg)
/*
* Extract the AdapterFibContext from the Input parameters.
*/
- if (fibctx->unique == f.fibctx) { /* We found a winner */
+ if (fibctx->unique == f.fibctx) { /* We found a winner */
break;
}
entry = entry->next;
fibctx = NULL;
}
if (!fibctx) {
+ spin_unlock_irqrestore(&dev->fib_lock, flags);
dprintk ((KERN_INFO "Fib Context not found\n"));
return -EINVAL;
}
if((fibctx->type != FSAFS_NTC_GET_ADAPTER_FIB_CONTEXT) ||
(fibctx->size != sizeof(struct aac_fib_context))) {
+ spin_unlock_irqrestore(&dev->fib_lock, flags);
dprintk ((KERN_INFO "Fib Context corrupt?\n"));
return -EINVAL;
}
status = 0;
- spin_lock_irqsave(&dev->fib_lock, flags);
/*
* If there are no fibs to send back, then either wait or return
* -EAGAIN
@@ -326,7 +328,9 @@ static int next_getadapter_fib(struct aac_dev * dev, void __user *arg)
int aac_close_fib_context(struct aac_dev * dev, struct aac_fib_context * fibctx)
{
struct fib *fib;
+ unsigned long flags;
+ spin_lock_irqsave(&dev->fib_lock, flags);
/*
* First free any FIBs that have not been consumed.
*/
@@ -349,6 +353,7 @@ int aac_close_fib_context(struct aac_dev * dev, struct aac_fib_context * fibctx)
* Remove the Context from the AdapterFibContext List
*/
list_del(&fibctx->next);
+ spin_unlock_irqrestore(&dev->fib_lock, flags);
/*
* Invalidate context
*/
@@ -414,8 +419,8 @@ static int close_getadapter_fib(struct aac_dev * dev, void __user *arg)
* @arg: ioctl arguments
*
* This routine returns the driver version.
- * Under Linux, there have been no version incompatibilities, so this is
- * simple!
+ * Under Linux, there have been no version incompatibilities, so this is
+ * simple!
*/
static int check_revision(struct aac_dev *dev, void __user *arg)
@@ -463,7 +468,7 @@ static int aac_send_raw_srb(struct aac_dev* dev, void __user * arg)
u32 data_dir;
void __user *sg_user[32];
void *sg_list[32];
- u32 sg_indx = 0;
+ u32 sg_indx = 0;
u32 byte_count = 0;
u32 actual_fibsize64, actual_fibsize = 0;
int i;
@@ -517,11 +522,11 @@ static int aac_send_raw_srb(struct aac_dev* dev, void __user * arg)
// Fix up srb for endian and force some values
srbcmd->function = cpu_to_le32(SRBF_ExecuteScsi); // Force this
- srbcmd->channel = cpu_to_le32(user_srbcmd->channel);
+ srbcmd->channel = cpu_to_le32(user_srbcmd->channel);
srbcmd->id = cpu_to_le32(user_srbcmd->id);
- srbcmd->lun = cpu_to_le32(user_srbcmd->lun);
- srbcmd->timeout = cpu_to_le32(user_srbcmd->timeout);
- srbcmd->flags = cpu_to_le32(flags);
+ srbcmd->lun = cpu_to_le32(user_srbcmd->lun);
+ srbcmd->timeout = cpu_to_le32(user_srbcmd->timeout);
+ srbcmd->flags = cpu_to_le32(flags);
srbcmd->retry_limit = 0; // Obsolete parameter
srbcmd->cdb_size = cpu_to_le32(user_srbcmd->cdb_size);
memcpy(srbcmd->cdb, user_srbcmd->cdb, sizeof(srbcmd->cdb));
@@ -786,9 +791,9 @@ static int aac_get_pci_info(struct aac_dev* dev, void __user *arg)
pci_info.bus = dev->pdev->bus->number;
pci_info.slot = PCI_SLOT(dev->pdev->devfn);
- if (copy_to_user(arg, &pci_info, sizeof(struct aac_pci_info))) {
- dprintk((KERN_DEBUG "aacraid: Could not copy pci info\n"));
- return -EFAULT;
+ if (copy_to_user(arg, &pci_info, sizeof(struct aac_pci_info))) {
+ dprintk((KERN_DEBUG "aacraid: Could not copy pci info\n"));
+ return -EFAULT;
}
return 0;
}
diff --git a/trunk/drivers/scsi/aacraid/linit.c b/trunk/drivers/scsi/aacraid/linit.c
index 0e8267c1e915..61be22774e99 100644
--- a/trunk/drivers/scsi/aacraid/linit.c
+++ b/trunk/drivers/scsi/aacraid/linit.c
@@ -1032,6 +1032,7 @@ static struct scsi_host_template aac_driver_template = {
.cmd_per_lun = AAC_NUM_IO_FIB,
#endif
.use_clustering = ENABLE_CLUSTERING,
+ .use_sg_chaining = ENABLE_SG_CHAINING,
.emulated = 1,
};
diff --git a/trunk/drivers/scsi/aha1740.c b/trunk/drivers/scsi/aha1740.c
index 7c45d88a205b..be58a0b097c7 100644
--- a/trunk/drivers/scsi/aha1740.c
+++ b/trunk/drivers/scsi/aha1740.c
@@ -563,6 +563,7 @@ static struct scsi_host_template aha1740_template = {
.sg_tablesize = AHA1740_SCATTER,
.cmd_per_lun = AHA1740_CMDLUN,
.use_clustering = ENABLE_CLUSTERING,
+ .use_sg_chaining = ENABLE_SG_CHAINING,
.eh_abort_handler = aha1740_eh_abort_handler,
};
diff --git a/trunk/drivers/scsi/aic7xxx/aic79xx.h b/trunk/drivers/scsi/aic7xxx/aic79xx.h
index 2f00467b6b8c..ce638aa6005a 100644
--- a/trunk/drivers/scsi/aic7xxx/aic79xx.h
+++ b/trunk/drivers/scsi/aic7xxx/aic79xx.h
@@ -1340,10 +1340,8 @@ struct ahd_pci_identity *ahd_find_pci_device(ahd_dev_softc_t);
int ahd_pci_config(struct ahd_softc *,
struct ahd_pci_identity *);
int ahd_pci_test_register_access(struct ahd_softc *);
-#ifdef CONFIG_PM
void ahd_pci_suspend(struct ahd_softc *);
void ahd_pci_resume(struct ahd_softc *);
-#endif
/************************** SCB and SCB queue management **********************/
void ahd_qinfifo_requeue_tail(struct ahd_softc *ahd,
@@ -1354,10 +1352,8 @@ struct ahd_softc *ahd_alloc(void *platform_arg, char *name);
int ahd_softc_init(struct ahd_softc *);
void ahd_controller_info(struct ahd_softc *ahd, char *buf);
int ahd_init(struct ahd_softc *ahd);
-#ifdef CONFIG_PM
int ahd_suspend(struct ahd_softc *ahd);
void ahd_resume(struct ahd_softc *ahd);
-#endif
int ahd_default_config(struct ahd_softc *ahd);
int ahd_parse_vpddata(struct ahd_softc *ahd,
struct vpd_config *vpd);
@@ -1365,6 +1361,7 @@ int ahd_parse_cfgdata(struct ahd_softc *ahd,
struct seeprom_config *sc);
void ahd_intr_enable(struct ahd_softc *ahd, int enable);
void ahd_pause_and_flushwork(struct ahd_softc *ahd);
+int ahd_suspend(struct ahd_softc *ahd);
void ahd_set_unit(struct ahd_softc *, int);
void ahd_set_name(struct ahd_softc *, char *);
struct scb *ahd_get_scb(struct ahd_softc *ahd, u_int col_idx);
diff --git a/trunk/drivers/scsi/aic7xxx/aic79xx_core.c b/trunk/drivers/scsi/aic7xxx/aic79xx_core.c
index ade0fb8fbdb2..a7dd8cdda472 100644
--- a/trunk/drivers/scsi/aic7xxx/aic79xx_core.c
+++ b/trunk/drivers/scsi/aic7xxx/aic79xx_core.c
@@ -7175,7 +7175,6 @@ ahd_pause_and_flushwork(struct ahd_softc *ahd)
ahd->flags &= ~AHD_ALL_INTERRUPTS;
}
-#ifdef CONFIG_PM
int
ahd_suspend(struct ahd_softc *ahd)
{
@@ -7198,7 +7197,6 @@ ahd_resume(struct ahd_softc *ahd)
ahd_intr_enable(ahd, TRUE);
ahd_restart(ahd);
}
-#endif
/************************** Busy Target Table *********************************/
/*
diff --git a/trunk/drivers/scsi/aic7xxx/aic79xx_osm.c b/trunk/drivers/scsi/aic7xxx/aic79xx_osm.c
index 014654792901..0e4708fd43c8 100644
--- a/trunk/drivers/scsi/aic7xxx/aic79xx_osm.c
+++ b/trunk/drivers/scsi/aic7xxx/aic79xx_osm.c
@@ -766,6 +766,7 @@ struct scsi_host_template aic79xx_driver_template = {
.max_sectors = 8192,
.cmd_per_lun = 2,
.use_clustering = ENABLE_CLUSTERING,
+ .use_sg_chaining = ENABLE_SG_CHAINING,
.slave_alloc = ahd_linux_slave_alloc,
.slave_configure = ahd_linux_slave_configure,
.target_alloc = ahd_linux_target_alloc,
@@ -1921,7 +1922,7 @@ ahd_linux_queue_cmd_complete(struct ahd_softc *ahd, struct scsi_cmnd *cmd)
struct scsi_sense_data *sense;
sense = (struct scsi_sense_data *)
- cmd->sense_buffer;
+ &cmd->sense_buffer;
if (sense->extra_len >= 5 &&
(sense->add_sense_code == 0x47
|| sense->add_sense_code == 0x48))
diff --git a/trunk/drivers/scsi/aic7xxx/aic79xx_osm_pci.c b/trunk/drivers/scsi/aic7xxx/aic79xx_osm_pci.c
index 4150c8a8fdc2..66f0259edb69 100644
--- a/trunk/drivers/scsi/aic7xxx/aic79xx_osm_pci.c
+++ b/trunk/drivers/scsi/aic7xxx/aic79xx_osm_pci.c
@@ -43,6 +43,17 @@
#include "aic79xx_inline.h"
#include "aic79xx_pci.h"
+static int ahd_linux_pci_dev_probe(struct pci_dev *pdev,
+ const struct pci_device_id *ent);
+static int ahd_linux_pci_reserve_io_regions(struct ahd_softc *ahd,
+ u_long *base, u_long *base2);
+static int ahd_linux_pci_reserve_mem_region(struct ahd_softc *ahd,
+ u_long *bus_addr,
+ uint8_t __iomem **maddr);
+static int ahd_linux_pci_dev_suspend(struct pci_dev *pdev, pm_message_t mesg);
+static int ahd_linux_pci_dev_resume(struct pci_dev *pdev);
+static void ahd_linux_pci_dev_remove(struct pci_dev *pdev);
+
/* Define the macro locally since it's different for different class of chips.
*/
#define ID(x) \
@@ -74,7 +85,17 @@ static struct pci_device_id ahd_linux_pci_id_table[] = {
MODULE_DEVICE_TABLE(pci, ahd_linux_pci_id_table);
+static struct pci_driver aic79xx_pci_driver = {
+ .name = "aic79xx",
+ .probe = ahd_linux_pci_dev_probe,
#ifdef CONFIG_PM
+ .suspend = ahd_linux_pci_dev_suspend,
+ .resume = ahd_linux_pci_dev_resume,
+#endif
+ .remove = ahd_linux_pci_dev_remove,
+ .id_table = ahd_linux_pci_id_table
+};
+
static int
ahd_linux_pci_dev_suspend(struct pci_dev *pdev, pm_message_t mesg)
{
@@ -118,7 +139,6 @@ ahd_linux_pci_dev_resume(struct pci_dev *pdev)
return rc;
}
-#endif
static void
ahd_linux_pci_dev_remove(struct pci_dev *pdev)
@@ -225,17 +245,6 @@ ahd_linux_pci_dev_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
return (0);
}
-static struct pci_driver aic79xx_pci_driver = {
- .name = "aic79xx",
- .probe = ahd_linux_pci_dev_probe,
-#ifdef CONFIG_PM
- .suspend = ahd_linux_pci_dev_suspend,
- .resume = ahd_linux_pci_dev_resume,
-#endif
- .remove = ahd_linux_pci_dev_remove,
- .id_table = ahd_linux_pci_id_table
-};
-
int
ahd_linux_pci_init(void)
{
diff --git a/trunk/drivers/scsi/aic7xxx/aic79xx_pci.c b/trunk/drivers/scsi/aic7xxx/aic79xx_pci.c
index df853676e66a..7a203a90601a 100644
--- a/trunk/drivers/scsi/aic7xxx/aic79xx_pci.c
+++ b/trunk/drivers/scsi/aic7xxx/aic79xx_pci.c
@@ -389,7 +389,6 @@ ahd_pci_config(struct ahd_softc *ahd, struct ahd_pci_identity *entry)
return error;
}
-#ifdef CONFIG_PM
void
ahd_pci_suspend(struct ahd_softc *ahd)
{
@@ -416,7 +415,6 @@ ahd_pci_resume(struct ahd_softc *ahd)
ahd_pci_write_config(ahd->dev_softc, CSIZE_LATTIME,
ahd->suspend_state.pci_state.csize_lattime, /*bytes*/1);
}
-#endif
/*
* Perform some simple tests that should catch situations where
diff --git a/trunk/drivers/scsi/aic7xxx/aic7xxx.h b/trunk/drivers/scsi/aic7xxx/aic7xxx.h
index c0344e617651..3d4e42d90452 100644
--- a/trunk/drivers/scsi/aic7xxx/aic7xxx.h
+++ b/trunk/drivers/scsi/aic7xxx/aic7xxx.h
@@ -1143,9 +1143,7 @@ struct ahc_pci_identity *ahc_find_pci_device(ahc_dev_softc_t);
int ahc_pci_config(struct ahc_softc *,
struct ahc_pci_identity *);
int ahc_pci_test_register_access(struct ahc_softc *);
-#ifdef CONFIG_PM
void ahc_pci_resume(struct ahc_softc *ahc);
-#endif
/*************************** EISA/VL Front End ********************************/
struct aic7770_identity *aic7770_find_device(uint32_t);
@@ -1172,10 +1170,8 @@ int ahc_chip_init(struct ahc_softc *ahc);
int ahc_init(struct ahc_softc *ahc);
void ahc_intr_enable(struct ahc_softc *ahc, int enable);
void ahc_pause_and_flushwork(struct ahc_softc *ahc);
-#ifdef CONFIG_PM
int ahc_suspend(struct ahc_softc *ahc);
int ahc_resume(struct ahc_softc *ahc);
-#endif
void ahc_set_unit(struct ahc_softc *, int);
void ahc_set_name(struct ahc_softc *, char *);
void ahc_alloc_scbs(struct ahc_softc *ahc);
diff --git a/trunk/drivers/scsi/aic7xxx/aic7xxx_core.c b/trunk/drivers/scsi/aic7xxx/aic7xxx_core.c
index 6d2ae641273c..f350b5e89e76 100644
--- a/trunk/drivers/scsi/aic7xxx/aic7xxx_core.c
+++ b/trunk/drivers/scsi/aic7xxx/aic7xxx_core.c
@@ -5078,7 +5078,6 @@ ahc_pause_and_flushwork(struct ahc_softc *ahc)
ahc->flags &= ~AHC_ALL_INTERRUPTS;
}
-#ifdef CONFIG_PM
int
ahc_suspend(struct ahc_softc *ahc)
{
@@ -5114,7 +5113,7 @@ ahc_resume(struct ahc_softc *ahc)
ahc_restart(ahc);
return (0);
}
-#endif
+
/************************** Busy Target Table *********************************/
/*
* Return the untagged transaction id for a given target/channel lun.
diff --git a/trunk/drivers/scsi/aic7xxx/aic7xxx_osm.c b/trunk/drivers/scsi/aic7xxx/aic7xxx_osm.c
index 99a3b33a3233..e310e414067f 100644
--- a/trunk/drivers/scsi/aic7xxx/aic7xxx_osm.c
+++ b/trunk/drivers/scsi/aic7xxx/aic7xxx_osm.c
@@ -747,6 +747,7 @@ struct scsi_host_template aic7xxx_driver_template = {
.max_sectors = 8192,
.cmd_per_lun = 2,
.use_clustering = ENABLE_CLUSTERING,
+ .use_sg_chaining = ENABLE_SG_CHAINING,
.slave_alloc = ahc_linux_slave_alloc,
.slave_configure = ahc_linux_slave_configure,
.target_alloc = ahc_linux_target_alloc,
@@ -1657,12 +1658,9 @@ ahc_done(struct ahc_softc *ahc, struct scb *scb)
untagged_q = &(ahc->untagged_queues[target_offset]);
TAILQ_REMOVE(untagged_q, scb, links.tqe);
BUG_ON(!TAILQ_EMPTY(untagged_q));
- } else if ((scb->flags & SCB_ACTIVE) == 0) {
- /*
- * Transactions aborted from the untagged queue may
- * not have been dispatched to the controller, so
- * only check the SCB_ACTIVE flag for tagged transactions.
- */
+ }
+
+ if ((scb->flags & SCB_ACTIVE) == 0) {
printf("SCB %d done'd twice\n", scb->hscb->tag);
ahc_dump_card_state(ahc);
panic("Stopping for safety");
diff --git a/trunk/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c b/trunk/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c
index dd6e21d6f1dd..4488946cff2e 100644
--- a/trunk/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c
+++ b/trunk/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c
@@ -42,6 +42,17 @@
#include "aic7xxx_osm.h"
#include "aic7xxx_pci.h"
+static int ahc_linux_pci_dev_probe(struct pci_dev *pdev,
+ const struct pci_device_id *ent);
+static int ahc_linux_pci_reserve_io_region(struct ahc_softc *ahc,
+ u_long *base);
+static int ahc_linux_pci_reserve_mem_region(struct ahc_softc *ahc,
+ u_long *bus_addr,
+ uint8_t __iomem **maddr);
+static int ahc_linux_pci_dev_suspend(struct pci_dev *pdev, pm_message_t mesg);
+static int ahc_linux_pci_dev_resume(struct pci_dev *pdev);
+static void ahc_linux_pci_dev_remove(struct pci_dev *pdev);
+
/* Define the macro locally since it's different for different class of chips.
*/
#define ID(x) ID_C(x, PCI_CLASS_STORAGE_SCSI)
@@ -121,7 +132,17 @@ static struct pci_device_id ahc_linux_pci_id_table[] = {
MODULE_DEVICE_TABLE(pci, ahc_linux_pci_id_table);
+static struct pci_driver aic7xxx_pci_driver = {
+ .name = "aic7xxx",
+ .probe = ahc_linux_pci_dev_probe,
#ifdef CONFIG_PM
+ .suspend = ahc_linux_pci_dev_suspend,
+ .resume = ahc_linux_pci_dev_resume,
+#endif
+ .remove = ahc_linux_pci_dev_remove,
+ .id_table = ahc_linux_pci_id_table
+};
+
static int
ahc_linux_pci_dev_suspend(struct pci_dev *pdev, pm_message_t mesg)
{
@@ -161,7 +182,6 @@ ahc_linux_pci_dev_resume(struct pci_dev *pdev)
return (ahc_resume(ahc));
}
-#endif
static void
ahc_linux_pci_dev_remove(struct pci_dev *pdev)
@@ -269,17 +289,6 @@ ahc_linux_pci_dev_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
return (0);
}
-static struct pci_driver aic7xxx_pci_driver = {
- .name = "aic7xxx",
- .probe = ahc_linux_pci_dev_probe,
-#ifdef CONFIG_PM
- .suspend = ahc_linux_pci_dev_suspend,
- .resume = ahc_linux_pci_dev_resume,
-#endif
- .remove = ahc_linux_pci_dev_remove,
- .id_table = ahc_linux_pci_id_table
-};
-
int
ahc_linux_pci_init(void)
{
diff --git a/trunk/drivers/scsi/aic7xxx/aic7xxx_pci.c b/trunk/drivers/scsi/aic7xxx/aic7xxx_pci.c
index 56848f41e4f9..ae35937b8055 100644
--- a/trunk/drivers/scsi/aic7xxx/aic7xxx_pci.c
+++ b/trunk/drivers/scsi/aic7xxx/aic7xxx_pci.c
@@ -2020,7 +2020,6 @@ ahc_pci_chip_init(struct ahc_softc *ahc)
return (ahc_chip_init(ahc));
}
-#ifdef CONFIG_PM
void
ahc_pci_resume(struct ahc_softc *ahc)
{
@@ -2052,7 +2051,6 @@ ahc_pci_resume(struct ahc_softc *ahc)
ahc_release_seeprom(&sd);
}
}
-#endif
static int
ahc_aic785X_setup(struct ahc_softc *ahc)
diff --git a/trunk/drivers/scsi/aic7xxx_old.c b/trunk/drivers/scsi/aic7xxx_old.c
index 3bfd9296bbfa..bcb0b870320c 100644
--- a/trunk/drivers/scsi/aic7xxx_old.c
+++ b/trunk/drivers/scsi/aic7xxx_old.c
@@ -11141,6 +11141,7 @@ static struct scsi_host_template driver_template = {
.max_sectors = 2048,
.cmd_per_lun = 3,
.use_clustering = ENABLE_CLUSTERING,
+ .use_sg_chaining = ENABLE_SG_CHAINING,
};
#include "scsi_module.c"
diff --git a/trunk/drivers/scsi/arcmsr/arcmsr_hba.c b/trunk/drivers/scsi/arcmsr/arcmsr_hba.c
index f4a202e8df26..d80dba913a75 100644
--- a/trunk/drivers/scsi/arcmsr/arcmsr_hba.c
+++ b/trunk/drivers/scsi/arcmsr/arcmsr_hba.c
@@ -122,6 +122,7 @@ static struct scsi_host_template arcmsr_scsi_host_template = {
.max_sectors = ARCMSR_MAX_XFER_SECTORS,
.cmd_per_lun = ARCMSR_MAX_CMD_PERLUN,
.use_clustering = ENABLE_CLUSTERING,
+ .use_sg_chaining = ENABLE_SG_CHAINING,
.shost_attrs = arcmsr_host_attrs,
};
#ifdef CONFIG_SCSI_ARCMSR_AER
diff --git a/trunk/drivers/scsi/dc395x.c b/trunk/drivers/scsi/dc395x.c
index 22ef3716e786..f93c73c0ba53 100644
--- a/trunk/drivers/scsi/dc395x.c
+++ b/trunk/drivers/scsi/dc395x.c
@@ -4763,6 +4763,7 @@ static struct scsi_host_template dc395x_driver_template = {
.eh_bus_reset_handler = dc395x_eh_bus_reset,
.unchecked_isa_dma = 0,
.use_clustering = DISABLE_CLUSTERING,
+ .use_sg_chaining = ENABLE_SG_CHAINING,
};
diff --git a/trunk/drivers/scsi/dpt_i2o.c b/trunk/drivers/scsi/dpt_i2o.c
index c9dd8392aab2..19cce125124c 100644
--- a/trunk/drivers/scsi/dpt_i2o.c
+++ b/trunk/drivers/scsi/dpt_i2o.c
@@ -3340,6 +3340,7 @@ static struct scsi_host_template driver_template = {
.this_id = 7,
.cmd_per_lun = 1,
.use_clustering = ENABLE_CLUSTERING,
+ .use_sg_chaining = ENABLE_SG_CHAINING,
};
#include "scsi_module.c"
MODULE_LICENSE("GPL");
diff --git a/trunk/drivers/scsi/eata.c b/trunk/drivers/scsi/eata.c
index 8be3d76656fa..05163cefec12 100644
--- a/trunk/drivers/scsi/eata.c
+++ b/trunk/drivers/scsi/eata.c
@@ -524,6 +524,7 @@ static struct scsi_host_template driver_template = {
.this_id = 7,
.unchecked_isa_dma = 1,
.use_clustering = ENABLE_CLUSTERING,
+ .use_sg_chaining = ENABLE_SG_CHAINING,
};
#if !defined(__BIG_ENDIAN_BITFIELD) && !defined(__LITTLE_ENDIAN_BITFIELD)
diff --git a/trunk/drivers/scsi/hosts.c b/trunk/drivers/scsi/hosts.c
index 880c78bff0e1..5ea1f986220c 100644
--- a/trunk/drivers/scsi/hosts.c
+++ b/trunk/drivers/scsi/hosts.c
@@ -342,6 +342,7 @@ struct Scsi_Host *scsi_host_alloc(struct scsi_host_template *sht, int privsize)
shost->use_clustering = sht->use_clustering;
shost->ordered_tag = sht->ordered_tag;
shost->active_mode = sht->supported_mode;
+ shost->use_sg_chaining = sht->use_sg_chaining;
if (sht->supported_mode == MODE_UNKNOWN)
/* means we didn't set it ... default to INITIATOR */
diff --git a/trunk/drivers/scsi/hptiop.c b/trunk/drivers/scsi/hptiop.c
index ff149ad6bc4e..e7b2f3575ce9 100644
--- a/trunk/drivers/scsi/hptiop.c
+++ b/trunk/drivers/scsi/hptiop.c
@@ -573,7 +573,7 @@ static void hptiop_finish_scsi_req(struct hptiop_hba *hba, u32 tag,
scsi_set_resid(scp,
scsi_bufflen(scp) - le32_to_cpu(req->dataxfer_length));
scp->result = SAM_STAT_CHECK_CONDITION;
- memcpy(scp->sense_buffer, &req->sg_list,
+ memcpy(&scp->sense_buffer, &req->sg_list,
min_t(size_t, SCSI_SENSE_BUFFERSIZE,
le32_to_cpu(req->dataxfer_length)));
break;
@@ -906,6 +906,7 @@ static struct scsi_host_template driver_template = {
.unchecked_isa_dma = 0,
.emulated = 0,
.use_clustering = ENABLE_CLUSTERING,
+ .use_sg_chaining = ENABLE_SG_CHAINING,
.proc_name = driver_name,
.shost_attrs = hptiop_attrs,
.this_id = -1,
diff --git a/trunk/drivers/scsi/ibmmca.c b/trunk/drivers/scsi/ibmmca.c
index 4d15a62914e9..db004a450732 100644
--- a/trunk/drivers/scsi/ibmmca.c
+++ b/trunk/drivers/scsi/ibmmca.c
@@ -1501,6 +1501,7 @@ static struct scsi_host_template ibmmca_driver_template = {
.sg_tablesize = 16,
.cmd_per_lun = 1,
.use_clustering = ENABLE_CLUSTERING,
+ .use_sg_chaining = ENABLE_SG_CHAINING,
};
static int ibmmca_probe(struct device *dev)
diff --git a/trunk/drivers/scsi/ibmvscsi/ibmvscsi.c b/trunk/drivers/scsi/ibmvscsi/ibmvscsi.c
index 78d46a900bb5..30819012898f 100644
--- a/trunk/drivers/scsi/ibmvscsi/ibmvscsi.c
+++ b/trunk/drivers/scsi/ibmvscsi/ibmvscsi.c
@@ -1600,6 +1600,7 @@ static struct scsi_host_template driver_template = {
.this_id = -1,
.sg_tablesize = SG_ALL,
.use_clustering = ENABLE_CLUSTERING,
+ .use_sg_chaining = ENABLE_SG_CHAINING,
.shost_attrs = ibmvscsi_attrs,
};
diff --git a/trunk/drivers/scsi/initio.c b/trunk/drivers/scsi/initio.c
index 0cc8868ea35d..a10a5c74b48d 100644
--- a/trunk/drivers/scsi/initio.c
+++ b/trunk/drivers/scsi/initio.c
@@ -2833,6 +2833,7 @@ static struct scsi_host_template initio_template = {
.sg_tablesize = SG_ALL,
.cmd_per_lun = 1,
.use_clustering = ENABLE_CLUSTERING,
+ .use_sg_chaining = ENABLE_SG_CHAINING,
};
static int initio_probe_one(struct pci_dev *pdev,
diff --git a/trunk/drivers/scsi/iscsi_tcp.c b/trunk/drivers/scsi/iscsi_tcp.c
index b6f99dfbb038..e5be5fd4ef58 100644
--- a/trunk/drivers/scsi/iscsi_tcp.c
+++ b/trunk/drivers/scsi/iscsi_tcp.c
@@ -1933,6 +1933,7 @@ static struct scsi_host_template iscsi_sht = {
.eh_device_reset_handler= iscsi_eh_device_reset,
.eh_host_reset_handler = iscsi_eh_host_reset,
.use_clustering = DISABLE_CLUSTERING,
+ .use_sg_chaining = ENABLE_SG_CHAINING,
.slave_configure = iscsi_tcp_slave_configure,
.proc_name = "iscsi_tcp",
.this_id = -1,
diff --git a/trunk/drivers/scsi/libsrp.c b/trunk/drivers/scsi/libsrp.c
index 6d6a76e65a6c..5cff0204227d 100644
--- a/trunk/drivers/scsi/libsrp.c
+++ b/trunk/drivers/scsi/libsrp.c
@@ -426,8 +426,8 @@ int srp_cmd_queue(struct Scsi_Host *shost, struct srp_cmd *cmd, void *info,
sc->SCp.ptr = info;
memcpy(sc->cmnd, cmd->cdb, MAX_COMMAND_SIZE);
- sc->sdb.length = len;
- sc->sdb.table.sgl = (void *) (unsigned long) addr;
+ sc->request_bufflen = len;
+ sc->request_buffer = (void *) (unsigned long) addr;
sc->tag = tag;
err = scsi_tgt_queue_command(sc, itn_id, (struct scsi_lun *)&cmd->lun,
cmd->tag);
diff --git a/trunk/drivers/scsi/lpfc/lpfc_scsi.c b/trunk/drivers/scsi/lpfc/lpfc_scsi.c
index fc5c3a42b05a..6483c62730b3 100644
--- a/trunk/drivers/scsi/lpfc/lpfc_scsi.c
+++ b/trunk/drivers/scsi/lpfc/lpfc_scsi.c
@@ -1459,6 +1459,7 @@ struct scsi_host_template lpfc_template = {
.scan_finished = lpfc_scan_finished,
.this_id = -1,
.sg_tablesize = LPFC_DEFAULT_SG_SEG_CNT,
+ .use_sg_chaining = ENABLE_SG_CHAINING,
.cmd_per_lun = LPFC_CMD_PER_LUN,
.use_clustering = ENABLE_CLUSTERING,
.shost_attrs = lpfc_hba_attrs,
@@ -1481,6 +1482,7 @@ struct scsi_host_template lpfc_vport_template = {
.sg_tablesize = LPFC_DEFAULT_SG_SEG_CNT,
.cmd_per_lun = LPFC_CMD_PER_LUN,
.use_clustering = ENABLE_CLUSTERING,
+ .use_sg_chaining = ENABLE_SG_CHAINING,
.shost_attrs = lpfc_vport_attrs,
.max_sectors = 0xFFFF,
};
diff --git a/trunk/drivers/scsi/mac53c94.c b/trunk/drivers/scsi/mac53c94.c
index b12ad7c7c673..a035001f4438 100644
--- a/trunk/drivers/scsi/mac53c94.c
+++ b/trunk/drivers/scsi/mac53c94.c
@@ -402,6 +402,7 @@ static struct scsi_host_template mac53c94_template = {
.sg_tablesize = SG_ALL,
.cmd_per_lun = 1,
.use_clustering = DISABLE_CLUSTERING,
+ .use_sg_chaining = ENABLE_SG_CHAINING,
};
static int mac53c94_probe(struct macio_dev *mdev, const struct of_device_id *match)
diff --git a/trunk/drivers/scsi/megaraid.c b/trunk/drivers/scsi/megaraid.c
index 4d59ae8491a4..765c24d2bc38 100644
--- a/trunk/drivers/scsi/megaraid.c
+++ b/trunk/drivers/scsi/megaraid.c
@@ -4490,6 +4490,7 @@ static struct scsi_host_template megaraid_template = {
.sg_tablesize = MAX_SGLIST,
.cmd_per_lun = DEF_CMD_PER_LUN,
.use_clustering = ENABLE_CLUSTERING,
+ .use_sg_chaining = ENABLE_SG_CHAINING,
.eh_abort_handler = megaraid_abort,
.eh_device_reset_handler = megaraid_reset,
.eh_bus_reset_handler = megaraid_reset,
diff --git a/trunk/drivers/scsi/megaraid/megaraid_mbox.c b/trunk/drivers/scsi/megaraid/megaraid_mbox.c
index 6db77c00e3ee..24e32e446e76 100644
--- a/trunk/drivers/scsi/megaraid/megaraid_mbox.c
+++ b/trunk/drivers/scsi/megaraid/megaraid_mbox.c
@@ -361,6 +361,7 @@ static struct scsi_host_template megaraid_template_g = {
.eh_host_reset_handler = megaraid_reset_handler,
.change_queue_depth = megaraid_change_queue_depth,
.use_clustering = ENABLE_CLUSTERING,
+ .use_sg_chaining = ENABLE_SG_CHAINING,
.sdev_attrs = megaraid_sdev_attrs,
.shost_attrs = megaraid_shost_attrs,
};
diff --git a/trunk/drivers/scsi/megaraid/megaraid_sas.c b/trunk/drivers/scsi/megaraid/megaraid_sas.c
index 672c759ac24d..d7ec921865c4 100644
--- a/trunk/drivers/scsi/megaraid/megaraid_sas.c
+++ b/trunk/drivers/scsi/megaraid/megaraid_sas.c
@@ -1192,6 +1192,7 @@ static struct scsi_host_template megasas_template = {
.eh_timed_out = megasas_reset_timer,
.bios_param = megasas_bios_param,
.use_clustering = ENABLE_CLUSTERING,
+ .use_sg_chaining = ENABLE_SG_CHAINING,
};
/**
diff --git a/trunk/drivers/scsi/mesh.c b/trunk/drivers/scsi/mesh.c
index 651d09b08f2a..7470ff39ab22 100644
--- a/trunk/drivers/scsi/mesh.c
+++ b/trunk/drivers/scsi/mesh.c
@@ -1843,6 +1843,7 @@ static struct scsi_host_template mesh_template = {
.sg_tablesize = SG_ALL,
.cmd_per_lun = 2,
.use_clustering = DISABLE_CLUSTERING,
+ .use_sg_chaining = ENABLE_SG_CHAINING,
};
static int mesh_probe(struct macio_dev *mdev, const struct of_device_id *match)
diff --git a/trunk/drivers/scsi/ncr53c8xx.c b/trunk/drivers/scsi/ncr53c8xx.c
index c5ebf018b378..c02771aa6c9b 100644
--- a/trunk/drivers/scsi/ncr53c8xx.c
+++ b/trunk/drivers/scsi/ncr53c8xx.c
@@ -4967,7 +4967,7 @@ void ncr_complete (struct ncb *np, struct ccb *cp)
sizeof(cp->sense_buf)));
if (DEBUG_FLAGS & (DEBUG_RESULT|DEBUG_TINY)) {
- u_char *p = cmd->sense_buffer;
+ u_char * p = (u_char*) & cmd->sense_buffer;
int i;
PRINT_ADDR(cmd, "sense data:");
for (i=0; i<14; i++) printk (" %x", *p++);
diff --git a/trunk/drivers/scsi/nsp32.c b/trunk/drivers/scsi/nsp32.c
index 7fed35372150..28161dc95e0d 100644
--- a/trunk/drivers/scsi/nsp32.c
+++ b/trunk/drivers/scsi/nsp32.c
@@ -281,6 +281,7 @@ static struct scsi_host_template nsp32_template = {
.cmd_per_lun = 1,
.this_id = NSP32_HOST_SCSIID,
.use_clustering = DISABLE_CLUSTERING,
+ .use_sg_chaining = ENABLE_SG_CHAINING,
.eh_abort_handler = nsp32_eh_abort,
.eh_bus_reset_handler = nsp32_eh_bus_reset,
.eh_host_reset_handler = nsp32_eh_host_reset,
diff --git a/trunk/drivers/scsi/pcmcia/sym53c500_cs.c b/trunk/drivers/scsi/pcmcia/sym53c500_cs.c
index 3454a5714749..969b9387a0c3 100644
--- a/trunk/drivers/scsi/pcmcia/sym53c500_cs.c
+++ b/trunk/drivers/scsi/pcmcia/sym53c500_cs.c
@@ -692,6 +692,7 @@ static struct scsi_host_template sym53c500_driver_template = {
.sg_tablesize = 32,
.cmd_per_lun = 1,
.use_clustering = ENABLE_CLUSTERING,
+ .use_sg_chaining = ENABLE_SG_CHAINING,
.shost_attrs = SYM53C500_shost_attrs
};
diff --git a/trunk/drivers/scsi/qla1280.c b/trunk/drivers/scsi/qla1280.c
index 68c0d09ffe78..c94906abfee3 100644
--- a/trunk/drivers/scsi/qla1280.c
+++ b/trunk/drivers/scsi/qla1280.c
@@ -4204,6 +4204,7 @@ static struct scsi_host_template qla1280_driver_template = {
.sg_tablesize = SG_ALL,
.cmd_per_lun = 1,
.use_clustering = ENABLE_CLUSTERING,
+ .use_sg_chaining = ENABLE_SG_CHAINING,
};
diff --git a/trunk/drivers/scsi/qla2xxx/qla_os.c b/trunk/drivers/scsi/qla2xxx/qla_os.c
index 3954ed2d7b51..aba1e6d48066 100644
--- a/trunk/drivers/scsi/qla2xxx/qla_os.c
+++ b/trunk/drivers/scsi/qla2xxx/qla_os.c
@@ -131,6 +131,7 @@ static struct scsi_host_template qla2x00_driver_template = {
.this_id = -1,
.cmd_per_lun = 3,
.use_clustering = ENABLE_CLUSTERING,
+ .use_sg_chaining = ENABLE_SG_CHAINING,
.sg_tablesize = SG_ALL,
/*
@@ -162,6 +163,7 @@ struct scsi_host_template qla24xx_driver_template = {
.this_id = -1,
.cmd_per_lun = 3,
.use_clustering = ENABLE_CLUSTERING,
+ .use_sg_chaining = ENABLE_SG_CHAINING,
.sg_tablesize = SG_ALL,
.max_sectors = 0xFFFF,
diff --git a/trunk/drivers/scsi/qla4xxx/ql4_os.c b/trunk/drivers/scsi/qla4xxx/ql4_os.c
index 2e2b9fedffcc..d3f86646cb08 100644
--- a/trunk/drivers/scsi/qla4xxx/ql4_os.c
+++ b/trunk/drivers/scsi/qla4xxx/ql4_os.c
@@ -94,6 +94,7 @@ static struct scsi_host_template qla4xxx_driver_template = {
.this_id = -1,
.cmd_per_lun = 3,
.use_clustering = ENABLE_CLUSTERING,
+ .use_sg_chaining = ENABLE_SG_CHAINING,
.sg_tablesize = SG_ALL,
.max_sectors = 0xFFFF,
diff --git a/trunk/drivers/scsi/qlogicfas.c b/trunk/drivers/scsi/qlogicfas.c
index 1e874f1fb5c6..1769f965eedf 100644
--- a/trunk/drivers/scsi/qlogicfas.c
+++ b/trunk/drivers/scsi/qlogicfas.c
@@ -197,6 +197,7 @@ static struct scsi_host_template qlogicfas_driver_template = {
.sg_tablesize = SG_ALL,
.cmd_per_lun = 1,
.use_clustering = DISABLE_CLUSTERING,
+ .use_sg_chaining = ENABLE_SG_CHAINING,
};
static __init int qlogicfas_init(void)
diff --git a/trunk/drivers/scsi/scsi.c b/trunk/drivers/scsi/scsi.c
index b35d19472caa..1a9fba6a9f92 100644
--- a/trunk/drivers/scsi/scsi.c
+++ b/trunk/drivers/scsi/scsi.c
@@ -757,7 +757,7 @@ void scsi_finish_command(struct scsi_cmnd *cmd)
"Notifying upper driver of completion "
"(result %x)\n", cmd->result));
- good_bytes = scsi_bufflen(cmd);
+ good_bytes = cmd->request_bufflen;
if (cmd->request->cmd_type != REQ_TYPE_BLOCK_PC) {
drv = scsi_cmd_to_driver(cmd);
if (drv->done)
diff --git a/trunk/drivers/scsi/scsi_debug.c b/trunk/drivers/scsi/scsi_debug.c
index 1541c174937a..82c06f0a9d02 100644
--- a/trunk/drivers/scsi/scsi_debug.c
+++ b/trunk/drivers/scsi/scsi_debug.c
@@ -280,8 +280,6 @@ static int resp_write(struct scsi_cmnd * SCpnt, unsigned long long lba,
unsigned int num, struct sdebug_dev_info * devip);
static int resp_report_luns(struct scsi_cmnd * SCpnt,
struct sdebug_dev_info * devip);
-static int resp_xdwriteread(struct scsi_cmnd *scp, unsigned long long lba,
- unsigned int num, struct sdebug_dev_info *devip);
static int fill_from_dev_buffer(struct scsi_cmnd * scp, unsigned char * arr,
int arr_len);
static int fetch_to_dev_buffer(struct scsi_cmnd * scp, unsigned char * arr,
@@ -313,48 +311,12 @@ static void sdebug_max_tgts_luns(void);
static struct device pseudo_primary;
static struct bus_type pseudo_lld_bus;
-static void get_data_transfer_info(unsigned char *cmd,
- unsigned long long *lba, unsigned int *num)
-{
- int i;
-
- switch (*cmd) {
- case WRITE_16:
- case READ_16:
- for (*lba = 0, i = 0; i < 8; ++i) {
- if (i > 0)
- *lba <<= 8;
- *lba += cmd[2 + i];
- }
- *num = cmd[13] + (cmd[12] << 8) +
- (cmd[11] << 16) + (cmd[10] << 24);
- break;
- case WRITE_12:
- case READ_12:
- *lba = cmd[5] + (cmd[4] << 8) + (cmd[3] << 16) + (cmd[2] << 24);
- *num = cmd[9] + (cmd[8] << 8) + (cmd[7] << 16) + (cmd[6] << 24);
- break;
- case WRITE_10:
- case READ_10:
- case XDWRITEREAD_10:
- *lba = cmd[5] + (cmd[4] << 8) + (cmd[3] << 16) + (cmd[2] << 24);
- *num = cmd[8] + (cmd[7] << 8);
- break;
- case WRITE_6:
- case READ_6:
- *lba = cmd[3] + (cmd[2] << 8) + ((cmd[1] & 0x1f) << 16);
- *num = (0 == cmd[4]) ? 256 : cmd[4];
- break;
- default:
- break;
- }
-}
static
int scsi_debug_queuecommand(struct scsi_cmnd * SCpnt, done_funct_t done)
{
unsigned char *cmd = (unsigned char *) SCpnt->cmnd;
- int len, k;
+ int len, k, j;
unsigned int num;
unsigned long long lba;
int errsts = 0;
@@ -490,7 +452,28 @@ int scsi_debug_queuecommand(struct scsi_cmnd * SCpnt, done_funct_t done)
break;
if (scsi_debug_fake_rw)
break;
- get_data_transfer_info(cmd, &lba, &num);
+ if ((*cmd) == READ_16) {
+ for (lba = 0, j = 0; j < 8; ++j) {
+ if (j > 0)
+ lba <<= 8;
+ lba += cmd[2 + j];
+ }
+ num = cmd[13] + (cmd[12] << 8) +
+ (cmd[11] << 16) + (cmd[10] << 24);
+ } else if ((*cmd) == READ_12) {
+ lba = cmd[5] + (cmd[4] << 8) +
+ (cmd[3] << 16) + (cmd[2] << 24);
+ num = cmd[9] + (cmd[8] << 8) +
+ (cmd[7] << 16) + (cmd[6] << 24);
+ } else if ((*cmd) == READ_10) {
+ lba = cmd[5] + (cmd[4] << 8) +
+ (cmd[3] << 16) + (cmd[2] << 24);
+ num = cmd[8] + (cmd[7] << 8);
+ } else { /* READ (6) */
+ lba = cmd[3] + (cmd[2] << 8) +
+ ((cmd[1] & 0x1f) << 16);
+ num = (0 == cmd[4]) ? 256 : cmd[4];
+ }
errsts = resp_read(SCpnt, lba, num, devip);
if (inj_recovered && (0 == errsts)) {
mk_sense_buffer(devip, RECOVERED_ERROR,
@@ -517,7 +500,28 @@ int scsi_debug_queuecommand(struct scsi_cmnd * SCpnt, done_funct_t done)
break;
if (scsi_debug_fake_rw)
break;
- get_data_transfer_info(cmd, &lba, &num);
+ if ((*cmd) == WRITE_16) {
+ for (lba = 0, j = 0; j < 8; ++j) {
+ if (j > 0)
+ lba <<= 8;
+ lba += cmd[2 + j];
+ }
+ num = cmd[13] + (cmd[12] << 8) +
+ (cmd[11] << 16) + (cmd[10] << 24);
+ } else if ((*cmd) == WRITE_12) {
+ lba = cmd[5] + (cmd[4] << 8) +
+ (cmd[3] << 16) + (cmd[2] << 24);
+ num = cmd[9] + (cmd[8] << 8) +
+ (cmd[7] << 16) + (cmd[6] << 24);
+ } else if ((*cmd) == WRITE_10) {
+ lba = cmd[5] + (cmd[4] << 8) +
+ (cmd[3] << 16) + (cmd[2] << 24);
+ num = cmd[8] + (cmd[7] << 8);
+ } else { /* WRITE (6) */
+ lba = cmd[3] + (cmd[2] << 8) +
+ ((cmd[1] & 0x1f) << 16);
+ num = (0 == cmd[4]) ? 256 : cmd[4];
+ }
errsts = resp_write(SCpnt, lba, num, devip);
if (inj_recovered && (0 == errsts)) {
mk_sense_buffer(devip, RECOVERED_ERROR,
@@ -545,28 +549,6 @@ int scsi_debug_queuecommand(struct scsi_cmnd * SCpnt, done_funct_t done)
case WRITE_BUFFER:
errsts = check_readiness(SCpnt, 1, devip);
break;
- case XDWRITEREAD_10:
- if (!scsi_bidi_cmnd(SCpnt)) {
- mk_sense_buffer(devip, ILLEGAL_REQUEST,
- INVALID_FIELD_IN_CDB, 0);
- errsts = check_condition_result;
- break;
- }
-
- errsts = check_readiness(SCpnt, 0, devip);
- if (errsts)
- break;
- if (scsi_debug_fake_rw)
- break;
- get_data_transfer_info(cmd, &lba, &num);
- errsts = resp_read(SCpnt, lba, num, devip);
- if (errsts)
- break;
- errsts = resp_write(SCpnt, lba, num, devip);
- if (errsts)
- break;
- errsts = resp_xdwriteread(SCpnt, lba, num, devip);
- break;
default:
if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts)
printk(KERN_INFO "scsi_debug: Opcode: 0x%x not "
@@ -619,18 +601,18 @@ static int fill_from_dev_buffer(struct scsi_cmnd * scp, unsigned char * arr,
int k, req_len, act_len, len, active;
void * kaddr;
void * kaddr_off;
- struct scatterlist *sg;
- struct scsi_data_buffer *sdb = scsi_in(scp);
+ struct scatterlist * sg;
- if (!sdb->length)
+ if (0 == scsi_bufflen(scp))
return 0;
- if (!sdb->table.sgl)
+ if (NULL == scsi_sglist(scp))
return (DID_ERROR << 16);
- if (!(scsi_bidi_cmnd(scp) || scp->sc_data_direction == DMA_FROM_DEVICE))
+ if (! ((scp->sc_data_direction == DMA_BIDIRECTIONAL) ||
+ (scp->sc_data_direction == DMA_FROM_DEVICE)))
return (DID_ERROR << 16);
active = 1;
req_len = act_len = 0;
- for_each_sg(sdb->table.sgl, sg, sdb->table.nents, k) {
+ scsi_for_each_sg(scp, sg, scsi_sg_count(scp), k) {
if (active) {
kaddr = (unsigned char *)
kmap_atomic(sg_page(sg), KM_USER0);
@@ -648,10 +630,10 @@ static int fill_from_dev_buffer(struct scsi_cmnd * scp, unsigned char * arr,
}
req_len += sg->length;
}
- if (sdb->resid)
- sdb->resid -= act_len;
+ if (scsi_get_resid(scp))
+ scsi_set_resid(scp, scsi_get_resid(scp) - act_len);
else
- sdb->resid = req_len - act_len;
+ scsi_set_resid(scp, req_len - act_len);
return 0;
}
@@ -668,7 +650,8 @@ static int fetch_to_dev_buffer(struct scsi_cmnd * scp, unsigned char * arr,
return 0;
if (NULL == scsi_sglist(scp))
return -1;
- if (!(scsi_bidi_cmnd(scp) || scp->sc_data_direction == DMA_TO_DEVICE))
+ if (! ((scp->sc_data_direction == DMA_BIDIRECTIONAL) ||
+ (scp->sc_data_direction == DMA_TO_DEVICE)))
return -1;
req_len = fin = 0;
scsi_for_each_sg(scp, sg, scsi_sg_count(scp), k) {
@@ -1973,50 +1956,6 @@ static int resp_report_luns(struct scsi_cmnd * scp,
min((int)alloc_len, SDEBUG_RLUN_ARR_SZ));
}
-static int resp_xdwriteread(struct scsi_cmnd *scp, unsigned long long lba,
- unsigned int num, struct sdebug_dev_info *devip)
-{
- int i, j, ret = -1;
- unsigned char *kaddr, *buf;
- unsigned int offset;
- struct scatterlist *sg;
- struct scsi_data_buffer *sdb = scsi_in(scp);
-
- /* better not to use temporary buffer. */
- buf = kmalloc(scsi_bufflen(scp), GFP_ATOMIC);
- if (!buf)
- return ret;
-
- offset = 0;
- scsi_for_each_sg(scp, sg, scsi_sg_count(scp), i) {
- kaddr = (unsigned char *)kmap_atomic(sg_page(sg), KM_USER0);
- if (!kaddr)
- goto out;
-
- memcpy(buf + offset, kaddr + sg->offset, sg->length);
- offset += sg->length;
- kunmap_atomic(kaddr, KM_USER0);
- }
-
- offset = 0;
- for_each_sg(sdb->table.sgl, sg, sdb->table.nents, i) {
- kaddr = (unsigned char *)kmap_atomic(sg_page(sg), KM_USER0);
- if (!kaddr)
- goto out;
-
- for (j = 0; j < sg->length; j++)
- *(kaddr + sg->offset + j) ^= *(buf + offset + j);
-
- offset += sg->length;
- kunmap_atomic(kaddr, KM_USER0);
- }
- ret = 0;
-out:
- kfree(buf);
-
- return ret;
-}
-
/* When timer goes off this function is called. */
static void timer_intr_handler(unsigned long indx)
{
@@ -2050,7 +1989,6 @@ static int scsi_debug_slave_alloc(struct scsi_device * sdp)
if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts)
printk(KERN_INFO "scsi_debug: slave_alloc <%u %u %u %u>\n",
sdp->host->host_no, sdp->channel, sdp->id, sdp->lun);
- set_bit(QUEUE_FLAG_BIDI, &sdp->request_queue->queue_flags);
return 0;
}
diff --git a/trunk/drivers/scsi/scsi_error.c b/trunk/drivers/scsi/scsi_error.c
index 045a0868fc7b..547e85aa414f 100644
--- a/trunk/drivers/scsi/scsi_error.c
+++ b/trunk/drivers/scsi/scsi_error.c
@@ -617,27 +617,29 @@ void scsi_eh_prep_cmnd(struct scsi_cmnd *scmd, struct scsi_eh_save *ses,
ses->cmd_len = scmd->cmd_len;
memcpy(ses->cmnd, scmd->cmnd, sizeof(scmd->cmnd));
ses->data_direction = scmd->sc_data_direction;
- ses->sdb = scmd->sdb;
- ses->next_rq = scmd->request->next_rq;
+ ses->bufflen = scmd->request_bufflen;
+ ses->buffer = scmd->request_buffer;
+ ses->use_sg = scmd->use_sg;
+ ses->resid = scmd->resid;
ses->result = scmd->result;
- memset(&scmd->sdb, 0, sizeof(scmd->sdb));
- scmd->request->next_rq = NULL;
-
if (sense_bytes) {
- scmd->sdb.length = min_t(unsigned, SCSI_SENSE_BUFFERSIZE,
- sense_bytes);
+ scmd->request_bufflen = min_t(unsigned,
+ SCSI_SENSE_BUFFERSIZE, sense_bytes);
sg_init_one(&ses->sense_sgl, scmd->sense_buffer,
- scmd->sdb.length);
- scmd->sdb.table.sgl = &ses->sense_sgl;
+ scmd->request_bufflen);
+ scmd->request_buffer = &ses->sense_sgl;
scmd->sc_data_direction = DMA_FROM_DEVICE;
- scmd->sdb.table.nents = 1;
+ scmd->use_sg = 1;
memset(scmd->cmnd, 0, sizeof(scmd->cmnd));
scmd->cmnd[0] = REQUEST_SENSE;
- scmd->cmnd[4] = scmd->sdb.length;
+ scmd->cmnd[4] = scmd->request_bufflen;
scmd->cmd_len = COMMAND_SIZE(scmd->cmnd[0]);
} else {
+ scmd->request_buffer = NULL;
+ scmd->request_bufflen = 0;
scmd->sc_data_direction = DMA_NONE;
+ scmd->use_sg = 0;
if (cmnd) {
memset(scmd->cmnd, 0, sizeof(scmd->cmnd));
memcpy(scmd->cmnd, cmnd, cmnd_size);
@@ -674,8 +676,10 @@ void scsi_eh_restore_cmnd(struct scsi_cmnd* scmd, struct scsi_eh_save *ses)
scmd->cmd_len = ses->cmd_len;
memcpy(scmd->cmnd, ses->cmnd, sizeof(scmd->cmnd));
scmd->sc_data_direction = ses->data_direction;
- scmd->sdb = ses->sdb;
- scmd->request->next_rq = ses->next_rq;
+ scmd->request_bufflen = ses->bufflen;
+ scmd->request_buffer = ses->buffer;
+ scmd->use_sg = ses->use_sg;
+ scmd->resid = ses->resid;
scmd->result = ses->result;
}
EXPORT_SYMBOL(scsi_eh_restore_cmnd);
@@ -1696,7 +1700,8 @@ scsi_reset_provider(struct scsi_device *dev, int flag)
memset(&scmd->cmnd, '\0', sizeof(scmd->cmnd));
scmd->scsi_done = scsi_reset_provider_done_command;
- memset(&scmd->sdb, 0, sizeof(scmd->sdb));
+ scmd->request_buffer = NULL;
+ scmd->request_bufflen = 0;
scmd->cmd_len = 0;
diff --git a/trunk/drivers/scsi/scsi_lib.c b/trunk/drivers/scsi/scsi_lib.c
index b12fb310e399..7c4c889c5221 100644
--- a/trunk/drivers/scsi/scsi_lib.c
+++ b/trunk/drivers/scsi/scsi_lib.c
@@ -8,7 +8,6 @@
*/
#include
-#include
#include
#include
#include
@@ -35,6 +34,13 @@
#define SG_MEMPOOL_NR ARRAY_SIZE(scsi_sg_pools)
#define SG_MEMPOOL_SIZE 2
+/*
+ * The maximum number of SG segments that we will put inside a scatterlist
+ * (unless chaining is used). Should ideally fit inside a single page, to
+ * avoid a higher order allocation.
+ */
+#define SCSI_MAX_SG_SEGMENTS 128
+
struct scsi_host_sg_pool {
size_t size;
char *name;
@@ -42,31 +48,22 @@ struct scsi_host_sg_pool {
mempool_t *pool;
};
-#define SP(x) { x, "sgpool-" __stringify(x) }
-#if (SCSI_MAX_SG_SEGMENTS < 32)
-#error SCSI_MAX_SG_SEGMENTS is too small (must be 32 or greater)
-#endif
+#define SP(x) { x, "sgpool-" #x }
static struct scsi_host_sg_pool scsi_sg_pools[] = {
SP(8),
SP(16),
-#if (SCSI_MAX_SG_SEGMENTS > 32)
+#if (SCSI_MAX_SG_SEGMENTS > 16)
SP(32),
-#if (SCSI_MAX_SG_SEGMENTS > 64)
+#if (SCSI_MAX_SG_SEGMENTS > 32)
SP(64),
-#if (SCSI_MAX_SG_SEGMENTS > 128)
+#if (SCSI_MAX_SG_SEGMENTS > 64)
SP(128),
-#if (SCSI_MAX_SG_SEGMENTS > 256)
-#error SCSI_MAX_SG_SEGMENTS is too large (256 MAX)
-#endif
#endif
#endif
#endif
- SP(SCSI_MAX_SG_SEGMENTS)
};
#undef SP
-static struct kmem_cache *scsi_bidi_sdb_cache;
-
static void scsi_run_queue(struct request_queue *q);
/*
@@ -443,7 +440,7 @@ EXPORT_SYMBOL_GPL(scsi_execute_async);
static void scsi_init_cmd_errh(struct scsi_cmnd *cmd)
{
cmd->serial_number = 0;
- scsi_set_resid(cmd, 0);
+ cmd->resid = 0;
memset(cmd->sense_buffer, 0, SCSI_SENSE_BUFFERSIZE);
if (cmd->cmd_len == 0)
cmd->cmd_len = COMMAND_SIZE(cmd->cmnd[0]);
@@ -693,16 +690,42 @@ static struct scsi_cmnd *scsi_end_request(struct scsi_cmnd *cmd, int error,
return NULL;
}
+/*
+ * Like SCSI_MAX_SG_SEGMENTS, but for archs that have sg chaining. This limit
+ * is totally arbitrary, a setting of 2048 will get you at least 8mb ios.
+ */
+#define SCSI_MAX_SG_CHAIN_SEGMENTS 2048
+
static inline unsigned int scsi_sgtable_index(unsigned short nents)
{
unsigned int index;
- BUG_ON(nents > SCSI_MAX_SG_SEGMENTS);
-
- if (nents <= 8)
+ switch (nents) {
+ case 1 ... 8:
index = 0;
- else
- index = get_count_order(nents) - 3;
+ break;
+ case 9 ... 16:
+ index = 1;
+ break;
+#if (SCSI_MAX_SG_SEGMENTS > 16)
+ case 17 ... 32:
+ index = 2;
+ break;
+#if (SCSI_MAX_SG_SEGMENTS > 32)
+ case 33 ... 64:
+ index = 3;
+ break;
+#if (SCSI_MAX_SG_SEGMENTS > 64)
+ case 65 ... 128:
+ index = 4;
+ break;
+#endif
+#endif
+#endif
+ default:
+ printk(KERN_ERR "scsi: bad segment count=%d\n", nents);
+ BUG();
+ }
return index;
}
@@ -723,27 +746,31 @@ static struct scatterlist *scsi_sg_alloc(unsigned int nents, gfp_t gfp_mask)
return mempool_alloc(sgp->pool, gfp_mask);
}
-static int scsi_alloc_sgtable(struct scsi_data_buffer *sdb, int nents,
- gfp_t gfp_mask)
+int scsi_alloc_sgtable(struct scsi_cmnd *cmd, gfp_t gfp_mask)
{
int ret;
- BUG_ON(!nents);
+ BUG_ON(!cmd->use_sg);
- ret = __sg_alloc_table(&sdb->table, nents, SCSI_MAX_SG_SEGMENTS,
- gfp_mask, scsi_sg_alloc);
+ ret = __sg_alloc_table(&cmd->sg_table, cmd->use_sg,
+ SCSI_MAX_SG_SEGMENTS, gfp_mask, scsi_sg_alloc);
if (unlikely(ret))
- __sg_free_table(&sdb->table, SCSI_MAX_SG_SEGMENTS,
+ __sg_free_table(&cmd->sg_table, SCSI_MAX_SG_SEGMENTS,
scsi_sg_free);
+ cmd->request_buffer = cmd->sg_table.sgl;
return ret;
}
-static void scsi_free_sgtable(struct scsi_data_buffer *sdb)
+EXPORT_SYMBOL(scsi_alloc_sgtable);
+
+void scsi_free_sgtable(struct scsi_cmnd *cmd)
{
- __sg_free_table(&sdb->table, SCSI_MAX_SG_SEGMENTS, scsi_sg_free);
+ __sg_free_table(&cmd->sg_table, SCSI_MAX_SG_SEGMENTS, scsi_sg_free);
}
+EXPORT_SYMBOL(scsi_free_sgtable);
+
/*
* Function: scsi_release_buffers()
*
@@ -761,49 +788,17 @@ static void scsi_free_sgtable(struct scsi_data_buffer *sdb)
* the scatter-gather table, and potentially any bounce
* buffers.
*/
-void scsi_release_buffers(struct scsi_cmnd *cmd)
-{
- if (cmd->sdb.table.nents)
- scsi_free_sgtable(&cmd->sdb);
-
- memset(&cmd->sdb, 0, sizeof(cmd->sdb));
-
- if (scsi_bidi_cmnd(cmd)) {
- struct scsi_data_buffer *bidi_sdb =
- cmd->request->next_rq->special;
- scsi_free_sgtable(bidi_sdb);
- kmem_cache_free(scsi_bidi_sdb_cache, bidi_sdb);
- cmd->request->next_rq->special = NULL;
- }
-}
-EXPORT_SYMBOL(scsi_release_buffers);
-
-/*
- * Bidi commands Must be complete as a whole, both sides at once.
- * If part of the bytes were written and lld returned
- * scsi_in()->resid and/or scsi_out()->resid this information will be left
- * in req->data_len and req->next_rq->data_len. The upper-layer driver can
- * decide what to do with this information.
- */
-void scsi_end_bidi_request(struct scsi_cmnd *cmd)
+static void scsi_release_buffers(struct scsi_cmnd *cmd)
{
- struct request *req = cmd->request;
- unsigned int dlen = req->data_len;
- unsigned int next_dlen = req->next_rq->data_len;
-
- req->data_len = scsi_out(cmd)->resid;
- req->next_rq->data_len = scsi_in(cmd)->resid;
-
- /* The req and req->next_rq have not been completed */
- BUG_ON(blk_end_bidi_request(req, 0, dlen, next_dlen));
-
- scsi_release_buffers(cmd);
+ if (cmd->use_sg)
+ scsi_free_sgtable(cmd);
/*
- * This will goose the queue request function at the end, so we don't
- * need to worry about launching another command.
+ * Zero these out. They now point to freed memory, and it is
+ * dangerous to hang onto the pointers.
*/
- scsi_next_command(cmd);
+ cmd->request_buffer = NULL;
+ cmd->request_bufflen = 0;
}
/*
@@ -837,7 +832,7 @@ void scsi_end_bidi_request(struct scsi_cmnd *cmd)
void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes)
{
int result = cmd->result;
- int this_count = scsi_bufflen(cmd);
+ int this_count = cmd->request_bufflen;
struct request_queue *q = cmd->device->request_queue;
struct request *req = cmd->request;
int clear_errors = 1;
@@ -845,6 +840,8 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes)
int sense_valid = 0;
int sense_deferred = 0;
+ scsi_release_buffers(cmd);
+
if (result) {
sense_valid = scsi_command_normalize_sense(cmd, &sshdr);
if (sense_valid)
@@ -867,17 +864,9 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes)
req->sense_len = len;
}
}
- if (scsi_bidi_cmnd(cmd)) {
- /* will also release_buffers */
- scsi_end_bidi_request(cmd);
- return;
- }
- req->data_len = scsi_get_resid(cmd);
+ req->data_len = cmd->resid;
}
- BUG_ON(blk_bidi_rq(req)); /* bidi not support for !blk_pc_request yet */
- scsi_release_buffers(cmd);
-
/*
* Next deal with any sectors which we were able to correctly
* handle.
@@ -885,6 +874,7 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes)
SCSI_LOG_HLCOMPLETE(1, printk("%ld sectors total, "
"%d bytes done.\n",
req->nr_sectors, good_bytes));
+ SCSI_LOG_HLCOMPLETE(1, printk("use_sg is %d\n", cmd->use_sg));
if (clear_errors)
req->errors = 0;
@@ -1001,80 +991,52 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes)
scsi_end_request(cmd, -EIO, this_count, !result);
}
-static int scsi_init_sgtable(struct request *req, struct scsi_data_buffer *sdb,
- gfp_t gfp_mask)
+/*
+ * Function: scsi_init_io()
+ *
+ * Purpose: SCSI I/O initialize function.
+ *
+ * Arguments: cmd - Command descriptor we wish to initialize
+ *
+ * Returns: 0 on success
+ * BLKPREP_DEFER if the failure is retryable
+ */
+static int scsi_init_io(struct scsi_cmnd *cmd)
{
- int count;
+ struct request *req = cmd->request;
+ int count;
+
+ /*
+ * We used to not use scatter-gather for single segment request,
+ * but now we do (it makes highmem I/O easier to support without
+ * kmapping pages)
+ */
+ cmd->use_sg = req->nr_phys_segments;
/*
* If sg table allocation fails, requeue request later.
*/
- if (unlikely(scsi_alloc_sgtable(sdb, req->nr_phys_segments,
- gfp_mask))) {
+ if (unlikely(scsi_alloc_sgtable(cmd, GFP_ATOMIC))) {
+ scsi_unprep_request(req);
return BLKPREP_DEFER;
}
req->buffer = NULL;
if (blk_pc_request(req))
- sdb->length = req->data_len;
+ cmd->request_bufflen = req->data_len;
else
- sdb->length = req->nr_sectors << 9;
+ cmd->request_bufflen = req->nr_sectors << 9;
/*
* Next, walk the list, and fill in the addresses and sizes of
* each segment.
*/
- count = blk_rq_map_sg(req->q, req, sdb->table.sgl);
- BUG_ON(count > sdb->table.nents);
- sdb->table.nents = count;
+ count = blk_rq_map_sg(req->q, req, cmd->request_buffer);
+ BUG_ON(count > cmd->use_sg);
+ cmd->use_sg = count;
return BLKPREP_OK;
}
-/*
- * Function: scsi_init_io()
- *
- * Purpose: SCSI I/O initialize function.
- *
- * Arguments: cmd - Command descriptor we wish to initialize
- *
- * Returns: 0 on success
- * BLKPREP_DEFER if the failure is retryable
- * BLKPREP_KILL if the failure is fatal
- */
-int scsi_init_io(struct scsi_cmnd *cmd, gfp_t gfp_mask)
-{
- int error = scsi_init_sgtable(cmd->request, &cmd->sdb, gfp_mask);
- if (error)
- goto err_exit;
-
- if (blk_bidi_rq(cmd->request)) {
- struct scsi_data_buffer *bidi_sdb = kmem_cache_zalloc(
- scsi_bidi_sdb_cache, GFP_ATOMIC);
- if (!bidi_sdb) {
- error = BLKPREP_DEFER;
- goto err_exit;
- }
-
- cmd->request->next_rq->special = bidi_sdb;
- error = scsi_init_sgtable(cmd->request->next_rq, bidi_sdb,
- GFP_ATOMIC);
- if (error)
- goto err_exit;
- }
-
- return BLKPREP_OK ;
-
-err_exit:
- scsi_release_buffers(cmd);
- if (error == BLKPREP_KILL)
- scsi_put_command(cmd);
- else /* BLKPREP_DEFER */
- scsi_unprep_request(cmd->request);
-
- return error;
-}
-EXPORT_SYMBOL(scsi_init_io);
-
static struct scsi_cmnd *scsi_get_cmd_from_req(struct scsi_device *sdev,
struct request *req)
{
@@ -1119,14 +1081,16 @@ int scsi_setup_blk_pc_cmnd(struct scsi_device *sdev, struct request *req)
BUG_ON(!req->nr_phys_segments);
- ret = scsi_init_io(cmd, GFP_ATOMIC);
+ ret = scsi_init_io(cmd);
if (unlikely(ret))
return ret;
} else {
BUG_ON(req->data_len);
BUG_ON(req->data);
- memset(&cmd->sdb, 0, sizeof(cmd->sdb));
+ cmd->request_bufflen = 0;
+ cmd->request_buffer = NULL;
+ cmd->use_sg = 0;
req->buffer = NULL;
}
@@ -1168,7 +1132,7 @@ int scsi_setup_fs_cmnd(struct scsi_device *sdev, struct request *req)
if (unlikely(!cmd))
return BLKPREP_DEFER;
- return scsi_init_io(cmd, GFP_ATOMIC);
+ return scsi_init_io(cmd);
}
EXPORT_SYMBOL(scsi_setup_fs_cmnd);
@@ -1578,7 +1542,20 @@ struct request_queue *__scsi_alloc_queue(struct Scsi_Host *shost,
* this limit is imposed by hardware restrictions
*/
blk_queue_max_hw_segments(q, shost->sg_tablesize);
- blk_queue_max_phys_segments(q, SCSI_MAX_SG_CHAIN_SEGMENTS);
+
+ /*
+ * In the future, sg chaining support will be mandatory and this
+ * ifdef can then go away. Right now we don't have all archs
+ * converted, so better keep it safe.
+ */
+#ifdef ARCH_HAS_SG_CHAIN
+ if (shost->use_sg_chaining)
+ blk_queue_max_phys_segments(q, SCSI_MAX_SG_CHAIN_SEGMENTS);
+ else
+ blk_queue_max_phys_segments(q, SCSI_MAX_SG_SEGMENTS);
+#else
+ blk_queue_max_phys_segments(q, SCSI_MAX_SG_SEGMENTS);
+#endif
blk_queue_max_sectors(q, shost->max_sectors);
blk_queue_bounce_limit(q, scsi_calculate_bounce_limit(shost));
@@ -1677,14 +1654,6 @@ int __init scsi_init_queue(void)
return -ENOMEM;
}
- scsi_bidi_sdb_cache = kmem_cache_create("scsi_bidi_sdb",
- sizeof(struct scsi_data_buffer),
- 0, 0, NULL);
- if (!scsi_bidi_sdb_cache) {
- printk(KERN_ERR "SCSI: can't init scsi bidi sdb cache\n");
- goto cleanup_io_context;
- }
-
for (i = 0; i < SG_MEMPOOL_NR; i++) {
struct scsi_host_sg_pool *sgp = scsi_sg_pools + i;
int size = sgp->size * sizeof(struct scatterlist);
@@ -1694,7 +1663,6 @@ int __init scsi_init_queue(void)
if (!sgp->slab) {
printk(KERN_ERR "SCSI: can't init sg slab %s\n",
sgp->name);
- goto cleanup_bidi_sdb;
}
sgp->pool = mempool_create_slab_pool(SG_MEMPOOL_SIZE,
@@ -1702,25 +1670,10 @@ int __init scsi_init_queue(void)
if (!sgp->pool) {
printk(KERN_ERR "SCSI: can't init sg mempool %s\n",
sgp->name);
- goto cleanup_bidi_sdb;
}
}
return 0;
-
-cleanup_bidi_sdb:
- for (i = 0; i < SG_MEMPOOL_NR; i++) {
- struct scsi_host_sg_pool *sgp = scsi_sg_pools + i;
- if (sgp->pool)
- mempool_destroy(sgp->pool);
- if (sgp->slab)
- kmem_cache_destroy(sgp->slab);
- }
- kmem_cache_destroy(scsi_bidi_sdb_cache);
-cleanup_io_context:
- kmem_cache_destroy(scsi_io_context_cache);
-
- return -ENOMEM;
}
void scsi_exit_queue(void)
@@ -1728,7 +1681,6 @@ void scsi_exit_queue(void)
int i;
kmem_cache_destroy(scsi_io_context_cache);
- kmem_cache_destroy(scsi_bidi_sdb_cache);
for (i = 0; i < SG_MEMPOOL_NR; i++) {
struct scsi_host_sg_pool *sgp = scsi_sg_pools + i;
diff --git a/trunk/drivers/scsi/scsi_tgt_lib.c b/trunk/drivers/scsi/scsi_tgt_lib.c
index 91630baea532..01e03f3f6ffa 100644
--- a/trunk/drivers/scsi/scsi_tgt_lib.c
+++ b/trunk/drivers/scsi/scsi_tgt_lib.c
@@ -331,7 +331,8 @@ static void scsi_tgt_cmd_done(struct scsi_cmnd *cmd)
scsi_tgt_uspace_send_status(cmd, tcmd->itn_id, tcmd->tag);
- scsi_release_buffers(cmd);
+ if (scsi_sglist(cmd))
+ scsi_free_sgtable(cmd);
queue_work(scsi_tgtd, &tcmd->work);
}
@@ -352,6 +353,25 @@ static int scsi_tgt_transfer_response(struct scsi_cmnd *cmd)
return 0;
}
+static int scsi_tgt_init_cmd(struct scsi_cmnd *cmd, gfp_t gfp_mask)
+{
+ struct request *rq = cmd->request;
+ int count;
+
+ cmd->use_sg = rq->nr_phys_segments;
+ if (scsi_alloc_sgtable(cmd, gfp_mask))
+ return -ENOMEM;
+
+ cmd->request_bufflen = rq->data_len;
+
+ dprintk("cmd %p cnt %d %lu\n", cmd, scsi_sg_count(cmd),
+ rq_data_dir(rq));
+ count = blk_rq_map_sg(rq->q, rq, scsi_sglist(cmd));
+ BUG_ON(count > cmd->use_sg);
+ cmd->use_sg = count;
+ return 0;
+}
+
/* TODO: test this crap and replace bio_map_user with new interface maybe */
static int scsi_map_user_pages(struct scsi_tgt_cmd *tcmd, struct scsi_cmnd *cmd,
unsigned long uaddr, unsigned int len, int rw)
@@ -377,11 +397,9 @@ static int scsi_map_user_pages(struct scsi_tgt_cmd *tcmd, struct scsi_cmnd *cmd,
}
tcmd->bio = rq->bio;
- err = scsi_init_io(cmd, GFP_KERNEL);
- if (err) {
- scsi_release_buffers(cmd);
+ err = scsi_tgt_init_cmd(cmd, GFP_KERNEL);
+ if (err)
goto unmap_rq;
- }
return 0;
diff --git a/trunk/drivers/scsi/sd.c b/trunk/drivers/scsi/sd.c
index 51a5557f42dd..24eba3118b5a 100644
--- a/trunk/drivers/scsi/sd.c
+++ b/trunk/drivers/scsi/sd.c
@@ -519,7 +519,7 @@ static int sd_prep_fn(struct request_queue *q, struct request *rq)
SCpnt->cmnd[4] = (unsigned char) this_count;
SCpnt->cmnd[5] = 0;
}
- SCpnt->sdb.length = this_count * sdp->sector_size;
+ SCpnt->request_bufflen = this_count * sdp->sector_size;
/*
* We shouldn't disconnect in the middle of a sector, so with a dumb
@@ -926,7 +926,7 @@ static struct block_device_operations sd_fops = {
static int sd_done(struct scsi_cmnd *SCpnt)
{
int result = SCpnt->result;
- unsigned int xfer_size = scsi_bufflen(SCpnt);
+ unsigned int xfer_size = SCpnt->request_bufflen;
unsigned int good_bytes = result ? 0 : xfer_size;
u64 start_lba = SCpnt->request->sector;
u64 bad_lba;
diff --git a/trunk/drivers/scsi/sgiwd93.c b/trunk/drivers/scsi/sgiwd93.c
index 26cfc56c7091..d4ebe8c67ba9 100644
--- a/trunk/drivers/scsi/sgiwd93.c
+++ b/trunk/drivers/scsi/sgiwd93.c
@@ -33,9 +33,10 @@
struct ip22_hostdata {
struct WD33C93_hostdata wh;
- dma_addr_t dma;
- void *cpu;
- struct device *dev;
+ struct hpc_data {
+ dma_addr_t dma;
+ void *cpu;
+ } hd;
};
#define host_to_hostdata(host) ((struct ip22_hostdata *)((host)->hostdata))
@@ -45,11 +46,6 @@ struct hpc_chunk {
u32 _padding; /* align to quadword boundary */
};
-/* space for hpc dma descriptors */
-#define HPC_DMA_SIZE PAGE_SIZE
-
-#define DMA_DIR(d) ((d == DATA_OUT_DIR) ? DMA_TO_DEVICE : DMA_FROM_DEVICE)
-
static irqreturn_t sgiwd93_intr(int irq, void *dev_id)
{
struct Scsi_Host * host = dev_id;
@@ -63,17 +59,15 @@ static irqreturn_t sgiwd93_intr(int irq, void *dev_id)
}
static inline
-void fill_hpc_entries(struct ip22_hostdata *hd, struct scsi_cmnd *cmd, int din)
+void fill_hpc_entries(struct hpc_chunk *hcp, struct scsi_cmnd *cmd, int datainp)
{
unsigned long len = cmd->SCp.this_residual;
void *addr = cmd->SCp.ptr;
dma_addr_t physaddr;
unsigned long count;
- struct hpc_chunk *hcp;
- physaddr = dma_map_single(hd->dev, addr, len, DMA_DIR(din));
+ physaddr = dma_map_single(NULL, addr, len, cmd->sc_data_direction);
cmd->SCp.dma_handle = physaddr;
- hcp = hd->cpu;
while (len) {
/*
@@ -95,9 +89,6 @@ void fill_hpc_entries(struct ip22_hostdata *hd, struct scsi_cmnd *cmd, int din)
*/
hcp->desc.pbuf = 0;
hcp->desc.cntinfo = HPCDMA_EOX;
- dma_cache_sync(hd->dev, hd->cpu,
- (unsigned long)(hcp + 1) - (unsigned long)hd->cpu,
- DMA_TO_DEVICE);
}
static int dma_setup(struct scsi_cmnd *cmd, int datainp)
@@ -105,8 +96,9 @@ static int dma_setup(struct scsi_cmnd *cmd, int datainp)
struct ip22_hostdata *hdata = host_to_hostdata(cmd->device->host);
struct hpc3_scsiregs *hregs =
(struct hpc3_scsiregs *) cmd->device->host->base;
+ struct hpc_chunk *hcp = (struct hpc_chunk *) hdata->hd.cpu;
- pr_debug("dma_setup: datainp<%d> hcp<%p> ", datainp, hdata->cpu);
+ pr_debug("dma_setup: datainp<%d> hcp<%p> ", datainp, hcp);
hdata->wh.dma_dir = datainp;
@@ -119,12 +111,12 @@ static int dma_setup(struct scsi_cmnd *cmd, int datainp)
if (cmd->SCp.ptr == NULL || cmd->SCp.this_residual == 0)
return 1;
- fill_hpc_entries(hdata, cmd, datainp);
+ fill_hpc_entries(hcp, cmd, datainp);
pr_debug(" HPCGO\n");
/* Start up the HPC. */
- hregs->ndptr = hdata->dma;
+ hregs->ndptr = hdata->hd.dma;
if (datainp)
hregs->ctrl = HPC3_SCTRL_ACTIVE;
else
@@ -142,9 +134,6 @@ static void dma_stop(struct Scsi_Host *instance, struct scsi_cmnd *SCpnt,
if (!SCpnt)
return;
- if (SCpnt->SCp.ptr == NULL || SCpnt->SCp.this_residual == 0)
- return;
-
hregs = (struct hpc3_scsiregs *) SCpnt->device->host->base;
pr_debug("dma_stop: status<%d> ", status);
@@ -156,9 +145,8 @@ static void dma_stop(struct Scsi_Host *instance, struct scsi_cmnd *SCpnt,
barrier();
}
hregs->ctrl = 0;
- dma_unmap_single(hdata->dev, SCpnt->SCp.dma_handle,
- SCpnt->SCp.this_residual,
- DMA_DIR(hdata->wh.dma_dir));
+ dma_unmap_single(NULL, SCpnt->SCp.dma_handle, SCpnt->SCp.this_residual,
+ SCpnt->sc_data_direction);
pr_debug("\n");
}
@@ -173,23 +161,22 @@ void sgiwd93_reset(unsigned long base)
}
EXPORT_SYMBOL_GPL(sgiwd93_reset);
-static inline void init_hpc_chain(struct ip22_hostdata *hdata)
+static inline void init_hpc_chain(struct hpc_data *hd)
{
- struct hpc_chunk *hcp = (struct hpc_chunk *)hdata->cpu;
- dma_addr_t dma = hdata->dma;
+ struct hpc_chunk *hcp = (struct hpc_chunk *) hd->cpu;
+ struct hpc_chunk *dma = (struct hpc_chunk *) hd->dma;
unsigned long start, end;
start = (unsigned long) hcp;
- end = start + HPC_DMA_SIZE;
+ end = start + PAGE_SIZE;
while (start < end) {
- hcp->desc.pnext = (u32) (dma + sizeof(struct hpc_chunk));
+ hcp->desc.pnext = (u32) (dma + 1);
hcp->desc.cntinfo = HPCDMA_EOX;
- hcp++;
- dma += sizeof(struct hpc_chunk);
+ hcp++; dma++;
start += sizeof(struct hpc_chunk);
};
hcp--;
- hcp->desc.pnext = hdata->dma;
+ hcp->desc.pnext = hd->dma;
}
static int sgiwd93_bus_reset(struct scsi_cmnd *cmd)
@@ -248,17 +235,16 @@ static int __init sgiwd93_probe(struct platform_device *pdev)
host->irq = irq;
hdata = host_to_hostdata(host);
- hdata->dev = &pdev->dev;
- hdata->cpu = dma_alloc_noncoherent(&pdev->dev, HPC_DMA_SIZE,
- &hdata->dma, GFP_KERNEL);
- if (!hdata->cpu) {
+ hdata->hd.cpu = dma_alloc_coherent(&pdev->dev, PAGE_SIZE,
+ &hdata->hd.dma, GFP_KERNEL);
+ if (!hdata->hd.cpu) {
printk(KERN_WARNING "sgiwd93: Could not allocate memory for "
"host %d buffer.\n", unit);
err = -ENOMEM;
goto out_put;
}
- init_hpc_chain(hdata);
+ init_hpc_chain(&hdata->hd);
regs.SASR = wdregs + 3;
regs.SCMD = wdregs + 7;
@@ -288,7 +274,7 @@ static int __init sgiwd93_probe(struct platform_device *pdev)
out_irq:
free_irq(irq, host);
out_free:
- dma_free_noncoherent(&pdev->dev, HPC_DMA_SIZE, hdata->cpu, hdata->dma);
+ dma_free_coherent(NULL, PAGE_SIZE, hdata->hd.cpu, hdata->hd.dma);
out_put:
scsi_host_put(host);
out:
@@ -304,7 +290,7 @@ static void __exit sgiwd93_remove(struct platform_device *pdev)
scsi_remove_host(host);
free_irq(pd->irq, host);
- dma_free_noncoherent(&pdev->dev, HPC_DMA_SIZE, hdata->cpu, hdata->dma);
+ dma_free_coherent(&pdev->dev, PAGE_SIZE, hdata->hd.cpu, hdata->hd.dma);
scsi_host_put(host);
}
diff --git a/trunk/drivers/scsi/sr.c b/trunk/drivers/scsi/sr.c
index 50ba49250203..1fcee16fa36d 100644
--- a/trunk/drivers/scsi/sr.c
+++ b/trunk/drivers/scsi/sr.c
@@ -231,7 +231,7 @@ static int sr_media_change(struct cdrom_device_info *cdi, int slot)
static int sr_done(struct scsi_cmnd *SCpnt)
{
int result = SCpnt->result;
- int this_count = scsi_bufflen(SCpnt);
+ int this_count = SCpnt->request_bufflen;
int good_bytes = (result == 0 ? this_count : 0);
int block_sectors = 0;
long error_sector;
@@ -379,18 +379,17 @@ static int sr_prep_fn(struct request_queue *q, struct request *rq)
}
{
- struct scatterlist *sg;
- int i, size = 0, sg_count = scsi_sg_count(SCpnt);
+ struct scatterlist *sg = SCpnt->request_buffer;
+ int i, size = 0;
+ for (i = 0; i < SCpnt->use_sg; i++)
+ size += sg[i].length;
- scsi_for_each_sg(SCpnt, sg, sg_count, i)
- size += sg->length;
-
- if (size != scsi_bufflen(SCpnt)) {
+ if (size != SCpnt->request_bufflen && SCpnt->use_sg) {
scmd_printk(KERN_ERR, SCpnt,
"mismatch count %d, bytes %d\n",
- size, scsi_bufflen(SCpnt));
- if (scsi_bufflen(SCpnt) > size)
- SCpnt->sdb.length = size;
+ size, SCpnt->request_bufflen);
+ if (SCpnt->request_bufflen > size)
+ SCpnt->request_bufflen = size;
}
}
@@ -398,12 +397,12 @@ static int sr_prep_fn(struct request_queue *q, struct request *rq)
* request doesn't start on hw block boundary, add scatter pads
*/
if (((unsigned int)rq->sector % (s_size >> 9)) ||
- (scsi_bufflen(SCpnt) % s_size)) {
+ (SCpnt->request_bufflen % s_size)) {
scmd_printk(KERN_NOTICE, SCpnt, "unaligned transfer\n");
goto out;
}
- this_count = (scsi_bufflen(SCpnt) >> 9) / (s_size >> 9);
+ this_count = (SCpnt->request_bufflen >> 9) / (s_size >> 9);
SCSI_LOG_HLQUEUE(2, printk("%s : %s %d/%ld 512 byte blocks.\n",
@@ -417,7 +416,7 @@ static int sr_prep_fn(struct request_queue *q, struct request *rq)
if (this_count > 0xffff) {
this_count = 0xffff;
- SCpnt->sdb.length = this_count * s_size;
+ SCpnt->request_bufflen = this_count * s_size;
}
SCpnt->cmnd[2] = (unsigned char) (block >> 24) & 0xff;
diff --git a/trunk/drivers/scsi/stex.c b/trunk/drivers/scsi/stex.c
index 72f6d8015358..e3fab3a6aed7 100644
--- a/trunk/drivers/scsi/stex.c
+++ b/trunk/drivers/scsi/stex.c
@@ -1123,6 +1123,7 @@ static struct scsi_host_template driver_template = {
.this_id = -1,
.sg_tablesize = ST_MAX_SG,
.cmd_per_lun = ST_CMD_PER_LUN,
+ .use_sg_chaining = ENABLE_SG_CHAINING,
};
static int stex_set_dma_mask(struct pci_dev * pdev)
diff --git a/trunk/drivers/scsi/sym53c416.c b/trunk/drivers/scsi/sym53c416.c
index 6325901e5093..1f6fd1680335 100644
--- a/trunk/drivers/scsi/sym53c416.c
+++ b/trunk/drivers/scsi/sym53c416.c
@@ -840,5 +840,6 @@ static struct scsi_host_template driver_template = {
.cmd_per_lun = 1,
.unchecked_isa_dma = 1,
.use_clustering = ENABLE_CLUSTERING,
+ .use_sg_chaining = ENABLE_SG_CHAINING,
};
#include "scsi_module.c"
diff --git a/trunk/drivers/scsi/sym53c8xx_2/sym_glue.c b/trunk/drivers/scsi/sym53c8xx_2/sym_glue.c
index d39107b7669b..21e926dcdab0 100644
--- a/trunk/drivers/scsi/sym53c8xx_2/sym_glue.c
+++ b/trunk/drivers/scsi/sym53c8xx_2/sym_glue.c
@@ -207,7 +207,7 @@ void sym_set_cam_result_error(struct sym_hcb *np, struct sym_ccb *cp, int resid)
/*
* Bounce back the sense data to user.
*/
- memset(cmd->sense_buffer, 0, SCSI_SENSE_BUFFERSIZE);
+ memset(&cmd->sense_buffer, 0, SCSI_SENSE_BUFFERSIZE);
memcpy(cmd->sense_buffer, cp->sns_bbuf,
min(SCSI_SENSE_BUFFERSIZE, SYM_SNS_BBUF_LEN));
#if 0
@@ -1681,6 +1681,7 @@ static struct scsi_host_template sym2_template = {
.eh_host_reset_handler = sym53c8xx_eh_host_reset_handler,
.this_id = 7,
.use_clustering = ENABLE_CLUSTERING,
+ .use_sg_chaining = ENABLE_SG_CHAINING,
.max_sectors = 0xFFFF,
#ifdef SYM_LINUX_PROC_INFO_SUPPORT
.proc_info = sym53c8xx_proc_info,
diff --git a/trunk/drivers/scsi/u14-34f.c b/trunk/drivers/scsi/u14-34f.c
index 662c00451be4..4bc5407f9695 100644
--- a/trunk/drivers/scsi/u14-34f.c
+++ b/trunk/drivers/scsi/u14-34f.c
@@ -451,6 +451,7 @@ static struct scsi_host_template driver_template = {
.this_id = 7,
.unchecked_isa_dma = 1,
.use_clustering = ENABLE_CLUSTERING,
+ .use_sg_chaining = ENABLE_SG_CHAINING,
};
#if !defined(__BIG_ENDIAN_BITFIELD) && !defined(__LITTLE_ENDIAN_BITFIELD)
diff --git a/trunk/drivers/scsi/ultrastor.c b/trunk/drivers/scsi/ultrastor.c
index f385dce8dfbe..75eca6b22db5 100644
--- a/trunk/drivers/scsi/ultrastor.c
+++ b/trunk/drivers/scsi/ultrastor.c
@@ -1204,5 +1204,6 @@ static struct scsi_host_template driver_template = {
.cmd_per_lun = ULTRASTOR_MAX_CMDS_PER_LUN,
.unchecked_isa_dma = 1,
.use_clustering = ENABLE_CLUSTERING,
+ .use_sg_chaining = ENABLE_SG_CHAINING,
};
#include "scsi_module.c"
diff --git a/trunk/drivers/scsi/wd7000.c b/trunk/drivers/scsi/wd7000.c
index c975c01b3a02..b4304ae78527 100644
--- a/trunk/drivers/scsi/wd7000.c
+++ b/trunk/drivers/scsi/wd7000.c
@@ -1671,6 +1671,7 @@ static struct scsi_host_template driver_template = {
.cmd_per_lun = 1,
.unchecked_isa_dma = 1,
.use_clustering = ENABLE_CLUSTERING,
+ .use_sg_chaining = ENABLE_SG_CHAINING,
};
#include "scsi_module.c"
diff --git a/trunk/drivers/usb/storage/isd200.c b/trunk/drivers/usb/storage/isd200.c
index 0db488624ab1..178e8c2a8a2f 100644
--- a/trunk/drivers/usb/storage/isd200.c
+++ b/trunk/drivers/usb/storage/isd200.c
@@ -415,14 +415,14 @@ static void isd200_set_srb(struct isd200_info *info,
sg_init_one(&info->sg, buff, bufflen);
srb->sc_data_direction = dir;
- srb->sdb.table.sgl = buff ? &info->sg : NULL;
- srb->sdb.length = bufflen;
- srb->sdb.table.nents = buff ? 1 : 0;
+ srb->request_buffer = buff ? &info->sg : NULL;
+ srb->request_bufflen = bufflen;
+ srb->use_sg = buff ? 1 : 0;
}
static void isd200_srb_set_bufflen(struct scsi_cmnd *srb, unsigned bufflen)
{
- srb->sdb.length = bufflen;
+ srb->request_bufflen = bufflen;
}
diff --git a/trunk/fs/dlm/dir.c b/trunk/fs/dlm/dir.c
index ff97ba924333..46754553fdcc 100644
--- a/trunk/fs/dlm/dir.c
+++ b/trunk/fs/dlm/dir.c
@@ -49,7 +49,7 @@ static struct dlm_direntry *get_free_de(struct dlm_ls *ls, int len)
spin_unlock(&ls->ls_recover_list_lock);
if (!found)
- de = kzalloc(sizeof(struct dlm_direntry) + len, GFP_KERNEL);
+ de = allocate_direntry(ls, len);
return de;
}
@@ -62,7 +62,7 @@ void dlm_clear_free_entries(struct dlm_ls *ls)
de = list_entry(ls->ls_recover_list.next, struct dlm_direntry,
list);
list_del(&de->list);
- kfree(de);
+ free_direntry(de);
}
spin_unlock(&ls->ls_recover_list_lock);
}
@@ -171,7 +171,7 @@ void dlm_dir_remove_entry(struct dlm_ls *ls, int nodeid, char *name, int namelen
}
list_del(&de->list);
- kfree(de);
+ free_direntry(de);
out:
write_unlock(&ls->ls_dirtbl[bucket].lock);
}
@@ -302,7 +302,7 @@ static int get_entry(struct dlm_ls *ls, int nodeid, char *name,
write_unlock(&ls->ls_dirtbl[bucket].lock);
- de = kzalloc(sizeof(struct dlm_direntry) + namelen, GFP_KERNEL);
+ de = allocate_direntry(ls, namelen);
if (!de)
return -ENOMEM;
@@ -313,7 +313,7 @@ static int get_entry(struct dlm_ls *ls, int nodeid, char *name,
write_lock(&ls->ls_dirtbl[bucket].lock);
tmp = search_bucket(ls, name, namelen, bucket);
if (tmp) {
- kfree(de);
+ free_direntry(de);
de = tmp;
} else {
list_add_tail(&de->list, &ls->ls_dirtbl[bucket].list);
@@ -329,48 +329,50 @@ int dlm_dir_lookup(struct dlm_ls *ls, int nodeid, char *name, int namelen,
return get_entry(ls, nodeid, name, namelen, r_nodeid);
}
-static struct dlm_rsb *find_rsb_root(struct dlm_ls *ls, char *name, int len)
-{
- struct dlm_rsb *r;
-
- down_read(&ls->ls_root_sem);
- list_for_each_entry(r, &ls->ls_root_list, res_root_list) {
- if (len == r->res_length && !memcmp(name, r->res_name, len)) {
- up_read(&ls->ls_root_sem);
- return r;
- }
- }
- up_read(&ls->ls_root_sem);
- return NULL;
-}
-
-/* Find the rsb where we left off (or start again), then send rsb names
- for rsb's we're master of and whose directory node matches the requesting
- node. inbuf is the rsb name last sent, inlen is the name's length */
+/* Copy the names of master rsb's into the buffer provided.
+ Only select names whose dir node is the given nodeid. */
void dlm_copy_master_names(struct dlm_ls *ls, char *inbuf, int inlen,
char *outbuf, int outlen, int nodeid)
{
struct list_head *list;
- struct dlm_rsb *r;
- int offset = 0, dir_nodeid;
+ struct dlm_rsb *start_r = NULL, *r = NULL;
+ int offset = 0, start_namelen, error, dir_nodeid;
+ char *start_name;
uint16_t be_namelen;
- down_read(&ls->ls_root_sem);
+ /*
+ * Find the rsb where we left off (or start again)
+ */
- if (inlen > 1) {
- r = find_rsb_root(ls, inbuf, inlen);
- if (!r) {
- inbuf[inlen - 1] = '\0';
- log_error(ls, "copy_master_names from %d start %d %s",
- nodeid, inlen, inbuf);
- goto out;
- }
- list = r->res_root_list.next;
- } else {
- list = ls->ls_root_list.next;
+ start_namelen = inlen;
+ start_name = inbuf;
+
+ if (start_namelen > 1) {
+ /*
+ * We could also use a find_rsb_root() function here that
+ * searched the ls_root_list.
+ */
+ error = dlm_find_rsb(ls, start_name, start_namelen, R_MASTER,
+ &start_r);
+ DLM_ASSERT(!error && start_r,
+ printk("error %d\n", error););
+ DLM_ASSERT(!list_empty(&start_r->res_root_list),
+ dlm_print_rsb(start_r););
+ dlm_put_rsb(start_r);
}
+ /*
+ * Send rsb names for rsb's we're master of and whose directory node
+ * matches the requesting node.
+ */
+
+ down_read(&ls->ls_root_sem);
+ if (start_r)
+ list = start_r->res_root_list.next;
+ else
+ list = ls->ls_root_list.next;
+
for (offset = 0; list != &ls->ls_root_list; list = list->next) {
r = list_entry(list, struct dlm_rsb, res_root_list);
if (r->res_nodeid)
diff --git a/trunk/fs/dlm/dlm_internal.h b/trunk/fs/dlm/dlm_internal.h
index ec61bbaf25df..d2fc2384c3be 100644
--- a/trunk/fs/dlm/dlm_internal.h
+++ b/trunk/fs/dlm/dlm_internal.h
@@ -570,21 +570,5 @@ static inline int dlm_no_directory(struct dlm_ls *ls)
return (ls->ls_exflags & DLM_LSFL_NODIR) ? 1 : 0;
}
-int dlm_netlink_init(void);
-void dlm_netlink_exit(void);
-void dlm_timeout_warn(struct dlm_lkb *lkb);
-
-#ifdef CONFIG_DLM_DEBUG
-int dlm_register_debugfs(void);
-void dlm_unregister_debugfs(void);
-int dlm_create_debug_file(struct dlm_ls *ls);
-void dlm_delete_debug_file(struct dlm_ls *ls);
-#else
-static inline int dlm_register_debugfs(void) { return 0; }
-static inline void dlm_unregister_debugfs(void) { }
-static inline int dlm_create_debug_file(struct dlm_ls *ls) { return 0; }
-static inline void dlm_delete_debug_file(struct dlm_ls *ls) { }
-#endif
-
#endif /* __DLM_INTERNAL_DOT_H__ */
diff --git a/trunk/fs/dlm/lock.c b/trunk/fs/dlm/lock.c
index ff4a198fa677..3915b8e14146 100644
--- a/trunk/fs/dlm/lock.c
+++ b/trunk/fs/dlm/lock.c
@@ -1,7 +1,7 @@
/******************************************************************************
*******************************************************************************
**
-** Copyright (C) 2005-2008 Red Hat, Inc. All rights reserved.
+** Copyright (C) 2005-2007 Red Hat, Inc. All rights reserved.
**
** This copyrighted material is made available to anyone wishing to use,
** modify, copy, or redistribute it subject to the terms and conditions
@@ -88,6 +88,7 @@ static void __receive_convert_reply(struct dlm_rsb *r, struct dlm_lkb *lkb,
static int receive_extralen(struct dlm_message *ms);
static void do_purge(struct dlm_ls *ls, int nodeid, int pid);
static void del_timeout(struct dlm_lkb *lkb);
+void dlm_timeout_warn(struct dlm_lkb *lkb);
/*
* Lock compatibilty matrix - thanks Steve
@@ -334,7 +335,7 @@ static struct dlm_rsb *create_rsb(struct dlm_ls *ls, char *name, int len)
{
struct dlm_rsb *r;
- r = dlm_allocate_rsb(ls, len);
+ r = allocate_rsb(ls, len);
if (!r)
return NULL;
@@ -477,7 +478,7 @@ static int find_rsb(struct dlm_ls *ls, char *name, int namelen,
error = _search_rsb(ls, name, namelen, bucket, 0, &tmp);
if (!error) {
write_unlock(&ls->ls_rsbtbl[bucket].lock);
- dlm_free_rsb(r);
+ free_rsb(r);
r = tmp;
goto out;
}
@@ -489,6 +490,12 @@ static int find_rsb(struct dlm_ls *ls, char *name, int namelen,
return error;
}
+int dlm_find_rsb(struct dlm_ls *ls, char *name, int namelen,
+ unsigned int flags, struct dlm_rsb **r_ret)
+{
+ return find_rsb(ls, name, namelen, flags, r_ret);
+}
+
/* This is only called to add a reference when the code already holds
a valid reference to the rsb, so there's no need for locking. */
@@ -512,7 +519,7 @@ static void toss_rsb(struct kref *kref)
list_move(&r->res_hashchain, &ls->ls_rsbtbl[r->res_bucket].toss);
r->res_toss_time = jiffies;
if (r->res_lvbptr) {
- dlm_free_lvb(r->res_lvbptr);
+ free_lvb(r->res_lvbptr);
r->res_lvbptr = NULL;
}
}
@@ -582,7 +589,7 @@ static int create_lkb(struct dlm_ls *ls, struct dlm_lkb **lkb_ret)
uint32_t lkid = 0;
uint16_t bucket;
- lkb = dlm_allocate_lkb(ls);
+ lkb = allocate_lkb(ls);
if (!lkb)
return -ENOMEM;
@@ -676,8 +683,8 @@ static int __put_lkb(struct dlm_ls *ls, struct dlm_lkb *lkb)
/* for local/process lkbs, lvbptr points to caller's lksb */
if (lkb->lkb_lvbptr && is_master_copy(lkb))
- dlm_free_lvb(lkb->lkb_lvbptr);
- dlm_free_lkb(lkb);
+ free_lvb(lkb->lkb_lvbptr);
+ free_lkb(lkb);
return 1;
} else {
write_unlock(&ls->ls_lkbtbl[bucket].lock);
@@ -981,7 +988,7 @@ static int shrink_bucket(struct dlm_ls *ls, int b)
if (is_master(r))
dir_remove(r);
- dlm_free_rsb(r);
+ free_rsb(r);
count++;
} else {
write_unlock(&ls->ls_rsbtbl[b].lock);
@@ -1164,7 +1171,7 @@ static void set_lvb_lock(struct dlm_rsb *r, struct dlm_lkb *lkb)
return;
if (!r->res_lvbptr)
- r->res_lvbptr = dlm_allocate_lvb(r->res_ls);
+ r->res_lvbptr = allocate_lvb(r->res_ls);
if (!r->res_lvbptr)
return;
@@ -1196,7 +1203,7 @@ static void set_lvb_unlock(struct dlm_rsb *r, struct dlm_lkb *lkb)
return;
if (!r->res_lvbptr)
- r->res_lvbptr = dlm_allocate_lvb(r->res_ls);
+ r->res_lvbptr = allocate_lvb(r->res_ls);
if (!r->res_lvbptr)
return;
@@ -1845,7 +1852,7 @@ static void send_blocking_asts_all(struct dlm_rsb *r, struct dlm_lkb *lkb)
static int set_master(struct dlm_rsb *r, struct dlm_lkb *lkb)
{
struct dlm_ls *ls = r->res_ls;
- int i, error, dir_nodeid, ret_nodeid, our_nodeid = dlm_our_nodeid();
+ int error, dir_nodeid, ret_nodeid, our_nodeid = dlm_our_nodeid();
if (rsb_flag(r, RSB_MASTER_UNCERTAIN)) {
rsb_clear_flag(r, RSB_MASTER_UNCERTAIN);
@@ -1879,7 +1886,7 @@ static int set_master(struct dlm_rsb *r, struct dlm_lkb *lkb)
return 1;
}
- for (i = 0; i < 2; i++) {
+ for (;;) {
/* It's possible for dlm_scand to remove an old rsb for
this same resource from the toss list, us to create
a new one, look up the master locally, and find it
@@ -1893,8 +1900,6 @@ static int set_master(struct dlm_rsb *r, struct dlm_lkb *lkb)
log_debug(ls, "dir_lookup error %d %s", error, r->res_name);
schedule();
}
- if (error && error != -EEXIST)
- return error;
if (ret_nodeid == our_nodeid) {
r->res_first_lkid = 0;
@@ -1936,11 +1941,8 @@ static void confirm_master(struct dlm_rsb *r, int error)
break;
case -EAGAIN:
- case -EBADR:
- case -ENOTBLK:
- /* the remote request failed and won't be retried (it was
- a NOQUEUE, or has been canceled/unlocked); make a waiting
- lkb the first_lkid */
+ /* the remote master didn't queue our NOQUEUE request;
+ make a waiting lkb the first_lkid */
r->res_first_lkid = 0;
@@ -2106,18 +2108,17 @@ static int validate_unlock_args(struct dlm_lkb *lkb, struct dlm_args *args)
/* an lkb may be waiting for an rsb lookup to complete where the
lookup was initiated by another lock */
- if (!list_empty(&lkb->lkb_rsb_lookup)) {
- if (args->flags & (DLM_LKF_CANCEL | DLM_LKF_FORCEUNLOCK)) {
+ if (args->flags & (DLM_LKF_CANCEL | DLM_LKF_FORCEUNLOCK)) {
+ if (!list_empty(&lkb->lkb_rsb_lookup)) {
log_debug(ls, "unlock on rsb_lookup %x", lkb->lkb_id);
list_del_init(&lkb->lkb_rsb_lookup);
queue_cast(lkb->lkb_resource, lkb,
args->flags & DLM_LKF_CANCEL ?
-DLM_ECANCEL : -DLM_EUNLOCK);
unhold_lkb(lkb); /* undoes create_lkb() */
+ rv = -EBUSY;
+ goto out;
}
- /* caller changes -EBUSY to 0 for CANCEL and FORCEUNLOCK */
- rv = -EBUSY;
- goto out;
}
/* cancel not allowed with another cancel/unlock in progress */
@@ -2985,7 +2986,7 @@ static int receive_lvb(struct dlm_ls *ls, struct dlm_lkb *lkb,
if (lkb->lkb_exflags & DLM_LKF_VALBLK) {
if (!lkb->lkb_lvbptr)
- lkb->lkb_lvbptr = dlm_allocate_lvb(ls);
+ lkb->lkb_lvbptr = allocate_lvb(ls);
if (!lkb->lkb_lvbptr)
return -ENOMEM;
len = receive_extralen(ms);
@@ -3005,9 +3006,11 @@ static int receive_request_args(struct dlm_ls *ls, struct dlm_lkb *lkb,
lkb->lkb_bastaddr = (void *) (long) (ms->m_asts & AST_BAST);
lkb->lkb_astaddr = (void *) (long) (ms->m_asts & AST_COMP);
+ DLM_ASSERT(is_master_copy(lkb), dlm_print_lkb(lkb););
+
if (lkb->lkb_exflags & DLM_LKF_VALBLK) {
/* lkb was just created so there won't be an lvb yet */
- lkb->lkb_lvbptr = dlm_allocate_lvb(ls);
+ lkb->lkb_lvbptr = allocate_lvb(ls);
if (!lkb->lkb_lvbptr)
return -ENOMEM;
}
@@ -3018,6 +3021,16 @@ static int receive_request_args(struct dlm_ls *ls, struct dlm_lkb *lkb,
static int receive_convert_args(struct dlm_ls *ls, struct dlm_lkb *lkb,
struct dlm_message *ms)
{
+ if (lkb->lkb_nodeid != ms->m_header.h_nodeid) {
+ log_error(ls, "convert_args nodeid %d %d lkid %x %x",
+ lkb->lkb_nodeid, ms->m_header.h_nodeid,
+ lkb->lkb_id, lkb->lkb_remid);
+ return -EINVAL;
+ }
+
+ if (!is_master_copy(lkb))
+ return -EINVAL;
+
if (lkb->lkb_status != DLM_LKSTS_GRANTED)
return -EBUSY;
@@ -3033,6 +3046,8 @@ static int receive_convert_args(struct dlm_ls *ls, struct dlm_lkb *lkb,
static int receive_unlock_args(struct dlm_ls *ls, struct dlm_lkb *lkb,
struct dlm_message *ms)
{
+ if (!is_master_copy(lkb))
+ return -EINVAL;
if (receive_lvb(ls, lkb, ms))
return -ENOMEM;
return 0;
@@ -3048,50 +3063,6 @@ static void setup_stub_lkb(struct dlm_ls *ls, struct dlm_message *ms)
lkb->lkb_remid = ms->m_lkid;
}
-/* This is called after the rsb is locked so that we can safely inspect
- fields in the lkb. */
-
-static int validate_message(struct dlm_lkb *lkb, struct dlm_message *ms)
-{
- int from = ms->m_header.h_nodeid;
- int error = 0;
-
- switch (ms->m_type) {
- case DLM_MSG_CONVERT:
- case DLM_MSG_UNLOCK:
- case DLM_MSG_CANCEL:
- if (!is_master_copy(lkb) || lkb->lkb_nodeid != from)
- error = -EINVAL;
- break;
-
- case DLM_MSG_CONVERT_REPLY:
- case DLM_MSG_UNLOCK_REPLY:
- case DLM_MSG_CANCEL_REPLY:
- case DLM_MSG_GRANT:
- case DLM_MSG_BAST:
- if (!is_process_copy(lkb) || lkb->lkb_nodeid != from)
- error = -EINVAL;
- break;
-
- case DLM_MSG_REQUEST_REPLY:
- if (!is_process_copy(lkb))
- error = -EINVAL;
- else if (lkb->lkb_nodeid != -1 && lkb->lkb_nodeid != from)
- error = -EINVAL;
- break;
-
- default:
- error = -EINVAL;
- }
-
- if (error)
- log_error(lkb->lkb_resource->res_ls,
- "ignore invalid message %d from %d %x %x %x %d",
- ms->m_type, from, lkb->lkb_id, lkb->lkb_remid,
- lkb->lkb_flags, lkb->lkb_nodeid);
- return error;
-}
-
static void receive_request(struct dlm_ls *ls, struct dlm_message *ms)
{
struct dlm_lkb *lkb;
@@ -3153,21 +3124,17 @@ static void receive_convert(struct dlm_ls *ls, struct dlm_message *ms)
hold_rsb(r);
lock_rsb(r);
- error = validate_message(lkb, ms);
- if (error)
- goto out;
-
receive_flags(lkb, ms);
error = receive_convert_args(ls, lkb, ms);
if (error)
- goto out_reply;
+ goto out;
reply = !down_conversion(lkb);
error = do_convert(r, lkb);
- out_reply:
+ out:
if (reply)
send_convert_reply(r, lkb, error);
- out:
+
unlock_rsb(r);
put_rsb(r);
dlm_put_lkb(lkb);
@@ -3193,19 +3160,15 @@ static void receive_unlock(struct dlm_ls *ls, struct dlm_message *ms)
hold_rsb(r);
lock_rsb(r);
- error = validate_message(lkb, ms);
- if (error)
- goto out;
-
receive_flags(lkb, ms);
error = receive_unlock_args(ls, lkb, ms);
if (error)
- goto out_reply;
+ goto out;
error = do_unlock(r, lkb);
- out_reply:
- send_unlock_reply(r, lkb, error);
out:
+ send_unlock_reply(r, lkb, error);
+
unlock_rsb(r);
put_rsb(r);
dlm_put_lkb(lkb);
@@ -3233,13 +3196,9 @@ static void receive_cancel(struct dlm_ls *ls, struct dlm_message *ms)
hold_rsb(r);
lock_rsb(r);
- error = validate_message(lkb, ms);
- if (error)
- goto out;
-
error = do_cancel(r, lkb);
send_cancel_reply(r, lkb, error);
- out:
+
unlock_rsb(r);
put_rsb(r);
dlm_put_lkb(lkb);
@@ -3258,26 +3217,22 @@ static void receive_grant(struct dlm_ls *ls, struct dlm_message *ms)
error = find_lkb(ls, ms->m_remid, &lkb);
if (error) {
- log_debug(ls, "receive_grant from %d no lkb %x",
- ms->m_header.h_nodeid, ms->m_remid);
+ log_error(ls, "receive_grant no lkb");
return;
}
+ DLM_ASSERT(is_process_copy(lkb), dlm_print_lkb(lkb););
r = lkb->lkb_resource;
hold_rsb(r);
lock_rsb(r);
- error = validate_message(lkb, ms);
- if (error)
- goto out;
-
receive_flags_reply(lkb, ms);
if (is_altmode(lkb))
munge_altmode(lkb, ms);
grant_lock_pc(r, lkb, ms);
queue_cast(r, lkb, 0);
- out:
+
unlock_rsb(r);
put_rsb(r);
dlm_put_lkb(lkb);
@@ -3291,22 +3246,18 @@ static void receive_bast(struct dlm_ls *ls, struct dlm_message *ms)
error = find_lkb(ls, ms->m_remid, &lkb);
if (error) {
- log_debug(ls, "receive_bast from %d no lkb %x",
- ms->m_header.h_nodeid, ms->m_remid);
+ log_error(ls, "receive_bast no lkb");
return;
}
+ DLM_ASSERT(is_process_copy(lkb), dlm_print_lkb(lkb););
r = lkb->lkb_resource;
hold_rsb(r);
lock_rsb(r);
- error = validate_message(lkb, ms);
- if (error)
- goto out;
-
queue_bast(r, lkb, ms->m_bastmode);
- out:
+
unlock_rsb(r);
put_rsb(r);
dlm_put_lkb(lkb);
@@ -3372,19 +3323,15 @@ static void receive_request_reply(struct dlm_ls *ls, struct dlm_message *ms)
error = find_lkb(ls, ms->m_remid, &lkb);
if (error) {
- log_debug(ls, "receive_request_reply from %d no lkb %x",
- ms->m_header.h_nodeid, ms->m_remid);
+ log_error(ls, "receive_request_reply no lkb");
return;
}
+ DLM_ASSERT(is_process_copy(lkb), dlm_print_lkb(lkb););
r = lkb->lkb_resource;
hold_rsb(r);
lock_rsb(r);
- error = validate_message(lkb, ms);
- if (error)
- goto out;
-
mstype = lkb->lkb_wait_type;
error = remove_from_waiters(lkb, DLM_MSG_REQUEST_REPLY);
if (error)
@@ -3436,7 +3383,6 @@ static void receive_request_reply(struct dlm_ls *ls, struct dlm_message *ms)
if (is_overlap(lkb)) {
/* we'll ignore error in cancel/unlock reply */
queue_cast_overlap(r, lkb);
- confirm_master(r, result);
unhold_lkb(lkb); /* undoes create_lkb() */
} else
_request_lock(r, lkb);
@@ -3517,10 +3463,6 @@ static void _receive_convert_reply(struct dlm_lkb *lkb, struct dlm_message *ms)
hold_rsb(r);
lock_rsb(r);
- error = validate_message(lkb, ms);
- if (error)
- goto out;
-
/* stub reply can happen with waiters_mutex held */
error = remove_from_waiters_ms(lkb, ms);
if (error)
@@ -3539,10 +3481,10 @@ static void receive_convert_reply(struct dlm_ls *ls, struct dlm_message *ms)
error = find_lkb(ls, ms->m_remid, &lkb);
if (error) {
- log_debug(ls, "receive_convert_reply from %d no lkb %x",
- ms->m_header.h_nodeid, ms->m_remid);
+ log_error(ls, "receive_convert_reply no lkb");
return;
}
+ DLM_ASSERT(is_process_copy(lkb), dlm_print_lkb(lkb););
_receive_convert_reply(lkb, ms);
dlm_put_lkb(lkb);
@@ -3556,10 +3498,6 @@ static void _receive_unlock_reply(struct dlm_lkb *lkb, struct dlm_message *ms)
hold_rsb(r);
lock_rsb(r);
- error = validate_message(lkb, ms);
- if (error)
- goto out;
-
/* stub reply can happen with waiters_mutex held */
error = remove_from_waiters_ms(lkb, ms);
if (error)
@@ -3591,10 +3529,10 @@ static void receive_unlock_reply(struct dlm_ls *ls, struct dlm_message *ms)
error = find_lkb(ls, ms->m_remid, &lkb);
if (error) {
- log_debug(ls, "receive_unlock_reply from %d no lkb %x",
- ms->m_header.h_nodeid, ms->m_remid);
+ log_error(ls, "receive_unlock_reply no lkb");
return;
}
+ DLM_ASSERT(is_process_copy(lkb), dlm_print_lkb(lkb););
_receive_unlock_reply(lkb, ms);
dlm_put_lkb(lkb);
@@ -3608,10 +3546,6 @@ static void _receive_cancel_reply(struct dlm_lkb *lkb, struct dlm_message *ms)
hold_rsb(r);
lock_rsb(r);
- error = validate_message(lkb, ms);
- if (error)
- goto out;
-
/* stub reply can happen with waiters_mutex held */
error = remove_from_waiters_ms(lkb, ms);
if (error)
@@ -3643,10 +3577,10 @@ static void receive_cancel_reply(struct dlm_ls *ls, struct dlm_message *ms)
error = find_lkb(ls, ms->m_remid, &lkb);
if (error) {
- log_debug(ls, "receive_cancel_reply from %d no lkb %x",
- ms->m_header.h_nodeid, ms->m_remid);
+ log_error(ls, "receive_cancel_reply no lkb");
return;
}
+ DLM_ASSERT(is_process_copy(lkb), dlm_print_lkb(lkb););
_receive_cancel_reply(lkb, ms);
dlm_put_lkb(lkb);
@@ -3706,13 +3640,6 @@ static void receive_lookup_reply(struct dlm_ls *ls, struct dlm_message *ms)
static void _receive_message(struct dlm_ls *ls, struct dlm_message *ms)
{
- if (!dlm_is_member(ls, ms->m_header.h_nodeid)) {
- log_debug(ls, "ignore non-member message %d from %d %x %x %d",
- ms->m_type, ms->m_header.h_nodeid, ms->m_lkid,
- ms->m_remid, ms->m_result);
- return;
- }
-
switch (ms->m_type) {
/* messages sent to a master node */
@@ -3851,9 +3778,8 @@ void dlm_receive_buffer(struct dlm_header *hd, int nodeid)
ls = dlm_find_lockspace_global(hd->h_lockspace);
if (!ls) {
- if (dlm_config.ci_log_debug)
- log_print("invalid lockspace %x from %d cmd %d type %d",
- hd->h_lockspace, nodeid, hd->h_cmd, type);
+ log_print("invalid h_lockspace %x from %d cmd %d type %d",
+ hd->h_lockspace, nodeid, hd->h_cmd, type);
if (hd->h_cmd == DLM_RCOM && type == DLM_RCOM_STATUS)
dlm_send_ls_not_ready(nodeid, rc);
@@ -3880,7 +3806,6 @@ static void recover_convert_waiter(struct dlm_ls *ls, struct dlm_lkb *lkb)
ls->ls_stub_ms.m_type = DLM_MSG_CONVERT_REPLY;
ls->ls_stub_ms.m_result = -EINPROGRESS;
ls->ls_stub_ms.m_flags = lkb->lkb_flags;
- ls->ls_stub_ms.m_header.h_nodeid = lkb->lkb_nodeid;
_receive_convert_reply(lkb, &ls->ls_stub_ms);
/* Same special case as in receive_rcom_lock_args() */
@@ -3922,7 +3847,6 @@ static int waiter_needs_recovery(struct dlm_ls *ls, struct dlm_lkb *lkb)
void dlm_recover_waiters_pre(struct dlm_ls *ls)
{
struct dlm_lkb *lkb, *safe;
- int wait_type, stub_unlock_result, stub_cancel_result;
mutex_lock(&ls->ls_waiters_mutex);
@@ -3941,33 +3865,7 @@ void dlm_recover_waiters_pre(struct dlm_ls *ls)
if (!waiter_needs_recovery(ls, lkb))
continue;
- wait_type = lkb->lkb_wait_type;
- stub_unlock_result = -DLM_EUNLOCK;
- stub_cancel_result = -DLM_ECANCEL;
-
- /* Main reply may have been received leaving a zero wait_type,
- but a reply for the overlapping op may not have been
- received. In that case we need to fake the appropriate
- reply for the overlap op. */
-
- if (!wait_type) {
- if (is_overlap_cancel(lkb)) {
- wait_type = DLM_MSG_CANCEL;
- if (lkb->lkb_grmode == DLM_LOCK_IV)
- stub_cancel_result = 0;
- }
- if (is_overlap_unlock(lkb)) {
- wait_type = DLM_MSG_UNLOCK;
- if (lkb->lkb_grmode == DLM_LOCK_IV)
- stub_unlock_result = -ENOENT;
- }
-
- log_debug(ls, "rwpre overlap %x %x %d %d %d",
- lkb->lkb_id, lkb->lkb_flags, wait_type,
- stub_cancel_result, stub_unlock_result);
- }
-
- switch (wait_type) {
+ switch (lkb->lkb_wait_type) {
case DLM_MSG_REQUEST:
lkb->lkb_flags |= DLM_IFL_RESEND;
@@ -3980,9 +3878,8 @@ void dlm_recover_waiters_pre(struct dlm_ls *ls)
case DLM_MSG_UNLOCK:
hold_lkb(lkb);
ls->ls_stub_ms.m_type = DLM_MSG_UNLOCK_REPLY;
- ls->ls_stub_ms.m_result = stub_unlock_result;
+ ls->ls_stub_ms.m_result = -DLM_EUNLOCK;
ls->ls_stub_ms.m_flags = lkb->lkb_flags;
- ls->ls_stub_ms.m_header.h_nodeid = lkb->lkb_nodeid;
_receive_unlock_reply(lkb, &ls->ls_stub_ms);
dlm_put_lkb(lkb);
break;
@@ -3990,16 +3887,15 @@ void dlm_recover_waiters_pre(struct dlm_ls *ls)
case DLM_MSG_CANCEL:
hold_lkb(lkb);
ls->ls_stub_ms.m_type = DLM_MSG_CANCEL_REPLY;
- ls->ls_stub_ms.m_result = stub_cancel_result;
+ ls->ls_stub_ms.m_result = -DLM_ECANCEL;
ls->ls_stub_ms.m_flags = lkb->lkb_flags;
- ls->ls_stub_ms.m_header.h_nodeid = lkb->lkb_nodeid;
_receive_cancel_reply(lkb, &ls->ls_stub_ms);
dlm_put_lkb(lkb);
break;
default:
- log_error(ls, "invalid lkb wait_type %d %d",
- lkb->lkb_wait_type, wait_type);
+ log_error(ls, "invalid lkb wait_type %d",
+ lkb->lkb_wait_type);
}
schedule();
}
@@ -4288,7 +4184,7 @@ static int receive_rcom_lock_args(struct dlm_ls *ls, struct dlm_lkb *lkb,
lkb->lkb_astaddr = (void *) (long) (rl->rl_asts & AST_COMP);
if (lkb->lkb_exflags & DLM_LKF_VALBLK) {
- lkb->lkb_lvbptr = dlm_allocate_lvb(ls);
+ lkb->lkb_lvbptr = allocate_lvb(ls);
if (!lkb->lkb_lvbptr)
return -ENOMEM;
lvblen = rc->rc_header.h_length - sizeof(struct dlm_rcom) -
@@ -4363,7 +4259,7 @@ int dlm_recover_master_copy(struct dlm_ls *ls, struct dlm_rcom *rc)
put_rsb(r);
out:
if (error)
- log_debug(ls, "recover_master_copy %d %x", error, rl->rl_lkid);
+ log_print("recover_master_copy %d %x", error, rl->rl_lkid);
rl->rl_result = error;
return error;
}
@@ -4446,7 +4342,7 @@ int dlm_user_request(struct dlm_ls *ls, struct dlm_user_args *ua,
}
}
- /* After ua is attached to lkb it will be freed by dlm_free_lkb().
+ /* After ua is attached to lkb it will be freed by free_lkb().
When DLM_IFL_USER is set, the dlm knows that this is a userspace
lock and that lkb_astparam is the dlm_user_args structure. */
@@ -4783,7 +4679,6 @@ void dlm_clear_proc_locks(struct dlm_ls *ls, struct dlm_user_proc *proc)
}
list_for_each_entry_safe(lkb, safe, &proc->asts, lkb_astqueue) {
- lkb->lkb_ast_type = 0;
list_del(&lkb->lkb_astqueue);
dlm_put_lkb(lkb);
}
diff --git a/trunk/fs/dlm/lock.h b/trunk/fs/dlm/lock.h
index 27b6ed302911..ada04680a1e5 100644
--- a/trunk/fs/dlm/lock.h
+++ b/trunk/fs/dlm/lock.h
@@ -19,6 +19,8 @@ void dlm_print_lkb(struct dlm_lkb *lkb);
void dlm_receive_message_saved(struct dlm_ls *ls, struct dlm_message *ms);
void dlm_receive_buffer(struct dlm_header *hd, int nodeid);
int dlm_modes_compat(int mode1, int mode2);
+int dlm_find_rsb(struct dlm_ls *ls, char *name, int namelen,
+ unsigned int flags, struct dlm_rsb **r_ret);
void dlm_put_rsb(struct dlm_rsb *r);
void dlm_hold_rsb(struct dlm_rsb *r);
int dlm_put_lkb(struct dlm_lkb *lkb);
diff --git a/trunk/fs/dlm/lockspace.c b/trunk/fs/dlm/lockspace.c
index b180fdc51085..5c108c49cb8c 100644
--- a/trunk/fs/dlm/lockspace.c
+++ b/trunk/fs/dlm/lockspace.c
@@ -24,6 +24,14 @@
#include "recover.h"
#include "requestqueue.h"
+#ifdef CONFIG_DLM_DEBUG
+int dlm_create_debug_file(struct dlm_ls *ls);
+void dlm_delete_debug_file(struct dlm_ls *ls);
+#else
+static inline int dlm_create_debug_file(struct dlm_ls *ls) { return 0; }
+static inline void dlm_delete_debug_file(struct dlm_ls *ls) { }
+#endif
+
static int ls_count;
static struct mutex ls_lock;
static struct list_head lslist;
@@ -676,9 +684,9 @@ static int release_lockspace(struct dlm_ls *ls, int force)
dlm_del_ast(lkb);
if (lkb->lkb_lvbptr && lkb->lkb_flags & DLM_IFL_MSTCPY)
- dlm_free_lvb(lkb->lkb_lvbptr);
+ free_lvb(lkb->lkb_lvbptr);
- dlm_free_lkb(lkb);
+ free_lkb(lkb);
}
}
dlm_astd_resume();
@@ -696,7 +704,7 @@ static int release_lockspace(struct dlm_ls *ls, int force)
res_hashchain);
list_del(&rsb->res_hashchain);
- dlm_free_rsb(rsb);
+ free_rsb(rsb);
}
head = &ls->ls_rsbtbl[i].toss;
@@ -704,7 +712,7 @@ static int release_lockspace(struct dlm_ls *ls, int force)
rsb = list_entry(head->next, struct dlm_rsb,
res_hashchain);
list_del(&rsb->res_hashchain);
- dlm_free_rsb(rsb);
+ free_rsb(rsb);
}
}
diff --git a/trunk/fs/dlm/lowcomms.c b/trunk/fs/dlm/lowcomms.c
index 7c1e5e5cccd8..e9923ca9c2d9 100644
--- a/trunk/fs/dlm/lowcomms.c
+++ b/trunk/fs/dlm/lowcomms.c
@@ -864,7 +864,7 @@ static void sctp_init_assoc(struct connection *con)
static void tcp_connect_to_sock(struct connection *con)
{
int result = -EHOSTUNREACH;
- struct sockaddr_storage saddr, src_addr;
+ struct sockaddr_storage saddr;
int addr_len;
struct socket *sock;
@@ -898,17 +898,6 @@ static void tcp_connect_to_sock(struct connection *con)
con->connect_action = tcp_connect_to_sock;
add_sock(sock, con);
- /* Bind to our cluster-known address connecting to avoid
- routing problems */
- memcpy(&src_addr, dlm_local_addr[0], sizeof(src_addr));
- make_sockaddr(&src_addr, 0, &addr_len);
- result = sock->ops->bind(sock, (struct sockaddr *) &src_addr,
- addr_len);
- if (result < 0) {
- log_print("could not bind for connect: %d", result);
- /* This *may* not indicate a critical error */
- }
-
make_sockaddr(&saddr, dlm_config.ci_tcp_port, &addr_len);
log_print("connecting to %d", con->nodeid);
@@ -1437,8 +1426,6 @@ void dlm_lowcomms_stop(void)
con = __nodeid2con(i, 0);
if (con) {
close_connection(con, true);
- if (con->othercon)
- kmem_cache_free(con_cache, con->othercon);
kmem_cache_free(con_cache, con);
}
}
diff --git a/trunk/fs/dlm/main.c b/trunk/fs/dlm/main.c
index 58487fb95a4c..eca2907f2386 100644
--- a/trunk/fs/dlm/main.c
+++ b/trunk/fs/dlm/main.c
@@ -18,6 +18,16 @@
#include "memory.h"
#include "config.h"
+#ifdef CONFIG_DLM_DEBUG
+int dlm_register_debugfs(void);
+void dlm_unregister_debugfs(void);
+#else
+static inline int dlm_register_debugfs(void) { return 0; }
+static inline void dlm_unregister_debugfs(void) { }
+#endif
+int dlm_netlink_init(void);
+void dlm_netlink_exit(void);
+
static int __init init_dlm(void)
{
int error;
diff --git a/trunk/fs/dlm/member.c b/trunk/fs/dlm/member.c
index fa17f5a27883..e9cdcab306e2 100644
--- a/trunk/fs/dlm/member.c
+++ b/trunk/fs/dlm/member.c
@@ -1,7 +1,7 @@
/******************************************************************************
*******************************************************************************
**
-** Copyright (C) 2005-2008 Red Hat, Inc. All rights reserved.
+** Copyright (C) 2005-2007 Red Hat, Inc. All rights reserved.
**
** This copyrighted material is made available to anyone wishing to use,
** modify, copy, or redistribute it subject to the terms and conditions
@@ -70,7 +70,7 @@ static void dlm_remove_member(struct dlm_ls *ls, struct dlm_member *memb)
ls->ls_num_nodes--;
}
-int dlm_is_member(struct dlm_ls *ls, int nodeid)
+static int dlm_is_member(struct dlm_ls *ls, int nodeid)
{
struct dlm_member *memb;
diff --git a/trunk/fs/dlm/member.h b/trunk/fs/dlm/member.h
index 7a26fca1e0b5..927c08c19214 100644
--- a/trunk/fs/dlm/member.h
+++ b/trunk/fs/dlm/member.h
@@ -1,7 +1,7 @@
/******************************************************************************
*******************************************************************************
**
-** Copyright (C) 2005-2008 Red Hat, Inc. All rights reserved.
+** Copyright (C) 2005 Red Hat, Inc. All rights reserved.
**
** This copyrighted material is made available to anyone wishing to use,
** modify, copy, or redistribute it subject to the terms and conditions
@@ -19,7 +19,6 @@ void dlm_clear_members(struct dlm_ls *ls);
void dlm_clear_members_gone(struct dlm_ls *ls);
int dlm_recover_members(struct dlm_ls *ls, struct dlm_recover *rv,int *neg_out);
int dlm_is_removed(struct dlm_ls *ls, int nodeid);
-int dlm_is_member(struct dlm_ls *ls, int nodeid);
#endif /* __MEMBER_DOT_H__ */
diff --git a/trunk/fs/dlm/memory.c b/trunk/fs/dlm/memory.c
index f7783867491a..ecf0e5cb2035 100644
--- a/trunk/fs/dlm/memory.c
+++ b/trunk/fs/dlm/memory.c
@@ -2,7 +2,7 @@
*******************************************************************************
**
** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved.
-** Copyright (C) 2004-2007 Red Hat, Inc. All rights reserved.
+** Copyright (C) 2004-2005 Red Hat, Inc. All rights reserved.
**
** This copyrighted material is made available to anyone wishing to use,
** modify, copy, or redistribute it subject to the terms and conditions
@@ -35,7 +35,7 @@ void dlm_memory_exit(void)
kmem_cache_destroy(lkb_cache);
}
-char *dlm_allocate_lvb(struct dlm_ls *ls)
+char *allocate_lvb(struct dlm_ls *ls)
{
char *p;
@@ -43,7 +43,7 @@ char *dlm_allocate_lvb(struct dlm_ls *ls)
return p;
}
-void dlm_free_lvb(char *p)
+void free_lvb(char *p)
{
kfree(p);
}
@@ -51,7 +51,7 @@ void dlm_free_lvb(char *p)
/* FIXME: have some minimal space built-in to rsb for the name and
kmalloc a separate name if needed, like dentries are done */
-struct dlm_rsb *dlm_allocate_rsb(struct dlm_ls *ls, int namelen)
+struct dlm_rsb *allocate_rsb(struct dlm_ls *ls, int namelen)
{
struct dlm_rsb *r;
@@ -61,14 +61,14 @@ struct dlm_rsb *dlm_allocate_rsb(struct dlm_ls *ls, int namelen)
return r;
}
-void dlm_free_rsb(struct dlm_rsb *r)
+void free_rsb(struct dlm_rsb *r)
{
if (r->res_lvbptr)
- dlm_free_lvb(r->res_lvbptr);
+ free_lvb(r->res_lvbptr);
kfree(r);
}
-struct dlm_lkb *dlm_allocate_lkb(struct dlm_ls *ls)
+struct dlm_lkb *allocate_lkb(struct dlm_ls *ls)
{
struct dlm_lkb *lkb;
@@ -76,7 +76,7 @@ struct dlm_lkb *dlm_allocate_lkb(struct dlm_ls *ls)
return lkb;
}
-void dlm_free_lkb(struct dlm_lkb *lkb)
+void free_lkb(struct dlm_lkb *lkb)
{
if (lkb->lkb_flags & DLM_IFL_USER) {
struct dlm_user_args *ua;
@@ -90,3 +90,19 @@ void dlm_free_lkb(struct dlm_lkb *lkb)
kmem_cache_free(lkb_cache, lkb);
}
+struct dlm_direntry *allocate_direntry(struct dlm_ls *ls, int namelen)
+{
+ struct dlm_direntry *de;
+
+ DLM_ASSERT(namelen <= DLM_RESNAME_MAXLEN,
+ printk("namelen = %d\n", namelen););
+
+ de = kzalloc(sizeof(*de) + namelen, GFP_KERNEL);
+ return de;
+}
+
+void free_direntry(struct dlm_direntry *de)
+{
+ kfree(de);
+}
+
diff --git a/trunk/fs/dlm/memory.h b/trunk/fs/dlm/memory.h
index 485fb29143bd..6ead158ccc5c 100644
--- a/trunk/fs/dlm/memory.h
+++ b/trunk/fs/dlm/memory.h
@@ -2,7 +2,7 @@
*******************************************************************************
**
** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved.
-** Copyright (C) 2004-2007 Red Hat, Inc. All rights reserved.
+** Copyright (C) 2004-2005 Red Hat, Inc. All rights reserved.
**
** This copyrighted material is made available to anyone wishing to use,
** modify, copy, or redistribute it subject to the terms and conditions
@@ -16,12 +16,14 @@
int dlm_memory_init(void);
void dlm_memory_exit(void);
-struct dlm_rsb *dlm_allocate_rsb(struct dlm_ls *ls, int namelen);
-void dlm_free_rsb(struct dlm_rsb *r);
-struct dlm_lkb *dlm_allocate_lkb(struct dlm_ls *ls);
-void dlm_free_lkb(struct dlm_lkb *l);
-char *dlm_allocate_lvb(struct dlm_ls *ls);
-void dlm_free_lvb(char *l);
+struct dlm_rsb *allocate_rsb(struct dlm_ls *ls, int namelen);
+void free_rsb(struct dlm_rsb *r);
+struct dlm_lkb *allocate_lkb(struct dlm_ls *ls);
+void free_lkb(struct dlm_lkb *l);
+struct dlm_direntry *allocate_direntry(struct dlm_ls *ls, int namelen);
+void free_direntry(struct dlm_direntry *de);
+char *allocate_lvb(struct dlm_ls *ls);
+void free_lvb(char *l);
#endif /* __MEMORY_DOT_H__ */
diff --git a/trunk/fs/dlm/midcomms.c b/trunk/fs/dlm/midcomms.c
index e69926e984db..f8c69dda16a0 100644
--- a/trunk/fs/dlm/midcomms.c
+++ b/trunk/fs/dlm/midcomms.c
@@ -2,7 +2,7 @@
*******************************************************************************
**
** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved.
-** Copyright (C) 2004-2008 Red Hat, Inc. All rights reserved.
+** Copyright (C) 2004-2007 Red Hat, Inc. All rights reserved.
**
** This copyrighted material is made available to anyone wishing to use,
** modify, copy, or redistribute it subject to the terms and conditions
@@ -58,12 +58,8 @@ static void copy_from_cb(void *dst, const void *base, unsigned offset,
int dlm_process_incoming_buffer(int nodeid, const void *base,
unsigned offset, unsigned len, unsigned limit)
{
- union {
- unsigned char __buf[DLM_INBUF_LEN];
- /* this is to force proper alignment on some arches */
- struct dlm_header dlm;
- } __tmp;
- struct dlm_header *msg = &__tmp.dlm;
+ unsigned char __tmp[DLM_INBUF_LEN];
+ struct dlm_header *msg = (struct dlm_header *) __tmp;
int ret = 0;
int err = 0;
uint16_t msglen;
@@ -104,7 +100,8 @@ int dlm_process_incoming_buffer(int nodeid, const void *base,
in the buffer on the stack (which should work for most
ordinary messages). */
- if (msglen > DLM_INBUF_LEN && msg == &__tmp.dlm) {
+ if (msglen > sizeof(__tmp) &&
+ msg == (struct dlm_header *) __tmp) {
msg = kmalloc(dlm_config.ci_buffer_size, GFP_KERNEL);
if (msg == NULL)
return ret;
@@ -122,7 +119,7 @@ int dlm_process_incoming_buffer(int nodeid, const void *base,
dlm_receive_buffer(msg, nodeid);
}
- if (msg != &__tmp.dlm)
+ if (msg != (struct dlm_header *) __tmp)
kfree(msg);
return err ? err : ret;
diff --git a/trunk/fs/dlm/rcom.c b/trunk/fs/dlm/rcom.c
index 026824cd3acb..ae2fd97fa4ad 100644
--- a/trunk/fs/dlm/rcom.c
+++ b/trunk/fs/dlm/rcom.c
@@ -2,7 +2,7 @@
*******************************************************************************
**
** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved.
-** Copyright (C) 2005-2008 Red Hat, Inc. All rights reserved.
+** Copyright (C) 2005-2007 Red Hat, Inc. All rights reserved.
**
** This copyrighted material is made available to anyone wishing to use,
** modify, copy, or redistribute it subject to the terms and conditions
@@ -197,6 +197,11 @@ static void receive_sync_reply(struct dlm_ls *ls, struct dlm_rcom *rc_in)
spin_unlock(&ls->ls_rcom_spin);
}
+static void receive_rcom_status_reply(struct dlm_ls *ls, struct dlm_rcom *rc_in)
+{
+ receive_sync_reply(ls, rc_in);
+}
+
int dlm_rcom_names(struct dlm_ls *ls, int nodeid, char *last_name, int last_len)
{
struct dlm_rcom *rc;
@@ -249,6 +254,11 @@ static void receive_rcom_names(struct dlm_ls *ls, struct dlm_rcom *rc_in)
send_rcom(ls, mh, rc);
}
+static void receive_rcom_names_reply(struct dlm_ls *ls, struct dlm_rcom *rc_in)
+{
+ receive_sync_reply(ls, rc_in);
+}
+
int dlm_send_rcom_lookup(struct dlm_rsb *r, int dir_nodeid)
{
struct dlm_rcom *rc;
@@ -371,6 +381,11 @@ static void receive_rcom_lock(struct dlm_ls *ls, struct dlm_rcom *rc_in)
send_rcom(ls, mh, rc);
}
+static void receive_rcom_lock_reply(struct dlm_ls *ls, struct dlm_rcom *rc_in)
+{
+ dlm_recover_process_copy(ls, rc_in);
+}
+
/* If the lockspace doesn't exist then still send a status message
back; it's possible that it just doesn't have its global_id yet. */
@@ -466,11 +481,11 @@ void dlm_receive_rcom(struct dlm_ls *ls, struct dlm_rcom *rc, int nodeid)
break;
case DLM_RCOM_STATUS_REPLY:
- receive_sync_reply(ls, rc);
+ receive_rcom_status_reply(ls, rc);
break;
case DLM_RCOM_NAMES_REPLY:
- receive_sync_reply(ls, rc);
+ receive_rcom_names_reply(ls, rc);
break;
case DLM_RCOM_LOOKUP_REPLY:
@@ -478,11 +493,11 @@ void dlm_receive_rcom(struct dlm_ls *ls, struct dlm_rcom *rc, int nodeid)
break;
case DLM_RCOM_LOCK_REPLY:
- dlm_recover_process_copy(ls, rc);
+ receive_rcom_lock_reply(ls, rc);
break;
default:
- log_error(ls, "receive_rcom bad type %d", rc->rc_type);
+ DLM_ASSERT(0, printk("rc_type=%x\n", rc->rc_type););
}
out:
return;
diff --git a/trunk/fs/dlm/recover.c b/trunk/fs/dlm/recover.c
index df075dc300fa..c2cc7694cd16 100644
--- a/trunk/fs/dlm/recover.c
+++ b/trunk/fs/dlm/recover.c
@@ -629,7 +629,7 @@ static void recover_lvb(struct dlm_rsb *r)
goto out;
if (!r->res_lvbptr) {
- r->res_lvbptr = dlm_allocate_lvb(r->res_ls);
+ r->res_lvbptr = allocate_lvb(r->res_ls);
if (!r->res_lvbptr)
goto out;
}
@@ -731,20 +731,6 @@ int dlm_create_root_list(struct dlm_ls *ls)
list_add(&r->res_root_list, &ls->ls_root_list);
dlm_hold_rsb(r);
}
-
- /* If we're using a directory, add tossed rsbs to the root
- list; they'll have entries created in the new directory,
- but no other recovery steps should do anything with them. */
-
- if (dlm_no_directory(ls)) {
- read_unlock(&ls->ls_rsbtbl[i].lock);
- continue;
- }
-
- list_for_each_entry(r, &ls->ls_rsbtbl[i].toss, res_hashchain) {
- list_add(&r->res_root_list, &ls->ls_root_list);
- dlm_hold_rsb(r);
- }
read_unlock(&ls->ls_rsbtbl[i].lock);
}
out:
@@ -764,11 +750,6 @@ void dlm_release_root_list(struct dlm_ls *ls)
up_write(&ls->ls_root_sem);
}
-/* If not using a directory, clear the entire toss list, there's no benefit to
- caching the master value since it's fixed. If we are using a dir, keep the
- rsb's we're the master of. Recovery will add them to the root list and from
- there they'll be entered in the rebuilt directory. */
-
void dlm_clear_toss_list(struct dlm_ls *ls)
{
struct dlm_rsb *r, *safe;
@@ -778,10 +759,8 @@ void dlm_clear_toss_list(struct dlm_ls *ls)
write_lock(&ls->ls_rsbtbl[i].lock);
list_for_each_entry_safe(r, safe, &ls->ls_rsbtbl[i].toss,
res_hashchain) {
- if (dlm_no_directory(ls) || !is_master(r)) {
- list_del(&r->res_hashchain);
- dlm_free_rsb(r);
- }
+ list_del(&r->res_hashchain);
+ free_rsb(r);
}
write_unlock(&ls->ls_rsbtbl[i].lock);
}
diff --git a/trunk/fs/dlm/recoverd.c b/trunk/fs/dlm/recoverd.c
index 997f9531d594..4b89e20eebe7 100644
--- a/trunk/fs/dlm/recoverd.c
+++ b/trunk/fs/dlm/recoverd.c
@@ -67,18 +67,17 @@ static int ls_recover(struct dlm_ls *ls, struct dlm_recover *rv)
dlm_astd_resume();
/*
- * Free non-master tossed rsb's. Master rsb's are kept on toss
- * list and put on root list to be included in resdir recovery.
+ * This list of root rsb's will be the basis of most of the recovery
+ * routines.
*/
- dlm_clear_toss_list(ls);
+ dlm_create_root_list(ls);
/*
- * This list of root rsb's will be the basis of most of the recovery
- * routines.
+ * Free all the tossed rsb's so we don't have to recover them.
*/
- dlm_create_root_list(ls);
+ dlm_clear_toss_list(ls);
/*
* Add or remove nodes from the lockspace's ls_nodes list.
diff --git a/trunk/fs/dlm/user.c b/trunk/fs/dlm/user.c
index 7cbc6826239b..4f741546f4bb 100644
--- a/trunk/fs/dlm/user.c
+++ b/trunk/fs/dlm/user.c
@@ -24,7 +24,8 @@
#include "lvb_table.h"
#include "user.h"
-static const char name_prefix[] = "dlm";
+static const char *name_prefix="dlm";
+static struct miscdevice ctl_device;
static const struct file_operations device_fops;
#ifdef CONFIG_COMPAT
@@ -81,8 +82,7 @@ struct dlm_lock_result32 {
};
static void compat_input(struct dlm_write_request *kb,
- struct dlm_write_request32 *kb32,
- int max_namelen)
+ struct dlm_write_request32 *kb32)
{
kb->version[0] = kb32->version[0];
kb->version[1] = kb32->version[1];
@@ -112,11 +112,7 @@ static void compat_input(struct dlm_write_request *kb,
kb->i.lock.bastaddr = (void *)(long)kb32->i.lock.bastaddr;
kb->i.lock.lksb = (void *)(long)kb32->i.lock.lksb;
memcpy(kb->i.lock.lvb, kb32->i.lock.lvb, DLM_USER_LVB_LEN);
- if (kb->i.lock.namelen <= max_namelen)
- memcpy(kb->i.lock.name, kb32->i.lock.name,
- kb->i.lock.namelen);
- else
- kb->i.lock.namelen = max_namelen;
+ memcpy(kb->i.lock.name, kb32->i.lock.name, kb->i.lock.namelen);
}
}
@@ -240,12 +236,12 @@ void dlm_user_add_ast(struct dlm_lkb *lkb, int type)
spin_unlock(&proc->asts_spin);
if (eol) {
- spin_lock(&proc->locks_spin);
+ spin_lock(&ua->proc->locks_spin);
if (!list_empty(&lkb->lkb_ownqueue)) {
list_del_init(&lkb->lkb_ownqueue);
dlm_put_lkb(lkb);
}
- spin_unlock(&proc->locks_spin);
+ spin_unlock(&ua->proc->locks_spin);
}
out:
mutex_unlock(&ls->ls_clear_proc_locks);
@@ -533,8 +529,7 @@ static ssize_t device_write(struct file *file, const char __user *buf,
if (proc)
set_bit(DLM_PROC_FLAGS_COMPAT, &proc->flags);
- compat_input(kbuf, k32buf,
- count - sizeof(struct dlm_write_request32));
+ compat_input(kbuf, k32buf);
kfree(k32buf);
}
#endif
@@ -901,16 +896,14 @@ static const struct file_operations ctl_device_fops = {
.owner = THIS_MODULE,
};
-static struct miscdevice ctl_device = {
- .name = "dlm-control",
- .fops = &ctl_device_fops,
- .minor = MISC_DYNAMIC_MINOR,
-};
-
int dlm_user_init(void)
{
int error;
+ ctl_device.name = "dlm-control";
+ ctl_device.fops = &ctl_device_fops;
+ ctl_device.minor = MISC_DYNAMIC_MINOR;
+
error = misc_register(&ctl_device);
if (error)
log_print("misc_register failed for control device");
diff --git a/trunk/fs/dlm/util.c b/trunk/fs/dlm/util.c
index 4d9c1f4e1bd1..963889cf6740 100644
--- a/trunk/fs/dlm/util.c
+++ b/trunk/fs/dlm/util.c
@@ -1,7 +1,7 @@
/******************************************************************************
*******************************************************************************
**
-** Copyright (C) 2005-2008 Red Hat, Inc. All rights reserved.
+** Copyright (C) 2005 Red Hat, Inc. All rights reserved.
**
** This copyrighted material is made available to anyone wishing to use,
** modify, copy, or redistribute it subject to the terms and conditions
@@ -14,14 +14,6 @@
#include "rcom.h"
#include "util.h"
-#define DLM_ERRNO_EDEADLK 35
-#define DLM_ERRNO_EBADR 53
-#define DLM_ERRNO_EBADSLT 57
-#define DLM_ERRNO_EPROTO 71
-#define DLM_ERRNO_EOPNOTSUPP 95
-#define DLM_ERRNO_ETIMEDOUT 110
-#define DLM_ERRNO_EINPROGRESS 115
-
static void header_out(struct dlm_header *hd)
{
hd->h_version = cpu_to_le32(hd->h_version);
@@ -38,54 +30,11 @@ static void header_in(struct dlm_header *hd)
hd->h_length = le16_to_cpu(hd->h_length);
}
-/* higher errno values are inconsistent across architectures, so select
- one set of values for on the wire */
-
-static int to_dlm_errno(int err)
-{
- switch (err) {
- case -EDEADLK:
- return -DLM_ERRNO_EDEADLK;
- case -EBADR:
- return -DLM_ERRNO_EBADR;
- case -EBADSLT:
- return -DLM_ERRNO_EBADSLT;
- case -EPROTO:
- return -DLM_ERRNO_EPROTO;
- case -EOPNOTSUPP:
- return -DLM_ERRNO_EOPNOTSUPP;
- case -ETIMEDOUT:
- return -DLM_ERRNO_ETIMEDOUT;
- case -EINPROGRESS:
- return -DLM_ERRNO_EINPROGRESS;
- }
- return err;
-}
-
-static int from_dlm_errno(int err)
-{
- switch (err) {
- case -DLM_ERRNO_EDEADLK:
- return -EDEADLK;
- case -DLM_ERRNO_EBADR:
- return -EBADR;
- case -DLM_ERRNO_EBADSLT:
- return -EBADSLT;
- case -DLM_ERRNO_EPROTO:
- return -EPROTO;
- case -DLM_ERRNO_EOPNOTSUPP:
- return -EOPNOTSUPP;
- case -DLM_ERRNO_ETIMEDOUT:
- return -ETIMEDOUT;
- case -DLM_ERRNO_EINPROGRESS:
- return -EINPROGRESS;
- }
- return err;
-}
-
void dlm_message_out(struct dlm_message *ms)
{
- header_out(&ms->m_header);
+ struct dlm_header *hd = (struct dlm_header *) ms;
+
+ header_out(hd);
ms->m_type = cpu_to_le32(ms->m_type);
ms->m_nodeid = cpu_to_le32(ms->m_nodeid);
@@ -104,12 +53,14 @@ void dlm_message_out(struct dlm_message *ms)
ms->m_rqmode = cpu_to_le32(ms->m_rqmode);
ms->m_bastmode = cpu_to_le32(ms->m_bastmode);
ms->m_asts = cpu_to_le32(ms->m_asts);
- ms->m_result = cpu_to_le32(to_dlm_errno(ms->m_result));
+ ms->m_result = cpu_to_le32(ms->m_result);
}
void dlm_message_in(struct dlm_message *ms)
{
- header_in(&ms->m_header);
+ struct dlm_header *hd = (struct dlm_header *) ms;
+
+ header_in(hd);
ms->m_type = le32_to_cpu(ms->m_type);
ms->m_nodeid = le32_to_cpu(ms->m_nodeid);
@@ -128,7 +79,7 @@ void dlm_message_in(struct dlm_message *ms)
ms->m_rqmode = le32_to_cpu(ms->m_rqmode);
ms->m_bastmode = le32_to_cpu(ms->m_bastmode);
ms->m_asts = le32_to_cpu(ms->m_asts);
- ms->m_result = from_dlm_errno(le32_to_cpu(ms->m_result));
+ ms->m_result = le32_to_cpu(ms->m_result);
}
static void rcom_lock_out(struct rcom_lock *rl)
@@ -175,9 +126,10 @@ static void rcom_config_in(struct rcom_config *rf)
void dlm_rcom_out(struct dlm_rcom *rc)
{
+ struct dlm_header *hd = (struct dlm_header *) rc;
int type = rc->rc_type;
- header_out(&rc->rc_header);
+ header_out(hd);
rc->rc_type = cpu_to_le32(rc->rc_type);
rc->rc_result = cpu_to_le32(rc->rc_result);
@@ -185,7 +137,7 @@ void dlm_rcom_out(struct dlm_rcom *rc)
rc->rc_seq = cpu_to_le64(rc->rc_seq);
rc->rc_seq_reply = cpu_to_le64(rc->rc_seq_reply);
- if ((type == DLM_RCOM_LOCK) || (type == DLM_RCOM_LOCK_REPLY))
+ if (type == DLM_RCOM_LOCK)
rcom_lock_out((struct rcom_lock *) rc->rc_buf);
else if (type == DLM_RCOM_STATUS_REPLY)
@@ -194,9 +146,9 @@ void dlm_rcom_out(struct dlm_rcom *rc)
void dlm_rcom_in(struct dlm_rcom *rc)
{
- int type;
+ struct dlm_header *hd = (struct dlm_header *) rc;
- header_in(&rc->rc_header);
+ header_in(hd);
rc->rc_type = le32_to_cpu(rc->rc_type);
rc->rc_result = le32_to_cpu(rc->rc_result);
@@ -204,12 +156,10 @@ void dlm_rcom_in(struct dlm_rcom *rc)
rc->rc_seq = le64_to_cpu(rc->rc_seq);
rc->rc_seq_reply = le64_to_cpu(rc->rc_seq_reply);
- type = rc->rc_type;
-
- if ((type == DLM_RCOM_LOCK) || (type == DLM_RCOM_LOCK_REPLY))
+ if (rc->rc_type == DLM_RCOM_LOCK)
rcom_lock_in((struct rcom_lock *) rc->rc_buf);
- else if (type == DLM_RCOM_STATUS_REPLY)
+ else if (rc->rc_type == DLM_RCOM_STATUS_REPLY)
rcom_config_in((struct rcom_config *) rc->rc_buf);
}
diff --git a/trunk/include/scsi/scsi.h b/trunk/include/scsi/scsi.h
index 82251575a9b4..702fcfeb37f1 100644
--- a/trunk/include/scsi/scsi.h
+++ b/trunk/include/scsi/scsi.h
@@ -10,25 +10,6 @@
#include
-/*
- * The maximum number of SG segments that we will put inside a
- * scatterlist (unless chaining is used). Should ideally fit inside a
- * single page, to avoid a higher order allocation. We could define this
- * to SG_MAX_SINGLE_ALLOC to pack correctly at the highest order. The
- * minimum value is 32
- */
-#define SCSI_MAX_SG_SEGMENTS 128
-
-/*
- * Like SCSI_MAX_SG_SEGMENTS, but for archs that have sg chaining. This limit
- * is totally arbitrary, a setting of 2048 will get you at least 8mb ios.
- */
-#ifdef ARCH_HAS_SG_CHAIN
-#define SCSI_MAX_SG_CHAIN_SEGMENTS 2048
-#else
-#define SCSI_MAX_SG_CHAIN_SEGMENTS SCSI_MAX_SG_SEGMENTS
-#endif
-
/*
* SCSI command lengths
*/
@@ -102,7 +83,6 @@ extern const unsigned char scsi_command_size[8];
#define READ_TOC 0x43
#define LOG_SELECT 0x4c
#define LOG_SENSE 0x4d
-#define XDWRITEREAD_10 0x53
#define MODE_SELECT_10 0x55
#define RESERVE_10 0x56
#define RELEASE_10 0x57
diff --git a/trunk/include/scsi/scsi_cmnd.h b/trunk/include/scsi/scsi_cmnd.h
index de28aab820b0..a457fca66f61 100644
--- a/trunk/include/scsi/scsi_cmnd.h
+++ b/trunk/include/scsi/scsi_cmnd.h
@@ -2,20 +2,15 @@
#define _SCSI_SCSI_CMND_H
#include
-#include
#include
#include
#include
#include
+struct request;
struct Scsi_Host;
struct scsi_device;
-struct scsi_data_buffer {
- struct sg_table table;
- unsigned length;
- int resid;
-};
/* embedded in scsi_cmnd */
struct scsi_pointer {
@@ -66,11 +61,15 @@ struct scsi_cmnd {
/* These elements define the operation we are about to perform */
#define MAX_COMMAND_SIZE 16
unsigned char cmnd[MAX_COMMAND_SIZE];
+ unsigned request_bufflen; /* Actual request size */
struct timer_list eh_timeout; /* Used to time out the command. */
+ void *request_buffer; /* Actual requested buffer */
/* These elements define the operation we ultimately want to perform */
- struct scsi_data_buffer sdb;
+ struct sg_table sg_table;
+ unsigned short use_sg; /* Number of pieces of scatter-gather */
+
unsigned underflow; /* Return error if less than
this amount is transferred */
@@ -80,6 +79,10 @@ struct scsi_cmnd {
reconnects. Probably == sector
size */
+ int resid; /* Number of bytes requested to be
+ transferred less actual number
+ transferred (0 if not supported) */
+
struct request *request; /* The command we are
working on */
@@ -124,55 +127,27 @@ extern void *scsi_kmap_atomic_sg(struct scatterlist *sg, int sg_count,
size_t *offset, size_t *len);
extern void scsi_kunmap_atomic_sg(void *virt);
-extern int scsi_init_io(struct scsi_cmnd *cmd, gfp_t gfp_mask);
-extern void scsi_release_buffers(struct scsi_cmnd *cmd);
+extern int scsi_alloc_sgtable(struct scsi_cmnd *, gfp_t);
+extern void scsi_free_sgtable(struct scsi_cmnd *);
extern int scsi_dma_map(struct scsi_cmnd *cmd);
extern void scsi_dma_unmap(struct scsi_cmnd *cmd);
-static inline unsigned scsi_sg_count(struct scsi_cmnd *cmd)
-{
- return cmd->sdb.table.nents;
-}
-
-static inline struct scatterlist *scsi_sglist(struct scsi_cmnd *cmd)
-{
- return cmd->sdb.table.sgl;
-}
-
-static inline unsigned scsi_bufflen(struct scsi_cmnd *cmd)
-{
- return cmd->sdb.length;
-}
+#define scsi_sg_count(cmd) ((cmd)->use_sg)
+#define scsi_sglist(cmd) ((cmd)->sg_table.sgl)
+#define scsi_bufflen(cmd) ((cmd)->request_bufflen)
static inline void scsi_set_resid(struct scsi_cmnd *cmd, int resid)
{
- cmd->sdb.resid = resid;
+ cmd->resid = resid;
}
static inline int scsi_get_resid(struct scsi_cmnd *cmd)
{
- return cmd->sdb.resid;
+ return cmd->resid;
}
#define scsi_for_each_sg(cmd, sg, nseg, __i) \
for_each_sg(scsi_sglist(cmd), sg, nseg, __i)
-static inline int scsi_bidi_cmnd(struct scsi_cmnd *cmd)
-{
- return blk_bidi_rq(cmd->request) &&
- (cmd->request->next_rq->special != NULL);
-}
-
-static inline struct scsi_data_buffer *scsi_in(struct scsi_cmnd *cmd)
-{
- return scsi_bidi_cmnd(cmd) ?
- cmd->request->next_rq->special : &cmd->sdb;
-}
-
-static inline struct scsi_data_buffer *scsi_out(struct scsi_cmnd *cmd)
-{
- return &cmd->sdb;
-}
-
#endif /* _SCSI_SCSI_CMND_H */
diff --git a/trunk/include/scsi/scsi_eh.h b/trunk/include/scsi/scsi_eh.h
index 25071d5d9bf8..d21b8913ceb3 100644
--- a/trunk/include/scsi/scsi_eh.h
+++ b/trunk/include/scsi/scsi_eh.h
@@ -68,15 +68,16 @@ extern int scsi_get_sense_info_fld(const u8 * sense_buffer, int sb_len,
extern int scsi_reset_provider(struct scsi_device *, int);
struct scsi_eh_save {
- /* saved state */
int result;
enum dma_data_direction data_direction;
unsigned char cmd_len;
unsigned char cmnd[MAX_COMMAND_SIZE];
- struct scsi_data_buffer sdb;
- struct request *next_rq;
- /* new command support */
+ void *buffer;
+ unsigned bufflen;
+ unsigned short use_sg;
+ int resid;
+
struct scatterlist sense_sgl;
};
diff --git a/trunk/include/scsi/scsi_host.h b/trunk/include/scsi/scsi_host.h
index 5c58d594126a..0fd4746ee39d 100644
--- a/trunk/include/scsi/scsi_host.h
+++ b/trunk/include/scsi/scsi_host.h
@@ -39,6 +39,9 @@ struct blk_queue_tags;
#define DISABLE_CLUSTERING 0
#define ENABLE_CLUSTERING 1
+#define DISABLE_SG_CHAINING 0
+#define ENABLE_SG_CHAINING 1
+
enum scsi_eh_timer_return {
EH_NOT_HANDLED,
EH_HANDLED,
@@ -133,9 +136,9 @@ struct scsi_host_template {
* the done callback is invoked.
*
* This is called to inform the LLD to transfer
- * scsi_bufflen(cmd) bytes. scsi_sg_count(cmd) speciefies the
+ * cmd->request_bufflen bytes. The cmd->use_sg speciefies the
* number of scatterlist entried in the command and
- * scsi_sglist(cmd) returns the scatterlist.
+ * cmd->request_buffer contains the scatterlist.
*
* return values: see queuecommand
*
@@ -442,6 +445,15 @@ struct scsi_host_template {
*/
unsigned ordered_tag:1;
+ /*
+ * true if the low-level driver can support sg chaining. this
+ * will be removed eventually when all the drivers are
+ * converted to support sg chaining.
+ *
+ * Status: OBSOLETE
+ */
+ unsigned use_sg_chaining:1;
+
/*
* Countdown for host blocking with no commands outstanding
*/
@@ -586,6 +598,7 @@ struct Scsi_Host {
unsigned unchecked_isa_dma:1;
unsigned use_clustering:1;
unsigned use_blk_tcq:1;
+ unsigned use_sg_chaining:1;
/*
* Host has requested that no further requests come through for the