From ac5f61997eedae3c9340fc30fa9255c0092e425f Mon Sep 17 00:00:00 2001 From: Anthony Liguori Date: Mon, 17 Sep 2007 14:57:49 -0500 Subject: [PATCH] --- yaml --- r: 80623 b: refs/heads/master c: aca7f96600b170e470b3056aba0ed8d7df8d330d h: refs/heads/master i: 80621: 1cd1c97a0b50bda074404d1004d9f04a8e512f39 80619: 4263622fc703980c9f1ac1fd6e2391d96fb6f97a 80615: 63d551448f1ab432808be592419cf68dee615944 80607: e7277ed889aaa3b831144d3e023bdcc067e35edb v: v3 --- [refs] | 2 +- trunk/Documentation/DocBook/kernel-api.tmpl | 8 +- trunk/arch/ia64/hp/sim/simscsi.c | 1 + trunk/block/bsg.c | 1 - trunk/drivers/base/class.c | 2 +- trunk/drivers/infiniband/ulp/srp/ib_srp.c | 1 + trunk/drivers/kvm/x86_emulate.c | 23 +- trunk/drivers/s390/scsi/zfcp_fsf.c | 4 +- trunk/drivers/scsi/3w-9xxx.c | 1 + trunk/drivers/scsi/3w-xxxx.c | 1 + trunk/drivers/scsi/BusLogic.c | 1 + trunk/drivers/scsi/Kconfig | 2 +- trunk/drivers/scsi/NCR53c406a.c | 1 + trunk/drivers/scsi/a100u2w.c | 1 + trunk/drivers/scsi/aacraid/commctrl.c | 29 +- trunk/drivers/scsi/aacraid/linit.c | 1 + trunk/drivers/scsi/aha1740.c | 1 + trunk/drivers/scsi/aic7xxx/aic79xx.h | 5 +- trunk/drivers/scsi/aic7xxx/aic79xx_core.c | 2 - trunk/drivers/scsi/aic7xxx/aic79xx_osm.c | 3 +- trunk/drivers/scsi/aic7xxx/aic79xx_osm_pci.c | 33 ++- trunk/drivers/scsi/aic7xxx/aic79xx_pci.c | 2 - trunk/drivers/scsi/aic7xxx/aic7xxx.h | 4 - trunk/drivers/scsi/aic7xxx/aic7xxx_core.c | 3 +- trunk/drivers/scsi/aic7xxx/aic7xxx_osm.c | 10 +- trunk/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c | 33 ++- trunk/drivers/scsi/aic7xxx/aic7xxx_pci.c | 2 - trunk/drivers/scsi/aic7xxx_old.c | 1 + trunk/drivers/scsi/arcmsr/arcmsr_hba.c | 1 + trunk/drivers/scsi/dc395x.c | 1 + trunk/drivers/scsi/dpt_i2o.c | 1 + trunk/drivers/scsi/eata.c | 1 + trunk/drivers/scsi/hosts.c | 1 + trunk/drivers/scsi/hptiop.c | 3 +- trunk/drivers/scsi/ibmmca.c | 1 + trunk/drivers/scsi/ibmvscsi/ibmvscsi.c | 1 + trunk/drivers/scsi/initio.c | 1 + trunk/drivers/scsi/iscsi_tcp.c | 1 + trunk/drivers/scsi/libsrp.c | 4 +- trunk/drivers/scsi/lpfc/lpfc_scsi.c | 2 + trunk/drivers/scsi/mac53c94.c | 1 + trunk/drivers/scsi/megaraid.c | 1 + trunk/drivers/scsi/megaraid/megaraid_mbox.c | 1 + trunk/drivers/scsi/megaraid/megaraid_sas.c | 1 + trunk/drivers/scsi/mesh.c | 1 + trunk/drivers/scsi/ncr53c8xx.c | 2 +- trunk/drivers/scsi/nsp32.c | 1 + trunk/drivers/scsi/pcmcia/sym53c500_cs.c | 1 + trunk/drivers/scsi/qla1280.c | 1 + trunk/drivers/scsi/qla2xxx/qla_os.c | 2 + trunk/drivers/scsi/qla4xxx/ql4_os.c | 1 + trunk/drivers/scsi/qlogicfas.c | 1 + trunk/drivers/scsi/scsi.c | 2 +- trunk/drivers/scsi/scsi_debug.c | 174 ++++-------- trunk/drivers/scsi/scsi_error.c | 33 ++- trunk/drivers/scsi/scsi_lib.c | 274 ++++++++----------- trunk/drivers/scsi/scsi_tgt_lib.c | 28 +- trunk/drivers/scsi/sd.c | 4 +- trunk/drivers/scsi/sgiwd93.c | 64 ++--- trunk/drivers/scsi/sr.c | 25 +- trunk/drivers/scsi/stex.c | 1 + trunk/drivers/scsi/sym53c416.c | 1 + trunk/drivers/scsi/sym53c8xx_2/sym_glue.c | 3 +- trunk/drivers/scsi/u14-34f.c | 1 + trunk/drivers/scsi/ultrastor.c | 1 + trunk/drivers/scsi/wd7000.c | 1 + trunk/drivers/usb/storage/isd200.c | 8 +- trunk/fs/dlm/dir.c | 76 ++--- trunk/fs/dlm/dlm_internal.h | 16 -- trunk/fs/dlm/lock.c | 249 +++++------------ trunk/fs/dlm/lock.h | 2 + trunk/fs/dlm/lockspace.c | 16 +- trunk/fs/dlm/lowcomms.c | 15 +- trunk/fs/dlm/main.c | 10 + trunk/fs/dlm/member.c | 4 +- trunk/fs/dlm/member.h | 3 +- trunk/fs/dlm/memory.c | 32 ++- trunk/fs/dlm/memory.h | 16 +- trunk/fs/dlm/midcomms.c | 15 +- trunk/fs/dlm/rcom.c | 25 +- trunk/fs/dlm/recover.c | 27 +- trunk/fs/dlm/recoverd.c | 11 +- trunk/fs/dlm/user.c | 29 +- trunk/fs/dlm/util.c | 82 ++---- trunk/include/scsi/scsi.h | 20 -- trunk/include/scsi/scsi_cmnd.h | 59 ++-- trunk/include/scsi/scsi_eh.h | 9 +- trunk/include/scsi/scsi_host.h | 17 +- 88 files changed, 660 insertions(+), 903 deletions(-) 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