[PATCH 6/9] hpsa: rework pci pm related code for simplification
Use pci core pm interface to simplify code. Signed-off-by: Yijing Wang Cc: "Stephen M. Cameron" Cc: "James E.J. Bottomley" Cc: iss_storage...@hp.com Cc: linux-scsi@vger.kernel.org Cc: linux-ker...@vger.kernel.org --- drivers/scsi/hpsa.c | 16 +++- 1 files changed, 3 insertions(+), 13 deletions(-) diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c index 7f4f790..f5ba6d4 100644 --- a/drivers/scsi/hpsa.c +++ b/drivers/scsi/hpsa.c @@ -3753,9 +3753,6 @@ static int hpsa_message(struct pci_dev *pdev, unsigned char opcode, static int hpsa_controller_hard_reset(struct pci_dev *pdev, void * __iomem vaddr, u32 use_doorbell) { - u16 pmcsr; - int pos; - if (use_doorbell) { /* For everything after the P600, the PCI power state method * of resetting the controller doesn't work, so we have this @@ -3773,8 +3770,7 @@ static int hpsa_controller_hard_reset(struct pci_dev *pdev, * this causes a secondary PCI reset which will reset the * controller." */ - pos = pci_find_capability(pdev, PCI_CAP_ID_PM); - if (pos == 0) { + if (!pdev->pm_cap) { dev_err(&pdev->dev, "hpsa_reset_controller: " "PCI PM not supported\n"); @@ -3782,18 +3778,12 @@ static int hpsa_controller_hard_reset(struct pci_dev *pdev, } dev_info(&pdev->dev, "using PCI PM to reset controller\n"); /* enter the D3hot power management state */ - pci_read_config_word(pdev, pos + PCI_PM_CTRL, &pmcsr); - pmcsr &= ~PCI_PM_CTRL_STATE_MASK; - pmcsr |= PCI_D3hot; - pci_write_config_word(pdev, pos + PCI_PM_CTRL, pmcsr); + pci_set_power_state(pdev, PCI_D3hot); msleep(500); /* enter the D0 power management state */ - pmcsr &= ~PCI_PM_CTRL_STATE_MASK; - pmcsr |= PCI_D0; - pci_write_config_word(pdev, pos + PCI_PM_CTRL, pmcsr); - + pci_set_power_state(pdev, PCI_D0); /* * The P600 requires a small delay when changing states. * Otherwise we may think the board did not reset and we bail. -- 1.7.1 -- To unsubscribe from this list: send the line "unsubscribe linux-scsi" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 8/9] scsi/pm8001: use pdev->pm_cap instead of pci_find_capability(..,PCI_CAP_ID_PM)
Pci core has been saved pm cap register offset by pdev->pm_cap in pci_pm_init() in init path. So we can use pdev->pm_cap instead of using pci_find_capability(pdev, PCI_CAP_ID_PM) for better performance and simplified code. Signed-off-by: Yijing Wang Cc: xjtu...@gmail.com Cc: lindar_...@usish.com Cc: "James E.J. Bottomley" Cc: linux-scsi@vger.kernel.org Cc: linux-ker...@vger.kernel.org --- drivers/scsi/pm8001/pm8001_init.c |7 +++ 1 files changed, 3 insertions(+), 4 deletions(-) diff --git a/drivers/scsi/pm8001/pm8001_init.c b/drivers/scsi/pm8001/pm8001_init.c index e4b9bc7..3861aa1 100644 --- a/drivers/scsi/pm8001/pm8001_init.c +++ b/drivers/scsi/pm8001/pm8001_init.c @@ -912,14 +912,13 @@ static int pm8001_pci_suspend(struct pci_dev *pdev, pm_message_t state) { struct sas_ha_struct *sha = pci_get_drvdata(pdev); struct pm8001_hba_info *pm8001_ha; - int i , pos; + int i; u32 device_state; pm8001_ha = sha->lldd_ha; flush_workqueue(pm8001_wq); scsi_block_requests(pm8001_ha->shost); - pos = pci_find_capability(pdev, PCI_CAP_ID_PM); - if (pos == 0) { - printk(KERN_ERR " PCI PM not supported\n"); + if (!pdev->pm_cap) { + dev_err(&pdev->dev, " PCI PM not supported\n"); return -ENODEV; } PM8001_CHIP_DISP->interrupt_disable(pm8001_ha, 0xFF); -- 1.7.1 -- To unsubscribe from this list: send the line "unsubscribe linux-scsi" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
RE: [PATCH 8/9] scsi/pm8001: use pdev->pm_cap instead of pci_find_capability(..,PCI_CAP_ID_PM)
It works, thanks. Lindar. -Original Message- From: Yijing Wang [mailto:wangyij...@huawei.com] Sent: Tuesday, June 18, 2013 4:24 PM To: James E.J. Bottomley Cc: linux-ker...@vger.kernel.org; Hanjun Guo; jiang@huawei.com; Yijing Wang; xjtu...@gmail.com; lindar_...@usish.com; linux-scsi@vger.kernel.org Subject: [PATCH 8/9] scsi/pm8001: use pdev->pm_cap instead of pci_find_capability(..,PCI_CAP_ID_PM) Pci core has been saved pm cap register offset by pdev->pm_cap in pci_pm_init() in init path. So we can use pdev->pm_cap instead of using pci_find_capability(pdev, PCI_CAP_ID_PM) for better performance and simplified code. Signed-off-by: Yijing Wang Cc: xjtu...@gmail.com Cc: lindar_...@usish.com Cc: "James E.J. Bottomley" Cc: linux-scsi@vger.kernel.org Cc: linux-ker...@vger.kernel.org --- drivers/scsi/pm8001/pm8001_init.c |7 +++ 1 files changed, 3 insertions(+), 4 deletions(-) diff --git a/drivers/scsi/pm8001/pm8001_init.c b/drivers/scsi/pm8001/pm8001_init.c index e4b9bc7..3861aa1 100644 --- a/drivers/scsi/pm8001/pm8001_init.c +++ b/drivers/scsi/pm8001/pm8001_init.c @@ -912,14 +912,13 @@ static int pm8001_pci_suspend(struct pci_dev *pdev, pm_message_t state) { struct sas_ha_struct *sha = pci_get_drvdata(pdev); struct pm8001_hba_info *pm8001_ha; - int i , pos; + int i; u32 device_state; pm8001_ha = sha->lldd_ha; flush_workqueue(pm8001_wq); scsi_block_requests(pm8001_ha->shost); - pos = pci_find_capability(pdev, PCI_CAP_ID_PM); - if (pos == 0) { - printk(KERN_ERR " PCI PM not supported\n"); + if (!pdev->pm_cap) { + dev_err(&pdev->dev, " PCI PM not supported\n"); return -ENODEV; } PM8001_CHIP_DISP->interrupt_disable(pm8001_ha, 0xFF); -- 1.7.1 -- To unsubscribe from this list: send the line "unsubscribe linux-scsi" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: Re: [SCSI] mvsas: Fix the kernel panic due to unaligned data access
Hi James, Thanks for the reply. See more below. > On Wed, 2013-05-08 at 15:01 +0800, Paul Guo wrote: >> It's easy to find the address and symbol that causes the unalignd data >> access according to the stack dump information. The following small >> patch will fix it. > > Do you have the panic log? because it sounds like a bug in your > platform code. All platforms have to support unaligned accesses because > some of the kernel parsers generate them as well. You can see examples > of how to do this in e.g. arch/parisc/kernel/unaligned.c Yes, our HW has the trap type for unaligned data access. Our kernel (see arch/tile/kernel/unaligned.c) has the ability to do fixup for user unaligned data access but we have limited ability to do fixup for kernel unaligned data access (In theory we can do it better but the work is more complex), and I'm not sure other platforms which do not support unaligned data access on HW could do kernel data fixup or not, but many kernel components have had considered the alignment for either performance or functionality purpose. At least we have run well with network stack, storage io stack, etc. I have to admit that there seems to exist kernel code that does not consider unaligned data access much, but why not try to fix them, for whatever reason. Following is the panic stack, from the PC register I can easily find which code line causes the unaligned data access. Pid: 0, comm: swapper, CPU: 1 r0 : 0xfe43f67e2c94 r1 : 0xfe43f86b2450 r2 : 0xfe43f86b2450 r3 : 0xfe43f86b2440 r4 : 0x r5 : 0x r6 : 0x r7 : 0x r8 : 0x r9 : 0x r10: 0xfe43f86b2450 r11: 0xfe43f86b2448 r12: 0xe03780f29b84 r13: 0x1fc87f0d647c r14: 0x0001 r15: 0x0080 r16: 0x0040 r17: 0x0002 r18: 0x0001 r19: 0xfe43f86b2448 r20: 0x0001 r21: 0x0002 r22: 0xfe43ffedfaa8 r23: 0x0002 r24: 0xfe43ffedfab0 r25: 0xfe43ffedfaf0 r26: 0xfe43ffedfab8 r27: 0xfe03f8a64648 r28: 0x000245f0 r29: 0x245f r30: 0xfe43f86b2300 r31: 0xfe03f8a4 r32: 0x0001 r33: 0xfe03f8a42590 r34: 0x0001 r35: 0x00030001 r36: 0xfe43f86b2318 r37: 0xfe03f8a40058 r38: 0xfe03f8a64610 r39: 0x0001 r40: 0x r41: 0x r42: 0xfea856f8 r43: 0xfe9a78d8 r44: 0xfe8e1298 r45: 0xfea70080 r46: 0x0001 r47: 0x r48: 0x r49: 0x r50: 0x r51: 0x r52: 0xfe43ffedfc40 tp : 0x01f4ff73 sp : 0xfe43ffedfa90 lr : 0xfff7002abec0 pc : 0xfff7002ac370 ex1: 1 faultnum: 17 Starting stack dump of tid 0, pid 0 (swapper) on cpu 1 at cycle 341465978177 frame 0: 0xfff7002ac370 mvs_slot_complete+0x5f0/0x12a0 (sp 0xfe43ffedfa90) frame 1: 0xfff7002abec0 mvs_slot_complete+0x140/0x12a0 (sp 0xfe43ffedfa90) frame 2: 0xfff7005cc840 mvs_int_rx+0x140/0x2a0 (sp 0xfe43ffedfb00) frame 3: 0xfff7005bbaf0 mvs_94xx_isr+0xd8/0x2b8 (sp 0xfe43ffedfb68) frame 4: 0xfff700658ba0 mvs_tasklet+0x128/0x1f8 (sp 0xfe43ffedfba8) frame 5: 0xfff7003e8230 tasklet_action+0x178/0x2c8 (sp 0xfe43ffedfbe0) frame 6: 0xfff700103850 __do_softirq+0x210/0x398 (sp 0xfe43ffedfc40) frame 7: 0xfff700180308 do_softirq+0xc8/0x140 (sp 0xfe43ffedfcd8) frame 8: 0xfff7000bd7f0 irq_exit+0xb0/0x158 (sp 0xfe43ffedfcf0) frame 9: 0xfff70013fa58 tile_dev_intr+0x1d8/0x2f0 (sp 0xfe43ffedfd00) frame 10: 0xfff70044ca78 handle_interrupt+0x270/0x278 (sp 0xfe43ffedfd40) frame 11: 0xfff700143e68 _cpu_idle_nap+0x0/0x18 (sp 0xfe43ffedffb0) frame 12: 0xfff700482480 cpu_idle+0x310/0x428 (sp 0xfe43ffedffb0) Stack dump complete Kernel panic - not syncing: Kernel unalign fault running the idle task! Starting stack dump of tid 0, pid 0 (swapper) on cpu 1 at cycle 341586172541 frame 0: 0xfff700140ee0 dump_stack+0x0/0x20 (sp 0xfe43ffedf420) frame 1: 0xfff700283270 panic+0x150/0x3a0 (sp 0xfe43ffedf420) frame 2: 0xfff70012bff8 jit_bundle_gen+0xfd8/0x27e0 (sp 0xfe43ffedf4c8) frame 3: 0xfff7003b5b68 do_unaligned+0xc0/0x5a0 (sp 0xfe43ffedf710) frame 4: 0xfff70044ca78 handle_interrupt+0x270/0x278 (sp 0xfe43ffedf840) frame 5: 0xfff7002ac370 mvs_slot_complete+0x5f0/0x12a0 (sp 0xfe43ffedfa90) frame 6: 0xfff7002abec0 mvs_slot_complete+0x140/0x12a0 (sp 0xfe43ffedfa90) frame 7: 0xfff7005cc840 mvs_int_rx+0x140/0x2a0 (sp 0xfe43ffedfb00) frame 8: 0xfff7005bbaf0 mvs_94xx_isr+0xd8/0x2b8 (sp 0xfe43ffedfb68) frame 9: 0xfff700658ba0 mvs_tasklet+0x128/0x1f8 (sp 0xfe43ffedfba8) f
[PATCH 1/1] aacraid: Fix for arrays are going offline in the system. System hangs
Hi James, One of the customer had reported that the set of raid logical arrays will become unavailable (I/O offline) after a long hours of IO stress test. The OS wouldn`t be accessible afterwards and require a hard reset. This driver patch has a fix for race condition between the doorbell and the circular buffer. The driver is modified to do an extra read after clearing the doorbell in case there had been a completion posted during the small timing window. With this fix, we ran IO stress for ~13 days. There were no IO failures. Signed-off-by: Mahesh Rajashekhara --- drivers/scsi/aacraid/src.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/scsi/aacraid/src.c b/drivers/scsi/aacraid/src.c index 0f56d8d..7e17107 100644 --- a/drivers/scsi/aacraid/src.c +++ b/drivers/scsi/aacraid/src.c @@ -93,6 +93,9 @@ static irqreturn_t aac_src_intr_message(int irq, void *dev_id) int send_it = 0; extern int aac_sync_mode; + src_writel(dev, MUnit.ODR_C, bellbits); + src_readl(dev, MUnit.ODR_C); + if (!aac_sync_mode) { src_writel(dev, MUnit.ODR_C, bellbits); src_readl(dev, MUnit.ODR_C); -- 1.7.11.7 -- To unsubscribe from this list: send the line "unsubscribe linux-scsi" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v2 0/4] introduce sg_pcopy_from_buffer() and sg_pcopy_to_buffer()
This patch set introduces sg_pcopy_from_buffer() and sg_pcopy_to_buffer(), which copy data between a linear buffer and an SG list. The only difference between sg_pcopy_{from,to}_buffer() and sg_copy_{from,to}_buffer() is an additional argument that specifies the number of bytes to skip the SG list before copying. The main reason for introducing these functions is to fix a problem in scsi_debug module. And there is a local function in crypto/talitos module, which can be replaced by sg_pcopy_to_buffer(). * Changes from v1 - Separate the change that factors out sg_miter_get_next_page() from the patch "introduce sg_pcopy_from_buffer() and sg_pcopy_to_buffer()" - Add function comment for internal function sg_miter_seek() - Simplify the assignment of sdb->resid in fill_from_dev_buffer() in scsi_debug Akinobu Mita (4): lib/scatterlist: factor out sg_miter_get_next_page() from sg_miter_next() lib/scatterlist: introduce sg_pcopy_from_buffer() and sg_pcopy_to_buffer() crypto: talitos: use sg_pcopy_to_buffer() scsi_debug: fix do_device_access() with wrap around range drivers/crypto/talitos.c| 60 + drivers/scsi/scsi_debug.c | 48 + include/linux/scatterlist.h | 5 ++ lib/scatterlist.c | 127 +--- 4 files changed, 150 insertions(+), 90 deletions(-) Cc: Tejun Heo Cc: Imre Deak Cc: Herbert Xu Cc: "David S. Miller" Cc: linux-cry...@vger.kernel.org Cc: "James E.J. Bottomley" Cc: Douglas Gilbert Cc: linux-scsi@vger.kernel.org -- 1.8.1.4 -- To unsubscribe from this list: send the line "unsubscribe linux-scsi" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v2 1/4] lib/scatterlist: factor out sg_miter_get_next_page() from sg_miter_next()
This function is used to proceed page iterator to the next page if necessary, and will be used to implement the variants of sg_copy_{from,to}_buffer() later. Signed-off-by: Akinobu Mita Cc: Tejun Heo Cc: Imre Deak Cc: Herbert Xu Cc: "David S. Miller" Cc: linux-cry...@vger.kernel.org Cc: "James E.J. Bottomley" Cc: Douglas Gilbert Cc: linux-scsi@vger.kernel.org --- * New patch from v2 lib/scatterlist.c | 39 --- 1 file changed, 24 insertions(+), 15 deletions(-) diff --git a/lib/scatterlist.c b/lib/scatterlist.c index a1cf8ca..c35b929 100644 --- a/lib/scatterlist.c +++ b/lib/scatterlist.c @@ -453,6 +453,28 @@ void sg_miter_start(struct sg_mapping_iter *miter, struct scatterlist *sgl, } EXPORT_SYMBOL(sg_miter_start); +static bool sg_miter_get_next_page(struct sg_mapping_iter *miter) +{ + if (!miter->__remaining) { + struct scatterlist *sg; + unsigned long pgoffset; + + if (!__sg_page_iter_next(&miter->piter)) + return false; + + sg = miter->piter.sg; + pgoffset = miter->piter.sg_pgoffset; + + miter->__offset = pgoffset ? 0 : sg->offset; + miter->__remaining = sg->offset + sg->length - + (pgoffset << PAGE_SHIFT) - miter->__offset; + miter->__remaining = min_t(unsigned long, miter->__remaining, + PAGE_SIZE - miter->__offset); + } + + return true; +} + /** * sg_miter_next - proceed mapping iterator to the next mapping * @miter: sg mapping iter to proceed @@ -478,22 +500,9 @@ bool sg_miter_next(struct sg_mapping_iter *miter) * Get to the next page if necessary. * __remaining, __offset is adjusted by sg_miter_stop */ - if (!miter->__remaining) { - struct scatterlist *sg; - unsigned long pgoffset; - - if (!__sg_page_iter_next(&miter->piter)) - return false; - - sg = miter->piter.sg; - pgoffset = miter->piter.sg_pgoffset; + if (!sg_miter_get_next_page(miter)) + return false; - miter->__offset = pgoffset ? 0 : sg->offset; - miter->__remaining = sg->offset + sg->length - - (pgoffset << PAGE_SHIFT) - miter->__offset; - miter->__remaining = min_t(unsigned long, miter->__remaining, - PAGE_SIZE - miter->__offset); - } miter->page = sg_page_iter_page(&miter->piter); miter->consumed = miter->length = miter->__remaining; -- 1.8.1.4 -- To unsubscribe from this list: send the line "unsubscribe linux-scsi" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v2 2/4] lib/scatterlist: introduce sg_pcopy_from_buffer() and sg_pcopy_to_buffer()
The only difference between sg_pcopy_{from,to}_buffer() and sg_copy_{from,to}_buffer() is an additional argument that specifies the number of bytes to skip the SG list before copying. Signed-off-by: Akinobu Mita Cc: Tejun Heo Cc: Imre Deak Cc: Herbert Xu Cc: "David S. Miller" Cc: linux-cry...@vger.kernel.org Cc: "James E.J. Bottomley" Cc: Douglas Gilbert Cc: linux-scsi@vger.kernel.org --- * Change from v2 - Separate the change that factors out sg_miter_get_next_page() - Add function comment for internal function sg_miter_seek() include/linux/scatterlist.h | 5 +++ lib/scatterlist.c | 88 ++--- 2 files changed, 88 insertions(+), 5 deletions(-) diff --git a/include/linux/scatterlist.h b/include/linux/scatterlist.h index 2680677..adae88f 100644 --- a/include/linux/scatterlist.h +++ b/include/linux/scatterlist.h @@ -244,6 +244,11 @@ size_t sg_copy_from_buffer(struct scatterlist *sgl, unsigned int nents, size_t sg_copy_to_buffer(struct scatterlist *sgl, unsigned int nents, void *buf, size_t buflen); +size_t sg_pcopy_from_buffer(struct scatterlist *sgl, unsigned int nents, + void *buf, size_t buflen, off_t skip); +size_t sg_pcopy_to_buffer(struct scatterlist *sgl, unsigned int nents, + void *buf, size_t buflen, off_t skip); + /* * Maximum number of entries that will be allocated in one piece, if * a list larger than this is required then chaining will be utilized. diff --git a/lib/scatterlist.c b/lib/scatterlist.c index c35b929..f167392 100644 --- a/lib/scatterlist.c +++ b/lib/scatterlist.c @@ -476,6 +476,43 @@ static bool sg_miter_get_next_page(struct sg_mapping_iter *miter) } /** + * sg_miter_seek - reposition mapping iterator + * @miter: sg mapping iter to be seeked + * @offset: number of bytes to plus the current location + * + * Description: + * Sets the offset of @miter to its current location plus @offset bytes. + * + * Notes: + * This function must be called just after sg_miter_start() or sg_miter_stop() + * + * Context: + * Don't care. + * + * Returns: + * true if @miter contains the valid mapping. false if end of sg + * list is reached. + */ +static bool sg_miter_seek(struct sg_mapping_iter *miter, off_t offset) +{ + WARN_ON(miter->addr); + + while (offset) { + off_t consumed; + + if (!sg_miter_get_next_page(miter)) + return false; + + consumed = min_t(off_t, offset, miter->__remaining); + miter->__offset += consumed; + miter->__remaining -= consumed; + offset -= consumed; + } + + return true; +} + +/** * sg_miter_next - proceed mapping iterator to the next mapping * @miter: sg mapping iter to proceed * @@ -561,14 +598,16 @@ EXPORT_SYMBOL(sg_miter_stop); * @nents: Number of SG entries * @buf:Where to copy from * @buflen: The number of bytes to copy - * @to_buffer: transfer direction (non zero == from an sg list to a - * buffer, 0 == from a buffer to an sg list + * @skip: Number of bytes to skip before copying + * @to_buffer: transfer direction (true == from an sg list to a + * buffer, false == from a buffer to an sg list * * Returns the number of copied bytes. * **/ static size_t sg_copy_buffer(struct scatterlist *sgl, unsigned int nents, -void *buf, size_t buflen, int to_buffer) +void *buf, size_t buflen, off_t skip, +bool to_buffer) { unsigned int offset = 0; struct sg_mapping_iter miter; @@ -582,6 +621,9 @@ static size_t sg_copy_buffer(struct scatterlist *sgl, unsigned int nents, sg_miter_start(&miter, sgl, nents, sg_flags); + if (!sg_miter_seek(&miter, skip)) + return false; + local_irq_save(flags); while (sg_miter_next(&miter) && offset < buflen) { @@ -616,7 +658,7 @@ static size_t sg_copy_buffer(struct scatterlist *sgl, unsigned int nents, size_t sg_copy_from_buffer(struct scatterlist *sgl, unsigned int nents, void *buf, size_t buflen) { - return sg_copy_buffer(sgl, nents, buf, buflen, 0); + return sg_copy_buffer(sgl, nents, buf, buflen, 0, false); } EXPORT_SYMBOL(sg_copy_from_buffer); @@ -633,6 +675,42 @@ EXPORT_SYMBOL(sg_copy_from_buffer); size_t sg_copy_to_buffer(struct scatterlist *sgl, unsigned int nents, void *buf, size_t buflen) { - return sg_copy_buffer(sgl, nents, buf, buflen, 1); + return sg_copy_buffer(sgl, nents, buf, buflen, 0, true); } EXPORT_SYMBOL(sg_copy_to_buffer); + +/** + * sg_pcopy_from_buffer - Copy from a linear buffer to an SG list + * @sgl:The SG list + * @nents: Number of SG en
[PATCH v2 4/4] scsi_debug: fix do_device_access() with wrap around range
do_device_access() is a function that abstracts copying SG list from/to ramdisk storage (fake_storep). It must deal with the ranges exceeding actual fake_storep size, because such ranges are valid if virtual_gb is set greater than zero, and they should be treated as fake_storep is repeatedly mirrored up to virtual size. Unfortunately, it can't deal with the range which wraps around the end of fake_storep. A wrap around range is copied by two sg_copy_{from,to}_buffer() calls, but sg_copy_{from,to}_buffer() can't copy from/to in the middle of SG list, therefore the second call can't copy correctly. This fixes it by using sg_pcopy_{from,to}_buffer() that can copy from/to the middle of SG list. This also simplifies the assignment of sdb->resid in fill_from_dev_buffer(). Because fill_from_dev_buffer() is now only called once per command execution cycle. So it is not necessary to take care to decrease sdb->resid if fill_from_dev_buffer() is called more than once. Signed-off-by: Akinobu Mita Cc: "James E.J. Bottomley" Cc: Douglas Gilbert Cc: linux-scsi@vger.kernel.org --- * Change from v2 - Simplify the assignment of sdb->resid in fill_from_dev_buffer() drivers/scsi/scsi_debug.c | 48 --- 1 file changed, 37 insertions(+), 11 deletions(-) diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c index 21239b3..1b15f98 100644 --- a/drivers/scsi/scsi_debug.c +++ b/drivers/scsi/scsi_debug.c @@ -417,10 +417,7 @@ static int fill_from_dev_buffer(struct scsi_cmnd *scp, unsigned char *arr, act_len = sg_copy_from_buffer(sdb->table.sgl, sdb->table.nents, arr, arr_len); - if (sdb->resid) - sdb->resid -= act_len; - else - sdb->resid = scsi_bufflen(scp) - act_len; + sdb->resid = scsi_bufflen(scp) - act_len; return 0; } @@ -1614,24 +1611,48 @@ static int check_device_access_params(struct sdebug_dev_info *devi, return 0; } +/* Returns number of bytes copied or -1 if error. */ static int do_device_access(struct scsi_cmnd *scmd, struct sdebug_dev_info *devi, unsigned long long lba, unsigned int num, int write) { int ret; unsigned long long block, rest = 0; - int (*func)(struct scsi_cmnd *, unsigned char *, int); + struct scsi_data_buffer *sdb; + enum dma_data_direction dir; + size_t (*func)(struct scatterlist *, unsigned int, void *, size_t, + off_t); + + if (write) { + sdb = scsi_out(scmd); + dir = DMA_TO_DEVICE; + func = sg_pcopy_to_buffer; + } else { + sdb = scsi_in(scmd); + dir = DMA_FROM_DEVICE; + func = sg_pcopy_from_buffer; + } - func = write ? fetch_to_dev_buffer : fill_from_dev_buffer; + if (!sdb->length) + return 0; + if (!(scsi_bidi_cmnd(scmd) || scmd->sc_data_direction == dir)) + return -1; block = do_div(lba, sdebug_store_sectors); if (block + num > sdebug_store_sectors) rest = block + num - sdebug_store_sectors; - ret = func(scmd, fake_storep + (block * scsi_debug_sector_size), - (num - rest) * scsi_debug_sector_size); - if (!ret && rest) - ret = func(scmd, fake_storep, rest * scsi_debug_sector_size); + ret = func(sdb->table.sgl, sdb->table.nents, + fake_storep + (block * scsi_debug_sector_size), + (num - rest) * scsi_debug_sector_size, 0); + if (ret != (num - rest) * scsi_debug_sector_size) + return ret; + + if (rest) { + ret += func(sdb->table.sgl, sdb->table.nents, + fake_storep, rest * scsi_debug_sector_size, + (num - rest) * scsi_debug_sector_size); + } return ret; } @@ -1888,7 +1909,12 @@ static int resp_read(struct scsi_cmnd *SCpnt, unsigned long long lba, read_lock_irqsave(&atomic_rw, iflags); ret = do_device_access(SCpnt, devip, lba, num, 0); read_unlock_irqrestore(&atomic_rw, iflags); - return ret; + if (ret == -1) + return DID_ERROR << 16; + + scsi_in(SCpnt)->resid = scsi_bufflen(SCpnt) - ret; + + return 0; } static void dump_sector(unsigned char *buf, int len) -- 1.8.1.4 -- To unsubscribe from this list: send the line "unsubscribe linux-scsi" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v2 1/4] lib/scatterlist: factor out sg_miter_get_next_page() from sg_miter_next()
On Tue, Jun 18, 2013 at 10:31:31PM +0900, Akinobu Mita wrote: > This function is used to proceed page iterator to the next page if > necessary, and will be used to implement the variants of > sg_copy_{from,to}_buffer() later. > > Signed-off-by: Akinobu Mita > Cc: Tejun Heo > Cc: Imre Deak > Cc: Herbert Xu > Cc: "David S. Miller" > Cc: linux-cry...@vger.kernel.org > Cc: "James E.J. Bottomley" > Cc: Douglas Gilbert > Cc: linux-scsi@vger.kernel.org Acked-by: Tejun Heo Thanks. -- tejun -- To unsubscribe from this list: send the line "unsubscribe linux-scsi" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v2 2/4] lib/scatterlist: introduce sg_pcopy_from_buffer() and sg_pcopy_to_buffer()
On Tue, Jun 18, 2013 at 10:31:32PM +0900, Akinobu Mita wrote: > /** > + * sg_miter_seek - reposition mapping iterator > + * @miter: sg mapping iter to be seeked > + * @offset: number of bytes to plus the current location > + * > + * Description: > + * Sets the offset of @miter to its current location plus @offset bytes. > + * > + * Notes: > + * This function must be called just after sg_miter_start() or > sg_miter_stop() It's not gonna be hard to make this function to handle any state, right? Wouldn't it be better to do that? It's a pretty generic feature after all. Also, maybe a better name is sg_miter_skip()? Thanks. -- tejun -- To unsubscribe from this list: send the line "unsubscribe linux-scsi" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
GUARANTEED LOAN OFFER
Do You Need Personal/Business Loan At 3%? If Yes Send Reply To This Email: williamsmark...@gmail.com 1. Name___2. Amount3. Country___4. Phone No___5. Duration_ All Repply Should Be Forwarded to This Email: williamsmark...@gmail.com-- To unsubscribe from this list: send the line "unsubscribe linux-scsi" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 07/14] scsi_transport_srp: Add transport layer error handling
Bart Van Assche wrote: On 06/14/13 19:59, Vu Pham wrote: On 06/13/13 21:43, Vu Pham wrote: +/** + * srp_tmo_valid() - check timeout combination validity + * + * If no fast I/O fail timeout has been configured then the device loss timeout + * must be below SCSI_DEVICE_BLOCK_MAX_TIMEOUT. If a fast I/O fail timeout has + * been configured then it must be below the device loss timeout. + */ +int srp_tmo_valid(int fast_io_fail_tmo, int dev_loss_tmo) +{ +return (fast_io_fail_tmo < 0 && 1 <= dev_loss_tmo && +dev_loss_tmo <= SCSI_DEVICE_BLOCK_MAX_TIMEOUT) +|| (0 <= fast_io_fail_tmo && +(dev_loss_tmo < 0 || + (fast_io_fail_tmo < dev_loss_tmo && + dev_loss_tmo < LONG_MAX / HZ))) ? 0 : -EINVAL; +} +EXPORT_SYMBOL_GPL(srp_tmo_valid); fast_io_fail_tmo is off, one cannot turn off dev_loss_tmo with negative value dev_loss_tmo is off, one cannot turn off fast_io_fail_tmo with negative value OK, will update the documentation such that it correctly refers to "off" instead of a negative value and I will also mention that dev_loss_tmo can now be disabled. It's not only the documentation but also the code logic, you cannot turn dev_loss_tmo off if fast_io_fail_tmo already turned off and vice versa with the return statement above. Does this mean that you think it would be useful to disable both the fast_io_fail and the dev_loss mechanisms, and hence rely on the user to remove remote ports that have disappeared and on the SCSI command timeout to detect path failures ? Yes. I'll start testing this to see whether that combination does not trigger any adverse behavior. Ok If rport's state is already SRP_RPORT_BLOCKED, I don't think we need to do extra block with scsi_block_requests() Please keep in mind that srp_reconnect_rport() can be called from two different contexts: that function can not only be called from inside the SRP transport layer but also from inside the SCSI error handler (see also the srp_reset_device() modifications in a later patch in this series). If this function is invoked from the context of the SCSI error handler the chance is high that the SCSI device will have another state than SDEV_BLOCK. Hence the scsi_block_requests() call in this function. Yes, srp_reconnect_rport() can be called from two contexts; however, it deals with same rport & rport's state. I'm thinking something like this: if (rport->state != SRP_RPORT_BLOCKED) { scsi_block_requests(shost); Sorry but I'm afraid that that approach would still allow the user to unblock one or more SCSI devices via sysfs during the i->f->reconnect(rport) call, something we do not want. I don't think that user can unblock scsi device(s) via sysfs if you use scsi_block_requests(shost) in srp_start_tl_fail_timers(). -vu I think that we can use only the pair scsi_block_requests()/scsi_unblock_requests() unless the advantage of multipathd recognizing the SDEV_BLOCK is noticeable. I think the advantage of multipathd recognizing the SDEV_BLOCK state before the fast_io_fail_tmo timer has expired is important. Multipathd does not queue I/O to paths that are in the SDEV_BLOCK state so setting that state helps I/O to fail over more quickly, especially for large values of fast_io_fail_tmo. Hope this helps, Bart. -- To unsubscribe from this list: send the line "unsubscribe linux-scsi" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Suply Sample
Hello sir/madam how are you doing i hope fine. Sir i contacted you r company so we can go into seriouse business . I will like you to supply the following product in a large quantity to my company i have attach a sample of it kindly view the sample in the attachment and see if you can supply much of it to my compnay. View it and get back to me as soon as possible so i can place and order for it. I look forward to hear from you soon thanks and have a great day . Kind regars Donald -- To unsubscribe from this list: send the line "unsubscribe linux-scsi" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html