Skip to content

Commit c206c70

Browse files
Philip J Kelleheraxboe
authored andcommitted
block: IBM RamSan 70/80 driver fixes
This patch includes the following driver fixes for the IBM RamSan 70/80 driver: o Changed the creg_ctrl lock from a mutex to a spinlock. o Added a count check for ioctl calls. o Removed unnecessary casting of void pointers. o Made every function static that needed to be. o Added comments to explain things more thoroughly. Signed-off-by: Philip J Kelleher <pjk1939@linux.vnet.ibm.com> Signed-off-by: Jens Axboe <axboe@kernel.dk>
1 parent ec8edc7 commit c206c70

7 files changed

Lines changed: 69 additions & 63 deletions

File tree

drivers/block/rsxx/config.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@
3131

3232
static void initialize_config(void *config)
3333
{
34-
struct rsxx_card_cfg *cfg = (struct rsxx_card_cfg *) config;
34+
struct rsxx_card_cfg *cfg = config;
3535

3636
cfg->hdr.version = RSXX_CFG_VERSION;
3737

@@ -97,7 +97,7 @@ static void config_data_cpu_to_le(struct rsxx_card_cfg *cfg)
9797

9898

9999
/*----------------- Config Operations ------------------*/
100-
int rsxx_save_config(struct rsxx_cardinfo *card)
100+
static int rsxx_save_config(struct rsxx_cardinfo *card)
101101
{
102102
struct rsxx_card_cfg cfg;
103103
int st;

drivers/block/rsxx/core.c

Lines changed: 21 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -102,9 +102,9 @@ void rsxx_disable_ier_and_isr(struct rsxx_cardinfo *card,
102102
iowrite32(card->ier_mask, card->regmap + IER);
103103
}
104104

105-
irqreturn_t rsxx_isr(int irq, void *pdata)
105+
static irqreturn_t rsxx_isr(int irq, void *pdata)
106106
{
107-
struct rsxx_cardinfo *card = (struct rsxx_cardinfo *) pdata;
107+
struct rsxx_cardinfo *card = pdata;
108108
unsigned int isr;
109109
int handled = 0;
110110
int reread_isr;
@@ -161,6 +161,17 @@ irqreturn_t rsxx_isr(int irq, void *pdata)
161161
}
162162

163163
/*----------------- Card Event Handler -------------------*/
164+
static char *rsxx_card_state_to_str(unsigned int state)
165+
{
166+
static char *state_strings[] = {
167+
"Unknown", "Shutdown", "Starting", "Formatting",
168+
"Uninitialized", "Good", "Shutting Down",
169+
"Fault", "Read Only Fault", "dStroying"
170+
};
171+
172+
return state_strings[ffs(state)];
173+
}
174+
164175
static void card_state_change(struct rsxx_cardinfo *card,
165176
unsigned int new_state)
166177
{
@@ -251,18 +262,6 @@ static void card_event_handler(struct work_struct *work)
251262
rsxx_read_hw_log(card);
252263
}
253264

254-
255-
char *rsxx_card_state_to_str(unsigned int state)
256-
{
257-
static char *state_strings[] = {
258-
"Unknown", "Shutdown", "Starting", "Formatting",
259-
"Uninitialized", "Good", "Shutting Down",
260-
"Fault", "Read Only Fault", "dStroying"
261-
};
262-
263-
return state_strings[ffs(state)];
264-
}
265-
266265
/*----------------- Card Operations -------------------*/
267266
static int card_shutdown(struct rsxx_cardinfo *card)
268267
{
@@ -323,7 +322,6 @@ static int rsxx_pci_probe(struct pci_dev *dev,
323322
const struct pci_device_id *id)
324323
{
325324
struct rsxx_cardinfo *card;
326-
unsigned long flags;
327325
int st;
328326

329327
dev_info(&dev->dev, "PCI-Flash SSD discovered\n");
@@ -386,9 +384,9 @@ static int rsxx_pci_probe(struct pci_dev *dev,
386384
spin_lock_init(&card->irq_lock);
387385
card->halt = 0;
388386

389-
spin_lock_irqsave(&card->irq_lock, flags);
387+
spin_lock_irq(&card->irq_lock);
390388
rsxx_disable_ier_and_isr(card, CR_INTR_ALL);
391-
spin_unlock_irqrestore(&card->irq_lock, flags);
389+
spin_unlock_irq(&card->irq_lock);
392390

393391
if (!force_legacy) {
394392
st = pci_enable_msi(dev);
@@ -408,9 +406,9 @@ static int rsxx_pci_probe(struct pci_dev *dev,
408406
/************* Setup Processor Command Interface *************/
409407
rsxx_creg_setup(card);
410408

411-
spin_lock_irqsave(&card->irq_lock, flags);
409+
spin_lock_irq(&card->irq_lock);
412410
rsxx_enable_ier_and_isr(card, CR_INTR_CREG);
413-
spin_unlock_irqrestore(&card->irq_lock, flags);
411+
spin_unlock_irq(&card->irq_lock);
414412

415413
st = rsxx_compatibility_check(card);
416414
if (st) {
@@ -463,9 +461,9 @@ static int rsxx_pci_probe(struct pci_dev *dev,
463461
* we can enable the event interrupt(it kicks off actions in
464462
* those layers so we couldn't enable it right away.)
465463
*/
466-
spin_lock_irqsave(&card->irq_lock, flags);
464+
spin_lock_irq(&card->irq_lock);
467465
rsxx_enable_ier_and_isr(card, CR_INTR_EVENT);
468-
spin_unlock_irqrestore(&card->irq_lock, flags);
466+
spin_unlock_irq(&card->irq_lock);
469467

470468
if (card->state == CARD_STATE_SHUTDOWN) {
471469
st = rsxx_issue_card_cmd(card, CARD_CMD_STARTUP);
@@ -487,9 +485,9 @@ static int rsxx_pci_probe(struct pci_dev *dev,
487485
rsxx_dma_destroy(card);
488486
failed_dma_setup:
489487
failed_compatiblity_check:
490-
spin_lock_irqsave(&card->irq_lock, flags);
488+
spin_lock_irq(&card->irq_lock);
491489
rsxx_disable_ier_and_isr(card, CR_INTR_ALL);
492-
spin_unlock_irqrestore(&card->irq_lock, flags);
490+
spin_unlock_irq(&card->irq_lock);
493491
free_irq(dev->irq, card);
494492
if (!force_legacy)
495493
pci_disable_msi(dev);

drivers/block/rsxx/cregs.c

Lines changed: 37 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -107,10 +107,10 @@ static struct creg_cmd *pop_active_cmd(struct rsxx_cardinfo *card)
107107
* Spin lock is needed because this can be called in atomic/interrupt
108108
* context.
109109
*/
110-
spin_lock_bh(&card->creg_ctrl.pop_lock);
110+
spin_lock_bh(&card->creg_ctrl.lock);
111111
cmd = card->creg_ctrl.active_cmd;
112112
card->creg_ctrl.active_cmd = NULL;
113-
spin_unlock_bh(&card->creg_ctrl.pop_lock);
113+
spin_unlock_bh(&card->creg_ctrl.lock);
114114

115115
return cmd;
116116
}
@@ -126,7 +126,11 @@ static void creg_issue_cmd(struct rsxx_cardinfo *card, struct creg_cmd *cmd)
126126
cmd->buf, cmd->stream);
127127
}
128128

129-
/* Data copy must complete before initiating the command. */
129+
/*
130+
* Data copy must complete before initiating the command. This is
131+
* needed for weakly ordered processors (i.e. PowerPC), so that all
132+
* neccessary registers are written before we kick the hardware.
133+
*/
130134
wmb();
131135

132136
/* Setting the valid bit will kick off the command. */
@@ -192,11 +196,11 @@ static int creg_queue_cmd(struct rsxx_cardinfo *card,
192196
cmd->cb_private = cb_private;
193197
cmd->status = 0;
194198

195-
mutex_lock(&card->creg_ctrl.lock);
199+
spin_lock(&card->creg_ctrl.lock);
196200
list_add_tail(&cmd->list, &card->creg_ctrl.queue);
197201
card->creg_ctrl.q_depth++;
198202
creg_kick_queue(card);
199-
mutex_unlock(&card->creg_ctrl.lock);
203+
spin_unlock(&card->creg_ctrl.lock);
200204

201205
return 0;
202206
}
@@ -219,10 +223,11 @@ static void creg_cmd_timed_out(unsigned long data)
219223

220224
kmem_cache_free(creg_cmd_pool, cmd);
221225

222-
spin_lock(&card->creg_ctrl.pop_lock);
226+
227+
spin_lock(&card->creg_ctrl.lock);
223228
card->creg_ctrl.active = 0;
224229
creg_kick_queue(card);
225-
spin_unlock(&card->creg_ctrl.pop_lock);
230+
spin_unlock(&card->creg_ctrl.lock);
226231
}
227232

228233

@@ -291,10 +296,10 @@ static void creg_cmd_done(struct work_struct *work)
291296

292297
kmem_cache_free(creg_cmd_pool, cmd);
293298

294-
mutex_lock(&card->creg_ctrl.lock);
299+
spin_lock(&card->creg_ctrl.lock);
295300
card->creg_ctrl.active = 0;
296301
creg_kick_queue(card);
297-
mutex_unlock(&card->creg_ctrl.lock);
302+
spin_unlock(&card->creg_ctrl.lock);
298303
}
299304

300305
static void creg_reset(struct rsxx_cardinfo *card)
@@ -303,6 +308,10 @@ static void creg_reset(struct rsxx_cardinfo *card)
303308
struct creg_cmd *tmp;
304309
unsigned long flags;
305310

311+
/*
312+
* mutex_trylock is used here because if reset_lock is taken then a
313+
* reset is already happening. So, we can just go ahead and return.
314+
*/
306315
if (!mutex_trylock(&card->creg_ctrl.reset_lock))
307316
return;
308317

@@ -315,7 +324,7 @@ static void creg_reset(struct rsxx_cardinfo *card)
315324
"Resetting creg interface for recovery\n");
316325

317326
/* Cancel outstanding commands */
318-
mutex_lock(&card->creg_ctrl.lock);
327+
spin_lock(&card->creg_ctrl.lock);
319328
list_for_each_entry_safe(cmd, tmp, &card->creg_ctrl.queue, list) {
320329
list_del(&cmd->list);
321330
card->creg_ctrl.q_depth--;
@@ -336,7 +345,7 @@ static void creg_reset(struct rsxx_cardinfo *card)
336345

337346
card->creg_ctrl.active = 0;
338347
}
339-
mutex_unlock(&card->creg_ctrl.lock);
348+
spin_unlock(&card->creg_ctrl.lock);
340349

341350
card->creg_ctrl.reset = 0;
342351
spin_lock_irqsave(&card->irq_lock, flags);
@@ -359,7 +368,7 @@ static void creg_cmd_done_cb(struct rsxx_cardinfo *card,
359368
{
360369
struct creg_completion *cmd_completion;
361370

362-
cmd_completion = (struct creg_completion *)cmd->cb_private;
371+
cmd_completion = cmd->cb_private;
363372
BUG_ON(!cmd_completion);
364373

365374
cmd_completion->st = st;
@@ -380,7 +389,6 @@ static int __issue_creg_rw(struct rsxx_cardinfo *card,
380389
unsigned long timeout;
381390
int st;
382391

383-
INIT_COMPLETION(cmd_done);
384392
completion.cmd_done = &cmd_done;
385393
completion.st = 0;
386394
completion.creg_status = 0;
@@ -390,8 +398,13 @@ static int __issue_creg_rw(struct rsxx_cardinfo *card,
390398
if (st)
391399
return st;
392400

401+
/*
402+
* This timeout is neccessary for unresponsive hardware. The additional
403+
* 20 seconds to used to guarantee that each cregs requests has time to
404+
* complete.
405+
*/
393406
timeout = msecs_to_jiffies((CREG_TIMEOUT_MSEC *
394-
card->creg_ctrl.q_depth) + 20000);
407+
card->creg_ctrl.q_depth) + 20000);
395408

396409
/*
397410
* The creg interface is guaranteed to complete. It has a timeout
@@ -443,7 +456,7 @@ static int issue_creg_rw(struct rsxx_cardinfo *card,
443456
if (st)
444457
return st;
445458

446-
data = (void *)((char *)data + xfer);
459+
data = (char *)data + xfer;
447460
addr += xfer;
448461
size8 -= xfer;
449462
} while (size8);
@@ -558,9 +571,9 @@ static void hw_log_msg(struct rsxx_cardinfo *card, const char *str, int len)
558571
}
559572

560573
/*
561-
* The substrncpy() function copies to string(up to count bytes) point to by src
562-
* (including the terminating '\0' character) to dest. Returns the number of
563-
* bytes copied to dest.
574+
* The substrncpy function copies the src string (which includes the
575+
* terminating '\0' character), up to the count into the dest pointer.
576+
* Returns the number of bytes copied to dest.
564577
*/
565578
static int substrncpy(char *dest, const char *src, int count)
566579
{
@@ -657,6 +670,9 @@ int rsxx_reg_access(struct rsxx_cardinfo *card,
657670
if (st)
658671
return -EFAULT;
659672

673+
if (cmd.cnt > RSXX_MAX_REG_CNT)
674+
return -EFAULT;
675+
660676
st = issue_reg_cmd(card, &cmd, read);
661677
if (st)
662678
return st;
@@ -682,8 +698,7 @@ int rsxx_creg_setup(struct rsxx_cardinfo *card)
682698
INIT_WORK(&card->creg_ctrl.done_work, creg_cmd_done);
683699
mutex_init(&card->creg_ctrl.reset_lock);
684700
INIT_LIST_HEAD(&card->creg_ctrl.queue);
685-
mutex_init(&card->creg_ctrl.lock);
686-
spin_lock_init(&card->creg_ctrl.pop_lock);
701+
spin_lock_init(&card->creg_ctrl.lock);
687702
setup_timer(&card->creg_ctrl.cmd_timer, creg_cmd_timed_out,
688703
(unsigned long) card);
689704

@@ -697,7 +712,7 @@ void rsxx_creg_destroy(struct rsxx_cardinfo *card)
697712
int cnt = 0;
698713

699714
/* Cancel outstanding commands */
700-
mutex_lock(&card->creg_ctrl.lock);
715+
spin_lock(&card->creg_ctrl.lock);
701716
list_for_each_entry_safe(cmd, tmp, &card->creg_ctrl.queue, list) {
702717
list_del(&cmd->list);
703718
if (cmd->cb)
@@ -722,7 +737,7 @@ void rsxx_creg_destroy(struct rsxx_cardinfo *card)
722737
"Canceled active creg command\n");
723738
kmem_cache_free(creg_cmd_pool, cmd);
724739
}
725-
mutex_unlock(&card->creg_ctrl.lock);
740+
spin_unlock(&card->creg_ctrl.lock);
726741

727742
cancel_work_sync(&card->creg_ctrl.done_work);
728743
}

drivers/block/rsxx/dev.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,7 @@ static void bio_dma_done_cb(struct rsxx_cardinfo *card,
149149
void *cb_data,
150150
unsigned int error)
151151
{
152-
struct rsxx_bio_meta *meta = (struct rsxx_bio_meta *)cb_data;
152+
struct rsxx_bio_meta *meta = cb_data;
153153

154154
if (error)
155155
atomic_set(&meta->error, 1);

drivers/block/rsxx/dma.c

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ struct dma_tracker_list {
102102

103103

104104
/*----------------- Misc Utility Functions -------------------*/
105-
unsigned int rsxx_addr8_to_laddr(u64 addr8, struct rsxx_cardinfo *card)
105+
static unsigned int rsxx_addr8_to_laddr(u64 addr8, struct rsxx_cardinfo *card)
106106
{
107107
unsigned long long tgt_addr8;
108108

@@ -113,7 +113,7 @@ unsigned int rsxx_addr8_to_laddr(u64 addr8, struct rsxx_cardinfo *card)
113113
return tgt_addr8;
114114
}
115115

116-
unsigned int rsxx_get_dma_tgt(struct rsxx_cardinfo *card, u64 addr8)
116+
static unsigned int rsxx_get_dma_tgt(struct rsxx_cardinfo *card, u64 addr8)
117117
{
118118
unsigned int tgt;
119119

@@ -757,7 +757,7 @@ static int rsxx_dma_ctrl_init(struct pci_dev *dev,
757757
INIT_LIST_HEAD(&ctrl->queue);
758758

759759
setup_timer(&ctrl->activity_timer, dma_engine_stalled,
760-
(unsigned long)ctrl);
760+
(unsigned long)ctrl);
761761

762762
ctrl->issue_wq = alloc_ordered_workqueue(DRIVER_NAME"_issue", 0);
763763
if (!ctrl->issue_wq)
@@ -803,7 +803,7 @@ static int rsxx_dma_ctrl_init(struct pci_dev *dev,
803803
return 0;
804804
}
805805

806-
int rsxx_dma_stripe_setup(struct rsxx_cardinfo *card,
806+
static int rsxx_dma_stripe_setup(struct rsxx_cardinfo *card,
807807
unsigned int stripe_size8)
808808
{
809809
if (!is_power_of_2(stripe_size8)) {
@@ -834,7 +834,7 @@ int rsxx_dma_stripe_setup(struct rsxx_cardinfo *card,
834834
return 0;
835835
}
836836

837-
int rsxx_dma_configure(struct rsxx_cardinfo *card)
837+
static int rsxx_dma_configure(struct rsxx_cardinfo *card)
838838
{
839839
u32 intr_coal;
840840

drivers/block/rsxx/rsxx.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,8 @@ struct rsxx_reg_access {
3535
__u32 data[8];
3636
};
3737

38+
#define RSXX_MAX_REG_CNT (8 * (sizeof(__u32)))
39+
3840
#define RSXX_IOC_MAGIC 'r'
3941

4042
#define RSXX_GETREG _IOWR(RSXX_IOC_MAGIC, 0x20, struct rsxx_reg_access)

0 commit comments

Comments
 (0)