From cb0258a2fb8e434b3b56856603754d998008d9ee Mon Sep 17 00:00:00 2001 From: Christoph Hellwig <hch@lst.de> Date: Mon, 31 Oct 2005 20:12:07 +0100 Subject: [SCSI] megaraid (legacy): remove scsi_assign_lock usage just take the adapter lock in megaraid_queue. Additional benefit is that we can get rid of the awkward conditional locking in mega_internal_command. Signed-off-by: Christoph Hellwig <hch@lst.de> Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com> --- drivers/scsi/megaraid.c | 32 +++++++++++++------------------- 1 file changed, 13 insertions(+), 19 deletions(-) (limited to 'drivers/scsi/megaraid.c') diff --git a/drivers/scsi/megaraid.c b/drivers/scsi/megaraid.c index 61a6fd810bb..93c95bc82c1 100644 --- a/drivers/scsi/megaraid.c +++ b/drivers/scsi/megaraid.c @@ -362,6 +362,7 @@ megaraid_queue(Scsi_Cmnd *scmd, void (*done)(Scsi_Cmnd *)) adapter_t *adapter; scb_t *scb; int busy=0; + unsigned long flags; adapter = (adapter_t *)scmd->device->host->hostdata; @@ -377,6 +378,7 @@ megaraid_queue(Scsi_Cmnd *scmd, void (*done)(Scsi_Cmnd *)) * return 0 in that case. */ + spin_lock_irqsave(&adapter->lock, flags); scb = mega_build_cmd(adapter, scmd, &busy); if(scb) { @@ -393,6 +395,7 @@ megaraid_queue(Scsi_Cmnd *scmd, void (*done)(Scsi_Cmnd *)) } return 0; } + spin_unlock_irqrestore(&adapter->lock, flags); return busy; } @@ -1981,7 +1984,7 @@ megaraid_reset(struct scsi_cmnd *cmd) mc.cmd = MEGA_CLUSTER_CMD; mc.opcode = MEGA_RESET_RESERVATIONS; - if( mega_internal_command(adapter, LOCK_INT, &mc, NULL) != 0 ) { + if( mega_internal_command(adapter, &mc, NULL) != 0 ) { printk(KERN_WARNING "megaraid: reservation reset failed.\n"); } @@ -3011,7 +3014,7 @@ proc_rdrv(adapter_t *adapter, char *page, int start, int end ) mc.cmd = FC_NEW_CONFIG; mc.opcode = OP_DCMD_READ_CONFIG; - if( mega_internal_command(adapter, LOCK_INT, &mc, NULL) ) { + if( mega_internal_command(adapter, &mc, NULL) ) { len = sprintf(page, "40LD read config failed.\n"); @@ -3029,11 +3032,11 @@ proc_rdrv(adapter_t *adapter, char *page, int start, int end ) else { mc.cmd = NEW_READ_CONFIG_8LD; - if( mega_internal_command(adapter, LOCK_INT, &mc, NULL) ) { + if( mega_internal_command(adapter, &mc, NULL) ) { mc.cmd = READ_CONFIG_8LD; - if( mega_internal_command(adapter, LOCK_INT, &mc, + if( mega_internal_command(adapter, &mc, NULL) ){ len = sprintf(page, @@ -3632,7 +3635,7 @@ megadev_ioctl(struct inode *inode, struct file *filep, unsigned int cmd, /* * Issue the command */ - mega_internal_command(adapter, LOCK_INT, &mc, pthru); + mega_internal_command(adapter, &mc, pthru); rval = mega_n_to_m((void __user *)arg, &mc); @@ -3715,7 +3718,7 @@ freemem_and_return: /* * Issue the command */ - mega_internal_command(adapter, LOCK_INT, &mc, NULL); + mega_internal_command(adapter, &mc, NULL); rval = mega_n_to_m((void __user *)arg, &mc); @@ -4234,7 +4237,7 @@ mega_do_del_logdrv(adapter_t *adapter, int logdrv) mc.opcode = OP_DEL_LOGDRV; mc.subopcode = logdrv; - rval = mega_internal_command(adapter, LOCK_INT, &mc, NULL); + rval = mega_internal_command(adapter, &mc, NULL); /* log this event */ if(rval) { @@ -4367,7 +4370,7 @@ mega_adapinq(adapter_t *adapter, dma_addr_t dma_handle) mc.xferaddr = (u32)dma_handle; - if ( mega_internal_command(adapter, LOCK_INT, &mc, NULL) != 0 ) { + if ( mega_internal_command(adapter, &mc, NULL) != 0 ) { return -1; } @@ -4435,7 +4438,7 @@ mega_internal_dev_inquiry(adapter_t *adapter, u8 ch, u8 tgt, mc.cmd = MEGA_MBOXCMD_PASSTHRU; mc.xferaddr = (u32)pthru_dma_handle; - rval = mega_internal_command(adapter, LOCK_INT, &mc, pthru); + rval = mega_internal_command(adapter, &mc, pthru); pci_free_consistent(pdev, sizeof(mega_passthru), pthru, pthru_dma_handle); @@ -4449,7 +4452,6 @@ mega_internal_dev_inquiry(adapter_t *adapter, u8 ch, u8 tgt, /** * mega_internal_command() * @adapter - pointer to our soft state - * @ls - the scope of the exclusion lock. * @mc - the mailbox command * @pthru - Passthru structure for DCDB commands * @@ -4463,8 +4465,7 @@ mega_internal_dev_inquiry(adapter_t *adapter, u8 ch, u8 tgt, * Note: parameter 'pthru' is null for non-passthru commands. */ static int -mega_internal_command(adapter_t *adapter, lockscope_t ls, megacmd_t *mc, - mega_passthru *pthru ) +mega_internal_command(adapter_t *adapter, megacmd_t *mc, mega_passthru *pthru) { Scsi_Cmnd *scmd; struct scsi_device *sdev; @@ -4508,15 +4509,8 @@ mega_internal_command(adapter_t *adapter, lockscope_t ls, megacmd_t *mc, scb->idx = CMDID_INT_CMDS; - /* - * Get the lock only if the caller has not acquired it already - */ - if( ls == LOCK_INT ) spin_lock_irqsave(&adapter->lock, flags); - megaraid_queue(scmd, mega_internal_done); - if( ls == LOCK_INT ) spin_unlock_irqrestore(&adapter->lock, flags); - wait_for_completion(&adapter->int_waitq); rval = scmd->result; -- cgit v1.2.3-70-g09d2 From 0a04137e75204e370dbdf2376033853eea126de7 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig <hch@lst.de> Date: Mon, 31 Oct 2005 18:31:56 +0100 Subject: [SCSI] remove Scsi_Pointer typedef Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com> --- drivers/scsi/arm/acornscsi.c | 2 +- drivers/scsi/arm/acornscsi.h | 2 +- drivers/scsi/arm/arxescsi.c | 6 +++--- drivers/scsi/arm/cumana_2.c | 6 +++--- drivers/scsi/arm/eesox.c | 6 +++--- drivers/scsi/arm/fas216.c | 6 +++--- drivers/scsi/arm/fas216.h | 8 ++++---- drivers/scsi/arm/powertec.c | 4 ++-- drivers/scsi/arm/scsi.h | 8 ++++---- drivers/scsi/megaraid.c | 2 +- drivers/scsi/scsi_typedefs.h | 1 - 11 files changed, 25 insertions(+), 26 deletions(-) (limited to 'drivers/scsi/megaraid.c') diff --git a/drivers/scsi/arm/acornscsi.c b/drivers/scsi/arm/acornscsi.c index cbf420c5394..29a86ee0aa2 100644 --- a/drivers/scsi/arm/acornscsi.c +++ b/drivers/scsi/arm/acornscsi.c @@ -896,7 +896,7 @@ void acornscsi_done(AS_Host *host, Scsi_Cmnd **SCpntp, unsigned int result) * Notes : this will only be one SG entry or less */ static -void acornscsi_data_updateptr(AS_Host *host, Scsi_Pointer *SCp, unsigned int length) +void acornscsi_data_updateptr(AS_Host *host, struct scsi_pointer *SCp, unsigned int length) { SCp->ptr += length; SCp->this_residual -= length; diff --git a/drivers/scsi/arm/acornscsi.h b/drivers/scsi/arm/acornscsi.h index 03881f09164..2142290f840 100644 --- a/drivers/scsi/arm/acornscsi.h +++ b/drivers/scsi/arm/acornscsi.h @@ -292,7 +292,7 @@ typedef struct acornscsi_hostdata { unsigned char tag; /* reconnected tag */ } reconnected; - Scsi_Pointer SCp; /* current commands data pointer */ + struct scsi_pointer SCp; /* current commands data pointer */ MsgQueue_t msgs; diff --git a/drivers/scsi/arm/arxescsi.c b/drivers/scsi/arm/arxescsi.c index 8b8c0187bd9..804125e35fc 100644 --- a/drivers/scsi/arm/arxescsi.c +++ b/drivers/scsi/arm/arxescsi.c @@ -65,7 +65,7 @@ struct arxescsi_info { * Returns : 0 if we should not set CMD_WITHDMA for transfer info command */ static fasdmatype_t -arxescsi_dma_setup(struct Scsi_Host *host, Scsi_Pointer *SCp, +arxescsi_dma_setup(struct Scsi_Host *host, struct scsi_pointer *SCp, fasdmadir_t direction, fasdmatype_t min_type) { /* @@ -111,7 +111,7 @@ static void arxescsi_pseudo_dma_write(unsigned char *addr, void __iomem *base) * transfer - minimum number of bytes we expect to transfer */ static void -arxescsi_dma_pseudo(struct Scsi_Host *host, Scsi_Pointer *SCp, +arxescsi_dma_pseudo(struct Scsi_Host *host, struct scsi_pointer *SCp, fasdmadir_t direction, int transfer) { struct arxescsi_info *info = (struct arxescsi_info *)host->hostdata; @@ -197,7 +197,7 @@ arxescsi_dma_pseudo(struct Scsi_Host *host, Scsi_Pointer *SCp, * Params : host - host * SCpnt - command */ -static void arxescsi_dma_stop(struct Scsi_Host *host, Scsi_Pointer *SCp) +static void arxescsi_dma_stop(struct Scsi_Host *host, struct scsi_pointer *SCp) { /* * no DMA to stop diff --git a/drivers/scsi/arm/cumana_2.c b/drivers/scsi/arm/cumana_2.c index 18a6f9930fc..3a7a46b0dc4 100644 --- a/drivers/scsi/arm/cumana_2.c +++ b/drivers/scsi/arm/cumana_2.c @@ -157,7 +157,7 @@ cumanascsi_2_intr(int irq, void *dev_id, struct pt_regs *regs) * Returns : type of transfer to be performed */ static fasdmatype_t -cumanascsi_2_dma_setup(struct Scsi_Host *host, Scsi_Pointer *SCp, +cumanascsi_2_dma_setup(struct Scsi_Host *host, struct scsi_pointer *SCp, fasdmadir_t direction, fasdmatype_t min_type) { struct cumanascsi2_info *info = (struct cumanascsi2_info *)host->hostdata; @@ -209,7 +209,7 @@ cumanascsi_2_dma_setup(struct Scsi_Host *host, Scsi_Pointer *SCp, * transfer - minimum number of bytes we expect to transfer */ static void -cumanascsi_2_dma_pseudo(struct Scsi_Host *host, Scsi_Pointer *SCp, +cumanascsi_2_dma_pseudo(struct Scsi_Host *host, struct scsi_pointer *SCp, fasdmadir_t direction, int transfer) { struct cumanascsi2_info *info = (struct cumanascsi2_info *)host->hostdata; @@ -283,7 +283,7 @@ cumanascsi_2_dma_pseudo(struct Scsi_Host *host, Scsi_Pointer *SCp, * SCpnt - command */ static void -cumanascsi_2_dma_stop(struct Scsi_Host *host, Scsi_Pointer *SCp) +cumanascsi_2_dma_stop(struct Scsi_Host *host, struct scsi_pointer *SCp) { struct cumanascsi2_info *info = (struct cumanascsi2_info *)host->hostdata; if (info->info.scsi.dma != NO_DMA) { diff --git a/drivers/scsi/arm/eesox.c b/drivers/scsi/arm/eesox.c index ced21fe128c..4d1e8f52c92 100644 --- a/drivers/scsi/arm/eesox.c +++ b/drivers/scsi/arm/eesox.c @@ -158,7 +158,7 @@ eesoxscsi_intr(int irq, void *dev_id, struct pt_regs *regs) * Returns : type of transfer to be performed */ static fasdmatype_t -eesoxscsi_dma_setup(struct Scsi_Host *host, Scsi_Pointer *SCp, +eesoxscsi_dma_setup(struct Scsi_Host *host, struct scsi_pointer *SCp, fasdmadir_t direction, fasdmatype_t min_type) { struct eesoxscsi_info *info = (struct eesoxscsi_info *)host->hostdata; @@ -353,7 +353,7 @@ static void eesoxscsi_buffer_out(void *buf, int length, void __iomem *base) } static void -eesoxscsi_dma_pseudo(struct Scsi_Host *host, Scsi_Pointer *SCp, +eesoxscsi_dma_pseudo(struct Scsi_Host *host, struct scsi_pointer *SCp, fasdmadir_t dir, int transfer_size) { struct eesoxscsi_info *info = (struct eesoxscsi_info *)host->hostdata; @@ -370,7 +370,7 @@ eesoxscsi_dma_pseudo(struct Scsi_Host *host, Scsi_Pointer *SCp, * SCpnt - command */ static void -eesoxscsi_dma_stop(struct Scsi_Host *host, Scsi_Pointer *SCp) +eesoxscsi_dma_stop(struct Scsi_Host *host, struct scsi_pointer *SCp) { struct eesoxscsi_info *info = (struct eesoxscsi_info *)host->hostdata; if (info->info.scsi.dma != NO_DMA) diff --git a/drivers/scsi/arm/fas216.c b/drivers/scsi/arm/fas216.c index 4772fb317f3..55015e3c8d2 100644 --- a/drivers/scsi/arm/fas216.c +++ b/drivers/scsi/arm/fas216.c @@ -173,7 +173,7 @@ static void fas216_dumpstate(FAS216_Info *info) fas216_readb(info, REG_CTCH)); } -static void print_SCp(Scsi_Pointer *SCp, const char *prefix, const char *suffix) +static void print_SCp(struct scsi_pointer *SCp, const char *prefix, const char *suffix) { printk("%sptr %p this_residual 0x%x buffer %p buffers_residual 0x%x%s", prefix, SCp->ptr, SCp->this_residual, SCp->buffer, @@ -628,7 +628,7 @@ static void fas216_handlesync(FAS216_Info *info, char *msg) */ static void fas216_updateptrs(FAS216_Info *info, int bytes_transferred) { - Scsi_Pointer *SCp = &info->scsi.SCp; + struct scsi_pointer *SCp = &info->scsi.SCp; fas216_checkmagic(info); @@ -668,7 +668,7 @@ static void fas216_updateptrs(FAS216_Info *info, int bytes_transferred) */ static void fas216_pio(FAS216_Info *info, fasdmadir_t direction) { - Scsi_Pointer *SCp = &info->scsi.SCp; + struct scsi_pointer *SCp = &info->scsi.SCp; fas216_checkmagic(info); diff --git a/drivers/scsi/arm/fas216.h b/drivers/scsi/arm/fas216.h index 60a2a120205..540914d6fd3 100644 --- a/drivers/scsi/arm/fas216.h +++ b/drivers/scsi/arm/fas216.h @@ -243,7 +243,7 @@ typedef struct { unsigned int irq; /* interrupt */ int dma; /* dma channel */ - Scsi_Pointer SCp; /* current commands data pointer */ + struct scsi_pointer SCp; /* current commands data pointer */ MsgQueue_t msgs; /* message queue for connected device */ @@ -304,9 +304,9 @@ typedef struct { /* dma */ struct { fasdmatype_t transfer_type; /* current type of DMA transfer */ - fasdmatype_t (*setup) (struct Scsi_Host *host, Scsi_Pointer *SCp, fasdmadir_t direction, fasdmatype_t min_dma); - void (*pseudo)(struct Scsi_Host *host, Scsi_Pointer *SCp, fasdmadir_t direction, int transfer); - void (*stop) (struct Scsi_Host *host, Scsi_Pointer *SCp); + fasdmatype_t (*setup) (struct Scsi_Host *host, struct scsi_pointer *SCp, fasdmadir_t direction, fasdmatype_t min_dma); + void (*pseudo)(struct Scsi_Host *host, struct scsi_pointer *SCp, fasdmadir_t direction, int transfer); + void (*stop) (struct Scsi_Host *host, struct scsi_pointer *SCp); } dma; /* miscellaneous */ diff --git a/drivers/scsi/arm/powertec.c b/drivers/scsi/arm/powertec.c index 547daf9afe5..3333d7b3913 100644 --- a/drivers/scsi/arm/powertec.c +++ b/drivers/scsi/arm/powertec.c @@ -132,7 +132,7 @@ powertecscsi_intr(int irq, void *dev_id, struct pt_regs *regs) * Returns : type of transfer to be performed */ static fasdmatype_t -powertecscsi_dma_setup(struct Scsi_Host *host, Scsi_Pointer *SCp, +powertecscsi_dma_setup(struct Scsi_Host *host, struct scsi_pointer *SCp, fasdmadir_t direction, fasdmatype_t min_type) { struct powertec_info *info = (struct powertec_info *)host->hostdata; @@ -174,7 +174,7 @@ powertecscsi_dma_setup(struct Scsi_Host *host, Scsi_Pointer *SCp, * SCpnt - command */ static void -powertecscsi_dma_stop(struct Scsi_Host *host, Scsi_Pointer *SCp) +powertecscsi_dma_stop(struct Scsi_Host *host, struct scsi_pointer *SCp) { struct powertec_info *info = (struct powertec_info *)host->hostdata; if (info->info.scsi.dma != NO_DMA) diff --git a/drivers/scsi/arm/scsi.h b/drivers/scsi/arm/scsi.h index 19937640e2e..6dd544a5eb5 100644 --- a/drivers/scsi/arm/scsi.h +++ b/drivers/scsi/arm/scsi.h @@ -18,7 +18,7 @@ * The scatter-gather list handling. This contains all * the yucky stuff that needs to be fixed properly. */ -static inline int copy_SCp_to_sg(struct scatterlist *sg, Scsi_Pointer *SCp, int max) +static inline int copy_SCp_to_sg(struct scatterlist *sg, struct scsi_pointer *SCp, int max) { int bufs = SCp->buffers_residual; @@ -32,7 +32,7 @@ static inline int copy_SCp_to_sg(struct scatterlist *sg, Scsi_Pointer *SCp, int return bufs + 1; } -static inline int next_SCp(Scsi_Pointer *SCp) +static inline int next_SCp(struct scsi_pointer *SCp) { int ret = SCp->buffers_residual; if (ret) { @@ -49,7 +49,7 @@ static inline int next_SCp(Scsi_Pointer *SCp) return ret; } -static inline unsigned char get_next_SCp_byte(Scsi_Pointer *SCp) +static inline unsigned char get_next_SCp_byte(struct scsi_pointer *SCp) { char c = *SCp->ptr; @@ -59,7 +59,7 @@ static inline unsigned char get_next_SCp_byte(Scsi_Pointer *SCp) return c; } -static inline void put_next_SCp_byte(Scsi_Pointer *SCp, unsigned char c) +static inline void put_next_SCp_byte(struct scsi_pointer *SCp, unsigned char c) { *SCp->ptr = c; SCp->ptr += 1; diff --git a/drivers/scsi/megaraid.c b/drivers/scsi/megaraid.c index 93c95bc82c1..dfea346b00a 100644 --- a/drivers/scsi/megaraid.c +++ b/drivers/scsi/megaraid.c @@ -1686,7 +1686,7 @@ mega_rundoneq (adapter_t *adapter) list_for_each(pos, &adapter->completed_list) { - Scsi_Pointer* spos = (Scsi_Pointer *)pos; + struct scsi_pointer* spos = (struct scsi_pointer *)pos; cmd = list_entry(spos, Scsi_Cmnd, SCp); cmd->scsi_done(cmd); diff --git a/drivers/scsi/scsi_typedefs.h b/drivers/scsi/scsi_typedefs.h index 113dbc61469..6283c233335 100644 --- a/drivers/scsi/scsi_typedefs.h +++ b/drivers/scsi/scsi_typedefs.h @@ -2,4 +2,3 @@ typedef struct scsi_device Scsi_Device; typedef struct scsi_cmnd Scsi_Cmnd; typedef struct scsi_request Scsi_Request; -typedef struct scsi_pointer Scsi_Pointer; -- cgit v1.2.3-70-g09d2 From 238f9b063dcc9f23493a0d3fecca29fe332d4905 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig <hch@lst.de> Date: Tue, 29 Nov 2005 21:36:16 +0100 Subject: [PATCH] fix megaraid.c locking This fixes locking in megaraid.c, namely: (1) make sure megaraid_queue release the adapter lock by changing the code to have a single return (2) remove the errornous scsi_assign_lock call Testing by Burton Windle. Signed-off-by: Christoph Hellwig <hch@lst.de> Acked-by: Burton Windle <bwindle@fint.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org> --- drivers/scsi/megaraid.c | 29 ++++++++++++++--------------- 1 file changed, 14 insertions(+), 15 deletions(-) (limited to 'drivers/scsi/megaraid.c') diff --git a/drivers/scsi/megaraid.c b/drivers/scsi/megaraid.c index dfea346b00a..f9792528e33 100644 --- a/drivers/scsi/megaraid.c +++ b/drivers/scsi/megaraid.c @@ -380,23 +380,23 @@ megaraid_queue(Scsi_Cmnd *scmd, void (*done)(Scsi_Cmnd *)) spin_lock_irqsave(&adapter->lock, flags); scb = mega_build_cmd(adapter, scmd, &busy); + if (!scb) + goto out; - if(scb) { - scb->state |= SCB_PENDQ; - list_add_tail(&scb->list, &adapter->pending_list); + scb->state |= SCB_PENDQ; + list_add_tail(&scb->list, &adapter->pending_list); - /* - * Check if the HBA is in quiescent state, e.g., during a - * delete logical drive opertion. If it is, don't run - * the pending_list. - */ - if(atomic_read(&adapter->quiescent) == 0) { - mega_runpendq(adapter); - } - return 0; - } - spin_unlock_irqrestore(&adapter->lock, flags); + /* + * Check if the HBA is in quiescent state, e.g., during a + * delete logical drive opertion. If it is, don't run + * the pending_list. + */ + if (atomic_read(&adapter->quiescent) == 0) + mega_runpendq(adapter); + busy = 0; + out: + spin_unlock_irqrestore(&adapter->lock, flags); return busy; } @@ -4677,7 +4677,6 @@ megaraid_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) adapter->flag = flag; spin_lock_init(&adapter->lock); - scsi_assign_lock(host, &adapter->lock); host->cmd_per_lun = max_cmd_per_lun; host->max_sectors = max_sectors_per_io; -- cgit v1.2.3-70-g09d2 From f0353301e6752399ceb874ede7f44e3571c5e4f3 Mon Sep 17 00:00:00 2001 From: Mark Lord <lkml@rtr.ca> Date: Wed, 7 Dec 2005 17:46:57 -0500 Subject: [SCSI] Fix incorrect pointer in megaraid.c MODE_SENSE emulation The SCSI megaraid drive goes to great effort to kmap the scatterlist buffer (if used), but then uses the wrong pointer when copying to it afterward. Signed-off-by: Mark Lord <lkml@rtr.ca> Acked by: Ju, Seokmann <Seokmann.Ju@engenio.com> Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com> --- drivers/scsi/megaraid.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/scsi/megaraid.c') diff --git a/drivers/scsi/megaraid.c b/drivers/scsi/megaraid.c index f9792528e33..578143e93a6 100644 --- a/drivers/scsi/megaraid.c +++ b/drivers/scsi/megaraid.c @@ -664,7 +664,7 @@ mega_build_cmd(adapter_t *adapter, Scsi_Cmnd *cmd, int *busy) sg->offset; } else buf = cmd->request_buffer; - memset(cmd->request_buffer, 0, cmd->cmnd[4]); + memset(buf, 0, cmd->cmnd[4]); if (cmd->use_sg) { struct scatterlist *sg; -- cgit v1.2.3-70-g09d2