blob: 09a455d4b6ed31ee99b90ba13fba43e949b08194 [file] [log] [blame]
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001/*
2 *
3 * Linux MegaRAID driver for SAS based RAID controllers
4 *
bo yangf28cd7c2007-11-09 04:44:56 -05005 * Copyright (c) 2003-2005 LSI Corporation.
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04006 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version
10 * 2 of the License, or (at your option) any later version.
11 *
12 * FILE : megaraid_sas.c
Yang, Bo63bad452009-12-06 08:42:28 -070013 * Version : v00.00.04.17.1-rc1
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -040014 *
15 * Authors:
Sumant Patrocc5968c2007-02-14 13:05:42 -080016 * (email-id : megaraidlinux@lsi.com)
17 * Sreenivas Bagalkote
18 * Sumant Patro
19 * Bo Yang
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -040020 *
21 * List of supported controllers
22 *
23 * OEM Product Name VID DID SSVID SSID
24 * --- ------------ --- --- ---- ----
25 */
26
27#include <linux/kernel.h>
28#include <linux/types.h>
29#include <linux/pci.h>
30#include <linux/list.h>
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -040031#include <linux/moduleparam.h>
32#include <linux/module.h>
33#include <linux/spinlock.h>
34#include <linux/interrupt.h>
35#include <linux/delay.h>
36#include <linux/uio.h>
Tejun Heo5a0e3ad2010-03-24 17:04:11 +090037#include <linux/slab.h>
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -040038#include <asm/uaccess.h>
Al Viro43399232005-10-04 17:36:04 +010039#include <linux/fs.h>
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -040040#include <linux/compat.h>
Sumant Patrocf62a0a2007-02-14 12:41:55 -080041#include <linux/blkdev.h>
Arjan van de Ven0b950672006-01-11 13:16:10 +010042#include <linux/mutex.h>
Yang, Boc3518832009-10-06 14:18:02 -060043#include <linux/poll.h>
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -040044
45#include <scsi/scsi.h>
46#include <scsi/scsi_cmnd.h>
47#include <scsi/scsi_device.h>
48#include <scsi/scsi_host.h>
49#include "megaraid_sas.h"
50
bo yangad84db22007-11-09 04:40:16 -050051/*
52 * poll_mode_io:1- schedule complete completion from q cmd
53 */
54static unsigned int poll_mode_io;
55module_param_named(poll_mode_io, poll_mode_io, int, 0);
56MODULE_PARM_DESC(poll_mode_io,
57 "Complete cmds from IO path, (default=0)");
58
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -040059MODULE_LICENSE("GPL");
60MODULE_VERSION(MEGASAS_VERSION);
Sumant Patro3d6d1742006-12-29 08:13:54 -080061MODULE_AUTHOR("megaraidlinux@lsi.com");
bo yangf28cd7c2007-11-09 04:44:56 -050062MODULE_DESCRIPTION("LSI MegaRAID SAS Driver");
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -040063
bo yang39a98552010-09-22 22:36:29 -040064static int megasas_transition_to_ready(struct megasas_instance *instance);
65static int megasas_get_pd_list(struct megasas_instance *instance);
66static int megasas_issue_init_mfi(struct megasas_instance *instance);
67static int megasas_register_aen(struct megasas_instance *instance,
68 u32 seq_num, u32 class_locale_word);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -040069/*
70 * PCI ID table for all supported controllers
71 */
72static struct pci_device_id megasas_pci_table[] = {
73
Henrik Kretzschmarf3d72712006-08-15 11:17:21 +020074 {PCI_DEVICE(PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_SAS1064R)},
75 /* xscale IOP */
76 {PCI_DEVICE(PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_SAS1078R)},
77 /* ppc IOP */
bo yangaf7a5642008-03-17 04:13:07 -040078 {PCI_DEVICE(PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_SAS1078DE)},
79 /* ppc IOP */
Yang, Bo6610a6b2008-08-10 12:42:38 -070080 {PCI_DEVICE(PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_SAS1078GEN2)},
81 /* gen2*/
82 {PCI_DEVICE(PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_SAS0079GEN2)},
83 /* gen2*/
Yang, Bo87911122009-10-06 14:31:54 -060084 {PCI_DEVICE(PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_SAS0073SKINNY)},
85 /* skinny*/
86 {PCI_DEVICE(PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_SAS0071SKINNY)},
87 /* skinny*/
Henrik Kretzschmarf3d72712006-08-15 11:17:21 +020088 {PCI_DEVICE(PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_VERDE_ZCR)},
89 /* xscale IOP, vega */
90 {PCI_DEVICE(PCI_VENDOR_ID_DELL, PCI_DEVICE_ID_DELL_PERC5)},
91 /* xscale IOP */
92 {}
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -040093};
94
95MODULE_DEVICE_TABLE(pci, megasas_pci_table);
96
97static int megasas_mgmt_majorno;
98static struct megasas_mgmt_info megasas_mgmt_info;
99static struct fasync_struct *megasas_async_queue;
Arjan van de Ven0b950672006-01-11 13:16:10 +0100100static DEFINE_MUTEX(megasas_async_queue_mutex);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -0400101
Yang, Boc3518832009-10-06 14:18:02 -0600102static int megasas_poll_wait_aen;
103static DECLARE_WAIT_QUEUE_HEAD(megasas_poll_wait);
Yang, Bo72c4fd32009-10-06 14:20:59 -0600104static u32 support_poll_for_event;
Sumant Patro658dced2006-10-03 13:09:14 -0700105static u32 megasas_dbg_lvl;
Yang, Bo837f5fe2010-10-11 06:59:20 -0600106static u32 support_device_change;
Sumant Patro658dced2006-10-03 13:09:14 -0700107
Yang, Boc3518832009-10-06 14:18:02 -0600108/* define lock for aen poll */
109spinlock_t poll_aen_lock;
110
bo yang7343eb62007-11-09 04:35:44 -0500111static void
112megasas_complete_cmd(struct megasas_instance *instance, struct megasas_cmd *cmd,
113 u8 alt_status);
114
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -0400115/**
116 * megasas_get_cmd - Get a command from the free pool
117 * @instance: Adapter soft state
118 *
119 * Returns a free command from the pool
120 */
Arjan van de Ven858119e2006-01-14 13:20:43 -0800121static struct megasas_cmd *megasas_get_cmd(struct megasas_instance
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -0400122 *instance)
123{
124 unsigned long flags;
125 struct megasas_cmd *cmd = NULL;
126
127 spin_lock_irqsave(&instance->cmd_pool_lock, flags);
128
129 if (!list_empty(&instance->cmd_pool)) {
130 cmd = list_entry((&instance->cmd_pool)->next,
131 struct megasas_cmd, list);
132 list_del_init(&cmd->list);
133 } else {
134 printk(KERN_ERR "megasas: Command pool empty!\n");
135 }
136
137 spin_unlock_irqrestore(&instance->cmd_pool_lock, flags);
138 return cmd;
139}
140
141/**
142 * megasas_return_cmd - Return a cmd to free command pool
143 * @instance: Adapter soft state
144 * @cmd: Command packet to be returned to free command pool
145 */
146static inline void
147megasas_return_cmd(struct megasas_instance *instance, struct megasas_cmd *cmd)
148{
149 unsigned long flags;
150
151 spin_lock_irqsave(&instance->cmd_pool_lock, flags);
152
153 cmd->scmd = NULL;
154 list_add_tail(&cmd->list, &instance->cmd_pool);
155
156 spin_unlock_irqrestore(&instance->cmd_pool_lock, flags);
157}
158
Sumant Patro1341c932006-01-25 12:02:40 -0800159
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -0400160/**
Sumant Patro1341c932006-01-25 12:02:40 -0800161* The following functions are defined for xscale
162* (deviceid : 1064R, PERC5) controllers
163*/
164
165/**
166 * megasas_enable_intr_xscale - Enables interrupts
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -0400167 * @regs: MFI register set
168 */
169static inline void
Sumant Patro1341c932006-01-25 12:02:40 -0800170megasas_enable_intr_xscale(struct megasas_register_set __iomem * regs)
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -0400171{
bo yang39a98552010-09-22 22:36:29 -0400172 writel(0, &(regs)->outbound_intr_mask);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -0400173
174 /* Dummy readl to force pci flush */
175 readl(&regs->outbound_intr_mask);
176}
177
178/**
Sumant Patrob274cab2006-10-03 12:52:12 -0700179 * megasas_disable_intr_xscale -Disables interrupt
180 * @regs: MFI register set
181 */
182static inline void
183megasas_disable_intr_xscale(struct megasas_register_set __iomem * regs)
184{
185 u32 mask = 0x1f;
186 writel(mask, &regs->outbound_intr_mask);
187 /* Dummy readl to force pci flush */
188 readl(&regs->outbound_intr_mask);
189}
190
191/**
Sumant Patro1341c932006-01-25 12:02:40 -0800192 * megasas_read_fw_status_reg_xscale - returns the current FW status value
193 * @regs: MFI register set
194 */
195static u32
196megasas_read_fw_status_reg_xscale(struct megasas_register_set __iomem * regs)
197{
198 return readl(&(regs)->outbound_msg_0);
199}
200/**
201 * megasas_clear_interrupt_xscale - Check & clear interrupt
202 * @regs: MFI register set
203 */
204static int
205megasas_clear_intr_xscale(struct megasas_register_set __iomem * regs)
206{
207 u32 status;
bo yang39a98552010-09-22 22:36:29 -0400208 u32 mfiStatus = 0;
Sumant Patro1341c932006-01-25 12:02:40 -0800209 /*
210 * Check if it is our interrupt
211 */
212 status = readl(&regs->outbound_intr_status);
213
bo yang39a98552010-09-22 22:36:29 -0400214 if (status & MFI_OB_INTR_STATUS_MASK)
215 mfiStatus = MFI_INTR_FLAG_REPLY_MESSAGE;
216 if (status & MFI_XSCALE_OMR0_CHANGE_INTERRUPT)
217 mfiStatus |= MFI_INTR_FLAG_FIRMWARE_STATE_CHANGE;
Sumant Patro1341c932006-01-25 12:02:40 -0800218
219 /*
220 * Clear the interrupt by writing back the same value
221 */
bo yang39a98552010-09-22 22:36:29 -0400222 if (mfiStatus)
223 writel(status, &regs->outbound_intr_status);
Sumant Patro1341c932006-01-25 12:02:40 -0800224
Yang, Bo06f579d2008-08-10 12:42:37 -0700225 /* Dummy readl to force pci flush */
226 readl(&regs->outbound_intr_status);
227
bo yang39a98552010-09-22 22:36:29 -0400228 return mfiStatus;
Sumant Patro1341c932006-01-25 12:02:40 -0800229}
230
231/**
232 * megasas_fire_cmd_xscale - Sends command to the FW
233 * @frame_phys_addr : Physical address of cmd
234 * @frame_count : Number of frames for the command
235 * @regs : MFI register set
236 */
237static inline void
Yang, Bo0c79e682009-10-06 14:47:35 -0600238megasas_fire_cmd_xscale(struct megasas_instance *instance,
239 dma_addr_t frame_phys_addr,
240 u32 frame_count,
241 struct megasas_register_set __iomem *regs)
Sumant Patro1341c932006-01-25 12:02:40 -0800242{
bo yang39a98552010-09-22 22:36:29 -0400243 unsigned long flags;
244 spin_lock_irqsave(&instance->hba_lock, flags);
Sumant Patro1341c932006-01-25 12:02:40 -0800245 writel((frame_phys_addr >> 3)|(frame_count),
246 &(regs)->inbound_queue_port);
bo yang39a98552010-09-22 22:36:29 -0400247 spin_unlock_irqrestore(&instance->hba_lock, flags);
248}
249
250/**
251 * megasas_adp_reset_xscale - For controller reset
252 * @regs: MFI register set
253 */
254static int
255megasas_adp_reset_xscale(struct megasas_instance *instance,
256 struct megasas_register_set __iomem *regs)
257{
258 u32 i;
259 u32 pcidata;
260 writel(MFI_ADP_RESET, &regs->inbound_doorbell);
261
262 for (i = 0; i < 3; i++)
263 msleep(1000); /* sleep for 3 secs */
264 pcidata = 0;
265 pci_read_config_dword(instance->pdev, MFI_1068_PCSR_OFFSET, &pcidata);
266 printk(KERN_NOTICE "pcidata = %x\n", pcidata);
267 if (pcidata & 0x2) {
268 printk(KERN_NOTICE "mfi 1068 offset read=%x\n", pcidata);
269 pcidata &= ~0x2;
270 pci_write_config_dword(instance->pdev,
271 MFI_1068_PCSR_OFFSET, pcidata);
272
273 for (i = 0; i < 2; i++)
274 msleep(1000); /* need to wait 2 secs again */
275
276 pcidata = 0;
277 pci_read_config_dword(instance->pdev,
278 MFI_1068_FW_HANDSHAKE_OFFSET, &pcidata);
279 printk(KERN_NOTICE "1068 offset handshake read=%x\n", pcidata);
280 if ((pcidata & 0xffff0000) == MFI_1068_FW_READY) {
281 printk(KERN_NOTICE "1068 offset pcidt=%x\n", pcidata);
282 pcidata = 0;
283 pci_write_config_dword(instance->pdev,
284 MFI_1068_FW_HANDSHAKE_OFFSET, pcidata);
285 }
286 }
287 return 0;
288}
289
290/**
291 * megasas_check_reset_xscale - For controller reset check
292 * @regs: MFI register set
293 */
294static int
295megasas_check_reset_xscale(struct megasas_instance *instance,
296 struct megasas_register_set __iomem *regs)
297{
298 u32 consumer;
299 consumer = *instance->consumer;
300
301 if ((instance->adprecovery != MEGASAS_HBA_OPERATIONAL) &&
302 (*instance->consumer == MEGASAS_ADPRESET_INPROG_SIGN)) {
303 return 1;
304 }
305 return 0;
Sumant Patro1341c932006-01-25 12:02:40 -0800306}
307
308static struct megasas_instance_template megasas_instance_template_xscale = {
309
310 .fire_cmd = megasas_fire_cmd_xscale,
311 .enable_intr = megasas_enable_intr_xscale,
Sumant Patrob274cab2006-10-03 12:52:12 -0700312 .disable_intr = megasas_disable_intr_xscale,
Sumant Patro1341c932006-01-25 12:02:40 -0800313 .clear_intr = megasas_clear_intr_xscale,
314 .read_fw_status_reg = megasas_read_fw_status_reg_xscale,
bo yang39a98552010-09-22 22:36:29 -0400315 .adp_reset = megasas_adp_reset_xscale,
316 .check_reset = megasas_check_reset_xscale,
Sumant Patro1341c932006-01-25 12:02:40 -0800317};
318
319/**
320* This is the end of set of functions & definitions specific
321* to xscale (deviceid : 1064R, PERC5) controllers
322*/
323
324/**
Sumant Patrof9876f02006-02-03 15:34:35 -0800325* The following functions are defined for ppc (deviceid : 0x60)
326* controllers
327*/
328
329/**
330 * megasas_enable_intr_ppc - Enables interrupts
331 * @regs: MFI register set
332 */
333static inline void
334megasas_enable_intr_ppc(struct megasas_register_set __iomem * regs)
335{
336 writel(0xFFFFFFFF, &(regs)->outbound_doorbell_clear);
337
bo yang39a98552010-09-22 22:36:29 -0400338 writel(~0x80000000, &(regs)->outbound_intr_mask);
Sumant Patrof9876f02006-02-03 15:34:35 -0800339
340 /* Dummy readl to force pci flush */
341 readl(&regs->outbound_intr_mask);
342}
343
344/**
Sumant Patrob274cab2006-10-03 12:52:12 -0700345 * megasas_disable_intr_ppc - Disable interrupt
346 * @regs: MFI register set
347 */
348static inline void
349megasas_disable_intr_ppc(struct megasas_register_set __iomem * regs)
350{
351 u32 mask = 0xFFFFFFFF;
352 writel(mask, &regs->outbound_intr_mask);
353 /* Dummy readl to force pci flush */
354 readl(&regs->outbound_intr_mask);
355}
356
357/**
Sumant Patrof9876f02006-02-03 15:34:35 -0800358 * megasas_read_fw_status_reg_ppc - returns the current FW status value
359 * @regs: MFI register set
360 */
361static u32
362megasas_read_fw_status_reg_ppc(struct megasas_register_set __iomem * regs)
363{
364 return readl(&(regs)->outbound_scratch_pad);
365}
366
367/**
368 * megasas_clear_interrupt_ppc - Check & clear interrupt
369 * @regs: MFI register set
370 */
371static int
372megasas_clear_intr_ppc(struct megasas_register_set __iomem * regs)
373{
374 u32 status;
375 /*
376 * Check if it is our interrupt
377 */
378 status = readl(&regs->outbound_intr_status);
379
380 if (!(status & MFI_REPLY_1078_MESSAGE_INTERRUPT)) {
bo yang39a98552010-09-22 22:36:29 -0400381 return 0;
Sumant Patrof9876f02006-02-03 15:34:35 -0800382 }
383
384 /*
385 * Clear the interrupt by writing back the same value
386 */
387 writel(status, &regs->outbound_doorbell_clear);
388
Yang, Bo06f579d2008-08-10 12:42:37 -0700389 /* Dummy readl to force pci flush */
390 readl(&regs->outbound_doorbell_clear);
391
bo yang39a98552010-09-22 22:36:29 -0400392 return 1;
Sumant Patrof9876f02006-02-03 15:34:35 -0800393}
394/**
395 * megasas_fire_cmd_ppc - Sends command to the FW
396 * @frame_phys_addr : Physical address of cmd
397 * @frame_count : Number of frames for the command
398 * @regs : MFI register set
399 */
400static inline void
Yang, Bo0c79e682009-10-06 14:47:35 -0600401megasas_fire_cmd_ppc(struct megasas_instance *instance,
402 dma_addr_t frame_phys_addr,
403 u32 frame_count,
404 struct megasas_register_set __iomem *regs)
Sumant Patrof9876f02006-02-03 15:34:35 -0800405{
bo yang39a98552010-09-22 22:36:29 -0400406 unsigned long flags;
407 spin_lock_irqsave(&instance->hba_lock, flags);
Sumant Patrof9876f02006-02-03 15:34:35 -0800408 writel((frame_phys_addr | (frame_count<<1))|1,
409 &(regs)->inbound_queue_port);
bo yang39a98552010-09-22 22:36:29 -0400410 spin_unlock_irqrestore(&instance->hba_lock, flags);
Sumant Patrof9876f02006-02-03 15:34:35 -0800411}
412
bo yang39a98552010-09-22 22:36:29 -0400413/**
414 * megasas_adp_reset_ppc - For controller reset
415 * @regs: MFI register set
416 */
417static int
418megasas_adp_reset_ppc(struct megasas_instance *instance,
419 struct megasas_register_set __iomem *regs)
420{
421 return 0;
422}
423
424/**
425 * megasas_check_reset_ppc - For controller reset check
426 * @regs: MFI register set
427 */
428static int
429megasas_check_reset_ppc(struct megasas_instance *instance,
430 struct megasas_register_set __iomem *regs)
431{
432 return 0;
433}
Sumant Patrof9876f02006-02-03 15:34:35 -0800434static struct megasas_instance_template megasas_instance_template_ppc = {
435
436 .fire_cmd = megasas_fire_cmd_ppc,
437 .enable_intr = megasas_enable_intr_ppc,
Sumant Patrob274cab2006-10-03 12:52:12 -0700438 .disable_intr = megasas_disable_intr_ppc,
Sumant Patrof9876f02006-02-03 15:34:35 -0800439 .clear_intr = megasas_clear_intr_ppc,
440 .read_fw_status_reg = megasas_read_fw_status_reg_ppc,
bo yang39a98552010-09-22 22:36:29 -0400441 .adp_reset = megasas_adp_reset_ppc,
442 .check_reset = megasas_check_reset_ppc,
Sumant Patrof9876f02006-02-03 15:34:35 -0800443};
444
445/**
Yang, Bo87911122009-10-06 14:31:54 -0600446 * megasas_enable_intr_skinny - Enables interrupts
447 * @regs: MFI register set
448 */
449static inline void
450megasas_enable_intr_skinny(struct megasas_register_set __iomem *regs)
451{
452 writel(0xFFFFFFFF, &(regs)->outbound_intr_mask);
453
454 writel(~MFI_SKINNY_ENABLE_INTERRUPT_MASK, &(regs)->outbound_intr_mask);
455
456 /* Dummy readl to force pci flush */
457 readl(&regs->outbound_intr_mask);
458}
459
460/**
461 * megasas_disable_intr_skinny - Disables interrupt
462 * @regs: MFI register set
463 */
464static inline void
465megasas_disable_intr_skinny(struct megasas_register_set __iomem *regs)
466{
467 u32 mask = 0xFFFFFFFF;
468 writel(mask, &regs->outbound_intr_mask);
469 /* Dummy readl to force pci flush */
470 readl(&regs->outbound_intr_mask);
471}
472
473/**
474 * megasas_read_fw_status_reg_skinny - returns the current FW status value
475 * @regs: MFI register set
476 */
477static u32
478megasas_read_fw_status_reg_skinny(struct megasas_register_set __iomem *regs)
479{
480 return readl(&(regs)->outbound_scratch_pad);
481}
482
483/**
484 * megasas_clear_interrupt_skinny - Check & clear interrupt
485 * @regs: MFI register set
486 */
487static int
488megasas_clear_intr_skinny(struct megasas_register_set __iomem *regs)
489{
490 u32 status;
491 /*
492 * Check if it is our interrupt
493 */
494 status = readl(&regs->outbound_intr_status);
495
496 if (!(status & MFI_SKINNY_ENABLE_INTERRUPT_MASK)) {
bo yang39a98552010-09-22 22:36:29 -0400497 return 0;
Yang, Bo87911122009-10-06 14:31:54 -0600498 }
499
500 /*
501 * Clear the interrupt by writing back the same value
502 */
503 writel(status, &regs->outbound_intr_status);
504
505 /*
506 * dummy read to flush PCI
507 */
508 readl(&regs->outbound_intr_status);
509
bo yang39a98552010-09-22 22:36:29 -0400510 return 1;
Yang, Bo87911122009-10-06 14:31:54 -0600511}
512
513/**
514 * megasas_fire_cmd_skinny - Sends command to the FW
515 * @frame_phys_addr : Physical address of cmd
516 * @frame_count : Number of frames for the command
517 * @regs : MFI register set
518 */
519static inline void
Yang, Bo0c79e682009-10-06 14:47:35 -0600520megasas_fire_cmd_skinny(struct megasas_instance *instance,
521 dma_addr_t frame_phys_addr,
522 u32 frame_count,
Yang, Bo87911122009-10-06 14:31:54 -0600523 struct megasas_register_set __iomem *regs)
524{
Yang, Bo0c79e682009-10-06 14:47:35 -0600525 unsigned long flags;
bo yang39a98552010-09-22 22:36:29 -0400526 spin_lock_irqsave(&instance->hba_lock, flags);
Yang, Bo87911122009-10-06 14:31:54 -0600527 writel(0, &(regs)->inbound_high_queue_port);
528 writel((frame_phys_addr | (frame_count<<1))|1,
529 &(regs)->inbound_low_queue_port);
bo yang39a98552010-09-22 22:36:29 -0400530 spin_unlock_irqrestore(&instance->hba_lock, flags);
531}
532
533/**
534 * megasas_adp_reset_skinny - For controller reset
535 * @regs: MFI register set
536 */
537static int
538megasas_adp_reset_skinny(struct megasas_instance *instance,
539 struct megasas_register_set __iomem *regs)
540{
541 return 0;
542}
543
544/**
545 * megasas_check_reset_skinny - For controller reset check
546 * @regs: MFI register set
547 */
548static int
549megasas_check_reset_skinny(struct megasas_instance *instance,
550 struct megasas_register_set __iomem *regs)
551{
552 return 0;
Yang, Bo87911122009-10-06 14:31:54 -0600553}
554
555static struct megasas_instance_template megasas_instance_template_skinny = {
556
557 .fire_cmd = megasas_fire_cmd_skinny,
558 .enable_intr = megasas_enable_intr_skinny,
559 .disable_intr = megasas_disable_intr_skinny,
560 .clear_intr = megasas_clear_intr_skinny,
561 .read_fw_status_reg = megasas_read_fw_status_reg_skinny,
bo yang39a98552010-09-22 22:36:29 -0400562 .adp_reset = megasas_adp_reset_skinny,
563 .check_reset = megasas_check_reset_skinny,
Yang, Bo87911122009-10-06 14:31:54 -0600564};
565
566
567/**
Yang, Bo6610a6b2008-08-10 12:42:38 -0700568* The following functions are defined for gen2 (deviceid : 0x78 0x79)
569* controllers
570*/
571
572/**
573 * megasas_enable_intr_gen2 - Enables interrupts
574 * @regs: MFI register set
575 */
576static inline void
577megasas_enable_intr_gen2(struct megasas_register_set __iomem *regs)
578{
579 writel(0xFFFFFFFF, &(regs)->outbound_doorbell_clear);
580
581 /* write ~0x00000005 (4 & 1) to the intr mask*/
582 writel(~MFI_GEN2_ENABLE_INTERRUPT_MASK, &(regs)->outbound_intr_mask);
583
584 /* Dummy readl to force pci flush */
585 readl(&regs->outbound_intr_mask);
586}
587
588/**
589 * megasas_disable_intr_gen2 - Disables interrupt
590 * @regs: MFI register set
591 */
592static inline void
593megasas_disable_intr_gen2(struct megasas_register_set __iomem *regs)
594{
595 u32 mask = 0xFFFFFFFF;
596 writel(mask, &regs->outbound_intr_mask);
597 /* Dummy readl to force pci flush */
598 readl(&regs->outbound_intr_mask);
599}
600
601/**
602 * megasas_read_fw_status_reg_gen2 - returns the current FW status value
603 * @regs: MFI register set
604 */
605static u32
606megasas_read_fw_status_reg_gen2(struct megasas_register_set __iomem *regs)
607{
608 return readl(&(regs)->outbound_scratch_pad);
609}
610
611/**
612 * megasas_clear_interrupt_gen2 - Check & clear interrupt
613 * @regs: MFI register set
614 */
615static int
616megasas_clear_intr_gen2(struct megasas_register_set __iomem *regs)
617{
618 u32 status;
bo yang39a98552010-09-22 22:36:29 -0400619 u32 mfiStatus = 0;
Yang, Bo6610a6b2008-08-10 12:42:38 -0700620 /*
621 * Check if it is our interrupt
622 */
623 status = readl(&regs->outbound_intr_status);
624
bo yang39a98552010-09-22 22:36:29 -0400625 if (status & MFI_GEN2_ENABLE_INTERRUPT_MASK) {
626 mfiStatus = MFI_INTR_FLAG_REPLY_MESSAGE;
627 }
628 if (status & MFI_G2_OUTBOUND_DOORBELL_CHANGE_INTERRUPT) {
629 mfiStatus |= MFI_INTR_FLAG_FIRMWARE_STATE_CHANGE;
630 }
Yang, Bo6610a6b2008-08-10 12:42:38 -0700631
632 /*
633 * Clear the interrupt by writing back the same value
634 */
bo yang39a98552010-09-22 22:36:29 -0400635 if (mfiStatus)
636 writel(status, &regs->outbound_doorbell_clear);
Yang, Bo6610a6b2008-08-10 12:42:38 -0700637
638 /* Dummy readl to force pci flush */
639 readl(&regs->outbound_intr_status);
640
bo yang39a98552010-09-22 22:36:29 -0400641 return mfiStatus;
Yang, Bo6610a6b2008-08-10 12:42:38 -0700642}
643/**
644 * megasas_fire_cmd_gen2 - Sends command to the FW
645 * @frame_phys_addr : Physical address of cmd
646 * @frame_count : Number of frames for the command
647 * @regs : MFI register set
648 */
649static inline void
Yang, Bo0c79e682009-10-06 14:47:35 -0600650megasas_fire_cmd_gen2(struct megasas_instance *instance,
651 dma_addr_t frame_phys_addr,
652 u32 frame_count,
Yang, Bo6610a6b2008-08-10 12:42:38 -0700653 struct megasas_register_set __iomem *regs)
654{
bo yang39a98552010-09-22 22:36:29 -0400655 unsigned long flags;
656 spin_lock_irqsave(&instance->hba_lock, flags);
Yang, Bo6610a6b2008-08-10 12:42:38 -0700657 writel((frame_phys_addr | (frame_count<<1))|1,
658 &(regs)->inbound_queue_port);
bo yang39a98552010-09-22 22:36:29 -0400659 spin_unlock_irqrestore(&instance->hba_lock, flags);
660}
661
662/**
663 * megasas_adp_reset_gen2 - For controller reset
664 * @regs: MFI register set
665 */
666static int
667megasas_adp_reset_gen2(struct megasas_instance *instance,
668 struct megasas_register_set __iomem *reg_set)
669{
670 u32 retry = 0 ;
671 u32 HostDiag;
672
673 writel(0, &reg_set->seq_offset);
674 writel(4, &reg_set->seq_offset);
675 writel(0xb, &reg_set->seq_offset);
676 writel(2, &reg_set->seq_offset);
677 writel(7, &reg_set->seq_offset);
678 writel(0xd, &reg_set->seq_offset);
679 msleep(1000);
680
681 HostDiag = (u32)readl(&reg_set->host_diag);
682
683 while ( !( HostDiag & DIAG_WRITE_ENABLE) ) {
684 msleep(100);
685 HostDiag = (u32)readl(&reg_set->host_diag);
686 printk(KERN_NOTICE "RESETGEN2: retry=%x, hostdiag=%x\n",
687 retry, HostDiag);
688
689 if (retry++ >= 100)
690 return 1;
691
692 }
693
694 printk(KERN_NOTICE "ADP_RESET_GEN2: HostDiag=%x\n", HostDiag);
695
696 writel((HostDiag | DIAG_RESET_ADAPTER), &reg_set->host_diag);
697
698 ssleep(10);
699
700 HostDiag = (u32)readl(&reg_set->host_diag);
701 while ( ( HostDiag & DIAG_RESET_ADAPTER) ) {
702 msleep(100);
703 HostDiag = (u32)readl(&reg_set->host_diag);
704 printk(KERN_NOTICE "RESET_GEN2: retry=%x, hostdiag=%x\n",
705 retry, HostDiag);
706
707 if (retry++ >= 1000)
708 return 1;
709
710 }
711 return 0;
712}
713
714/**
715 * megasas_check_reset_gen2 - For controller reset check
716 * @regs: MFI register set
717 */
718static int
719megasas_check_reset_gen2(struct megasas_instance *instance,
720 struct megasas_register_set __iomem *regs)
721{
722 return 0;
Yang, Bo6610a6b2008-08-10 12:42:38 -0700723}
724
725static struct megasas_instance_template megasas_instance_template_gen2 = {
726
727 .fire_cmd = megasas_fire_cmd_gen2,
728 .enable_intr = megasas_enable_intr_gen2,
729 .disable_intr = megasas_disable_intr_gen2,
730 .clear_intr = megasas_clear_intr_gen2,
731 .read_fw_status_reg = megasas_read_fw_status_reg_gen2,
bo yang39a98552010-09-22 22:36:29 -0400732 .adp_reset = megasas_adp_reset_gen2,
733 .check_reset = megasas_check_reset_gen2,
Yang, Bo6610a6b2008-08-10 12:42:38 -0700734};
735
736/**
Sumant Patrof9876f02006-02-03 15:34:35 -0800737* This is the end of set of functions & definitions
bo yang39a98552010-09-22 22:36:29 -0400738* specific to gen2 (deviceid : 0x78, 0x79) controllers
Sumant Patrof9876f02006-02-03 15:34:35 -0800739*/
740
741/**
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -0400742 * megasas_issue_polled - Issues a polling command
743 * @instance: Adapter soft state
744 * @cmd: Command packet to be issued
745 *
746 * For polling, MFI requires the cmd_status to be set to 0xFF before posting.
747 */
748static int
749megasas_issue_polled(struct megasas_instance *instance, struct megasas_cmd *cmd)
750{
751 int i;
752 u32 msecs = MFI_POLL_TIMEOUT_SECS * 1000;
753
754 struct megasas_header *frame_hdr = &cmd->frame->hdr;
755
756 frame_hdr->cmd_status = 0xFF;
757 frame_hdr->flags |= MFI_FRAME_DONT_POST_IN_REPLY_QUEUE;
758
759 /*
760 * Issue the frame using inbound queue port
761 */
Yang, Bo0c79e682009-10-06 14:47:35 -0600762 instance->instancet->fire_cmd(instance,
763 cmd->frame_phys_addr, 0, instance->reg_set);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -0400764
765 /*
766 * Wait for cmd_status to change
767 */
768 for (i = 0; (i < msecs) && (frame_hdr->cmd_status == 0xff); i++) {
769 rmb();
770 msleep(1);
771 }
772
773 if (frame_hdr->cmd_status == 0xff)
774 return -ETIME;
775
776 return 0;
777}
778
779/**
780 * megasas_issue_blocked_cmd - Synchronous wrapper around regular FW cmds
781 * @instance: Adapter soft state
782 * @cmd: Command to be issued
783 *
784 * This function waits on an event for the command to be returned from ISR.
Sumant Patro2a3681e2006-10-03 13:19:21 -0700785 * Max wait time is MEGASAS_INTERNAL_CMD_WAIT_TIME secs
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -0400786 * Used to issue ioctl commands.
787 */
788static int
789megasas_issue_blocked_cmd(struct megasas_instance *instance,
790 struct megasas_cmd *cmd)
791{
792 cmd->cmd_status = ENODATA;
793
Yang, Bo0c79e682009-10-06 14:47:35 -0600794 instance->instancet->fire_cmd(instance,
795 cmd->frame_phys_addr, 0, instance->reg_set);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -0400796
bo yang39a98552010-09-22 22:36:29 -0400797 wait_event(instance->int_cmd_wait_q, cmd->cmd_status != ENODATA);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -0400798
799 return 0;
800}
801
802/**
803 * megasas_issue_blocked_abort_cmd - Aborts previously issued cmd
804 * @instance: Adapter soft state
805 * @cmd_to_abort: Previously issued cmd to be aborted
806 *
807 * MFI firmware can abort previously issued AEN comamnd (automatic event
808 * notification). The megasas_issue_blocked_abort_cmd() issues such abort
Sumant Patro2a3681e2006-10-03 13:19:21 -0700809 * cmd and waits for return status.
810 * Max wait time is MEGASAS_INTERNAL_CMD_WAIT_TIME secs
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -0400811 */
812static int
813megasas_issue_blocked_abort_cmd(struct megasas_instance *instance,
814 struct megasas_cmd *cmd_to_abort)
815{
816 struct megasas_cmd *cmd;
817 struct megasas_abort_frame *abort_fr;
818
819 cmd = megasas_get_cmd(instance);
820
821 if (!cmd)
822 return -1;
823
824 abort_fr = &cmd->frame->abort;
825
826 /*
827 * Prepare and issue the abort frame
828 */
829 abort_fr->cmd = MFI_CMD_ABORT;
830 abort_fr->cmd_status = 0xFF;
831 abort_fr->flags = 0;
832 abort_fr->abort_context = cmd_to_abort->index;
833 abort_fr->abort_mfi_phys_addr_lo = cmd_to_abort->frame_phys_addr;
834 abort_fr->abort_mfi_phys_addr_hi = 0;
835
836 cmd->sync_cmd = 1;
837 cmd->cmd_status = 0xFF;
838
Yang, Bo0c79e682009-10-06 14:47:35 -0600839 instance->instancet->fire_cmd(instance,
840 cmd->frame_phys_addr, 0, instance->reg_set);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -0400841
842 /*
843 * Wait for this cmd to complete
844 */
bo yang39a98552010-09-22 22:36:29 -0400845 wait_event(instance->abort_cmd_wait_q, cmd->cmd_status != 0xFF);
846 cmd->sync_cmd = 0;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -0400847
848 megasas_return_cmd(instance, cmd);
849 return 0;
850}
851
852/**
853 * megasas_make_sgl32 - Prepares 32-bit SGL
854 * @instance: Adapter soft state
855 * @scp: SCSI command from the mid-layer
856 * @mfi_sgl: SGL to be filled in
857 *
858 * If successful, this function returns the number of SG elements. Otherwise,
859 * it returnes -1.
860 */
Arjan van de Ven858119e2006-01-14 13:20:43 -0800861static int
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -0400862megasas_make_sgl32(struct megasas_instance *instance, struct scsi_cmnd *scp,
863 union megasas_sgl *mfi_sgl)
864{
865 int i;
866 int sge_count;
867 struct scatterlist *os_sgl;
868
FUJITA Tomonori155d98f2007-05-26 05:04:08 +0900869 sge_count = scsi_dma_map(scp);
870 BUG_ON(sge_count < 0);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -0400871
FUJITA Tomonori155d98f2007-05-26 05:04:08 +0900872 if (sge_count) {
873 scsi_for_each_sg(scp, os_sgl, sge_count, i) {
874 mfi_sgl->sge32[i].length = sg_dma_len(os_sgl);
875 mfi_sgl->sge32[i].phys_addr = sg_dma_address(os_sgl);
876 }
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -0400877 }
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -0400878 return sge_count;
879}
880
881/**
882 * megasas_make_sgl64 - Prepares 64-bit SGL
883 * @instance: Adapter soft state
884 * @scp: SCSI command from the mid-layer
885 * @mfi_sgl: SGL to be filled in
886 *
887 * If successful, this function returns the number of SG elements. Otherwise,
888 * it returnes -1.
889 */
Arjan van de Ven858119e2006-01-14 13:20:43 -0800890static int
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -0400891megasas_make_sgl64(struct megasas_instance *instance, struct scsi_cmnd *scp,
892 union megasas_sgl *mfi_sgl)
893{
894 int i;
895 int sge_count;
896 struct scatterlist *os_sgl;
897
FUJITA Tomonori155d98f2007-05-26 05:04:08 +0900898 sge_count = scsi_dma_map(scp);
899 BUG_ON(sge_count < 0);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -0400900
FUJITA Tomonori155d98f2007-05-26 05:04:08 +0900901 if (sge_count) {
902 scsi_for_each_sg(scp, os_sgl, sge_count, i) {
903 mfi_sgl->sge64[i].length = sg_dma_len(os_sgl);
904 mfi_sgl->sge64[i].phys_addr = sg_dma_address(os_sgl);
905 }
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -0400906 }
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -0400907 return sge_count;
908}
909
Yang, Bof4c9a132009-10-06 14:43:28 -0600910/**
911 * megasas_make_sgl_skinny - Prepares IEEE SGL
912 * @instance: Adapter soft state
913 * @scp: SCSI command from the mid-layer
914 * @mfi_sgl: SGL to be filled in
915 *
916 * If successful, this function returns the number of SG elements. Otherwise,
917 * it returnes -1.
918 */
919static int
920megasas_make_sgl_skinny(struct megasas_instance *instance,
921 struct scsi_cmnd *scp, union megasas_sgl *mfi_sgl)
922{
923 int i;
924 int sge_count;
925 struct scatterlist *os_sgl;
926
927 sge_count = scsi_dma_map(scp);
928
929 if (sge_count) {
930 scsi_for_each_sg(scp, os_sgl, sge_count, i) {
931 mfi_sgl->sge_skinny[i].length = sg_dma_len(os_sgl);
932 mfi_sgl->sge_skinny[i].phys_addr =
933 sg_dma_address(os_sgl);
934 }
935 }
936 return sge_count;
937}
938
Sumant Patrob1df99d2006-10-03 12:40:47 -0700939 /**
940 * megasas_get_frame_count - Computes the number of frames
bo yangd532dbe2008-03-17 03:36:43 -0400941 * @frame_type : type of frame- io or pthru frame
Sumant Patrob1df99d2006-10-03 12:40:47 -0700942 * @sge_count : number of sg elements
943 *
944 * Returns the number of frames required for numnber of sge's (sge_count)
945 */
946
Yang, Bof4c9a132009-10-06 14:43:28 -0600947static u32 megasas_get_frame_count(struct megasas_instance *instance,
948 u8 sge_count, u8 frame_type)
Sumant Patrob1df99d2006-10-03 12:40:47 -0700949{
950 int num_cnt;
951 int sge_bytes;
952 u32 sge_sz;
953 u32 frame_count=0;
954
955 sge_sz = (IS_DMA64) ? sizeof(struct megasas_sge64) :
956 sizeof(struct megasas_sge32);
957
Yang, Bof4c9a132009-10-06 14:43:28 -0600958 if (instance->flag_ieee) {
959 sge_sz = sizeof(struct megasas_sge_skinny);
960 }
961
Sumant Patrob1df99d2006-10-03 12:40:47 -0700962 /*
bo yangd532dbe2008-03-17 03:36:43 -0400963 * Main frame can contain 2 SGEs for 64-bit SGLs and
964 * 3 SGEs for 32-bit SGLs for ldio &
965 * 1 SGEs for 64-bit SGLs and
966 * 2 SGEs for 32-bit SGLs for pthru frame
967 */
968 if (unlikely(frame_type == PTHRU_FRAME)) {
Yang, Bof4c9a132009-10-06 14:43:28 -0600969 if (instance->flag_ieee == 1) {
970 num_cnt = sge_count - 1;
971 } else if (IS_DMA64)
bo yangd532dbe2008-03-17 03:36:43 -0400972 num_cnt = sge_count - 1;
973 else
974 num_cnt = sge_count - 2;
975 } else {
Yang, Bof4c9a132009-10-06 14:43:28 -0600976 if (instance->flag_ieee == 1) {
977 num_cnt = sge_count - 1;
978 } else if (IS_DMA64)
bo yangd532dbe2008-03-17 03:36:43 -0400979 num_cnt = sge_count - 2;
980 else
981 num_cnt = sge_count - 3;
982 }
Sumant Patrob1df99d2006-10-03 12:40:47 -0700983
984 if(num_cnt>0){
985 sge_bytes = sge_sz * num_cnt;
986
987 frame_count = (sge_bytes / MEGAMFI_FRAME_SIZE) +
988 ((sge_bytes % MEGAMFI_FRAME_SIZE) ? 1 : 0) ;
989 }
990 /* Main frame */
991 frame_count +=1;
992
993 if (frame_count > 7)
994 frame_count = 8;
995 return frame_count;
996}
997
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -0400998/**
999 * megasas_build_dcdb - Prepares a direct cdb (DCDB) command
1000 * @instance: Adapter soft state
1001 * @scp: SCSI command
1002 * @cmd: Command to be prepared in
1003 *
1004 * This function prepares CDB commands. These are typcially pass-through
1005 * commands to the devices.
1006 */
Arjan van de Ven858119e2006-01-14 13:20:43 -08001007static int
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001008megasas_build_dcdb(struct megasas_instance *instance, struct scsi_cmnd *scp,
1009 struct megasas_cmd *cmd)
1010{
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001011 u32 is_logical;
1012 u32 device_id;
1013 u16 flags = 0;
1014 struct megasas_pthru_frame *pthru;
1015
1016 is_logical = MEGASAS_IS_LOGICAL(scp);
1017 device_id = MEGASAS_DEV_INDEX(instance, scp);
1018 pthru = (struct megasas_pthru_frame *)cmd->frame;
1019
1020 if (scp->sc_data_direction == PCI_DMA_TODEVICE)
1021 flags = MFI_FRAME_DIR_WRITE;
1022 else if (scp->sc_data_direction == PCI_DMA_FROMDEVICE)
1023 flags = MFI_FRAME_DIR_READ;
1024 else if (scp->sc_data_direction == PCI_DMA_NONE)
1025 flags = MFI_FRAME_DIR_NONE;
1026
Yang, Bof4c9a132009-10-06 14:43:28 -06001027 if (instance->flag_ieee == 1) {
1028 flags |= MFI_FRAME_IEEE;
1029 }
1030
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001031 /*
1032 * Prepare the DCDB frame
1033 */
1034 pthru->cmd = (is_logical) ? MFI_CMD_LD_SCSI_IO : MFI_CMD_PD_SCSI_IO;
1035 pthru->cmd_status = 0x0;
1036 pthru->scsi_status = 0x0;
1037 pthru->target_id = device_id;
1038 pthru->lun = scp->device->lun;
1039 pthru->cdb_len = scp->cmd_len;
1040 pthru->timeout = 0;
Yang, Bo780a3762009-12-06 08:24:21 -07001041 pthru->pad_0 = 0;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001042 pthru->flags = flags;
FUJITA Tomonori155d98f2007-05-26 05:04:08 +09001043 pthru->data_xfer_len = scsi_bufflen(scp);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001044
1045 memcpy(pthru->cdb, scp->cmnd, scp->cmd_len);
1046
1047 /*
Yang, Bo8d568252009-10-06 14:12:21 -06001048 * If the command is for the tape device, set the
1049 * pthru timeout to the os layer timeout value.
1050 */
1051 if (scp->device->type == TYPE_TAPE) {
1052 if ((scp->request->timeout / HZ) > 0xFFFF)
1053 pthru->timeout = 0xFFFF;
1054 else
1055 pthru->timeout = scp->request->timeout / HZ;
1056 }
1057
1058 /*
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001059 * Construct SGL
1060 */
Yang, Bof4c9a132009-10-06 14:43:28 -06001061 if (instance->flag_ieee == 1) {
1062 pthru->flags |= MFI_FRAME_SGL64;
1063 pthru->sge_count = megasas_make_sgl_skinny(instance, scp,
1064 &pthru->sgl);
1065 } else if (IS_DMA64) {
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001066 pthru->flags |= MFI_FRAME_SGL64;
1067 pthru->sge_count = megasas_make_sgl64(instance, scp,
1068 &pthru->sgl);
1069 } else
1070 pthru->sge_count = megasas_make_sgl32(instance, scp,
1071 &pthru->sgl);
1072
Yang, Bobdc6fb82009-12-06 08:30:19 -07001073 if (pthru->sge_count > instance->max_num_sge) {
1074 printk(KERN_ERR "megasas: DCDB two many SGE NUM=%x\n",
1075 pthru->sge_count);
1076 return 0;
1077 }
1078
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001079 /*
1080 * Sense info specific
1081 */
1082 pthru->sense_len = SCSI_SENSE_BUFFERSIZE;
1083 pthru->sense_buf_phys_addr_hi = 0;
1084 pthru->sense_buf_phys_addr_lo = cmd->sense_phys_addr;
1085
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001086 /*
1087 * Compute the total number of frames this command consumes. FW uses
1088 * this number to pull sufficient number of frames from host memory.
1089 */
Yang, Bof4c9a132009-10-06 14:43:28 -06001090 cmd->frame_count = megasas_get_frame_count(instance, pthru->sge_count,
bo yangd532dbe2008-03-17 03:36:43 -04001091 PTHRU_FRAME);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001092
1093 return cmd->frame_count;
1094}
1095
1096/**
1097 * megasas_build_ldio - Prepares IOs to logical devices
1098 * @instance: Adapter soft state
1099 * @scp: SCSI command
Anand Gadiyarfd589a82009-07-16 17:13:03 +02001100 * @cmd: Command to be prepared
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001101 *
1102 * Frames (and accompanying SGLs) for regular SCSI IOs use this function.
1103 */
Arjan van de Ven858119e2006-01-14 13:20:43 -08001104static int
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001105megasas_build_ldio(struct megasas_instance *instance, struct scsi_cmnd *scp,
1106 struct megasas_cmd *cmd)
1107{
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001108 u32 device_id;
1109 u8 sc = scp->cmnd[0];
1110 u16 flags = 0;
1111 struct megasas_io_frame *ldio;
1112
1113 device_id = MEGASAS_DEV_INDEX(instance, scp);
1114 ldio = (struct megasas_io_frame *)cmd->frame;
1115
1116 if (scp->sc_data_direction == PCI_DMA_TODEVICE)
1117 flags = MFI_FRAME_DIR_WRITE;
1118 else if (scp->sc_data_direction == PCI_DMA_FROMDEVICE)
1119 flags = MFI_FRAME_DIR_READ;
1120
Yang, Bof4c9a132009-10-06 14:43:28 -06001121 if (instance->flag_ieee == 1) {
1122 flags |= MFI_FRAME_IEEE;
1123 }
1124
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001125 /*
Sumant Patrob1df99d2006-10-03 12:40:47 -07001126 * Prepare the Logical IO frame: 2nd bit is zero for all read cmds
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001127 */
1128 ldio->cmd = (sc & 0x02) ? MFI_CMD_LD_WRITE : MFI_CMD_LD_READ;
1129 ldio->cmd_status = 0x0;
1130 ldio->scsi_status = 0x0;
1131 ldio->target_id = device_id;
1132 ldio->timeout = 0;
1133 ldio->reserved_0 = 0;
1134 ldio->pad_0 = 0;
1135 ldio->flags = flags;
1136 ldio->start_lba_hi = 0;
1137 ldio->access_byte = (scp->cmd_len != 6) ? scp->cmnd[1] : 0;
1138
1139 /*
1140 * 6-byte READ(0x08) or WRITE(0x0A) cdb
1141 */
1142 if (scp->cmd_len == 6) {
1143 ldio->lba_count = (u32) scp->cmnd[4];
1144 ldio->start_lba_lo = ((u32) scp->cmnd[1] << 16) |
1145 ((u32) scp->cmnd[2] << 8) | (u32) scp->cmnd[3];
1146
1147 ldio->start_lba_lo &= 0x1FFFFF;
1148 }
1149
1150 /*
1151 * 10-byte READ(0x28) or WRITE(0x2A) cdb
1152 */
1153 else if (scp->cmd_len == 10) {
1154 ldio->lba_count = (u32) scp->cmnd[8] |
1155 ((u32) scp->cmnd[7] << 8);
1156 ldio->start_lba_lo = ((u32) scp->cmnd[2] << 24) |
1157 ((u32) scp->cmnd[3] << 16) |
1158 ((u32) scp->cmnd[4] << 8) | (u32) scp->cmnd[5];
1159 }
1160
1161 /*
1162 * 12-byte READ(0xA8) or WRITE(0xAA) cdb
1163 */
1164 else if (scp->cmd_len == 12) {
1165 ldio->lba_count = ((u32) scp->cmnd[6] << 24) |
1166 ((u32) scp->cmnd[7] << 16) |
1167 ((u32) scp->cmnd[8] << 8) | (u32) scp->cmnd[9];
1168
1169 ldio->start_lba_lo = ((u32) scp->cmnd[2] << 24) |
1170 ((u32) scp->cmnd[3] << 16) |
1171 ((u32) scp->cmnd[4] << 8) | (u32) scp->cmnd[5];
1172 }
1173
1174 /*
1175 * 16-byte READ(0x88) or WRITE(0x8A) cdb
1176 */
1177 else if (scp->cmd_len == 16) {
1178 ldio->lba_count = ((u32) scp->cmnd[10] << 24) |
1179 ((u32) scp->cmnd[11] << 16) |
1180 ((u32) scp->cmnd[12] << 8) | (u32) scp->cmnd[13];
1181
1182 ldio->start_lba_lo = ((u32) scp->cmnd[6] << 24) |
1183 ((u32) scp->cmnd[7] << 16) |
1184 ((u32) scp->cmnd[8] << 8) | (u32) scp->cmnd[9];
1185
1186 ldio->start_lba_hi = ((u32) scp->cmnd[2] << 24) |
1187 ((u32) scp->cmnd[3] << 16) |
1188 ((u32) scp->cmnd[4] << 8) | (u32) scp->cmnd[5];
1189
1190 }
1191
1192 /*
1193 * Construct SGL
1194 */
Yang, Bof4c9a132009-10-06 14:43:28 -06001195 if (instance->flag_ieee) {
1196 ldio->flags |= MFI_FRAME_SGL64;
1197 ldio->sge_count = megasas_make_sgl_skinny(instance, scp,
1198 &ldio->sgl);
1199 } else if (IS_DMA64) {
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001200 ldio->flags |= MFI_FRAME_SGL64;
1201 ldio->sge_count = megasas_make_sgl64(instance, scp, &ldio->sgl);
1202 } else
1203 ldio->sge_count = megasas_make_sgl32(instance, scp, &ldio->sgl);
1204
Yang, Bobdc6fb82009-12-06 08:30:19 -07001205 if (ldio->sge_count > instance->max_num_sge) {
1206 printk(KERN_ERR "megasas: build_ld_io: sge_count = %x\n",
1207 ldio->sge_count);
1208 return 0;
1209 }
1210
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001211 /*
1212 * Sense info specific
1213 */
1214 ldio->sense_len = SCSI_SENSE_BUFFERSIZE;
1215 ldio->sense_buf_phys_addr_hi = 0;
1216 ldio->sense_buf_phys_addr_lo = cmd->sense_phys_addr;
1217
Sumant Patrob1df99d2006-10-03 12:40:47 -07001218 /*
1219 * Compute the total number of frames this command consumes. FW uses
1220 * this number to pull sufficient number of frames from host memory.
1221 */
Yang, Bof4c9a132009-10-06 14:43:28 -06001222 cmd->frame_count = megasas_get_frame_count(instance,
1223 ldio->sge_count, IO_FRAME);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001224
1225 return cmd->frame_count;
1226}
1227
1228/**
Sumant Patrocb59aa62006-01-25 11:53:25 -08001229 * megasas_is_ldio - Checks if the cmd is for logical drive
1230 * @scmd: SCSI command
1231 *
1232 * Called by megasas_queue_command to find out if the command to be queued
1233 * is a logical drive command
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001234 */
Sumant Patrocb59aa62006-01-25 11:53:25 -08001235static inline int megasas_is_ldio(struct scsi_cmnd *cmd)
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001236{
Sumant Patrocb59aa62006-01-25 11:53:25 -08001237 if (!MEGASAS_IS_LOGICAL(cmd))
1238 return 0;
1239 switch (cmd->cmnd[0]) {
1240 case READ_10:
1241 case WRITE_10:
1242 case READ_12:
1243 case WRITE_12:
1244 case READ_6:
1245 case WRITE_6:
1246 case READ_16:
1247 case WRITE_16:
1248 return 1;
1249 default:
1250 return 0;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001251 }
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001252}
1253
Sumant Patro658dced2006-10-03 13:09:14 -07001254 /**
1255 * megasas_dump_pending_frames - Dumps the frame address of all pending cmds
1256 * in FW
1257 * @instance: Adapter soft state
1258 */
1259static inline void
1260megasas_dump_pending_frames(struct megasas_instance *instance)
1261{
1262 struct megasas_cmd *cmd;
1263 int i,n;
1264 union megasas_sgl *mfi_sgl;
1265 struct megasas_io_frame *ldio;
1266 struct megasas_pthru_frame *pthru;
1267 u32 sgcount;
1268 u32 max_cmd = instance->max_fw_cmds;
1269
1270 printk(KERN_ERR "\nmegasas[%d]: Dumping Frame Phys Address of all pending cmds in FW\n",instance->host->host_no);
1271 printk(KERN_ERR "megasas[%d]: Total OS Pending cmds : %d\n",instance->host->host_no,atomic_read(&instance->fw_outstanding));
1272 if (IS_DMA64)
1273 printk(KERN_ERR "\nmegasas[%d]: 64 bit SGLs were sent to FW\n",instance->host->host_no);
1274 else
1275 printk(KERN_ERR "\nmegasas[%d]: 32 bit SGLs were sent to FW\n",instance->host->host_no);
1276
1277 printk(KERN_ERR "megasas[%d]: Pending OS cmds in FW : \n",instance->host->host_no);
1278 for (i = 0; i < max_cmd; i++) {
1279 cmd = instance->cmd_list[i];
1280 if(!cmd->scmd)
1281 continue;
1282 printk(KERN_ERR "megasas[%d]: Frame addr :0x%08lx : ",instance->host->host_no,(unsigned long)cmd->frame_phys_addr);
1283 if (megasas_is_ldio(cmd->scmd)){
1284 ldio = (struct megasas_io_frame *)cmd->frame;
1285 mfi_sgl = &ldio->sgl;
1286 sgcount = ldio->sge_count;
1287 printk(KERN_ERR "megasas[%d]: frame count : 0x%x, Cmd : 0x%x, Tgt id : 0x%x, lba lo : 0x%x, lba_hi : 0x%x, sense_buf addr : 0x%x,sge count : 0x%x\n",instance->host->host_no, cmd->frame_count,ldio->cmd,ldio->target_id, ldio->start_lba_lo,ldio->start_lba_hi,ldio->sense_buf_phys_addr_lo,sgcount);
1288 }
1289 else {
1290 pthru = (struct megasas_pthru_frame *) cmd->frame;
1291 mfi_sgl = &pthru->sgl;
1292 sgcount = pthru->sge_count;
1293 printk(KERN_ERR "megasas[%d]: frame count : 0x%x, Cmd : 0x%x, Tgt id : 0x%x, lun : 0x%x, cdb_len : 0x%x, data xfer len : 0x%x, sense_buf addr : 0x%x,sge count : 0x%x\n",instance->host->host_no,cmd->frame_count,pthru->cmd,pthru->target_id,pthru->lun,pthru->cdb_len , pthru->data_xfer_len,pthru->sense_buf_phys_addr_lo,sgcount);
1294 }
1295 if(megasas_dbg_lvl & MEGASAS_DBG_LVL){
1296 for (n = 0; n < sgcount; n++){
1297 if (IS_DMA64)
1298 printk(KERN_ERR "megasas: sgl len : 0x%x, sgl addr : 0x%08lx ",mfi_sgl->sge64[n].length , (unsigned long)mfi_sgl->sge64[n].phys_addr) ;
1299 else
1300 printk(KERN_ERR "megasas: sgl len : 0x%x, sgl addr : 0x%x ",mfi_sgl->sge32[n].length , mfi_sgl->sge32[n].phys_addr) ;
1301 }
1302 }
1303 printk(KERN_ERR "\n");
1304 } /*for max_cmd*/
1305 printk(KERN_ERR "\nmegasas[%d]: Pending Internal cmds in FW : \n",instance->host->host_no);
1306 for (i = 0; i < max_cmd; i++) {
1307
1308 cmd = instance->cmd_list[i];
1309
1310 if(cmd->sync_cmd == 1){
1311 printk(KERN_ERR "0x%08lx : ", (unsigned long)cmd->frame_phys_addr);
1312 }
1313 }
1314 printk(KERN_ERR "megasas[%d]: Dumping Done.\n\n",instance->host->host_no);
1315}
1316
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001317/**
1318 * megasas_queue_command - Queue entry point
1319 * @scmd: SCSI command to be queued
1320 * @done: Callback entry point
1321 */
1322static int
1323megasas_queue_command(struct scsi_cmnd *scmd, void (*done) (struct scsi_cmnd *))
1324{
1325 u32 frame_count;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001326 struct megasas_cmd *cmd;
1327 struct megasas_instance *instance;
bo yang39a98552010-09-22 22:36:29 -04001328 unsigned long flags;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001329
1330 instance = (struct megasas_instance *)
1331 scmd->device->host->hostdata;
Sumant Patroaf37acf2007-02-14 12:34:46 -08001332
bo yang39a98552010-09-22 22:36:29 -04001333 if (instance->issuepend_done == 0)
Sumant Patroaf37acf2007-02-14 12:34:46 -08001334 return SCSI_MLQUEUE_HOST_BUSY;
1335
bo yang39a98552010-09-22 22:36:29 -04001336 spin_lock_irqsave(&instance->hba_lock, flags);
1337 if (instance->adprecovery != MEGASAS_HBA_OPERATIONAL) {
1338 spin_unlock_irqrestore(&instance->hba_lock, flags);
1339 return SCSI_MLQUEUE_HOST_BUSY;
1340 }
1341
1342 spin_unlock_irqrestore(&instance->hba_lock, flags);
1343
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001344 scmd->scsi_done = done;
1345 scmd->result = 0;
1346
Sumant Patrocb59aa62006-01-25 11:53:25 -08001347 if (MEGASAS_IS_LOGICAL(scmd) &&
1348 (scmd->device->id >= MEGASAS_MAX_LD || scmd->device->lun)) {
1349 scmd->result = DID_BAD_TARGET << 16;
1350 goto out_done;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001351 }
1352
Sumant Patro02b01e02007-02-14 13:00:55 -08001353 switch (scmd->cmnd[0]) {
1354 case SYNCHRONIZE_CACHE:
1355 /*
1356 * FW takes care of flush cache on its own
1357 * No need to send it down
1358 */
1359 scmd->result = DID_OK << 16;
1360 goto out_done;
1361 default:
1362 break;
1363 }
1364
Sumant Patrocb59aa62006-01-25 11:53:25 -08001365 cmd = megasas_get_cmd(instance);
1366 if (!cmd)
1367 return SCSI_MLQUEUE_HOST_BUSY;
1368
1369 /*
1370 * Logical drive command
1371 */
1372 if (megasas_is_ldio(scmd))
1373 frame_count = megasas_build_ldio(instance, scmd, cmd);
1374 else
1375 frame_count = megasas_build_dcdb(instance, scmd, cmd);
1376
1377 if (!frame_count)
1378 goto out_return_cmd;
1379
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001380 cmd->scmd = scmd;
Sumant Patro05e9ebb2007-05-17 05:47:51 -07001381 scmd->SCp.ptr = (char *)cmd;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001382
1383 /*
1384 * Issue the command to the FW
1385 */
Sumant Patroe4a082c2006-05-30 12:03:37 -07001386 atomic_inc(&instance->fw_outstanding);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001387
Yang, Bo0c79e682009-10-06 14:47:35 -06001388 instance->instancet->fire_cmd(instance, cmd->frame_phys_addr,
1389 cmd->frame_count-1, instance->reg_set);
bo yangad84db22007-11-09 04:40:16 -05001390 /*
1391 * Check if we have pend cmds to be completed
1392 */
1393 if (poll_mode_io && atomic_read(&instance->fw_outstanding))
1394 tasklet_schedule(&instance->isr_tasklet);
1395
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001396
1397 return 0;
Sumant Patrocb59aa62006-01-25 11:53:25 -08001398
1399 out_return_cmd:
1400 megasas_return_cmd(instance, cmd);
1401 out_done:
1402 done(scmd);
1403 return 0;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001404}
1405
Yang, Bo044833b2009-10-06 14:33:06 -06001406static struct megasas_instance *megasas_lookup_instance(u16 host_no)
1407{
1408 int i;
1409
1410 for (i = 0; i < megasas_mgmt_info.max_index; i++) {
1411
1412 if ((megasas_mgmt_info.instance[i]) &&
1413 (megasas_mgmt_info.instance[i]->host->host_no == host_no))
1414 return megasas_mgmt_info.instance[i];
1415 }
1416
1417 return NULL;
1418}
1419
Christoph Hellwig147aab62006-02-17 12:13:48 +01001420static int megasas_slave_configure(struct scsi_device *sdev)
1421{
Yang, Bo044833b2009-10-06 14:33:06 -06001422 u16 pd_index = 0;
1423 struct megasas_instance *instance ;
1424
1425 instance = megasas_lookup_instance(sdev->host->host_no);
Christoph Hellwige5b3a652006-03-10 17:08:57 +01001426
1427 /*
Yang, Bo044833b2009-10-06 14:33:06 -06001428 * Don't export physical disk devices to the disk driver.
1429 *
1430 * FIXME: Currently we don't export them to the midlayer at all.
1431 * That will be fixed once LSI engineers have audited the
1432 * firmware for possible issues.
1433 */
1434 if (sdev->channel < MEGASAS_MAX_PD_CHANNELS &&
1435 sdev->type == TYPE_DISK) {
1436 pd_index = (sdev->channel * MEGASAS_MAX_DEV_PER_CHANNEL) +
1437 sdev->id;
1438 if (instance->pd_list[pd_index].driveState ==
1439 MR_PD_STATE_SYSTEM) {
1440 blk_queue_rq_timeout(sdev->request_queue,
1441 MEGASAS_DEFAULT_CMD_TIMEOUT * HZ);
1442 return 0;
1443 }
1444 return -ENXIO;
1445 }
1446
1447 /*
1448 * The RAID firmware may require extended timeouts.
1449 */
1450 blk_queue_rq_timeout(sdev->request_queue,
1451 MEGASAS_DEFAULT_CMD_TIMEOUT * HZ);
1452 return 0;
1453}
1454
1455static int megasas_slave_alloc(struct scsi_device *sdev)
1456{
1457 u16 pd_index = 0;
1458 struct megasas_instance *instance ;
1459 instance = megasas_lookup_instance(sdev->host->host_no);
1460 if ((sdev->channel < MEGASAS_MAX_PD_CHANNELS) &&
1461 (sdev->type == TYPE_DISK)) {
1462 /*
1463 * Open the OS scan to the SYSTEM PD
1464 */
1465 pd_index =
1466 (sdev->channel * MEGASAS_MAX_DEV_PER_CHANNEL) +
1467 sdev->id;
1468 if ((instance->pd_list[pd_index].driveState ==
1469 MR_PD_STATE_SYSTEM) &&
1470 (instance->pd_list[pd_index].driveType ==
1471 TYPE_DISK)) {
1472 return 0;
1473 }
1474 return -ENXIO;
1475 }
Christoph Hellwig147aab62006-02-17 12:13:48 +01001476 return 0;
1477}
1478
bo yang39a98552010-09-22 22:36:29 -04001479static void megaraid_sas_kill_hba(struct megasas_instance *instance)
1480{
1481 if ((instance->pdev->device == PCI_DEVICE_ID_LSI_SAS0073SKINNY) ||
1482 (instance->pdev->device == PCI_DEVICE_ID_LSI_SAS0071SKINNY)) {
1483 writel(MFI_STOP_ADP,
1484 &instance->reg_set->reserved_0[0]);
1485 } else {
1486 writel(MFI_STOP_ADP,
1487 &instance->reg_set->inbound_doorbell);
1488 }
1489}
1490
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001491/**
bo yang7343eb62007-11-09 04:35:44 -05001492 * megasas_complete_cmd_dpc - Returns FW's controller structure
1493 * @instance_addr: Address of adapter soft state
1494 *
1495 * Tasklet to complete cmds
1496 */
1497static void megasas_complete_cmd_dpc(unsigned long instance_addr)
1498{
1499 u32 producer;
1500 u32 consumer;
1501 u32 context;
1502 struct megasas_cmd *cmd;
1503 struct megasas_instance *instance =
1504 (struct megasas_instance *)instance_addr;
1505 unsigned long flags;
1506
1507 /* If we have already declared adapter dead, donot complete cmds */
bo yang39a98552010-09-22 22:36:29 -04001508 if (instance->adprecovery == MEGASAS_HW_CRITICAL_ERROR )
bo yang7343eb62007-11-09 04:35:44 -05001509 return;
1510
1511 spin_lock_irqsave(&instance->completion_lock, flags);
1512
1513 producer = *instance->producer;
1514 consumer = *instance->consumer;
1515
1516 while (consumer != producer) {
1517 context = instance->reply_queue[consumer];
bo yang39a98552010-09-22 22:36:29 -04001518 if (context >= instance->max_fw_cmds) {
1519 printk(KERN_ERR "Unexpected context value %x\n",
1520 context);
1521 BUG();
1522 }
bo yang7343eb62007-11-09 04:35:44 -05001523
1524 cmd = instance->cmd_list[context];
1525
1526 megasas_complete_cmd(instance, cmd, DID_OK);
1527
1528 consumer++;
1529 if (consumer == (instance->max_fw_cmds + 1)) {
1530 consumer = 0;
1531 }
1532 }
1533
1534 *instance->consumer = producer;
1535
1536 spin_unlock_irqrestore(&instance->completion_lock, flags);
1537
1538 /*
1539 * Check if we can restore can_queue
1540 */
1541 if (instance->flag & MEGASAS_FW_BUSY
1542 && time_after(jiffies, instance->last_time + 5 * HZ)
1543 && atomic_read(&instance->fw_outstanding) < 17) {
1544
1545 spin_lock_irqsave(instance->host->host_lock, flags);
1546 instance->flag &= ~MEGASAS_FW_BUSY;
Yang, Bo7bebf5c2009-10-06 14:40:58 -06001547 if ((instance->pdev->device ==
1548 PCI_DEVICE_ID_LSI_SAS0073SKINNY) ||
1549 (instance->pdev->device ==
1550 PCI_DEVICE_ID_LSI_SAS0071SKINNY)) {
1551 instance->host->can_queue =
1552 instance->max_fw_cmds - MEGASAS_SKINNY_INT_CMDS;
1553 } else
1554 instance->host->can_queue =
bo yang7343eb62007-11-09 04:35:44 -05001555 instance->max_fw_cmds - MEGASAS_INT_CMDS;
1556
1557 spin_unlock_irqrestore(instance->host->host_lock, flags);
1558 }
1559}
1560
1561/**
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001562 * megasas_wait_for_outstanding - Wait for all outstanding cmds
1563 * @instance: Adapter soft state
1564 *
1565 * This function waits for upto MEGASAS_RESET_WAIT_TIME seconds for FW to
1566 * complete all its outstanding commands. Returns error if one or more IOs
1567 * are pending after this time period. It also marks the controller dead.
1568 */
1569static int megasas_wait_for_outstanding(struct megasas_instance *instance)
1570{
1571 int i;
bo yang39a98552010-09-22 22:36:29 -04001572 u32 reset_index;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001573 u32 wait_time = MEGASAS_RESET_WAIT_TIME;
bo yang39a98552010-09-22 22:36:29 -04001574 u8 adprecovery;
1575 unsigned long flags;
1576 struct list_head clist_local;
1577 struct megasas_cmd *reset_cmd;
1578
1579 spin_lock_irqsave(&instance->hba_lock, flags);
1580 adprecovery = instance->adprecovery;
1581 spin_unlock_irqrestore(&instance->hba_lock, flags);
1582
1583 if (adprecovery != MEGASAS_HBA_OPERATIONAL) {
1584
1585 INIT_LIST_HEAD(&clist_local);
1586 spin_lock_irqsave(&instance->hba_lock, flags);
1587 list_splice_init(&instance->internal_reset_pending_q,
1588 &clist_local);
1589 spin_unlock_irqrestore(&instance->hba_lock, flags);
1590
1591 printk(KERN_NOTICE "megasas: HBA reset wait ...\n");
1592 for (i = 0; i < wait_time; i++) {
1593 msleep(1000);
1594 spin_lock_irqsave(&instance->hba_lock, flags);
1595 adprecovery = instance->adprecovery;
1596 spin_unlock_irqrestore(&instance->hba_lock, flags);
1597 if (adprecovery == MEGASAS_HBA_OPERATIONAL)
1598 break;
1599 }
1600
1601 if (adprecovery != MEGASAS_HBA_OPERATIONAL) {
1602 printk(KERN_NOTICE "megasas: reset: Stopping HBA.\n");
1603 spin_lock_irqsave(&instance->hba_lock, flags);
1604 instance->adprecovery = MEGASAS_HW_CRITICAL_ERROR;
1605 spin_unlock_irqrestore(&instance->hba_lock, flags);
1606 return FAILED;
1607 }
1608
1609 reset_index = 0;
1610 while (!list_empty(&clist_local)) {
1611 reset_cmd = list_entry((&clist_local)->next,
1612 struct megasas_cmd, list);
1613 list_del_init(&reset_cmd->list);
1614 if (reset_cmd->scmd) {
1615 reset_cmd->scmd->result = DID_RESET << 16;
1616 printk(KERN_NOTICE "%d:%p reset [%02x], %#lx\n",
1617 reset_index, reset_cmd,
1618 reset_cmd->scmd->cmnd[0],
1619 reset_cmd->scmd->serial_number);
1620
1621 reset_cmd->scmd->scsi_done(reset_cmd->scmd);
1622 megasas_return_cmd(instance, reset_cmd);
1623 } else if (reset_cmd->sync_cmd) {
1624 printk(KERN_NOTICE "megasas:%p synch cmds"
1625 "reset queue\n",
1626 reset_cmd);
1627
1628 reset_cmd->cmd_status = ENODATA;
1629 instance->instancet->fire_cmd(instance,
1630 reset_cmd->frame_phys_addr,
1631 0, instance->reg_set);
1632 } else {
1633 printk(KERN_NOTICE "megasas: %p unexpected"
1634 "cmds lst\n",
1635 reset_cmd);
1636 }
1637 reset_index++;
1638 }
1639
1640 return SUCCESS;
1641 }
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001642
1643 for (i = 0; i < wait_time; i++) {
1644
Sumant Patroe4a082c2006-05-30 12:03:37 -07001645 int outstanding = atomic_read(&instance->fw_outstanding);
1646
1647 if (!outstanding)
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001648 break;
1649
1650 if (!(i % MEGASAS_RESET_NOTICE_INTERVAL)) {
1651 printk(KERN_NOTICE "megasas: [%2d]waiting for %d "
Sumant Patroe4a082c2006-05-30 12:03:37 -07001652 "commands to complete\n",i,outstanding);
bo yang7343eb62007-11-09 04:35:44 -05001653 /*
1654 * Call cmd completion routine. Cmd to be
1655 * be completed directly without depending on isr.
1656 */
1657 megasas_complete_cmd_dpc((unsigned long)instance);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001658 }
1659
1660 msleep(1000);
1661 }
1662
Sumant Patroe4a082c2006-05-30 12:03:37 -07001663 if (atomic_read(&instance->fw_outstanding)) {
bo yang39a98552010-09-22 22:36:29 -04001664 printk(KERN_NOTICE "megaraid_sas: pending cmds after reset\n");
Sumant Patroe3bbff92006-10-03 12:28:49 -07001665 /*
1666 * Send signal to FW to stop processing any pending cmds.
1667 * The controller will be taken offline by the OS now.
1668 */
Yang, Bo0c79e682009-10-06 14:47:35 -06001669 if ((instance->pdev->device ==
1670 PCI_DEVICE_ID_LSI_SAS0073SKINNY) ||
1671 (instance->pdev->device ==
1672 PCI_DEVICE_ID_LSI_SAS0071SKINNY)) {
1673 writel(MFI_STOP_ADP,
1674 &instance->reg_set->reserved_0[0]);
1675 } else {
1676 writel(MFI_STOP_ADP,
Sumant Patroe3bbff92006-10-03 12:28:49 -07001677 &instance->reg_set->inbound_doorbell);
Yang, Bo0c79e682009-10-06 14:47:35 -06001678 }
Sumant Patro658dced2006-10-03 13:09:14 -07001679 megasas_dump_pending_frames(instance);
bo yang39a98552010-09-22 22:36:29 -04001680 spin_lock_irqsave(&instance->hba_lock, flags);
1681 instance->adprecovery = MEGASAS_HW_CRITICAL_ERROR;
1682 spin_unlock_irqrestore(&instance->hba_lock, flags);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001683 return FAILED;
1684 }
1685
bo yang39a98552010-09-22 22:36:29 -04001686 printk(KERN_NOTICE "megaraid_sas: no pending cmds after reset\n");
1687
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001688 return SUCCESS;
1689}
1690
1691/**
1692 * megasas_generic_reset - Generic reset routine
1693 * @scmd: Mid-layer SCSI command
1694 *
1695 * This routine implements a generic reset handler for device, bus and host
1696 * reset requests. Device, bus and host specific reset handlers can use this
1697 * function after they do their specific tasks.
1698 */
1699static int megasas_generic_reset(struct scsi_cmnd *scmd)
1700{
1701 int ret_val;
1702 struct megasas_instance *instance;
1703
1704 instance = (struct megasas_instance *)scmd->device->host->hostdata;
1705
Sumant Patro05e9ebb2007-05-17 05:47:51 -07001706 scmd_printk(KERN_NOTICE, scmd, "megasas: RESET -%ld cmd=%x retries=%x\n",
1707 scmd->serial_number, scmd->cmnd[0], scmd->retries);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001708
bo yang39a98552010-09-22 22:36:29 -04001709 if (instance->adprecovery == MEGASAS_HW_CRITICAL_ERROR) {
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001710 printk(KERN_ERR "megasas: cannot recover from previous reset "
1711 "failures\n");
1712 return FAILED;
1713 }
1714
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001715 ret_val = megasas_wait_for_outstanding(instance);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001716 if (ret_val == SUCCESS)
1717 printk(KERN_NOTICE "megasas: reset successful \n");
1718 else
1719 printk(KERN_ERR "megasas: failed to do reset\n");
1720
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001721 return ret_val;
1722}
1723
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001724/**
Sumant Patro05e9ebb2007-05-17 05:47:51 -07001725 * megasas_reset_timer - quiesce the adapter if required
1726 * @scmd: scsi cmnd
1727 *
1728 * Sets the FW busy flag and reduces the host->can_queue if the
1729 * cmd has not been completed within the timeout period.
1730 */
1731static enum
Jens Axboe242f9dc2008-09-14 05:55:09 -07001732blk_eh_timer_return megasas_reset_timer(struct scsi_cmnd *scmd)
Sumant Patro05e9ebb2007-05-17 05:47:51 -07001733{
1734 struct megasas_cmd *cmd = (struct megasas_cmd *)scmd->SCp.ptr;
1735 struct megasas_instance *instance;
1736 unsigned long flags;
1737
1738 if (time_after(jiffies, scmd->jiffies_at_alloc +
1739 (MEGASAS_DEFAULT_CMD_TIMEOUT * 2) * HZ)) {
Jens Axboe242f9dc2008-09-14 05:55:09 -07001740 return BLK_EH_NOT_HANDLED;
Sumant Patro05e9ebb2007-05-17 05:47:51 -07001741 }
1742
1743 instance = cmd->instance;
1744 if (!(instance->flag & MEGASAS_FW_BUSY)) {
1745 /* FW is busy, throttle IO */
1746 spin_lock_irqsave(instance->host->host_lock, flags);
1747
1748 instance->host->can_queue = 16;
1749 instance->last_time = jiffies;
1750 instance->flag |= MEGASAS_FW_BUSY;
1751
1752 spin_unlock_irqrestore(instance->host->host_lock, flags);
1753 }
Jens Axboe242f9dc2008-09-14 05:55:09 -07001754 return BLK_EH_RESET_TIMER;
Sumant Patro05e9ebb2007-05-17 05:47:51 -07001755}
1756
1757/**
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001758 * megasas_reset_device - Device reset handler entry point
1759 */
1760static int megasas_reset_device(struct scsi_cmnd *scmd)
1761{
1762 int ret;
1763
1764 /*
1765 * First wait for all commands to complete
1766 */
1767 ret = megasas_generic_reset(scmd);
1768
1769 return ret;
1770}
1771
1772/**
1773 * megasas_reset_bus_host - Bus & host reset handler entry point
1774 */
1775static int megasas_reset_bus_host(struct scsi_cmnd *scmd)
1776{
1777 int ret;
1778
1779 /*
Uwe Zeisberger80682fa2006-03-22 00:21:33 +01001780 * First wait for all commands to complete
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001781 */
1782 ret = megasas_generic_reset(scmd);
1783
1784 return ret;
1785}
1786
1787/**
Sumant Patrocf62a0a2007-02-14 12:41:55 -08001788 * megasas_bios_param - Returns disk geometry for a disk
1789 * @sdev: device handle
1790 * @bdev: block device
1791 * @capacity: drive capacity
1792 * @geom: geometry parameters
1793 */
1794static int
1795megasas_bios_param(struct scsi_device *sdev, struct block_device *bdev,
1796 sector_t capacity, int geom[])
1797{
1798 int heads;
1799 int sectors;
1800 sector_t cylinders;
1801 unsigned long tmp;
1802 /* Default heads (64) & sectors (32) */
1803 heads = 64;
1804 sectors = 32;
1805
1806 tmp = heads * sectors;
1807 cylinders = capacity;
1808
1809 sector_div(cylinders, tmp);
1810
1811 /*
1812 * Handle extended translation size for logical drives > 1Gb
1813 */
1814
1815 if (capacity >= 0x200000) {
1816 heads = 255;
1817 sectors = 63;
1818 tmp = heads*sectors;
1819 cylinders = capacity;
1820 sector_div(cylinders, tmp);
1821 }
1822
1823 geom[0] = heads;
1824 geom[1] = sectors;
1825 geom[2] = cylinders;
1826
1827 return 0;
1828}
1829
Yang, Bo7e8a75f2009-10-06 14:50:17 -06001830static void megasas_aen_polling(struct work_struct *work);
1831
Sumant Patrocf62a0a2007-02-14 12:41:55 -08001832/**
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001833 * megasas_service_aen - Processes an event notification
1834 * @instance: Adapter soft state
1835 * @cmd: AEN command completed by the ISR
1836 *
1837 * For AEN, driver sends a command down to FW that is held by the FW till an
1838 * event occurs. When an event of interest occurs, FW completes the command
1839 * that it was previously holding.
1840 *
1841 * This routines sends SIGIO signal to processes that have registered with the
1842 * driver for AEN.
1843 */
1844static void
1845megasas_service_aen(struct megasas_instance *instance, struct megasas_cmd *cmd)
1846{
Yang, Boc3518832009-10-06 14:18:02 -06001847 unsigned long flags;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001848 /*
1849 * Don't signal app if it is just an aborted previously registered aen
1850 */
Yang, Boc3518832009-10-06 14:18:02 -06001851 if ((!cmd->abort_aen) && (instance->unload == 0)) {
1852 spin_lock_irqsave(&poll_aen_lock, flags);
1853 megasas_poll_wait_aen = 1;
1854 spin_unlock_irqrestore(&poll_aen_lock, flags);
1855 wake_up(&megasas_poll_wait);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001856 kill_fasync(&megasas_async_queue, SIGIO, POLL_IN);
Yang, Boc3518832009-10-06 14:18:02 -06001857 }
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001858 else
1859 cmd->abort_aen = 0;
1860
1861 instance->aen_cmd = NULL;
1862 megasas_return_cmd(instance, cmd);
Yang, Bo7e8a75f2009-10-06 14:50:17 -06001863
bo yang39a98552010-09-22 22:36:29 -04001864 if ((instance->unload == 0) &&
1865 ((instance->issuepend_done == 1))) {
Yang, Bo7e8a75f2009-10-06 14:50:17 -06001866 struct megasas_aen_event *ev;
1867 ev = kzalloc(sizeof(*ev), GFP_ATOMIC);
1868 if (!ev) {
1869 printk(KERN_ERR "megasas_service_aen: out of memory\n");
1870 } else {
1871 ev->instance = instance;
1872 instance->ev = ev;
1873 INIT_WORK(&ev->hotplug_work, megasas_aen_polling);
1874 schedule_delayed_work(
1875 (struct delayed_work *)&ev->hotplug_work, 0);
1876 }
1877 }
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001878}
1879
1880/*
1881 * Scsi host template for megaraid_sas driver
1882 */
1883static struct scsi_host_template megasas_template = {
1884
1885 .module = THIS_MODULE,
bo yangf28cd7c2007-11-09 04:44:56 -05001886 .name = "LSI SAS based MegaRAID driver",
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001887 .proc_name = "megaraid_sas",
Christoph Hellwig147aab62006-02-17 12:13:48 +01001888 .slave_configure = megasas_slave_configure,
Yang, Bo044833b2009-10-06 14:33:06 -06001889 .slave_alloc = megasas_slave_alloc,
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001890 .queuecommand = megasas_queue_command,
1891 .eh_device_reset_handler = megasas_reset_device,
1892 .eh_bus_reset_handler = megasas_reset_bus_host,
1893 .eh_host_reset_handler = megasas_reset_bus_host,
Sumant Patro05e9ebb2007-05-17 05:47:51 -07001894 .eh_timed_out = megasas_reset_timer,
Sumant Patrocf62a0a2007-02-14 12:41:55 -08001895 .bios_param = megasas_bios_param,
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001896 .use_clustering = ENABLE_CLUSTERING,
1897};
1898
1899/**
1900 * megasas_complete_int_cmd - Completes an internal command
1901 * @instance: Adapter soft state
1902 * @cmd: Command to be completed
1903 *
1904 * The megasas_issue_blocked_cmd() function waits for a command to complete
1905 * after it issues a command. This function wakes up that waiting routine by
1906 * calling wake_up() on the wait queue.
1907 */
1908static void
1909megasas_complete_int_cmd(struct megasas_instance *instance,
1910 struct megasas_cmd *cmd)
1911{
1912 cmd->cmd_status = cmd->frame->io.cmd_status;
1913
1914 if (cmd->cmd_status == ENODATA) {
1915 cmd->cmd_status = 0;
1916 }
1917 wake_up(&instance->int_cmd_wait_q);
1918}
1919
1920/**
1921 * megasas_complete_abort - Completes aborting a command
1922 * @instance: Adapter soft state
1923 * @cmd: Cmd that was issued to abort another cmd
1924 *
1925 * The megasas_issue_blocked_abort_cmd() function waits on abort_cmd_wait_q
1926 * after it issues an abort on a previously issued command. This function
1927 * wakes up all functions waiting on the same wait queue.
1928 */
1929static void
1930megasas_complete_abort(struct megasas_instance *instance,
1931 struct megasas_cmd *cmd)
1932{
1933 if (cmd->sync_cmd) {
1934 cmd->sync_cmd = 0;
1935 cmd->cmd_status = 0;
1936 wake_up(&instance->abort_cmd_wait_q);
1937 }
1938
1939 return;
1940}
1941
1942/**
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001943 * megasas_complete_cmd - Completes a command
1944 * @instance: Adapter soft state
1945 * @cmd: Command to be completed
1946 * @alt_status: If non-zero, use this value as status to
1947 * SCSI mid-layer instead of the value returned
1948 * by the FW. This should be used if caller wants
1949 * an alternate status (as in the case of aborted
1950 * commands)
1951 */
Arjan van de Ven858119e2006-01-14 13:20:43 -08001952static void
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001953megasas_complete_cmd(struct megasas_instance *instance, struct megasas_cmd *cmd,
1954 u8 alt_status)
1955{
1956 int exception = 0;
1957 struct megasas_header *hdr = &cmd->frame->hdr;
Yang, Boc3518832009-10-06 14:18:02 -06001958 unsigned long flags;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001959
bo yang39a98552010-09-22 22:36:29 -04001960 /* flag for the retry reset */
1961 cmd->retry_for_fw_reset = 0;
1962
Sumant Patro05e9ebb2007-05-17 05:47:51 -07001963 if (cmd->scmd)
1964 cmd->scmd->SCp.ptr = NULL;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001965
1966 switch (hdr->cmd) {
1967
1968 case MFI_CMD_PD_SCSI_IO:
1969 case MFI_CMD_LD_SCSI_IO:
1970
1971 /*
1972 * MFI_CMD_PD_SCSI_IO and MFI_CMD_LD_SCSI_IO could have been
1973 * issued either through an IO path or an IOCTL path. If it
1974 * was via IOCTL, we will send it to internal completion.
1975 */
1976 if (cmd->sync_cmd) {
1977 cmd->sync_cmd = 0;
1978 megasas_complete_int_cmd(instance, cmd);
1979 break;
1980 }
1981
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001982 case MFI_CMD_LD_READ:
1983 case MFI_CMD_LD_WRITE:
1984
1985 if (alt_status) {
1986 cmd->scmd->result = alt_status << 16;
1987 exception = 1;
1988 }
1989
1990 if (exception) {
1991
Sumant Patroe4a082c2006-05-30 12:03:37 -07001992 atomic_dec(&instance->fw_outstanding);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001993
FUJITA Tomonori155d98f2007-05-26 05:04:08 +09001994 scsi_dma_unmap(cmd->scmd);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001995 cmd->scmd->scsi_done(cmd->scmd);
1996 megasas_return_cmd(instance, cmd);
1997
1998 break;
1999 }
2000
2001 switch (hdr->cmd_status) {
2002
2003 case MFI_STAT_OK:
2004 cmd->scmd->result = DID_OK << 16;
2005 break;
2006
2007 case MFI_STAT_SCSI_IO_FAILED:
2008 case MFI_STAT_LD_INIT_IN_PROGRESS:
2009 cmd->scmd->result =
2010 (DID_ERROR << 16) | hdr->scsi_status;
2011 break;
2012
2013 case MFI_STAT_SCSI_DONE_WITH_ERROR:
2014
2015 cmd->scmd->result = (DID_OK << 16) | hdr->scsi_status;
2016
2017 if (hdr->scsi_status == SAM_STAT_CHECK_CONDITION) {
2018 memset(cmd->scmd->sense_buffer, 0,
2019 SCSI_SENSE_BUFFERSIZE);
2020 memcpy(cmd->scmd->sense_buffer, cmd->sense,
2021 hdr->sense_len);
2022
2023 cmd->scmd->result |= DRIVER_SENSE << 24;
2024 }
2025
2026 break;
2027
2028 case MFI_STAT_LD_OFFLINE:
2029 case MFI_STAT_DEVICE_NOT_FOUND:
2030 cmd->scmd->result = DID_BAD_TARGET << 16;
2031 break;
2032
2033 default:
2034 printk(KERN_DEBUG "megasas: MFI FW status %#x\n",
2035 hdr->cmd_status);
2036 cmd->scmd->result = DID_ERROR << 16;
2037 break;
2038 }
2039
Sumant Patroe4a082c2006-05-30 12:03:37 -07002040 atomic_dec(&instance->fw_outstanding);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04002041
FUJITA Tomonori155d98f2007-05-26 05:04:08 +09002042 scsi_dma_unmap(cmd->scmd);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04002043 cmd->scmd->scsi_done(cmd->scmd);
2044 megasas_return_cmd(instance, cmd);
2045
2046 break;
2047
2048 case MFI_CMD_SMP:
2049 case MFI_CMD_STP:
2050 case MFI_CMD_DCMD:
Yang, Boc3518832009-10-06 14:18:02 -06002051 if (cmd->frame->dcmd.opcode == MR_DCMD_CTRL_EVENT_GET_INFO ||
2052 cmd->frame->dcmd.opcode == MR_DCMD_CTRL_EVENT_GET) {
2053 spin_lock_irqsave(&poll_aen_lock, flags);
2054 megasas_poll_wait_aen = 0;
2055 spin_unlock_irqrestore(&poll_aen_lock, flags);
2056 }
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04002057
2058 /*
2059 * See if got an event notification
2060 */
2061 if (cmd->frame->dcmd.opcode == MR_DCMD_CTRL_EVENT_WAIT)
2062 megasas_service_aen(instance, cmd);
2063 else
2064 megasas_complete_int_cmd(instance, cmd);
2065
2066 break;
2067
2068 case MFI_CMD_ABORT:
2069 /*
2070 * Cmd issued to abort another cmd returned
2071 */
2072 megasas_complete_abort(instance, cmd);
2073 break;
2074
2075 default:
2076 printk("megasas: Unknown command completed! [0x%X]\n",
2077 hdr->cmd);
2078 break;
2079 }
2080}
2081
2082/**
bo yang39a98552010-09-22 22:36:29 -04002083 * megasas_issue_pending_cmds_again - issue all pending cmds
2084 * in FW again because of the fw reset
2085 * @instance: Adapter soft state
2086 */
2087static inline void
2088megasas_issue_pending_cmds_again(struct megasas_instance *instance)
2089{
2090 struct megasas_cmd *cmd;
2091 struct list_head clist_local;
2092 union megasas_evt_class_locale class_locale;
2093 unsigned long flags;
2094 u32 seq_num;
2095
2096 INIT_LIST_HEAD(&clist_local);
2097 spin_lock_irqsave(&instance->hba_lock, flags);
2098 list_splice_init(&instance->internal_reset_pending_q, &clist_local);
2099 spin_unlock_irqrestore(&instance->hba_lock, flags);
2100
2101 while (!list_empty(&clist_local)) {
2102 cmd = list_entry((&clist_local)->next,
2103 struct megasas_cmd, list);
2104 list_del_init(&cmd->list);
2105
2106 if (cmd->sync_cmd || cmd->scmd) {
2107 printk(KERN_NOTICE "megaraid_sas: command %p, %p:%d"
2108 "detected to be pending while HBA reset.\n",
2109 cmd, cmd->scmd, cmd->sync_cmd);
2110
2111 cmd->retry_for_fw_reset++;
2112
2113 if (cmd->retry_for_fw_reset == 3) {
2114 printk(KERN_NOTICE "megaraid_sas: cmd %p, %p:%d"
2115 "was tried multiple times during reset."
2116 "Shutting down the HBA\n",
2117 cmd, cmd->scmd, cmd->sync_cmd);
2118 megaraid_sas_kill_hba(instance);
2119
2120 instance->adprecovery =
2121 MEGASAS_HW_CRITICAL_ERROR;
2122 return;
2123 }
2124 }
2125
2126 if (cmd->sync_cmd == 1) {
2127 if (cmd->scmd) {
2128 printk(KERN_NOTICE "megaraid_sas: unexpected"
2129 "cmd attached to internal command!\n");
2130 }
2131 printk(KERN_NOTICE "megasas: %p synchronous cmd"
2132 "on the internal reset queue,"
2133 "issue it again.\n", cmd);
2134 cmd->cmd_status = ENODATA;
2135 instance->instancet->fire_cmd(instance,
2136 cmd->frame_phys_addr ,
2137 0, instance->reg_set);
2138 } else if (cmd->scmd) {
2139 printk(KERN_NOTICE "megasas: %p scsi cmd [%02x],%#lx"
2140 "detected on the internal queue, issue again.\n",
2141 cmd, cmd->scmd->cmnd[0], cmd->scmd->serial_number);
2142
2143 atomic_inc(&instance->fw_outstanding);
2144 instance->instancet->fire_cmd(instance,
2145 cmd->frame_phys_addr,
2146 cmd->frame_count-1, instance->reg_set);
2147 } else {
2148 printk(KERN_NOTICE "megasas: %p unexpected cmd on the"
2149 "internal reset defer list while re-issue!!\n",
2150 cmd);
2151 }
2152 }
2153
2154 if (instance->aen_cmd) {
2155 printk(KERN_NOTICE "megaraid_sas: aen_cmd in def process\n");
2156 megasas_return_cmd(instance, instance->aen_cmd);
2157
2158 instance->aen_cmd = NULL;
2159 }
2160
2161 /*
2162 * Initiate AEN (Asynchronous Event Notification)
2163 */
2164 seq_num = instance->last_seq_num;
2165 class_locale.members.reserved = 0;
2166 class_locale.members.locale = MR_EVT_LOCALE_ALL;
2167 class_locale.members.class = MR_EVT_CLASS_DEBUG;
2168
2169 megasas_register_aen(instance, seq_num, class_locale.word);
2170}
2171
2172/**
2173 * Move the internal reset pending commands to a deferred queue.
2174 *
2175 * We move the commands pending at internal reset time to a
2176 * pending queue. This queue would be flushed after successful
2177 * completion of the internal reset sequence. if the internal reset
2178 * did not complete in time, the kernel reset handler would flush
2179 * these commands.
2180 **/
2181static void
2182megasas_internal_reset_defer_cmds(struct megasas_instance *instance)
2183{
2184 struct megasas_cmd *cmd;
2185 int i;
2186 u32 max_cmd = instance->max_fw_cmds;
2187 u32 defer_index;
2188 unsigned long flags;
2189
2190 defer_index = 0;
2191 spin_lock_irqsave(&instance->cmd_pool_lock, flags);
2192 for (i = 0; i < max_cmd; i++) {
2193 cmd = instance->cmd_list[i];
2194 if (cmd->sync_cmd == 1 || cmd->scmd) {
2195 printk(KERN_NOTICE "megasas: moving cmd[%d]:%p:%d:%p"
2196 "on the defer queue as internal\n",
2197 defer_index, cmd, cmd->sync_cmd, cmd->scmd);
2198
2199 if (!list_empty(&cmd->list)) {
2200 printk(KERN_NOTICE "megaraid_sas: ERROR while"
2201 " moving this cmd:%p, %d %p, it was"
2202 "discovered on some list?\n",
2203 cmd, cmd->sync_cmd, cmd->scmd);
2204
2205 list_del_init(&cmd->list);
2206 }
2207 defer_index++;
2208 list_add_tail(&cmd->list,
2209 &instance->internal_reset_pending_q);
2210 }
2211 }
2212 spin_unlock_irqrestore(&instance->cmd_pool_lock, flags);
2213}
2214
2215
2216static void
2217process_fw_state_change_wq(struct work_struct *work)
2218{
2219 struct megasas_instance *instance =
2220 container_of(work, struct megasas_instance, work_init);
2221 u32 wait;
2222 unsigned long flags;
2223
2224 if (instance->adprecovery != MEGASAS_ADPRESET_SM_INFAULT) {
2225 printk(KERN_NOTICE "megaraid_sas: error, recovery st %x \n",
2226 instance->adprecovery);
2227 return ;
2228 }
2229
2230 if (instance->adprecovery == MEGASAS_ADPRESET_SM_INFAULT) {
2231 printk(KERN_NOTICE "megaraid_sas: FW detected to be in fault"
2232 "state, restarting it...\n");
2233
2234 instance->instancet->disable_intr(instance->reg_set);
2235 atomic_set(&instance->fw_outstanding, 0);
2236
2237 atomic_set(&instance->fw_reset_no_pci_access, 1);
2238 instance->instancet->adp_reset(instance, instance->reg_set);
2239 atomic_set(&instance->fw_reset_no_pci_access, 0 );
2240
2241 printk(KERN_NOTICE "megaraid_sas: FW restarted successfully,"
2242 "initiating next stage...\n");
2243
2244 printk(KERN_NOTICE "megaraid_sas: HBA recovery state machine,"
2245 "state 2 starting...\n");
2246
2247 /*waitting for about 20 second before start the second init*/
2248 for (wait = 0; wait < 30; wait++) {
2249 msleep(1000);
2250 }
2251
2252 if (megasas_transition_to_ready(instance)) {
2253 printk(KERN_NOTICE "megaraid_sas:adapter not ready\n");
2254
2255 megaraid_sas_kill_hba(instance);
2256 instance->adprecovery = MEGASAS_HW_CRITICAL_ERROR;
2257 return ;
2258 }
2259
2260 if ((instance->pdev->device == PCI_DEVICE_ID_LSI_SAS1064R) ||
2261 (instance->pdev->device == PCI_DEVICE_ID_DELL_PERC5) ||
2262 (instance->pdev->device == PCI_DEVICE_ID_LSI_VERDE_ZCR)
2263 ) {
2264 *instance->consumer = *instance->producer;
2265 } else {
2266 *instance->consumer = 0;
2267 *instance->producer = 0;
2268 }
2269
2270 megasas_issue_init_mfi(instance);
2271
2272 spin_lock_irqsave(&instance->hba_lock, flags);
2273 instance->adprecovery = MEGASAS_HBA_OPERATIONAL;
2274 spin_unlock_irqrestore(&instance->hba_lock, flags);
2275 instance->instancet->enable_intr(instance->reg_set);
2276
2277 megasas_issue_pending_cmds_again(instance);
2278 instance->issuepend_done = 1;
2279 }
2280 return ;
2281}
2282
2283/**
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04002284 * megasas_deplete_reply_queue - Processes all completed commands
2285 * @instance: Adapter soft state
2286 * @alt_status: Alternate status to be returned to
2287 * SCSI mid-layer instead of the status
2288 * returned by the FW
bo yang39a98552010-09-22 22:36:29 -04002289 * Note: this must be called with hba lock held
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04002290 */
Arjan van de Ven858119e2006-01-14 13:20:43 -08002291static int
bo yang39a98552010-09-22 22:36:29 -04002292megasas_deplete_reply_queue(struct megasas_instance *instance,
2293 u8 alt_status)
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04002294{
bo yang39a98552010-09-22 22:36:29 -04002295 u32 mfiStatus;
2296 u32 fw_state;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04002297
bo yang39a98552010-09-22 22:36:29 -04002298 if ((mfiStatus = instance->instancet->check_reset(instance,
2299 instance->reg_set)) == 1) {
2300 return IRQ_HANDLED;
2301 }
2302
2303 if ((mfiStatus = instance->instancet->clear_intr(
2304 instance->reg_set)
2305 ) == 0) {
2306 return IRQ_NONE;
2307 }
2308
2309 instance->mfiStatus = mfiStatus;
2310
2311 if ((mfiStatus & MFI_INTR_FLAG_FIRMWARE_STATE_CHANGE)) {
2312 fw_state = instance->instancet->read_fw_status_reg(
2313 instance->reg_set) & MFI_STATE_MASK;
2314
2315 if (fw_state != MFI_STATE_FAULT) {
2316 printk(KERN_NOTICE "megaraid_sas: fw state:%x\n",
2317 fw_state);
2318 }
2319
2320 if ((fw_state == MFI_STATE_FAULT) &&
2321 (instance->disableOnlineCtrlReset == 0)) {
2322 printk(KERN_NOTICE "megaraid_sas: wait adp restart\n");
2323
2324 if ((instance->pdev->device ==
2325 PCI_DEVICE_ID_LSI_SAS1064R) ||
2326 (instance->pdev->device ==
2327 PCI_DEVICE_ID_DELL_PERC5) ||
2328 (instance->pdev->device ==
2329 PCI_DEVICE_ID_LSI_VERDE_ZCR)) {
2330
2331 *instance->consumer =
2332 MEGASAS_ADPRESET_INPROG_SIGN;
2333 }
2334
2335
2336 instance->instancet->disable_intr(instance->reg_set);
2337 instance->adprecovery = MEGASAS_ADPRESET_SM_INFAULT;
2338 instance->issuepend_done = 0;
2339
2340 atomic_set(&instance->fw_outstanding, 0);
2341 megasas_internal_reset_defer_cmds(instance);
2342
2343 printk(KERN_NOTICE "megasas: fwState=%x, stage:%d\n",
2344 fw_state, instance->adprecovery);
2345
2346 schedule_work(&instance->work_init);
2347 return IRQ_HANDLED;
2348
2349 } else {
2350 printk(KERN_NOTICE "megasas: fwstate:%x, dis_OCR=%x\n",
2351 fw_state, instance->disableOnlineCtrlReset);
2352 }
2353 }
2354
Sumant Patro5d018ad2006-10-03 13:13:18 -07002355 tasklet_schedule(&instance->isr_tasklet);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04002356 return IRQ_HANDLED;
2357}
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04002358/**
2359 * megasas_isr - isr entry point
2360 */
David Howells7d12e782006-10-05 14:55:46 +01002361static irqreturn_t megasas_isr(int irq, void *devp)
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04002362{
bo yang39a98552010-09-22 22:36:29 -04002363 struct megasas_instance *instance;
2364 unsigned long flags;
2365 irqreturn_t rc;
2366
2367 if (atomic_read(
2368 &(((struct megasas_instance *)devp)->fw_reset_no_pci_access)))
2369 return IRQ_HANDLED;
2370
2371 instance = (struct megasas_instance *)devp;
2372
2373 spin_lock_irqsave(&instance->hba_lock, flags);
2374 rc = megasas_deplete_reply_queue(instance, DID_OK);
2375 spin_unlock_irqrestore(&instance->hba_lock, flags);
2376
2377 return rc;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04002378}
2379
2380/**
2381 * megasas_transition_to_ready - Move the FW to READY state
Sumant Patro1341c932006-01-25 12:02:40 -08002382 * @instance: Adapter soft state
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04002383 *
2384 * During the initialization, FW passes can potentially be in any one of
2385 * several possible states. If the FW in operational, waiting-for-handshake
2386 * states, driver must take steps to bring it to ready state. Otherwise, it
2387 * has to wait for the ready state.
2388 */
2389static int
Sumant Patro1341c932006-01-25 12:02:40 -08002390megasas_transition_to_ready(struct megasas_instance* instance)
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04002391{
2392 int i;
2393 u8 max_wait;
2394 u32 fw_state;
2395 u32 cur_state;
Yang, Bo7218df62009-10-06 14:52:20 -06002396 u32 abs_state, curr_abs_state;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04002397
Sumant Patro1341c932006-01-25 12:02:40 -08002398 fw_state = instance->instancet->read_fw_status_reg(instance->reg_set) & MFI_STATE_MASK;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04002399
Sumant Patroe3bbff92006-10-03 12:28:49 -07002400 if (fw_state != MFI_STATE_READY)
2401 printk(KERN_INFO "megasas: Waiting for FW to come to ready"
2402 " state\n");
2403
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04002404 while (fw_state != MFI_STATE_READY) {
2405
Yang, Bo7218df62009-10-06 14:52:20 -06002406 abs_state =
2407 instance->instancet->read_fw_status_reg(instance->reg_set);
2408
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04002409 switch (fw_state) {
2410
2411 case MFI_STATE_FAULT:
2412
2413 printk(KERN_DEBUG "megasas: FW in FAULT state!!\n");
2414 return -ENODEV;
2415
2416 case MFI_STATE_WAIT_HANDSHAKE:
2417 /*
2418 * Set the CLR bit in inbound doorbell
2419 */
Yang, Bo0c79e682009-10-06 14:47:35 -06002420 if ((instance->pdev->device ==
Yang, Bo87911122009-10-06 14:31:54 -06002421 PCI_DEVICE_ID_LSI_SAS0073SKINNY) ||
2422 (instance->pdev->device ==
2423 PCI_DEVICE_ID_LSI_SAS0071SKINNY)) {
2424
2425 writel(
2426 MFI_INIT_CLEAR_HANDSHAKE|MFI_INIT_HOTPLUG,
2427 &instance->reg_set->reserved_0[0]);
2428 } else {
2429 writel(
2430 MFI_INIT_CLEAR_HANDSHAKE|MFI_INIT_HOTPLUG,
2431 &instance->reg_set->inbound_doorbell);
2432 }
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04002433
Yang, Bo7218df62009-10-06 14:52:20 -06002434 max_wait = MEGASAS_RESET_WAIT_TIME;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04002435 cur_state = MFI_STATE_WAIT_HANDSHAKE;
2436 break;
2437
Sumant Patroe3bbff92006-10-03 12:28:49 -07002438 case MFI_STATE_BOOT_MESSAGE_PENDING:
Yang, Bo87911122009-10-06 14:31:54 -06002439 if ((instance->pdev->device ==
2440 PCI_DEVICE_ID_LSI_SAS0073SKINNY) ||
2441 (instance->pdev->device ==
2442 PCI_DEVICE_ID_LSI_SAS0071SKINNY)) {
2443 writel(MFI_INIT_HOTPLUG,
2444 &instance->reg_set->reserved_0[0]);
2445 } else
2446 writel(MFI_INIT_HOTPLUG,
2447 &instance->reg_set->inbound_doorbell);
Sumant Patroe3bbff92006-10-03 12:28:49 -07002448
Yang, Bo7218df62009-10-06 14:52:20 -06002449 max_wait = MEGASAS_RESET_WAIT_TIME;
Sumant Patroe3bbff92006-10-03 12:28:49 -07002450 cur_state = MFI_STATE_BOOT_MESSAGE_PENDING;
2451 break;
2452
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04002453 case MFI_STATE_OPERATIONAL:
2454 /*
Sumant Patroe3bbff92006-10-03 12:28:49 -07002455 * Bring it to READY state; assuming max wait 10 secs
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04002456 */
Sumant Patrob274cab2006-10-03 12:52:12 -07002457 instance->instancet->disable_intr(instance->reg_set);
Yang, Bo87911122009-10-06 14:31:54 -06002458 if ((instance->pdev->device ==
2459 PCI_DEVICE_ID_LSI_SAS0073SKINNY) ||
2460 (instance->pdev->device ==
2461 PCI_DEVICE_ID_LSI_SAS0071SKINNY)) {
2462 writel(MFI_RESET_FLAGS,
2463 &instance->reg_set->reserved_0[0]);
2464 } else
2465 writel(MFI_RESET_FLAGS,
2466 &instance->reg_set->inbound_doorbell);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04002467
Yang, Bo7218df62009-10-06 14:52:20 -06002468 max_wait = MEGASAS_RESET_WAIT_TIME;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04002469 cur_state = MFI_STATE_OPERATIONAL;
2470 break;
2471
2472 case MFI_STATE_UNDEFINED:
2473 /*
2474 * This state should not last for more than 2 seconds
2475 */
Yang, Bo7218df62009-10-06 14:52:20 -06002476 max_wait = MEGASAS_RESET_WAIT_TIME;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04002477 cur_state = MFI_STATE_UNDEFINED;
2478 break;
2479
2480 case MFI_STATE_BB_INIT:
Yang, Bo7218df62009-10-06 14:52:20 -06002481 max_wait = MEGASAS_RESET_WAIT_TIME;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04002482 cur_state = MFI_STATE_BB_INIT;
2483 break;
2484
2485 case MFI_STATE_FW_INIT:
Yang, Bo7218df62009-10-06 14:52:20 -06002486 max_wait = MEGASAS_RESET_WAIT_TIME;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04002487 cur_state = MFI_STATE_FW_INIT;
2488 break;
2489
2490 case MFI_STATE_FW_INIT_2:
Yang, Bo7218df62009-10-06 14:52:20 -06002491 max_wait = MEGASAS_RESET_WAIT_TIME;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04002492 cur_state = MFI_STATE_FW_INIT_2;
2493 break;
2494
2495 case MFI_STATE_DEVICE_SCAN:
Yang, Bo7218df62009-10-06 14:52:20 -06002496 max_wait = MEGASAS_RESET_WAIT_TIME;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04002497 cur_state = MFI_STATE_DEVICE_SCAN;
2498 break;
2499
2500 case MFI_STATE_FLUSH_CACHE:
Yang, Bo7218df62009-10-06 14:52:20 -06002501 max_wait = MEGASAS_RESET_WAIT_TIME;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04002502 cur_state = MFI_STATE_FLUSH_CACHE;
2503 break;
2504
2505 default:
2506 printk(KERN_DEBUG "megasas: Unknown state 0x%x\n",
2507 fw_state);
2508 return -ENODEV;
2509 }
2510
2511 /*
2512 * The cur_state should not last for more than max_wait secs
2513 */
2514 for (i = 0; i < (max_wait * 1000); i++) {
Sumant Patro1341c932006-01-25 12:02:40 -08002515 fw_state = instance->instancet->read_fw_status_reg(instance->reg_set) &
2516 MFI_STATE_MASK ;
Yang, Bo7218df62009-10-06 14:52:20 -06002517 curr_abs_state =
2518 instance->instancet->read_fw_status_reg(instance->reg_set);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04002519
Yang, Bo7218df62009-10-06 14:52:20 -06002520 if (abs_state == curr_abs_state) {
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04002521 msleep(1);
2522 } else
2523 break;
2524 }
2525
2526 /*
2527 * Return error if fw_state hasn't changed after max_wait
2528 */
Yang, Bo7218df62009-10-06 14:52:20 -06002529 if (curr_abs_state == abs_state) {
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04002530 printk(KERN_DEBUG "FW state [%d] hasn't changed "
2531 "in %d secs\n", fw_state, max_wait);
2532 return -ENODEV;
2533 }
bo yang39a98552010-09-22 22:36:29 -04002534 }
Sumant Patroe3bbff92006-10-03 12:28:49 -07002535 printk(KERN_INFO "megasas: FW now in Ready state\n");
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04002536
2537 return 0;
2538}
2539
2540/**
2541 * megasas_teardown_frame_pool - Destroy the cmd frame DMA pool
2542 * @instance: Adapter soft state
2543 */
2544static void megasas_teardown_frame_pool(struct megasas_instance *instance)
2545{
2546 int i;
2547 u32 max_cmd = instance->max_fw_cmds;
2548 struct megasas_cmd *cmd;
2549
2550 if (!instance->frame_dma_pool)
2551 return;
2552
2553 /*
2554 * Return all frames to pool
2555 */
2556 for (i = 0; i < max_cmd; i++) {
2557
2558 cmd = instance->cmd_list[i];
2559
2560 if (cmd->frame)
2561 pci_pool_free(instance->frame_dma_pool, cmd->frame,
2562 cmd->frame_phys_addr);
2563
2564 if (cmd->sense)
Sumant Patroe3bbff92006-10-03 12:28:49 -07002565 pci_pool_free(instance->sense_dma_pool, cmd->sense,
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04002566 cmd->sense_phys_addr);
2567 }
2568
2569 /*
2570 * Now destroy the pool itself
2571 */
2572 pci_pool_destroy(instance->frame_dma_pool);
2573 pci_pool_destroy(instance->sense_dma_pool);
2574
2575 instance->frame_dma_pool = NULL;
2576 instance->sense_dma_pool = NULL;
2577}
2578
2579/**
2580 * megasas_create_frame_pool - Creates DMA pool for cmd frames
2581 * @instance: Adapter soft state
2582 *
2583 * Each command packet has an embedded DMA memory buffer that is used for
2584 * filling MFI frame and the SG list that immediately follows the frame. This
2585 * function creates those DMA memory buffers for each command packet by using
2586 * PCI pool facility.
2587 */
2588static int megasas_create_frame_pool(struct megasas_instance *instance)
2589{
2590 int i;
2591 u32 max_cmd;
2592 u32 sge_sz;
2593 u32 sgl_sz;
2594 u32 total_sz;
2595 u32 frame_count;
2596 struct megasas_cmd *cmd;
2597
2598 max_cmd = instance->max_fw_cmds;
2599
2600 /*
2601 * Size of our frame is 64 bytes for MFI frame, followed by max SG
2602 * elements and finally SCSI_SENSE_BUFFERSIZE bytes for sense buffer
2603 */
2604 sge_sz = (IS_DMA64) ? sizeof(struct megasas_sge64) :
2605 sizeof(struct megasas_sge32);
2606
Yang, Bof4c9a132009-10-06 14:43:28 -06002607 if (instance->flag_ieee) {
2608 sge_sz = sizeof(struct megasas_sge_skinny);
2609 }
2610
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04002611 /*
2612 * Calculated the number of 64byte frames required for SGL
2613 */
2614 sgl_sz = sge_sz * instance->max_num_sge;
2615 frame_count = (sgl_sz + MEGAMFI_FRAME_SIZE - 1) / MEGAMFI_FRAME_SIZE;
bo yang39a98552010-09-22 22:36:29 -04002616 frame_count = 15;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04002617
2618 /*
2619 * We need one extra frame for the MFI command
2620 */
2621 frame_count++;
2622
2623 total_sz = MEGAMFI_FRAME_SIZE * frame_count;
2624 /*
2625 * Use DMA pool facility provided by PCI layer
2626 */
2627 instance->frame_dma_pool = pci_pool_create("megasas frame pool",
2628 instance->pdev, total_sz, 64,
2629 0);
2630
2631 if (!instance->frame_dma_pool) {
2632 printk(KERN_DEBUG "megasas: failed to setup frame pool\n");
2633 return -ENOMEM;
2634 }
2635
2636 instance->sense_dma_pool = pci_pool_create("megasas sense pool",
2637 instance->pdev, 128, 4, 0);
2638
2639 if (!instance->sense_dma_pool) {
2640 printk(KERN_DEBUG "megasas: failed to setup sense pool\n");
2641
2642 pci_pool_destroy(instance->frame_dma_pool);
2643 instance->frame_dma_pool = NULL;
2644
2645 return -ENOMEM;
2646 }
2647
2648 /*
2649 * Allocate and attach a frame to each of the commands in cmd_list.
2650 * By making cmd->index as the context instead of the &cmd, we can
2651 * always use 32bit context regardless of the architecture
2652 */
2653 for (i = 0; i < max_cmd; i++) {
2654
2655 cmd = instance->cmd_list[i];
2656
2657 cmd->frame = pci_pool_alloc(instance->frame_dma_pool,
2658 GFP_KERNEL, &cmd->frame_phys_addr);
2659
2660 cmd->sense = pci_pool_alloc(instance->sense_dma_pool,
2661 GFP_KERNEL, &cmd->sense_phys_addr);
2662
2663 /*
2664 * megasas_teardown_frame_pool() takes care of freeing
2665 * whatever has been allocated
2666 */
2667 if (!cmd->frame || !cmd->sense) {
2668 printk(KERN_DEBUG "megasas: pci_pool_alloc failed \n");
2669 megasas_teardown_frame_pool(instance);
2670 return -ENOMEM;
2671 }
2672
2673 cmd->frame->io.context = cmd->index;
Yang, Bo7e8a75f2009-10-06 14:50:17 -06002674 cmd->frame->io.pad_0 = 0;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04002675 }
2676
2677 return 0;
2678}
2679
2680/**
2681 * megasas_free_cmds - Free all the cmds in the free cmd pool
2682 * @instance: Adapter soft state
2683 */
2684static void megasas_free_cmds(struct megasas_instance *instance)
2685{
2686 int i;
2687 /* First free the MFI frame pool */
2688 megasas_teardown_frame_pool(instance);
2689
2690 /* Free all the commands in the cmd_list */
2691 for (i = 0; i < instance->max_fw_cmds; i++)
2692 kfree(instance->cmd_list[i]);
2693
2694 /* Free the cmd_list buffer itself */
2695 kfree(instance->cmd_list);
2696 instance->cmd_list = NULL;
2697
2698 INIT_LIST_HEAD(&instance->cmd_pool);
2699}
2700
2701/**
2702 * megasas_alloc_cmds - Allocates the command packets
2703 * @instance: Adapter soft state
2704 *
2705 * Each command that is issued to the FW, whether IO commands from the OS or
2706 * internal commands like IOCTLs, are wrapped in local data structure called
2707 * megasas_cmd. The frame embedded in this megasas_cmd is actually issued to
2708 * the FW.
2709 *
2710 * Each frame has a 32-bit field called context (tag). This context is used
2711 * to get back the megasas_cmd from the frame when a frame gets completed in
2712 * the ISR. Typically the address of the megasas_cmd itself would be used as
2713 * the context. But we wanted to keep the differences between 32 and 64 bit
2714 * systems to the mininum. We always use 32 bit integers for the context. In
2715 * this driver, the 32 bit values are the indices into an array cmd_list.
2716 * This array is used only to look up the megasas_cmd given the context. The
2717 * free commands themselves are maintained in a linked list called cmd_pool.
2718 */
2719static int megasas_alloc_cmds(struct megasas_instance *instance)
2720{
2721 int i;
2722 int j;
2723 u32 max_cmd;
2724 struct megasas_cmd *cmd;
2725
2726 max_cmd = instance->max_fw_cmds;
2727
2728 /*
2729 * instance->cmd_list is an array of struct megasas_cmd pointers.
2730 * Allocate the dynamic array first and then allocate individual
2731 * commands.
2732 */
Yoann Padioleaudd00cc42007-07-19 01:49:03 -07002733 instance->cmd_list = kcalloc(max_cmd, sizeof(struct megasas_cmd*), GFP_KERNEL);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04002734
2735 if (!instance->cmd_list) {
2736 printk(KERN_DEBUG "megasas: out of memory\n");
2737 return -ENOMEM;
2738 }
2739
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04002740
2741 for (i = 0; i < max_cmd; i++) {
2742 instance->cmd_list[i] = kmalloc(sizeof(struct megasas_cmd),
2743 GFP_KERNEL);
2744
2745 if (!instance->cmd_list[i]) {
2746
2747 for (j = 0; j < i; j++)
2748 kfree(instance->cmd_list[j]);
2749
2750 kfree(instance->cmd_list);
2751 instance->cmd_list = NULL;
2752
2753 return -ENOMEM;
2754 }
2755 }
2756
2757 /*
2758 * Add all the commands to command pool (instance->cmd_pool)
2759 */
2760 for (i = 0; i < max_cmd; i++) {
2761 cmd = instance->cmd_list[i];
2762 memset(cmd, 0, sizeof(struct megasas_cmd));
2763 cmd->index = i;
bo yang39a98552010-09-22 22:36:29 -04002764 cmd->scmd = NULL;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04002765 cmd->instance = instance;
2766
2767 list_add_tail(&cmd->list, &instance->cmd_pool);
2768 }
2769
2770 /*
2771 * Create a frame pool and assign one frame to each cmd
2772 */
2773 if (megasas_create_frame_pool(instance)) {
2774 printk(KERN_DEBUG "megasas: Error creating frame DMA pool\n");
2775 megasas_free_cmds(instance);
2776 }
2777
2778 return 0;
2779}
2780
Yang, Bo81e403c2009-10-06 14:27:54 -06002781/*
2782 * megasas_get_pd_list_info - Returns FW's pd_list structure
2783 * @instance: Adapter soft state
2784 * @pd_list: pd_list structure
2785 *
2786 * Issues an internal command (DCMD) to get the FW's controller PD
2787 * list structure. This information is mainly used to find out SYSTEM
2788 * supported by the FW.
2789 */
2790static int
2791megasas_get_pd_list(struct megasas_instance *instance)
2792{
2793 int ret = 0, pd_index = 0;
2794 struct megasas_cmd *cmd;
2795 struct megasas_dcmd_frame *dcmd;
2796 struct MR_PD_LIST *ci;
2797 struct MR_PD_ADDRESS *pd_addr;
2798 dma_addr_t ci_h = 0;
2799
2800 cmd = megasas_get_cmd(instance);
2801
2802 if (!cmd) {
2803 printk(KERN_DEBUG "megasas (get_pd_list): Failed to get cmd\n");
2804 return -ENOMEM;
2805 }
2806
2807 dcmd = &cmd->frame->dcmd;
2808
2809 ci = pci_alloc_consistent(instance->pdev,
2810 MEGASAS_MAX_PD * sizeof(struct MR_PD_LIST), &ci_h);
2811
2812 if (!ci) {
2813 printk(KERN_DEBUG "Failed to alloc mem for pd_list\n");
2814 megasas_return_cmd(instance, cmd);
2815 return -ENOMEM;
2816 }
2817
2818 memset(ci, 0, sizeof(*ci));
2819 memset(dcmd->mbox.b, 0, MFI_MBOX_SIZE);
2820
2821 dcmd->mbox.b[0] = MR_PD_QUERY_TYPE_EXPOSED_TO_HOST;
2822 dcmd->mbox.b[1] = 0;
2823 dcmd->cmd = MFI_CMD_DCMD;
2824 dcmd->cmd_status = 0xFF;
2825 dcmd->sge_count = 1;
2826 dcmd->flags = MFI_FRAME_DIR_READ;
2827 dcmd->timeout = 0;
Yang, Bo780a3762009-12-06 08:24:21 -07002828 dcmd->pad_0 = 0;
Yang, Bo81e403c2009-10-06 14:27:54 -06002829 dcmd->data_xfer_len = MEGASAS_MAX_PD * sizeof(struct MR_PD_LIST);
2830 dcmd->opcode = MR_DCMD_PD_LIST_QUERY;
2831 dcmd->sgl.sge32[0].phys_addr = ci_h;
2832 dcmd->sgl.sge32[0].length = MEGASAS_MAX_PD * sizeof(struct MR_PD_LIST);
2833
2834 if (!megasas_issue_polled(instance, cmd)) {
2835 ret = 0;
2836 } else {
2837 ret = -1;
2838 }
2839
2840 /*
2841 * the following function will get the instance PD LIST.
2842 */
2843
2844 pd_addr = ci->addr;
2845
2846 if ( ret == 0 &&
2847 (ci->count <
2848 (MEGASAS_MAX_PD_CHANNELS * MEGASAS_MAX_DEV_PER_CHANNEL))) {
2849
2850 memset(instance->pd_list, 0,
2851 MEGASAS_MAX_PD * sizeof(struct megasas_pd_list));
2852
2853 for (pd_index = 0; pd_index < ci->count; pd_index++) {
2854
2855 instance->pd_list[pd_addr->deviceId].tid =
2856 pd_addr->deviceId;
2857 instance->pd_list[pd_addr->deviceId].driveType =
2858 pd_addr->scsiDevType;
2859 instance->pd_list[pd_addr->deviceId].driveState =
2860 MR_PD_STATE_SYSTEM;
2861 pd_addr++;
2862 }
2863 }
2864
2865 pci_free_consistent(instance->pdev,
2866 MEGASAS_MAX_PD * sizeof(struct MR_PD_LIST),
2867 ci, ci_h);
2868 megasas_return_cmd(instance, cmd);
2869
2870 return ret;
2871}
2872
Yang, Bobdc6fb82009-12-06 08:30:19 -07002873/*
2874 * megasas_get_ld_list_info - Returns FW's ld_list structure
2875 * @instance: Adapter soft state
2876 * @ld_list: ld_list structure
2877 *
2878 * Issues an internal command (DCMD) to get the FW's controller PD
2879 * list structure. This information is mainly used to find out SYSTEM
2880 * supported by the FW.
2881 */
2882static int
2883megasas_get_ld_list(struct megasas_instance *instance)
2884{
2885 int ret = 0, ld_index = 0, ids = 0;
2886 struct megasas_cmd *cmd;
2887 struct megasas_dcmd_frame *dcmd;
2888 struct MR_LD_LIST *ci;
2889 dma_addr_t ci_h = 0;
2890
2891 cmd = megasas_get_cmd(instance);
2892
2893 if (!cmd) {
2894 printk(KERN_DEBUG "megasas_get_ld_list: Failed to get cmd\n");
2895 return -ENOMEM;
2896 }
2897
2898 dcmd = &cmd->frame->dcmd;
2899
2900 ci = pci_alloc_consistent(instance->pdev,
2901 sizeof(struct MR_LD_LIST),
2902 &ci_h);
2903
2904 if (!ci) {
2905 printk(KERN_DEBUG "Failed to alloc mem in get_ld_list\n");
2906 megasas_return_cmd(instance, cmd);
2907 return -ENOMEM;
2908 }
2909
2910 memset(ci, 0, sizeof(*ci));
2911 memset(dcmd->mbox.b, 0, MFI_MBOX_SIZE);
2912
2913 dcmd->cmd = MFI_CMD_DCMD;
2914 dcmd->cmd_status = 0xFF;
2915 dcmd->sge_count = 1;
2916 dcmd->flags = MFI_FRAME_DIR_READ;
2917 dcmd->timeout = 0;
2918 dcmd->data_xfer_len = sizeof(struct MR_LD_LIST);
2919 dcmd->opcode = MR_DCMD_LD_GET_LIST;
2920 dcmd->sgl.sge32[0].phys_addr = ci_h;
2921 dcmd->sgl.sge32[0].length = sizeof(struct MR_LD_LIST);
2922 dcmd->pad_0 = 0;
2923
2924 if (!megasas_issue_polled(instance, cmd)) {
2925 ret = 0;
2926 } else {
2927 ret = -1;
2928 }
2929
2930 /* the following function will get the instance PD LIST */
2931
bo yang39a98552010-09-22 22:36:29 -04002932 if ((ret == 0) && (ci->ldCount <= MAX_LOGICAL_DRIVES)) {
Yang, Bobdc6fb82009-12-06 08:30:19 -07002933 memset(instance->ld_ids, 0xff, MEGASAS_MAX_LD_IDS);
2934
2935 for (ld_index = 0; ld_index < ci->ldCount; ld_index++) {
2936 if (ci->ldList[ld_index].state != 0) {
2937 ids = ci->ldList[ld_index].ref.targetId;
2938 instance->ld_ids[ids] =
2939 ci->ldList[ld_index].ref.targetId;
2940 }
2941 }
2942 }
2943
2944 pci_free_consistent(instance->pdev,
2945 sizeof(struct MR_LD_LIST),
2946 ci,
2947 ci_h);
2948
2949 megasas_return_cmd(instance, cmd);
2950 return ret;
2951}
2952
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04002953/**
2954 * megasas_get_controller_info - Returns FW's controller structure
2955 * @instance: Adapter soft state
2956 * @ctrl_info: Controller information structure
2957 *
2958 * Issues an internal command (DCMD) to get the FW's controller structure.
2959 * This information is mainly used to find out the maximum IO transfer per
2960 * command supported by the FW.
2961 */
2962static int
2963megasas_get_ctrl_info(struct megasas_instance *instance,
2964 struct megasas_ctrl_info *ctrl_info)
2965{
2966 int ret = 0;
2967 struct megasas_cmd *cmd;
2968 struct megasas_dcmd_frame *dcmd;
2969 struct megasas_ctrl_info *ci;
2970 dma_addr_t ci_h = 0;
2971
2972 cmd = megasas_get_cmd(instance);
2973
2974 if (!cmd) {
2975 printk(KERN_DEBUG "megasas: Failed to get a free cmd\n");
2976 return -ENOMEM;
2977 }
2978
2979 dcmd = &cmd->frame->dcmd;
2980
2981 ci = pci_alloc_consistent(instance->pdev,
2982 sizeof(struct megasas_ctrl_info), &ci_h);
2983
2984 if (!ci) {
2985 printk(KERN_DEBUG "Failed to alloc mem for ctrl info\n");
2986 megasas_return_cmd(instance, cmd);
2987 return -ENOMEM;
2988 }
2989
2990 memset(ci, 0, sizeof(*ci));
2991 memset(dcmd->mbox.b, 0, MFI_MBOX_SIZE);
2992
2993 dcmd->cmd = MFI_CMD_DCMD;
2994 dcmd->cmd_status = 0xFF;
2995 dcmd->sge_count = 1;
2996 dcmd->flags = MFI_FRAME_DIR_READ;
2997 dcmd->timeout = 0;
Yang, Bo780a3762009-12-06 08:24:21 -07002998 dcmd->pad_0 = 0;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04002999 dcmd->data_xfer_len = sizeof(struct megasas_ctrl_info);
3000 dcmd->opcode = MR_DCMD_CTRL_GET_INFO;
3001 dcmd->sgl.sge32[0].phys_addr = ci_h;
3002 dcmd->sgl.sge32[0].length = sizeof(struct megasas_ctrl_info);
3003
3004 if (!megasas_issue_polled(instance, cmd)) {
3005 ret = 0;
3006 memcpy(ctrl_info, ci, sizeof(struct megasas_ctrl_info));
3007 } else {
3008 ret = -1;
3009 }
3010
3011 pci_free_consistent(instance->pdev, sizeof(struct megasas_ctrl_info),
3012 ci, ci_h);
3013
3014 megasas_return_cmd(instance, cmd);
3015 return ret;
3016}
3017
3018/**
bo yang31ea7082007-11-07 12:09:50 -05003019 * megasas_issue_init_mfi - Initializes the FW
3020 * @instance: Adapter soft state
3021 *
3022 * Issues the INIT MFI cmd
3023 */
3024static int
3025megasas_issue_init_mfi(struct megasas_instance *instance)
3026{
3027 u32 context;
3028
3029 struct megasas_cmd *cmd;
3030
3031 struct megasas_init_frame *init_frame;
3032 struct megasas_init_queue_info *initq_info;
3033 dma_addr_t init_frame_h;
3034 dma_addr_t initq_info_h;
3035
3036 /*
3037 * Prepare a init frame. Note the init frame points to queue info
3038 * structure. Each frame has SGL allocated after first 64 bytes. For
3039 * this frame - since we don't need any SGL - we use SGL's space as
3040 * queue info structure
3041 *
3042 * We will not get a NULL command below. We just created the pool.
3043 */
3044 cmd = megasas_get_cmd(instance);
3045
3046 init_frame = (struct megasas_init_frame *)cmd->frame;
3047 initq_info = (struct megasas_init_queue_info *)
3048 ((unsigned long)init_frame + 64);
3049
3050 init_frame_h = cmd->frame_phys_addr;
3051 initq_info_h = init_frame_h + 64;
3052
3053 context = init_frame->context;
3054 memset(init_frame, 0, MEGAMFI_FRAME_SIZE);
3055 memset(initq_info, 0, sizeof(struct megasas_init_queue_info));
3056 init_frame->context = context;
3057
3058 initq_info->reply_queue_entries = instance->max_fw_cmds + 1;
3059 initq_info->reply_queue_start_phys_addr_lo = instance->reply_queue_h;
3060
3061 initq_info->producer_index_phys_addr_lo = instance->producer_h;
3062 initq_info->consumer_index_phys_addr_lo = instance->consumer_h;
3063
3064 init_frame->cmd = MFI_CMD_INIT;
3065 init_frame->cmd_status = 0xFF;
3066 init_frame->queue_info_new_phys_addr_lo = initq_info_h;
3067
3068 init_frame->data_xfer_len = sizeof(struct megasas_init_queue_info);
3069
3070 /*
3071 * disable the intr before firing the init frame to FW
3072 */
3073 instance->instancet->disable_intr(instance->reg_set);
3074
3075 /*
3076 * Issue the init frame in polled mode
3077 */
3078
3079 if (megasas_issue_polled(instance, cmd)) {
3080 printk(KERN_ERR "megasas: Failed to init firmware\n");
3081 megasas_return_cmd(instance, cmd);
3082 goto fail_fw_init;
3083 }
3084
3085 megasas_return_cmd(instance, cmd);
3086
3087 return 0;
3088
3089fail_fw_init:
3090 return -EINVAL;
3091}
3092
3093/**
bo yangad84db22007-11-09 04:40:16 -05003094 * megasas_start_timer - Initializes a timer object
3095 * @instance: Adapter soft state
3096 * @timer: timer object to be initialized
3097 * @fn: timer function
3098 * @interval: time interval between timer function call
3099 */
3100static inline void
3101megasas_start_timer(struct megasas_instance *instance,
3102 struct timer_list *timer,
3103 void *fn, unsigned long interval)
3104{
3105 init_timer(timer);
3106 timer->expires = jiffies + interval;
3107 timer->data = (unsigned long)instance;
3108 timer->function = fn;
3109 add_timer(timer);
3110}
3111
3112/**
3113 * megasas_io_completion_timer - Timer fn
3114 * @instance_addr: Address of adapter soft state
3115 *
3116 * Schedules tasklet for cmd completion
3117 * if poll_mode_io is set
3118 */
3119static void
3120megasas_io_completion_timer(unsigned long instance_addr)
3121{
3122 struct megasas_instance *instance =
3123 (struct megasas_instance *)instance_addr;
3124
3125 if (atomic_read(&instance->fw_outstanding))
3126 tasklet_schedule(&instance->isr_tasklet);
3127
3128 /* Restart timer */
3129 if (poll_mode_io)
3130 mod_timer(&instance->io_completion_timer,
3131 jiffies + MEGASAS_COMPLETION_TIMER_INTERVAL);
3132}
3133
3134/**
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003135 * megasas_init_mfi - Initializes the FW
3136 * @instance: Adapter soft state
3137 *
3138 * This is the main function for initializing MFI firmware.
3139 */
3140static int megasas_init_mfi(struct megasas_instance *instance)
3141{
3142 u32 context_sz;
3143 u32 reply_q_sz;
3144 u32 max_sectors_1;
3145 u32 max_sectors_2;
bo yang14faea92007-11-09 04:14:00 -05003146 u32 tmp_sectors;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003147 struct megasas_register_set __iomem *reg_set;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003148 struct megasas_ctrl_info *ctrl_info;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003149 /*
3150 * Map the message registers
3151 */
Yang, Bo6610a6b2008-08-10 12:42:38 -07003152 if ((instance->pdev->device == PCI_DEVICE_ID_LSI_SAS1078GEN2) ||
Yang, Bo87911122009-10-06 14:31:54 -06003153 (instance->pdev->device == PCI_DEVICE_ID_LSI_SAS0071SKINNY) ||
3154 (instance->pdev->device == PCI_DEVICE_ID_LSI_SAS0073SKINNY) ||
Yang, Bo6610a6b2008-08-10 12:42:38 -07003155 (instance->pdev->device == PCI_DEVICE_ID_LSI_SAS0079GEN2)) {
3156 instance->base_addr = pci_resource_start(instance->pdev, 1);
3157 } else {
3158 instance->base_addr = pci_resource_start(instance->pdev, 0);
3159 }
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003160
Noriyuki Fujiiaeab3fd2009-11-20 16:27:20 +09003161 if (pci_request_selected_regions(instance->pdev,
3162 pci_select_bars(instance->pdev, IORESOURCE_MEM),
3163 "megasas: LSI")) {
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003164 printk(KERN_DEBUG "megasas: IO memory region busy!\n");
3165 return -EBUSY;
3166 }
3167
3168 instance->reg_set = ioremap_nocache(instance->base_addr, 8192);
3169
3170 if (!instance->reg_set) {
3171 printk(KERN_DEBUG "megasas: Failed to map IO mem\n");
3172 goto fail_ioremap;
3173 }
3174
3175 reg_set = instance->reg_set;
3176
Sumant Patrof9876f02006-02-03 15:34:35 -08003177 switch(instance->pdev->device)
3178 {
bo yangaf7a5642008-03-17 04:13:07 -04003179 case PCI_DEVICE_ID_LSI_SAS1078R:
3180 case PCI_DEVICE_ID_LSI_SAS1078DE:
Sumant Patrof9876f02006-02-03 15:34:35 -08003181 instance->instancet = &megasas_instance_template_ppc;
3182 break;
Yang, Bo6610a6b2008-08-10 12:42:38 -07003183 case PCI_DEVICE_ID_LSI_SAS1078GEN2:
3184 case PCI_DEVICE_ID_LSI_SAS0079GEN2:
3185 instance->instancet = &megasas_instance_template_gen2;
3186 break;
Yang, Bo87911122009-10-06 14:31:54 -06003187 case PCI_DEVICE_ID_LSI_SAS0073SKINNY:
3188 case PCI_DEVICE_ID_LSI_SAS0071SKINNY:
3189 instance->instancet = &megasas_instance_template_skinny;
3190 break;
Sumant Patrof9876f02006-02-03 15:34:35 -08003191 case PCI_DEVICE_ID_LSI_SAS1064R:
3192 case PCI_DEVICE_ID_DELL_PERC5:
3193 default:
3194 instance->instancet = &megasas_instance_template_xscale;
3195 break;
3196 }
Sumant Patro1341c932006-01-25 12:02:40 -08003197
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003198 /*
3199 * We expect the FW state to be READY
3200 */
Sumant Patro1341c932006-01-25 12:02:40 -08003201 if (megasas_transition_to_ready(instance))
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003202 goto fail_ready_state;
3203
3204 /*
3205 * Get various operational parameters from status register
3206 */
Sumant Patro1341c932006-01-25 12:02:40 -08003207 instance->max_fw_cmds = instance->instancet->read_fw_status_reg(reg_set) & 0x00FFFF;
Sumant Patroe3bbff92006-10-03 12:28:49 -07003208 /*
3209 * Reduce the max supported cmds by 1. This is to ensure that the
3210 * reply_q_sz (1 more than the max cmd that driver may send)
3211 * does not exceed max cmds that the FW can support
3212 */
3213 instance->max_fw_cmds = instance->max_fw_cmds-1;
Sumant Patro1341c932006-01-25 12:02:40 -08003214 instance->max_num_sge = (instance->instancet->read_fw_status_reg(reg_set) & 0xFF0000) >>
3215 0x10;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003216 /*
3217 * Create a pool of commands
3218 */
3219 if (megasas_alloc_cmds(instance))
3220 goto fail_alloc_cmds;
3221
3222 /*
3223 * Allocate memory for reply queue. Length of reply queue should
3224 * be _one_ more than the maximum commands handled by the firmware.
3225 *
3226 * Note: When FW completes commands, it places corresponding contex
3227 * values in this circular reply queue. This circular queue is a fairly
3228 * typical producer-consumer queue. FW is the producer (of completed
3229 * commands) and the driver is the consumer.
3230 */
3231 context_sz = sizeof(u32);
3232 reply_q_sz = context_sz * (instance->max_fw_cmds + 1);
3233
3234 instance->reply_queue = pci_alloc_consistent(instance->pdev,
3235 reply_q_sz,
3236 &instance->reply_queue_h);
3237
3238 if (!instance->reply_queue) {
3239 printk(KERN_DEBUG "megasas: Out of DMA mem for reply queue\n");
3240 goto fail_reply_queue;
3241 }
3242
bo yang31ea7082007-11-07 12:09:50 -05003243 if (megasas_issue_init_mfi(instance))
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003244 goto fail_fw_init;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003245
bo yang39a98552010-09-22 22:36:29 -04003246 instance->fw_support_ieee = 0;
3247 instance->fw_support_ieee =
3248 (instance->instancet->read_fw_status_reg(reg_set) &
3249 0x04000000);
3250
3251 printk(KERN_NOTICE "megasas_init_mfi: fw_support_ieee=%d",
3252 instance->fw_support_ieee);
3253
3254 if (instance->fw_support_ieee)
3255 instance->flag_ieee = 1;
3256
3257 /** for passthrough
3258 * the following function will get the PD LIST.
3259 */
3260
Yang, Bo81e403c2009-10-06 14:27:54 -06003261 memset(instance->pd_list, 0 ,
3262 (MEGASAS_MAX_PD * sizeof(struct megasas_pd_list)));
3263 megasas_get_pd_list(instance);
3264
Yang, Bobdc6fb82009-12-06 08:30:19 -07003265 memset(instance->ld_ids, 0xff, MEGASAS_MAX_LD_IDS);
3266 megasas_get_ld_list(instance);
3267
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003268 ctrl_info = kmalloc(sizeof(struct megasas_ctrl_info), GFP_KERNEL);
3269
3270 /*
3271 * Compute the max allowed sectors per IO: The controller info has two
3272 * limits on max sectors. Driver should use the minimum of these two.
3273 *
3274 * 1 << stripe_sz_ops.min = max sectors per strip
3275 *
3276 * Note that older firmwares ( < FW ver 30) didn't report information
3277 * to calculate max_sectors_1. So the number ended up as zero always.
3278 */
bo yang14faea92007-11-09 04:14:00 -05003279 tmp_sectors = 0;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003280 if (ctrl_info && !megasas_get_ctrl_info(instance, ctrl_info)) {
3281
3282 max_sectors_1 = (1 << ctrl_info->stripe_sz_ops.min) *
3283 ctrl_info->max_strips_per_io;
3284 max_sectors_2 = ctrl_info->max_request_size;
3285
bo yang14faea92007-11-09 04:14:00 -05003286 tmp_sectors = min_t(u32, max_sectors_1 , max_sectors_2);
bo yang39a98552010-09-22 22:36:29 -04003287 instance->disableOnlineCtrlReset =
3288 ctrl_info->properties.OnOffProperties.disableOnlineCtrlReset;
bo yang14faea92007-11-09 04:14:00 -05003289 }
3290
3291 instance->max_sectors_per_req = instance->max_num_sge *
3292 PAGE_SIZE / 512;
3293 if (tmp_sectors && (instance->max_sectors_per_req > tmp_sectors))
3294 instance->max_sectors_per_req = tmp_sectors;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003295
3296 kfree(ctrl_info);
3297
Sumant Patro5d018ad2006-10-03 13:13:18 -07003298 /*
3299 * Setup tasklet for cmd completion
3300 */
3301
bo yangad84db22007-11-09 04:40:16 -05003302 tasklet_init(&instance->isr_tasklet, megasas_complete_cmd_dpc,
3303 (unsigned long)instance);
3304
3305 /* Initialize the cmd completion timer */
3306 if (poll_mode_io)
3307 megasas_start_timer(instance, &instance->io_completion_timer,
3308 megasas_io_completion_timer,
3309 MEGASAS_COMPLETION_TIMER_INTERVAL);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003310 return 0;
3311
3312 fail_fw_init:
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003313
3314 pci_free_consistent(instance->pdev, reply_q_sz,
3315 instance->reply_queue, instance->reply_queue_h);
3316 fail_reply_queue:
3317 megasas_free_cmds(instance);
3318
3319 fail_alloc_cmds:
3320 fail_ready_state:
3321 iounmap(instance->reg_set);
3322
3323 fail_ioremap:
Noriyuki Fujiiaeab3fd2009-11-20 16:27:20 +09003324 pci_release_selected_regions(instance->pdev,
3325 pci_select_bars(instance->pdev, IORESOURCE_MEM));
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003326
3327 return -EINVAL;
3328}
3329
3330/**
3331 * megasas_release_mfi - Reverses the FW initialization
3332 * @intance: Adapter soft state
3333 */
3334static void megasas_release_mfi(struct megasas_instance *instance)
3335{
3336 u32 reply_q_sz = sizeof(u32) * (instance->max_fw_cmds + 1);
3337
3338 pci_free_consistent(instance->pdev, reply_q_sz,
3339 instance->reply_queue, instance->reply_queue_h);
3340
3341 megasas_free_cmds(instance);
3342
3343 iounmap(instance->reg_set);
3344
Noriyuki Fujiiaeab3fd2009-11-20 16:27:20 +09003345 pci_release_selected_regions(instance->pdev,
3346 pci_select_bars(instance->pdev, IORESOURCE_MEM));
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003347}
3348
3349/**
3350 * megasas_get_seq_num - Gets latest event sequence numbers
3351 * @instance: Adapter soft state
3352 * @eli: FW event log sequence numbers information
3353 *
3354 * FW maintains a log of all events in a non-volatile area. Upper layers would
3355 * usually find out the latest sequence number of the events, the seq number at
3356 * the boot etc. They would "read" all the events below the latest seq number
3357 * by issuing a direct fw cmd (DCMD). For the future events (beyond latest seq
3358 * number), they would subsribe to AEN (asynchronous event notification) and
3359 * wait for the events to happen.
3360 */
3361static int
3362megasas_get_seq_num(struct megasas_instance *instance,
3363 struct megasas_evt_log_info *eli)
3364{
3365 struct megasas_cmd *cmd;
3366 struct megasas_dcmd_frame *dcmd;
3367 struct megasas_evt_log_info *el_info;
3368 dma_addr_t el_info_h = 0;
3369
3370 cmd = megasas_get_cmd(instance);
3371
3372 if (!cmd) {
3373 return -ENOMEM;
3374 }
3375
3376 dcmd = &cmd->frame->dcmd;
3377 el_info = pci_alloc_consistent(instance->pdev,
3378 sizeof(struct megasas_evt_log_info),
3379 &el_info_h);
3380
3381 if (!el_info) {
3382 megasas_return_cmd(instance, cmd);
3383 return -ENOMEM;
3384 }
3385
3386 memset(el_info, 0, sizeof(*el_info));
3387 memset(dcmd->mbox.b, 0, MFI_MBOX_SIZE);
3388
3389 dcmd->cmd = MFI_CMD_DCMD;
3390 dcmd->cmd_status = 0x0;
3391 dcmd->sge_count = 1;
3392 dcmd->flags = MFI_FRAME_DIR_READ;
3393 dcmd->timeout = 0;
Yang, Bo780a3762009-12-06 08:24:21 -07003394 dcmd->pad_0 = 0;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003395 dcmd->data_xfer_len = sizeof(struct megasas_evt_log_info);
3396 dcmd->opcode = MR_DCMD_CTRL_EVENT_GET_INFO;
3397 dcmd->sgl.sge32[0].phys_addr = el_info_h;
3398 dcmd->sgl.sge32[0].length = sizeof(struct megasas_evt_log_info);
3399
3400 megasas_issue_blocked_cmd(instance, cmd);
3401
3402 /*
3403 * Copy the data back into callers buffer
3404 */
3405 memcpy(eli, el_info, sizeof(struct megasas_evt_log_info));
3406
3407 pci_free_consistent(instance->pdev, sizeof(struct megasas_evt_log_info),
3408 el_info, el_info_h);
3409
3410 megasas_return_cmd(instance, cmd);
3411
3412 return 0;
3413}
3414
3415/**
3416 * megasas_register_aen - Registers for asynchronous event notification
3417 * @instance: Adapter soft state
3418 * @seq_num: The starting sequence number
3419 * @class_locale: Class of the event
3420 *
3421 * This function subscribes for AEN for events beyond the @seq_num. It requests
3422 * to be notified if and only if the event is of type @class_locale
3423 */
3424static int
3425megasas_register_aen(struct megasas_instance *instance, u32 seq_num,
3426 u32 class_locale_word)
3427{
3428 int ret_val;
3429 struct megasas_cmd *cmd;
3430 struct megasas_dcmd_frame *dcmd;
3431 union megasas_evt_class_locale curr_aen;
3432 union megasas_evt_class_locale prev_aen;
3433
3434 /*
3435 * If there an AEN pending already (aen_cmd), check if the
3436 * class_locale of that pending AEN is inclusive of the new
3437 * AEN request we currently have. If it is, then we don't have
3438 * to do anything. In other words, whichever events the current
3439 * AEN request is subscribing to, have already been subscribed
3440 * to.
3441 *
3442 * If the old_cmd is _not_ inclusive, then we have to abort
3443 * that command, form a class_locale that is superset of both
3444 * old and current and re-issue to the FW
3445 */
3446
3447 curr_aen.word = class_locale_word;
3448
3449 if (instance->aen_cmd) {
3450
3451 prev_aen.word = instance->aen_cmd->frame->dcmd.mbox.w[1];
3452
3453 /*
3454 * A class whose enum value is smaller is inclusive of all
3455 * higher values. If a PROGRESS (= -1) was previously
3456 * registered, then a new registration requests for higher
3457 * classes need not be sent to FW. They are automatically
3458 * included.
3459 *
3460 * Locale numbers don't have such hierarchy. They are bitmap
3461 * values
3462 */
3463 if ((prev_aen.members.class <= curr_aen.members.class) &&
3464 !((prev_aen.members.locale & curr_aen.members.locale) ^
3465 curr_aen.members.locale)) {
3466 /*
3467 * Previously issued event registration includes
3468 * current request. Nothing to do.
3469 */
3470 return 0;
3471 } else {
3472 curr_aen.members.locale |= prev_aen.members.locale;
3473
3474 if (prev_aen.members.class < curr_aen.members.class)
3475 curr_aen.members.class = prev_aen.members.class;
3476
3477 instance->aen_cmd->abort_aen = 1;
3478 ret_val = megasas_issue_blocked_abort_cmd(instance,
3479 instance->
3480 aen_cmd);
3481
3482 if (ret_val) {
3483 printk(KERN_DEBUG "megasas: Failed to abort "
3484 "previous AEN command\n");
3485 return ret_val;
3486 }
3487 }
3488 }
3489
3490 cmd = megasas_get_cmd(instance);
3491
3492 if (!cmd)
3493 return -ENOMEM;
3494
3495 dcmd = &cmd->frame->dcmd;
3496
3497 memset(instance->evt_detail, 0, sizeof(struct megasas_evt_detail));
3498
3499 /*
3500 * Prepare DCMD for aen registration
3501 */
3502 memset(dcmd->mbox.b, 0, MFI_MBOX_SIZE);
3503
3504 dcmd->cmd = MFI_CMD_DCMD;
3505 dcmd->cmd_status = 0x0;
3506 dcmd->sge_count = 1;
3507 dcmd->flags = MFI_FRAME_DIR_READ;
3508 dcmd->timeout = 0;
Yang, Bo780a3762009-12-06 08:24:21 -07003509 dcmd->pad_0 = 0;
bo yang39a98552010-09-22 22:36:29 -04003510 instance->last_seq_num = seq_num;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003511 dcmd->data_xfer_len = sizeof(struct megasas_evt_detail);
3512 dcmd->opcode = MR_DCMD_CTRL_EVENT_WAIT;
3513 dcmd->mbox.w[0] = seq_num;
3514 dcmd->mbox.w[1] = curr_aen.word;
3515 dcmd->sgl.sge32[0].phys_addr = (u32) instance->evt_detail_h;
3516 dcmd->sgl.sge32[0].length = sizeof(struct megasas_evt_detail);
3517
Yang, Bof4c9a132009-10-06 14:43:28 -06003518 if (instance->aen_cmd != NULL) {
3519 megasas_return_cmd(instance, cmd);
3520 return 0;
3521 }
3522
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003523 /*
3524 * Store reference to the cmd used to register for AEN. When an
3525 * application wants us to register for AEN, we have to abort this
3526 * cmd and re-register with a new EVENT LOCALE supplied by that app
3527 */
3528 instance->aen_cmd = cmd;
3529
3530 /*
3531 * Issue the aen registration frame
3532 */
Yang, Bo0c79e682009-10-06 14:47:35 -06003533 instance->instancet->fire_cmd(instance,
3534 cmd->frame_phys_addr, 0, instance->reg_set);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003535
3536 return 0;
3537}
3538
3539/**
3540 * megasas_start_aen - Subscribes to AEN during driver load time
3541 * @instance: Adapter soft state
3542 */
3543static int megasas_start_aen(struct megasas_instance *instance)
3544{
3545 struct megasas_evt_log_info eli;
3546 union megasas_evt_class_locale class_locale;
3547
3548 /*
3549 * Get the latest sequence number from FW
3550 */
3551 memset(&eli, 0, sizeof(eli));
3552
3553 if (megasas_get_seq_num(instance, &eli))
3554 return -1;
3555
3556 /*
3557 * Register AEN with FW for latest sequence number plus 1
3558 */
3559 class_locale.members.reserved = 0;
3560 class_locale.members.locale = MR_EVT_LOCALE_ALL;
3561 class_locale.members.class = MR_EVT_CLASS_DEBUG;
3562
3563 return megasas_register_aen(instance, eli.newest_seq_num + 1,
3564 class_locale.word);
3565}
3566
3567/**
3568 * megasas_io_attach - Attaches this driver to SCSI mid-layer
3569 * @instance: Adapter soft state
3570 */
3571static int megasas_io_attach(struct megasas_instance *instance)
3572{
3573 struct Scsi_Host *host = instance->host;
3574
3575 /*
3576 * Export parameters required by SCSI mid-layer
3577 */
3578 host->irq = instance->pdev->irq;
3579 host->unique_id = instance->unique_id;
Yang, Bo7bebf5c2009-10-06 14:40:58 -06003580 if ((instance->pdev->device == PCI_DEVICE_ID_LSI_SAS0073SKINNY) ||
3581 (instance->pdev->device == PCI_DEVICE_ID_LSI_SAS0071SKINNY)) {
3582 host->can_queue =
3583 instance->max_fw_cmds - MEGASAS_SKINNY_INT_CMDS;
3584 } else
3585 host->can_queue =
3586 instance->max_fw_cmds - MEGASAS_INT_CMDS;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003587 host->this_id = instance->init_id;
3588 host->sg_tablesize = instance->max_num_sge;
3589 host->max_sectors = instance->max_sectors_per_req;
3590 host->cmd_per_lun = 128;
3591 host->max_channel = MEGASAS_MAX_CHANNELS - 1;
3592 host->max_id = MEGASAS_MAX_DEV_PER_CHANNEL;
3593 host->max_lun = MEGASAS_MAX_LUN;
Joshua Giles122da302006-02-03 15:34:17 -08003594 host->max_cmd_len = 16;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003595
3596 /*
3597 * Notify the mid-layer about the new controller
3598 */
3599 if (scsi_add_host(host, &instance->pdev->dev)) {
3600 printk(KERN_DEBUG "megasas: scsi_add_host failed\n");
3601 return -ENODEV;
3602 }
3603
3604 /*
3605 * Trigger SCSI to scan our drives
3606 */
3607 scsi_scan_host(host);
3608 return 0;
3609}
3610
bo yang31ea7082007-11-07 12:09:50 -05003611static int
3612megasas_set_dma_mask(struct pci_dev *pdev)
3613{
3614 /*
3615 * All our contollers are capable of performing 64-bit DMA
3616 */
3617 if (IS_DMA64) {
Yang Hongyang6a355282009-04-06 19:01:13 -07003618 if (pci_set_dma_mask(pdev, DMA_BIT_MASK(64)) != 0) {
bo yang31ea7082007-11-07 12:09:50 -05003619
Yang Hongyang284901a2009-04-06 19:01:15 -07003620 if (pci_set_dma_mask(pdev, DMA_BIT_MASK(32)) != 0)
bo yang31ea7082007-11-07 12:09:50 -05003621 goto fail_set_dma_mask;
3622 }
3623 } else {
Yang Hongyang284901a2009-04-06 19:01:15 -07003624 if (pci_set_dma_mask(pdev, DMA_BIT_MASK(32)) != 0)
bo yang31ea7082007-11-07 12:09:50 -05003625 goto fail_set_dma_mask;
3626 }
3627 return 0;
3628
3629fail_set_dma_mask:
3630 return 1;
3631}
3632
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003633/**
3634 * megasas_probe_one - PCI hotplug entry point
3635 * @pdev: PCI device structure
3636 * @id: PCI ids of supported hotplugged adapter
3637 */
3638static int __devinit
3639megasas_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
3640{
3641 int rval;
3642 struct Scsi_Host *host;
3643 struct megasas_instance *instance;
3644
3645 /*
3646 * Announce PCI information
3647 */
3648 printk(KERN_INFO "megasas: %#4.04x:%#4.04x:%#4.04x:%#4.04x: ",
3649 pdev->vendor, pdev->device, pdev->subsystem_vendor,
3650 pdev->subsystem_device);
3651
3652 printk("bus %d:slot %d:func %d\n",
3653 pdev->bus->number, PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn));
3654
3655 /*
3656 * PCI prepping: enable device set bus mastering and dma mask
3657 */
Noriyuki Fujiiaeab3fd2009-11-20 16:27:20 +09003658 rval = pci_enable_device_mem(pdev);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003659
3660 if (rval) {
3661 return rval;
3662 }
3663
3664 pci_set_master(pdev);
3665
bo yang31ea7082007-11-07 12:09:50 -05003666 if (megasas_set_dma_mask(pdev))
3667 goto fail_set_dma_mask;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003668
3669 host = scsi_host_alloc(&megasas_template,
3670 sizeof(struct megasas_instance));
3671
3672 if (!host) {
3673 printk(KERN_DEBUG "megasas: scsi_host_alloc failed\n");
3674 goto fail_alloc_instance;
3675 }
3676
3677 instance = (struct megasas_instance *)host->hostdata;
3678 memset(instance, 0, sizeof(*instance));
bo yang39a98552010-09-22 22:36:29 -04003679 atomic_set( &instance->fw_reset_no_pci_access, 0 );
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003680
3681 instance->producer = pci_alloc_consistent(pdev, sizeof(u32),
3682 &instance->producer_h);
3683 instance->consumer = pci_alloc_consistent(pdev, sizeof(u32),
3684 &instance->consumer_h);
3685
3686 if (!instance->producer || !instance->consumer) {
3687 printk(KERN_DEBUG "megasas: Failed to allocate memory for "
3688 "producer, consumer\n");
3689 goto fail_alloc_dma_buf;
3690 }
3691
3692 *instance->producer = 0;
3693 *instance->consumer = 0;
Yang, Boc3518832009-10-06 14:18:02 -06003694 megasas_poll_wait_aen = 0;
Yang, Bof4c9a132009-10-06 14:43:28 -06003695 instance->flag_ieee = 0;
Yang, Bo7e8a75f2009-10-06 14:50:17 -06003696 instance->ev = NULL;
bo yang39a98552010-09-22 22:36:29 -04003697 instance->issuepend_done = 1;
3698 instance->adprecovery = MEGASAS_HBA_OPERATIONAL;
3699 megasas_poll_wait_aen = 0;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003700
3701 instance->evt_detail = pci_alloc_consistent(pdev,
3702 sizeof(struct
3703 megasas_evt_detail),
3704 &instance->evt_detail_h);
3705
3706 if (!instance->evt_detail) {
3707 printk(KERN_DEBUG "megasas: Failed to allocate memory for "
3708 "event detail structure\n");
3709 goto fail_alloc_dma_buf;
3710 }
3711
3712 /*
3713 * Initialize locks and queues
3714 */
3715 INIT_LIST_HEAD(&instance->cmd_pool);
bo yang39a98552010-09-22 22:36:29 -04003716 INIT_LIST_HEAD(&instance->internal_reset_pending_q);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003717
Sumant Patroe4a082c2006-05-30 12:03:37 -07003718 atomic_set(&instance->fw_outstanding,0);
3719
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003720 init_waitqueue_head(&instance->int_cmd_wait_q);
3721 init_waitqueue_head(&instance->abort_cmd_wait_q);
3722
3723 spin_lock_init(&instance->cmd_pool_lock);
bo yang39a98552010-09-22 22:36:29 -04003724 spin_lock_init(&instance->hba_lock);
bo yang7343eb62007-11-09 04:35:44 -05003725 spin_lock_init(&instance->completion_lock);
Yang, Boc3518832009-10-06 14:18:02 -06003726 spin_lock_init(&poll_aen_lock);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003727
Matthias Kaehlckee5a69e22007-10-27 09:48:46 +02003728 mutex_init(&instance->aen_mutex);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003729
3730 /*
3731 * Initialize PCI related and misc parameters
3732 */
3733 instance->pdev = pdev;
3734 instance->host = host;
3735 instance->unique_id = pdev->bus->number << 8 | pdev->devfn;
3736 instance->init_id = MEGASAS_DEFAULT_INIT_ID;
3737
Yang, Bo7bebf5c2009-10-06 14:40:58 -06003738 if ((instance->pdev->device == PCI_DEVICE_ID_LSI_SAS0073SKINNY) ||
3739 (instance->pdev->device == PCI_DEVICE_ID_LSI_SAS0071SKINNY)) {
Yang, Bof4c9a132009-10-06 14:43:28 -06003740 instance->flag_ieee = 1;
Yang, Bo7bebf5c2009-10-06 14:40:58 -06003741 sema_init(&instance->ioctl_sem, MEGASAS_SKINNY_INT_CMDS);
3742 } else
3743 sema_init(&instance->ioctl_sem, MEGASAS_INT_CMDS);
3744
Sumant Patro658dced2006-10-03 13:09:14 -07003745 megasas_dbg_lvl = 0;
Sumant Patro05e9ebb2007-05-17 05:47:51 -07003746 instance->flag = 0;
Yang, Bo0c79e682009-10-06 14:47:35 -06003747 instance->unload = 1;
Sumant Patro05e9ebb2007-05-17 05:47:51 -07003748 instance->last_time = 0;
bo yang39a98552010-09-22 22:36:29 -04003749 instance->disableOnlineCtrlReset = 1;
3750
3751 INIT_WORK(&instance->work_init, process_fw_state_change_wq);
Sumant Patro658dced2006-10-03 13:09:14 -07003752
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003753 /*
3754 * Initialize MFI Firmware
3755 */
3756 if (megasas_init_mfi(instance))
3757 goto fail_init_mfi;
3758
3759 /*
3760 * Register IRQ
3761 */
Thomas Gleixner1d6f3592006-07-01 19:29:42 -07003762 if (request_irq(pdev->irq, megasas_isr, IRQF_SHARED, "megasas", instance)) {
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003763 printk(KERN_DEBUG "megasas: Failed to register IRQ\n");
3764 goto fail_irq;
3765 }
3766
Sumant Patro1341c932006-01-25 12:02:40 -08003767 instance->instancet->enable_intr(instance->reg_set);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003768
3769 /*
3770 * Store instance in PCI softstate
3771 */
3772 pci_set_drvdata(pdev, instance);
3773
3774 /*
3775 * Add this controller to megasas_mgmt_info structure so that it
3776 * can be exported to management applications
3777 */
3778 megasas_mgmt_info.count++;
3779 megasas_mgmt_info.instance[megasas_mgmt_info.max_index] = instance;
3780 megasas_mgmt_info.max_index++;
3781
3782 /*
3783 * Initiate AEN (Asynchronous Event Notification)
3784 */
3785 if (megasas_start_aen(instance)) {
3786 printk(KERN_DEBUG "megasas: start aen failed\n");
3787 goto fail_start_aen;
3788 }
3789
3790 /*
3791 * Register with SCSI mid-layer
3792 */
3793 if (megasas_io_attach(instance))
3794 goto fail_io_attach;
3795
Yang, Bo0c79e682009-10-06 14:47:35 -06003796 instance->unload = 0;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003797 return 0;
3798
3799 fail_start_aen:
3800 fail_io_attach:
3801 megasas_mgmt_info.count--;
3802 megasas_mgmt_info.instance[megasas_mgmt_info.max_index] = NULL;
3803 megasas_mgmt_info.max_index--;
3804
3805 pci_set_drvdata(pdev, NULL);
Sumant Patrob274cab2006-10-03 12:52:12 -07003806 instance->instancet->disable_intr(instance->reg_set);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003807 free_irq(instance->pdev->irq, instance);
3808
3809 megasas_release_mfi(instance);
3810
3811 fail_irq:
3812 fail_init_mfi:
3813 fail_alloc_dma_buf:
3814 if (instance->evt_detail)
3815 pci_free_consistent(pdev, sizeof(struct megasas_evt_detail),
3816 instance->evt_detail,
3817 instance->evt_detail_h);
3818
3819 if (instance->producer)
3820 pci_free_consistent(pdev, sizeof(u32), instance->producer,
3821 instance->producer_h);
3822 if (instance->consumer)
3823 pci_free_consistent(pdev, sizeof(u32), instance->consumer,
3824 instance->consumer_h);
3825 scsi_host_put(host);
3826
3827 fail_alloc_instance:
3828 fail_set_dma_mask:
3829 pci_disable_device(pdev);
3830
3831 return -ENODEV;
3832}
3833
3834/**
3835 * megasas_flush_cache - Requests FW to flush all its caches
3836 * @instance: Adapter soft state
3837 */
3838static void megasas_flush_cache(struct megasas_instance *instance)
3839{
3840 struct megasas_cmd *cmd;
3841 struct megasas_dcmd_frame *dcmd;
3842
bo yang39a98552010-09-22 22:36:29 -04003843 if (instance->adprecovery == MEGASAS_HW_CRITICAL_ERROR)
3844 return;
3845
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003846 cmd = megasas_get_cmd(instance);
3847
3848 if (!cmd)
3849 return;
3850
3851 dcmd = &cmd->frame->dcmd;
3852
3853 memset(dcmd->mbox.b, 0, MFI_MBOX_SIZE);
3854
3855 dcmd->cmd = MFI_CMD_DCMD;
3856 dcmd->cmd_status = 0x0;
3857 dcmd->sge_count = 0;
3858 dcmd->flags = MFI_FRAME_DIR_NONE;
3859 dcmd->timeout = 0;
Yang, Bo780a3762009-12-06 08:24:21 -07003860 dcmd->pad_0 = 0;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003861 dcmd->data_xfer_len = 0;
3862 dcmd->opcode = MR_DCMD_CTRL_CACHE_FLUSH;
3863 dcmd->mbox.b[0] = MR_FLUSH_CTRL_CACHE | MR_FLUSH_DISK_CACHE;
3864
3865 megasas_issue_blocked_cmd(instance, cmd);
3866
3867 megasas_return_cmd(instance, cmd);
3868
3869 return;
3870}
3871
3872/**
3873 * megasas_shutdown_controller - Instructs FW to shutdown the controller
3874 * @instance: Adapter soft state
bo yang31ea7082007-11-07 12:09:50 -05003875 * @opcode: Shutdown/Hibernate
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003876 */
bo yang31ea7082007-11-07 12:09:50 -05003877static void megasas_shutdown_controller(struct megasas_instance *instance,
3878 u32 opcode)
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003879{
3880 struct megasas_cmd *cmd;
3881 struct megasas_dcmd_frame *dcmd;
3882
bo yang39a98552010-09-22 22:36:29 -04003883 if (instance->adprecovery == MEGASAS_HW_CRITICAL_ERROR)
3884 return;
3885
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003886 cmd = megasas_get_cmd(instance);
3887
3888 if (!cmd)
3889 return;
3890
3891 if (instance->aen_cmd)
3892 megasas_issue_blocked_abort_cmd(instance, instance->aen_cmd);
3893
3894 dcmd = &cmd->frame->dcmd;
3895
3896 memset(dcmd->mbox.b, 0, MFI_MBOX_SIZE);
3897
3898 dcmd->cmd = MFI_CMD_DCMD;
3899 dcmd->cmd_status = 0x0;
3900 dcmd->sge_count = 0;
3901 dcmd->flags = MFI_FRAME_DIR_NONE;
3902 dcmd->timeout = 0;
Yang, Bo780a3762009-12-06 08:24:21 -07003903 dcmd->pad_0 = 0;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003904 dcmd->data_xfer_len = 0;
bo yang31ea7082007-11-07 12:09:50 -05003905 dcmd->opcode = opcode;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003906
3907 megasas_issue_blocked_cmd(instance, cmd);
3908
3909 megasas_return_cmd(instance, cmd);
3910
3911 return;
3912}
3913
Jiri Slaby33139b22008-05-01 17:56:02 +02003914#ifdef CONFIG_PM
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003915/**
bo yangad84db22007-11-09 04:40:16 -05003916 * megasas_suspend - driver suspend entry point
3917 * @pdev: PCI device structure
bo yang31ea7082007-11-07 12:09:50 -05003918 * @state: PCI power state to suspend routine
3919 */
Jiri Slaby33139b22008-05-01 17:56:02 +02003920static int
bo yang31ea7082007-11-07 12:09:50 -05003921megasas_suspend(struct pci_dev *pdev, pm_message_t state)
3922{
3923 struct Scsi_Host *host;
3924 struct megasas_instance *instance;
3925
3926 instance = pci_get_drvdata(pdev);
3927 host = instance->host;
Yang, Bo0c79e682009-10-06 14:47:35 -06003928 instance->unload = 1;
bo yang31ea7082007-11-07 12:09:50 -05003929
bo yangad84db22007-11-09 04:40:16 -05003930 if (poll_mode_io)
3931 del_timer_sync(&instance->io_completion_timer);
3932
bo yang31ea7082007-11-07 12:09:50 -05003933 megasas_flush_cache(instance);
3934 megasas_shutdown_controller(instance, MR_DCMD_HIBERNATE_SHUTDOWN);
Yang, Bo7e8a75f2009-10-06 14:50:17 -06003935
3936 /* cancel the delayed work if this work still in queue */
3937 if (instance->ev != NULL) {
3938 struct megasas_aen_event *ev = instance->ev;
3939 cancel_delayed_work(
3940 (struct delayed_work *)&ev->hotplug_work);
3941 flush_scheduled_work();
3942 instance->ev = NULL;
3943 }
3944
bo yang31ea7082007-11-07 12:09:50 -05003945 tasklet_kill(&instance->isr_tasklet);
3946
3947 pci_set_drvdata(instance->pdev, instance);
3948 instance->instancet->disable_intr(instance->reg_set);
3949 free_irq(instance->pdev->irq, instance);
3950
3951 pci_save_state(pdev);
3952 pci_disable_device(pdev);
3953
3954 pci_set_power_state(pdev, pci_choose_state(pdev, state));
3955
3956 return 0;
3957}
3958
3959/**
3960 * megasas_resume- driver resume entry point
3961 * @pdev: PCI device structure
3962 */
Jiri Slaby33139b22008-05-01 17:56:02 +02003963static int
bo yang31ea7082007-11-07 12:09:50 -05003964megasas_resume(struct pci_dev *pdev)
3965{
3966 int rval;
3967 struct Scsi_Host *host;
3968 struct megasas_instance *instance;
3969
3970 instance = pci_get_drvdata(pdev);
3971 host = instance->host;
3972 pci_set_power_state(pdev, PCI_D0);
3973 pci_enable_wake(pdev, PCI_D0, 0);
3974 pci_restore_state(pdev);
3975
3976 /*
3977 * PCI prepping: enable device set bus mastering and dma mask
3978 */
Noriyuki Fujiiaeab3fd2009-11-20 16:27:20 +09003979 rval = pci_enable_device_mem(pdev);
bo yang31ea7082007-11-07 12:09:50 -05003980
3981 if (rval) {
3982 printk(KERN_ERR "megasas: Enable device failed\n");
3983 return rval;
3984 }
3985
3986 pci_set_master(pdev);
3987
3988 if (megasas_set_dma_mask(pdev))
3989 goto fail_set_dma_mask;
3990
3991 /*
3992 * Initialize MFI Firmware
3993 */
3994
3995 *instance->producer = 0;
3996 *instance->consumer = 0;
3997
3998 atomic_set(&instance->fw_outstanding, 0);
3999
4000 /*
4001 * We expect the FW state to be READY
4002 */
4003 if (megasas_transition_to_ready(instance))
4004 goto fail_ready_state;
4005
4006 if (megasas_issue_init_mfi(instance))
4007 goto fail_init_mfi;
4008
4009 tasklet_init(&instance->isr_tasklet, megasas_complete_cmd_dpc,
4010 (unsigned long)instance);
4011
4012 /*
4013 * Register IRQ
4014 */
4015 if (request_irq(pdev->irq, megasas_isr, IRQF_SHARED,
4016 "megasas", instance)) {
4017 printk(KERN_ERR "megasas: Failed to register IRQ\n");
4018 goto fail_irq;
4019 }
4020
4021 instance->instancet->enable_intr(instance->reg_set);
4022
4023 /*
4024 * Initiate AEN (Asynchronous Event Notification)
4025 */
4026 if (megasas_start_aen(instance))
4027 printk(KERN_ERR "megasas: Start AEN failed\n");
4028
bo yangad84db22007-11-09 04:40:16 -05004029 /* Initialize the cmd completion timer */
4030 if (poll_mode_io)
4031 megasas_start_timer(instance, &instance->io_completion_timer,
4032 megasas_io_completion_timer,
4033 MEGASAS_COMPLETION_TIMER_INTERVAL);
Yang, Bo0c79e682009-10-06 14:47:35 -06004034 instance->unload = 0;
4035
bo yang31ea7082007-11-07 12:09:50 -05004036 return 0;
4037
4038fail_irq:
4039fail_init_mfi:
4040 if (instance->evt_detail)
4041 pci_free_consistent(pdev, sizeof(struct megasas_evt_detail),
4042 instance->evt_detail,
4043 instance->evt_detail_h);
4044
4045 if (instance->producer)
4046 pci_free_consistent(pdev, sizeof(u32), instance->producer,
4047 instance->producer_h);
4048 if (instance->consumer)
4049 pci_free_consistent(pdev, sizeof(u32), instance->consumer,
4050 instance->consumer_h);
4051 scsi_host_put(host);
4052
4053fail_set_dma_mask:
4054fail_ready_state:
4055
4056 pci_disable_device(pdev);
4057
4058 return -ENODEV;
4059}
Jiri Slaby33139b22008-05-01 17:56:02 +02004060#else
4061#define megasas_suspend NULL
4062#define megasas_resume NULL
4063#endif
bo yang31ea7082007-11-07 12:09:50 -05004064
4065/**
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004066 * megasas_detach_one - PCI hot"un"plug entry point
4067 * @pdev: PCI device structure
4068 */
Jiri Slaby33139b22008-05-01 17:56:02 +02004069static void __devexit megasas_detach_one(struct pci_dev *pdev)
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004070{
4071 int i;
4072 struct Scsi_Host *host;
4073 struct megasas_instance *instance;
4074
4075 instance = pci_get_drvdata(pdev);
Yang, Boc3518832009-10-06 14:18:02 -06004076 instance->unload = 1;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004077 host = instance->host;
4078
bo yangad84db22007-11-09 04:40:16 -05004079 if (poll_mode_io)
4080 del_timer_sync(&instance->io_completion_timer);
4081
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004082 scsi_remove_host(instance->host);
4083 megasas_flush_cache(instance);
bo yang31ea7082007-11-07 12:09:50 -05004084 megasas_shutdown_controller(instance, MR_DCMD_CTRL_SHUTDOWN);
Yang, Bo7e8a75f2009-10-06 14:50:17 -06004085
4086 /* cancel the delayed work if this work still in queue*/
4087 if (instance->ev != NULL) {
4088 struct megasas_aen_event *ev = instance->ev;
4089 cancel_delayed_work(
4090 (struct delayed_work *)&ev->hotplug_work);
4091 flush_scheduled_work();
4092 instance->ev = NULL;
4093 }
4094
Sumant Patro5d018ad2006-10-03 13:13:18 -07004095 tasklet_kill(&instance->isr_tasklet);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004096
4097 /*
4098 * Take the instance off the instance array. Note that we will not
4099 * decrement the max_index. We let this array be sparse array
4100 */
4101 for (i = 0; i < megasas_mgmt_info.max_index; i++) {
4102 if (megasas_mgmt_info.instance[i] == instance) {
4103 megasas_mgmt_info.count--;
4104 megasas_mgmt_info.instance[i] = NULL;
4105
4106 break;
4107 }
4108 }
4109
4110 pci_set_drvdata(instance->pdev, NULL);
4111
Sumant Patrob274cab2006-10-03 12:52:12 -07004112 instance->instancet->disable_intr(instance->reg_set);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004113
4114 free_irq(instance->pdev->irq, instance);
4115
4116 megasas_release_mfi(instance);
4117
4118 pci_free_consistent(pdev, sizeof(struct megasas_evt_detail),
4119 instance->evt_detail, instance->evt_detail_h);
4120
4121 pci_free_consistent(pdev, sizeof(u32), instance->producer,
4122 instance->producer_h);
4123
4124 pci_free_consistent(pdev, sizeof(u32), instance->consumer,
4125 instance->consumer_h);
4126
4127 scsi_host_put(host);
4128
4129 pci_set_drvdata(pdev, NULL);
4130
4131 pci_disable_device(pdev);
4132
4133 return;
4134}
4135
4136/**
4137 * megasas_shutdown - Shutdown entry point
4138 * @device: Generic device structure
4139 */
4140static void megasas_shutdown(struct pci_dev *pdev)
4141{
4142 struct megasas_instance *instance = pci_get_drvdata(pdev);
Yang, Bo0c79e682009-10-06 14:47:35 -06004143 instance->unload = 1;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004144 megasas_flush_cache(instance);
Yang, Bo530e6fc2008-08-10 12:42:37 -07004145 megasas_shutdown_controller(instance, MR_DCMD_CTRL_SHUTDOWN);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004146}
4147
4148/**
4149 * megasas_mgmt_open - char node "open" entry point
4150 */
4151static int megasas_mgmt_open(struct inode *inode, struct file *filep)
4152{
4153 /*
4154 * Allow only those users with admin rights
4155 */
4156 if (!capable(CAP_SYS_ADMIN))
4157 return -EACCES;
4158
4159 return 0;
4160}
4161
4162/**
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004163 * megasas_mgmt_fasync - Async notifier registration from applications
4164 *
4165 * This function adds the calling process to a driver global queue. When an
4166 * event occurs, SIGIO will be sent to all processes in this queue.
4167 */
4168static int megasas_mgmt_fasync(int fd, struct file *filep, int mode)
4169{
4170 int rc;
4171
Arjan van de Ven0b950672006-01-11 13:16:10 +01004172 mutex_lock(&megasas_async_queue_mutex);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004173
4174 rc = fasync_helper(fd, filep, mode, &megasas_async_queue);
4175
Arjan van de Ven0b950672006-01-11 13:16:10 +01004176 mutex_unlock(&megasas_async_queue_mutex);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004177
4178 if (rc >= 0) {
4179 /* For sanity check when we get ioctl */
4180 filep->private_data = filep;
4181 return 0;
4182 }
4183
4184 printk(KERN_DEBUG "megasas: fasync_helper failed [%d]\n", rc);
4185
4186 return rc;
4187}
4188
4189/**
Yang, Boc3518832009-10-06 14:18:02 -06004190 * megasas_mgmt_poll - char node "poll" entry point
4191 * */
4192static unsigned int megasas_mgmt_poll(struct file *file, poll_table *wait)
4193{
4194 unsigned int mask;
4195 unsigned long flags;
4196 poll_wait(file, &megasas_poll_wait, wait);
4197 spin_lock_irqsave(&poll_aen_lock, flags);
4198 if (megasas_poll_wait_aen)
4199 mask = (POLLIN | POLLRDNORM);
4200 else
4201 mask = 0;
4202 spin_unlock_irqrestore(&poll_aen_lock, flags);
4203 return mask;
4204}
4205
4206/**
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004207 * megasas_mgmt_fw_ioctl - Issues management ioctls to FW
4208 * @instance: Adapter soft state
4209 * @argp: User's ioctl packet
4210 */
4211static int
4212megasas_mgmt_fw_ioctl(struct megasas_instance *instance,
4213 struct megasas_iocpacket __user * user_ioc,
4214 struct megasas_iocpacket *ioc)
4215{
4216 struct megasas_sge32 *kern_sge32;
4217 struct megasas_cmd *cmd;
4218 void *kbuff_arr[MAX_IOCTL_SGE];
4219 dma_addr_t buf_handle = 0;
4220 int error = 0, i;
4221 void *sense = NULL;
4222 dma_addr_t sense_handle;
Yang, Bo7b2519a2009-10-06 14:52:20 -06004223 unsigned long *sense_ptr;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004224
4225 memset(kbuff_arr, 0, sizeof(kbuff_arr));
4226
4227 if (ioc->sge_count > MAX_IOCTL_SGE) {
4228 printk(KERN_DEBUG "megasas: SGE count [%d] > max limit [%d]\n",
4229 ioc->sge_count, MAX_IOCTL_SGE);
4230 return -EINVAL;
4231 }
4232
4233 cmd = megasas_get_cmd(instance);
4234 if (!cmd) {
4235 printk(KERN_DEBUG "megasas: Failed to get a cmd packet\n");
4236 return -ENOMEM;
4237 }
4238
4239 /*
4240 * User's IOCTL packet has 2 frames (maximum). Copy those two
4241 * frames into our cmd's frames. cmd->frame's context will get
4242 * overwritten when we copy from user's frames. So set that value
4243 * alone separately
4244 */
4245 memcpy(cmd->frame, ioc->frame.raw, 2 * MEGAMFI_FRAME_SIZE);
4246 cmd->frame->hdr.context = cmd->index;
Yang, Boc3518832009-10-06 14:18:02 -06004247 cmd->frame->hdr.pad_0 = 0;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004248
4249 /*
4250 * The management interface between applications and the fw uses
4251 * MFI frames. E.g, RAID configuration changes, LD property changes
4252 * etc are accomplishes through different kinds of MFI frames. The
4253 * driver needs to care only about substituting user buffers with
4254 * kernel buffers in SGLs. The location of SGL is embedded in the
4255 * struct iocpacket itself.
4256 */
4257 kern_sge32 = (struct megasas_sge32 *)
4258 ((unsigned long)cmd->frame + ioc->sgl_off);
4259
4260 /*
4261 * For each user buffer, create a mirror buffer and copy in
4262 */
4263 for (i = 0; i < ioc->sge_count; i++) {
Sumant Patro9f35fa8a2007-02-14 12:55:45 -08004264 kbuff_arr[i] = dma_alloc_coherent(&instance->pdev->dev,
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004265 ioc->sgl[i].iov_len,
Sumant Patro9f35fa8a2007-02-14 12:55:45 -08004266 &buf_handle, GFP_KERNEL);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004267 if (!kbuff_arr[i]) {
4268 printk(KERN_DEBUG "megasas: Failed to alloc "
4269 "kernel SGL buffer for IOCTL \n");
4270 error = -ENOMEM;
4271 goto out;
4272 }
4273
4274 /*
4275 * We don't change the dma_coherent_mask, so
4276 * pci_alloc_consistent only returns 32bit addresses
4277 */
4278 kern_sge32[i].phys_addr = (u32) buf_handle;
4279 kern_sge32[i].length = ioc->sgl[i].iov_len;
4280
4281 /*
4282 * We created a kernel buffer corresponding to the
4283 * user buffer. Now copy in from the user buffer
4284 */
4285 if (copy_from_user(kbuff_arr[i], ioc->sgl[i].iov_base,
4286 (u32) (ioc->sgl[i].iov_len))) {
4287 error = -EFAULT;
4288 goto out;
4289 }
4290 }
4291
4292 if (ioc->sense_len) {
Sumant Patro9f35fa8a2007-02-14 12:55:45 -08004293 sense = dma_alloc_coherent(&instance->pdev->dev, ioc->sense_len,
4294 &sense_handle, GFP_KERNEL);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004295 if (!sense) {
4296 error = -ENOMEM;
4297 goto out;
4298 }
4299
4300 sense_ptr =
Yang, Bo7b2519a2009-10-06 14:52:20 -06004301 (unsigned long *) ((unsigned long)cmd->frame + ioc->sense_off);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004302 *sense_ptr = sense_handle;
4303 }
4304
4305 /*
4306 * Set the sync_cmd flag so that the ISR knows not to complete this
4307 * cmd to the SCSI mid-layer
4308 */
4309 cmd->sync_cmd = 1;
4310 megasas_issue_blocked_cmd(instance, cmd);
4311 cmd->sync_cmd = 0;
4312
4313 /*
4314 * copy out the kernel buffers to user buffers
4315 */
4316 for (i = 0; i < ioc->sge_count; i++) {
4317 if (copy_to_user(ioc->sgl[i].iov_base, kbuff_arr[i],
4318 ioc->sgl[i].iov_len)) {
4319 error = -EFAULT;
4320 goto out;
4321 }
4322 }
4323
4324 /*
4325 * copy out the sense
4326 */
4327 if (ioc->sense_len) {
4328 /*
bo yangb70a41e2008-03-18 03:13:06 -04004329 * sense_ptr points to the location that has the user
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004330 * sense buffer address
4331 */
Yang, Bo7b2519a2009-10-06 14:52:20 -06004332 sense_ptr = (unsigned long *) ((unsigned long)ioc->frame.raw +
4333 ioc->sense_off);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004334
bo yangb70a41e2008-03-18 03:13:06 -04004335 if (copy_to_user((void __user *)((unsigned long)(*sense_ptr)),
4336 sense, ioc->sense_len)) {
bo yangb10c36a2007-11-09 04:28:47 -05004337 printk(KERN_ERR "megasas: Failed to copy out to user "
4338 "sense data\n");
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004339 error = -EFAULT;
4340 goto out;
4341 }
4342 }
4343
4344 /*
4345 * copy the status codes returned by the fw
4346 */
4347 if (copy_to_user(&user_ioc->frame.hdr.cmd_status,
4348 &cmd->frame->hdr.cmd_status, sizeof(u8))) {
4349 printk(KERN_DEBUG "megasas: Error copying out cmd_status\n");
4350 error = -EFAULT;
4351 }
4352
4353 out:
4354 if (sense) {
Sumant Patro9f35fa8a2007-02-14 12:55:45 -08004355 dma_free_coherent(&instance->pdev->dev, ioc->sense_len,
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004356 sense, sense_handle);
4357 }
4358
4359 for (i = 0; i < ioc->sge_count && kbuff_arr[i]; i++) {
Sumant Patro9f35fa8a2007-02-14 12:55:45 -08004360 dma_free_coherent(&instance->pdev->dev,
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004361 kern_sge32[i].length,
4362 kbuff_arr[i], kern_sge32[i].phys_addr);
4363 }
4364
4365 megasas_return_cmd(instance, cmd);
4366 return error;
4367}
4368
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004369static int megasas_mgmt_ioctl_fw(struct file *file, unsigned long arg)
4370{
4371 struct megasas_iocpacket __user *user_ioc =
4372 (struct megasas_iocpacket __user *)arg;
4373 struct megasas_iocpacket *ioc;
4374 struct megasas_instance *instance;
4375 int error;
bo yang39a98552010-09-22 22:36:29 -04004376 int i;
4377 unsigned long flags;
4378 u32 wait_time = MEGASAS_RESET_WAIT_TIME;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004379
4380 ioc = kmalloc(sizeof(*ioc), GFP_KERNEL);
4381 if (!ioc)
4382 return -ENOMEM;
4383
4384 if (copy_from_user(ioc, user_ioc, sizeof(*ioc))) {
4385 error = -EFAULT;
4386 goto out_kfree_ioc;
4387 }
4388
4389 instance = megasas_lookup_instance(ioc->host_no);
4390 if (!instance) {
4391 error = -ENODEV;
4392 goto out_kfree_ioc;
4393 }
4394
bo yang39a98552010-09-22 22:36:29 -04004395 if (instance->adprecovery == MEGASAS_HW_CRITICAL_ERROR) {
4396 printk(KERN_ERR "Controller in crit error\n");
Yang, Bo0c79e682009-10-06 14:47:35 -06004397 error = -ENODEV;
4398 goto out_kfree_ioc;
4399 }
4400
4401 if (instance->unload == 1) {
4402 error = -ENODEV;
4403 goto out_kfree_ioc;
4404 }
4405
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004406 /*
4407 * We will allow only MEGASAS_INT_CMDS number of parallel ioctl cmds
4408 */
4409 if (down_interruptible(&instance->ioctl_sem)) {
4410 error = -ERESTARTSYS;
4411 goto out_kfree_ioc;
4412 }
bo yang39a98552010-09-22 22:36:29 -04004413
4414 for (i = 0; i < wait_time; i++) {
4415
4416 spin_lock_irqsave(&instance->hba_lock, flags);
4417 if (instance->adprecovery == MEGASAS_HBA_OPERATIONAL) {
4418 spin_unlock_irqrestore(&instance->hba_lock, flags);
4419 break;
4420 }
4421 spin_unlock_irqrestore(&instance->hba_lock, flags);
4422
4423 if (!(i % MEGASAS_RESET_NOTICE_INTERVAL)) {
4424 printk(KERN_NOTICE "megasas: waiting"
4425 "for controller reset to finish\n");
4426 }
4427
4428 msleep(1000);
4429 }
4430
4431 spin_lock_irqsave(&instance->hba_lock, flags);
4432 if (instance->adprecovery != MEGASAS_HBA_OPERATIONAL) {
4433 spin_unlock_irqrestore(&instance->hba_lock, flags);
4434
4435 printk(KERN_ERR "megaraid_sas: timed out while"
4436 "waiting for HBA to recover\n");
4437 error = -ENODEV;
4438 goto out_kfree_ioc;
4439 }
4440 spin_unlock_irqrestore(&instance->hba_lock, flags);
4441
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004442 error = megasas_mgmt_fw_ioctl(instance, user_ioc, ioc);
4443 up(&instance->ioctl_sem);
4444
4445 out_kfree_ioc:
4446 kfree(ioc);
4447 return error;
4448}
4449
4450static int megasas_mgmt_ioctl_aen(struct file *file, unsigned long arg)
4451{
4452 struct megasas_instance *instance;
4453 struct megasas_aen aen;
4454 int error;
bo yang39a98552010-09-22 22:36:29 -04004455 int i;
4456 unsigned long flags;
4457 u32 wait_time = MEGASAS_RESET_WAIT_TIME;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004458
4459 if (file->private_data != file) {
4460 printk(KERN_DEBUG "megasas: fasync_helper was not "
4461 "called first\n");
4462 return -EINVAL;
4463 }
4464
4465 if (copy_from_user(&aen, (void __user *)arg, sizeof(aen)))
4466 return -EFAULT;
4467
4468 instance = megasas_lookup_instance(aen.host_no);
4469
4470 if (!instance)
4471 return -ENODEV;
4472
bo yang39a98552010-09-22 22:36:29 -04004473 if (instance->adprecovery == MEGASAS_HW_CRITICAL_ERROR) {
4474 return -ENODEV;
Yang, Bo0c79e682009-10-06 14:47:35 -06004475 }
4476
4477 if (instance->unload == 1) {
4478 return -ENODEV;
4479 }
4480
bo yang39a98552010-09-22 22:36:29 -04004481 for (i = 0; i < wait_time; i++) {
4482
4483 spin_lock_irqsave(&instance->hba_lock, flags);
4484 if (instance->adprecovery == MEGASAS_HBA_OPERATIONAL) {
4485 spin_unlock_irqrestore(&instance->hba_lock,
4486 flags);
4487 break;
4488 }
4489
4490 spin_unlock_irqrestore(&instance->hba_lock, flags);
4491
4492 if (!(i % MEGASAS_RESET_NOTICE_INTERVAL)) {
4493 printk(KERN_NOTICE "megasas: waiting for"
4494 "controller reset to finish\n");
4495 }
4496
4497 msleep(1000);
4498 }
4499
4500 spin_lock_irqsave(&instance->hba_lock, flags);
4501 if (instance->adprecovery != MEGASAS_HBA_OPERATIONAL) {
4502 spin_unlock_irqrestore(&instance->hba_lock, flags);
4503 printk(KERN_ERR "megaraid_sas: timed out while waiting"
4504 "for HBA to recover.\n");
4505 return -ENODEV;
4506 }
4507 spin_unlock_irqrestore(&instance->hba_lock, flags);
4508
Matthias Kaehlckee5a69e22007-10-27 09:48:46 +02004509 mutex_lock(&instance->aen_mutex);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004510 error = megasas_register_aen(instance, aen.seq_num,
4511 aen.class_locale_word);
Matthias Kaehlckee5a69e22007-10-27 09:48:46 +02004512 mutex_unlock(&instance->aen_mutex);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004513 return error;
4514}
4515
4516/**
4517 * megasas_mgmt_ioctl - char node ioctl entry point
4518 */
4519static long
4520megasas_mgmt_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
4521{
4522 switch (cmd) {
4523 case MEGASAS_IOC_FIRMWARE:
4524 return megasas_mgmt_ioctl_fw(file, arg);
4525
4526 case MEGASAS_IOC_GET_AEN:
4527 return megasas_mgmt_ioctl_aen(file, arg);
4528 }
4529
4530 return -ENOTTY;
4531}
4532
4533#ifdef CONFIG_COMPAT
4534static int megasas_mgmt_compat_ioctl_fw(struct file *file, unsigned long arg)
4535{
4536 struct compat_megasas_iocpacket __user *cioc =
4537 (struct compat_megasas_iocpacket __user *)arg;
4538 struct megasas_iocpacket __user *ioc =
4539 compat_alloc_user_space(sizeof(struct megasas_iocpacket));
4540 int i;
4541 int error = 0;
Tomas Henzlb3dc1a22010-02-11 18:01:50 +01004542 compat_uptr_t ptr;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004543
Jeff Garzik83aabc12006-10-04 06:34:03 -04004544 if (clear_user(ioc, sizeof(*ioc)))
4545 return -EFAULT;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004546
4547 if (copy_in_user(&ioc->host_no, &cioc->host_no, sizeof(u16)) ||
4548 copy_in_user(&ioc->sgl_off, &cioc->sgl_off, sizeof(u32)) ||
4549 copy_in_user(&ioc->sense_off, &cioc->sense_off, sizeof(u32)) ||
4550 copy_in_user(&ioc->sense_len, &cioc->sense_len, sizeof(u32)) ||
4551 copy_in_user(ioc->frame.raw, cioc->frame.raw, 128) ||
4552 copy_in_user(&ioc->sge_count, &cioc->sge_count, sizeof(u32)))
4553 return -EFAULT;
4554
Tomas Henzlb3dc1a22010-02-11 18:01:50 +01004555 /*
4556 * The sense_ptr is used in megasas_mgmt_fw_ioctl only when
4557 * sense_len is not null, so prepare the 64bit value under
4558 * the same condition.
4559 */
4560 if (ioc->sense_len) {
4561 void __user **sense_ioc_ptr =
4562 (void __user **)(ioc->frame.raw + ioc->sense_off);
4563 compat_uptr_t *sense_cioc_ptr =
4564 (compat_uptr_t *)(cioc->frame.raw + cioc->sense_off);
4565 if (get_user(ptr, sense_cioc_ptr) ||
4566 put_user(compat_ptr(ptr), sense_ioc_ptr))
4567 return -EFAULT;
4568 }
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004569
Tomas Henzlb3dc1a22010-02-11 18:01:50 +01004570 for (i = 0; i < MAX_IOCTL_SGE; i++) {
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004571 if (get_user(ptr, &cioc->sgl[i].iov_base) ||
4572 put_user(compat_ptr(ptr), &ioc->sgl[i].iov_base) ||
4573 copy_in_user(&ioc->sgl[i].iov_len,
4574 &cioc->sgl[i].iov_len, sizeof(compat_size_t)))
4575 return -EFAULT;
4576 }
4577
4578 error = megasas_mgmt_ioctl_fw(file, (unsigned long)ioc);
4579
4580 if (copy_in_user(&cioc->frame.hdr.cmd_status,
4581 &ioc->frame.hdr.cmd_status, sizeof(u8))) {
4582 printk(KERN_DEBUG "megasas: error copy_in_user cmd_status\n");
4583 return -EFAULT;
4584 }
4585 return error;
4586}
4587
4588static long
4589megasas_mgmt_compat_ioctl(struct file *file, unsigned int cmd,
4590 unsigned long arg)
4591{
4592 switch (cmd) {
Sumant Patrocb59aa62006-01-25 11:53:25 -08004593 case MEGASAS_IOC_FIRMWARE32:
4594 return megasas_mgmt_compat_ioctl_fw(file, arg);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004595 case MEGASAS_IOC_GET_AEN:
4596 return megasas_mgmt_ioctl_aen(file, arg);
4597 }
4598
4599 return -ENOTTY;
4600}
4601#endif
4602
4603/*
4604 * File operations structure for management interface
4605 */
Arjan van de Ven00977a52007-02-12 00:55:34 -08004606static const struct file_operations megasas_mgmt_fops = {
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004607 .owner = THIS_MODULE,
4608 .open = megasas_mgmt_open,
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004609 .fasync = megasas_mgmt_fasync,
4610 .unlocked_ioctl = megasas_mgmt_ioctl,
Yang, Boc3518832009-10-06 14:18:02 -06004611 .poll = megasas_mgmt_poll,
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004612#ifdef CONFIG_COMPAT
4613 .compat_ioctl = megasas_mgmt_compat_ioctl,
4614#endif
Arnd Bergmann6038f372010-08-15 18:52:59 +02004615 .llseek = noop_llseek,
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004616};
4617
4618/*
4619 * PCI hotplug support registration structure
4620 */
4621static struct pci_driver megasas_pci_driver = {
4622
4623 .name = "megaraid_sas",
4624 .id_table = megasas_pci_table,
4625 .probe = megasas_probe_one,
4626 .remove = __devexit_p(megasas_detach_one),
bo yang31ea7082007-11-07 12:09:50 -05004627 .suspend = megasas_suspend,
4628 .resume = megasas_resume,
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004629 .shutdown = megasas_shutdown,
4630};
4631
4632/*
4633 * Sysfs driver attributes
4634 */
4635static ssize_t megasas_sysfs_show_version(struct device_driver *dd, char *buf)
4636{
4637 return snprintf(buf, strlen(MEGASAS_VERSION) + 2, "%s\n",
4638 MEGASAS_VERSION);
4639}
4640
4641static DRIVER_ATTR(version, S_IRUGO, megasas_sysfs_show_version, NULL);
4642
4643static ssize_t
4644megasas_sysfs_show_release_date(struct device_driver *dd, char *buf)
4645{
4646 return snprintf(buf, strlen(MEGASAS_RELDATE) + 2, "%s\n",
4647 MEGASAS_RELDATE);
4648}
4649
4650static DRIVER_ATTR(release_date, S_IRUGO, megasas_sysfs_show_release_date,
4651 NULL);
4652
Sumant Patro658dced2006-10-03 13:09:14 -07004653static ssize_t
Yang, Bo72c4fd32009-10-06 14:20:59 -06004654megasas_sysfs_show_support_poll_for_event(struct device_driver *dd, char *buf)
4655{
4656 return sprintf(buf, "%u\n", support_poll_for_event);
4657}
4658
4659static DRIVER_ATTR(support_poll_for_event, S_IRUGO,
4660 megasas_sysfs_show_support_poll_for_event, NULL);
4661
Yang, Bo837f5fe2010-10-11 06:59:20 -06004662 static ssize_t
4663megasas_sysfs_show_support_device_change(struct device_driver *dd, char *buf)
4664{
4665 return sprintf(buf, "%u\n", support_device_change);
4666}
4667
4668static DRIVER_ATTR(support_device_change, S_IRUGO,
4669 megasas_sysfs_show_support_device_change, NULL);
4670
Yang, Bo72c4fd32009-10-06 14:20:59 -06004671static ssize_t
Sumant Patro658dced2006-10-03 13:09:14 -07004672megasas_sysfs_show_dbg_lvl(struct device_driver *dd, char *buf)
4673{
bo yangad84db22007-11-09 04:40:16 -05004674 return sprintf(buf, "%u\n", megasas_dbg_lvl);
Sumant Patro658dced2006-10-03 13:09:14 -07004675}
4676
4677static ssize_t
4678megasas_sysfs_set_dbg_lvl(struct device_driver *dd, const char *buf, size_t count)
4679{
4680 int retval = count;
4681 if(sscanf(buf,"%u",&megasas_dbg_lvl)<1){
4682 printk(KERN_ERR "megasas: could not set dbg_lvl\n");
4683 retval = -EINVAL;
4684 }
4685 return retval;
4686}
4687
Joe Malicki66dca9b2008-08-14 17:14:48 -04004688static DRIVER_ATTR(dbg_lvl, S_IRUGO|S_IWUSR, megasas_sysfs_show_dbg_lvl,
bo yangad84db22007-11-09 04:40:16 -05004689 megasas_sysfs_set_dbg_lvl);
4690
4691static ssize_t
4692megasas_sysfs_show_poll_mode_io(struct device_driver *dd, char *buf)
4693{
4694 return sprintf(buf, "%u\n", poll_mode_io);
4695}
4696
4697static ssize_t
4698megasas_sysfs_set_poll_mode_io(struct device_driver *dd,
4699 const char *buf, size_t count)
4700{
4701 int retval = count;
4702 int tmp = poll_mode_io;
4703 int i;
4704 struct megasas_instance *instance;
4705
4706 if (sscanf(buf, "%u", &poll_mode_io) < 1) {
4707 printk(KERN_ERR "megasas: could not set poll_mode_io\n");
4708 retval = -EINVAL;
4709 }
4710
4711 /*
4712 * Check if poll_mode_io is already set or is same as previous value
4713 */
4714 if ((tmp && poll_mode_io) || (tmp == poll_mode_io))
4715 goto out;
4716
4717 if (poll_mode_io) {
4718 /*
4719 * Start timers for all adapters
4720 */
4721 for (i = 0; i < megasas_mgmt_info.max_index; i++) {
4722 instance = megasas_mgmt_info.instance[i];
4723 if (instance) {
4724 megasas_start_timer(instance,
4725 &instance->io_completion_timer,
4726 megasas_io_completion_timer,
4727 MEGASAS_COMPLETION_TIMER_INTERVAL);
4728 }
4729 }
4730 } else {
4731 /*
4732 * Delete timers for all adapters
4733 */
4734 for (i = 0; i < megasas_mgmt_info.max_index; i++) {
4735 instance = megasas_mgmt_info.instance[i];
4736 if (instance)
4737 del_timer_sync(&instance->io_completion_timer);
4738 }
4739 }
4740
4741out:
4742 return retval;
4743}
4744
Yang, Bo7e8a75f2009-10-06 14:50:17 -06004745static void
4746megasas_aen_polling(struct work_struct *work)
4747{
4748 struct megasas_aen_event *ev =
4749 container_of(work, struct megasas_aen_event, hotplug_work);
4750 struct megasas_instance *instance = ev->instance;
4751 union megasas_evt_class_locale class_locale;
4752 struct Scsi_Host *host;
4753 struct scsi_device *sdev1;
4754 u16 pd_index = 0;
Yang, Boc9786842009-12-06 08:39:25 -07004755 u16 ld_index = 0;
Yang, Bo7e8a75f2009-10-06 14:50:17 -06004756 int i, j, doscan = 0;
4757 u32 seq_num;
4758 int error;
4759
4760 if (!instance) {
4761 printk(KERN_ERR "invalid instance!\n");
4762 kfree(ev);
4763 return;
4764 }
4765 instance->ev = NULL;
4766 host = instance->host;
4767 if (instance->evt_detail) {
4768
4769 switch (instance->evt_detail->code) {
4770 case MR_EVT_PD_INSERTED:
Yang, Boc9786842009-12-06 08:39:25 -07004771 if (megasas_get_pd_list(instance) == 0) {
4772 for (i = 0; i < MEGASAS_MAX_PD_CHANNELS; i++) {
4773 for (j = 0;
4774 j < MEGASAS_MAX_DEV_PER_CHANNEL;
4775 j++) {
4776
4777 pd_index =
4778 (i * MEGASAS_MAX_DEV_PER_CHANNEL) + j;
4779
4780 sdev1 =
4781 scsi_device_lookup(host, i, j, 0);
4782
4783 if (instance->pd_list[pd_index].driveState
4784 == MR_PD_STATE_SYSTEM) {
4785 if (!sdev1) {
4786 scsi_add_device(host, i, j, 0);
4787 }
4788
4789 if (sdev1)
4790 scsi_device_put(sdev1);
4791 }
4792 }
4793 }
4794 }
4795 doscan = 0;
4796 break;
4797
Yang, Bo7e8a75f2009-10-06 14:50:17 -06004798 case MR_EVT_PD_REMOVED:
Yang, Boc9786842009-12-06 08:39:25 -07004799 if (megasas_get_pd_list(instance) == 0) {
4800 megasas_get_pd_list(instance);
4801 for (i = 0; i < MEGASAS_MAX_PD_CHANNELS; i++) {
4802 for (j = 0;
4803 j < MEGASAS_MAX_DEV_PER_CHANNEL;
4804 j++) {
4805
4806 pd_index =
4807 (i * MEGASAS_MAX_DEV_PER_CHANNEL) + j;
4808
4809 sdev1 =
4810 scsi_device_lookup(host, i, j, 0);
4811
4812 if (instance->pd_list[pd_index].driveState
4813 == MR_PD_STATE_SYSTEM) {
4814 if (sdev1) {
4815 scsi_device_put(sdev1);
4816 }
4817 } else {
4818 if (sdev1) {
4819 scsi_remove_device(sdev1);
4820 scsi_device_put(sdev1);
4821 }
4822 }
4823 }
4824 }
4825 }
4826 doscan = 0;
4827 break;
4828
4829 case MR_EVT_LD_OFFLINE:
4830 case MR_EVT_LD_DELETED:
4831 megasas_get_ld_list(instance);
4832 for (i = 0; i < MEGASAS_MAX_LD_CHANNELS; i++) {
4833 for (j = 0;
4834 j < MEGASAS_MAX_DEV_PER_CHANNEL;
4835 j++) {
4836
4837 ld_index =
4838 (i * MEGASAS_MAX_DEV_PER_CHANNEL) + j;
4839
4840 sdev1 = scsi_device_lookup(host,
4841 i + MEGASAS_MAX_LD_CHANNELS,
4842 j,
4843 0);
4844
4845 if (instance->ld_ids[ld_index] != 0xff) {
4846 if (sdev1) {
4847 scsi_device_put(sdev1);
4848 }
4849 } else {
4850 if (sdev1) {
4851 scsi_remove_device(sdev1);
4852 scsi_device_put(sdev1);
4853 }
4854 }
4855 }
4856 }
4857 doscan = 0;
4858 break;
4859 case MR_EVT_LD_CREATED:
4860 megasas_get_ld_list(instance);
4861 for (i = 0; i < MEGASAS_MAX_LD_CHANNELS; i++) {
4862 for (j = 0;
4863 j < MEGASAS_MAX_DEV_PER_CHANNEL;
4864 j++) {
4865 ld_index =
4866 (i * MEGASAS_MAX_DEV_PER_CHANNEL) + j;
4867
4868 sdev1 = scsi_device_lookup(host,
4869 i+MEGASAS_MAX_LD_CHANNELS,
4870 j, 0);
4871
4872 if (instance->ld_ids[ld_index] !=
4873 0xff) {
4874 if (!sdev1) {
4875 scsi_add_device(host,
4876 i + 2,
4877 j, 0);
4878 }
4879 }
4880 if (sdev1) {
4881 scsi_device_put(sdev1);
4882 }
4883 }
4884 }
4885 doscan = 0;
4886 break;
Yang, Bo7e8a75f2009-10-06 14:50:17 -06004887 case MR_EVT_CTRL_HOST_BUS_SCAN_REQUESTED:
Yang, Boc9786842009-12-06 08:39:25 -07004888 case MR_EVT_FOREIGN_CFG_IMPORTED:
Yang, Bo7e8a75f2009-10-06 14:50:17 -06004889 doscan = 1;
4890 break;
4891 default:
4892 doscan = 0;
4893 break;
4894 }
4895 } else {
4896 printk(KERN_ERR "invalid evt_detail!\n");
4897 kfree(ev);
4898 return;
4899 }
4900
4901 if (doscan) {
4902 printk(KERN_INFO "scanning ...\n");
4903 megasas_get_pd_list(instance);
4904 for (i = 0; i < MEGASAS_MAX_PD_CHANNELS; i++) {
4905 for (j = 0; j < MEGASAS_MAX_DEV_PER_CHANNEL; j++) {
4906 pd_index = i*MEGASAS_MAX_DEV_PER_CHANNEL + j;
4907 sdev1 = scsi_device_lookup(host, i, j, 0);
4908 if (instance->pd_list[pd_index].driveState ==
4909 MR_PD_STATE_SYSTEM) {
4910 if (!sdev1) {
4911 scsi_add_device(host, i, j, 0);
4912 }
4913 if (sdev1)
4914 scsi_device_put(sdev1);
4915 } else {
4916 if (sdev1) {
4917 scsi_remove_device(sdev1);
4918 scsi_device_put(sdev1);
4919 }
4920 }
4921 }
4922 }
Yang, Boc9786842009-12-06 08:39:25 -07004923
4924 megasas_get_ld_list(instance);
4925 for (i = 0; i < MEGASAS_MAX_LD_CHANNELS; i++) {
4926 for (j = 0; j < MEGASAS_MAX_DEV_PER_CHANNEL; j++) {
4927 ld_index =
4928 (i * MEGASAS_MAX_DEV_PER_CHANNEL) + j;
4929
4930 sdev1 = scsi_device_lookup(host,
4931 i+MEGASAS_MAX_LD_CHANNELS, j, 0);
4932 if (instance->ld_ids[ld_index] != 0xff) {
4933 if (!sdev1) {
4934 scsi_add_device(host,
4935 i+2,
4936 j, 0);
4937 } else {
4938 scsi_device_put(sdev1);
4939 }
4940 } else {
4941 if (sdev1) {
4942 scsi_remove_device(sdev1);
4943 scsi_device_put(sdev1);
4944 }
4945 }
4946 }
4947 }
Yang, Bo7e8a75f2009-10-06 14:50:17 -06004948 }
4949
4950 if ( instance->aen_cmd != NULL ) {
4951 kfree(ev);
4952 return ;
4953 }
4954
4955 seq_num = instance->evt_detail->seq_num + 1;
4956
4957 /* Register AEN with FW for latest sequence number plus 1 */
4958 class_locale.members.reserved = 0;
4959 class_locale.members.locale = MR_EVT_LOCALE_ALL;
4960 class_locale.members.class = MR_EVT_CLASS_DEBUG;
4961 mutex_lock(&instance->aen_mutex);
4962 error = megasas_register_aen(instance, seq_num,
4963 class_locale.word);
4964 mutex_unlock(&instance->aen_mutex);
4965
4966 if (error)
4967 printk(KERN_ERR "register aen failed error %x\n", error);
4968
4969 kfree(ev);
4970}
4971
4972
Bryn M. Reevesbb7d3f22009-11-12 18:31:54 +00004973static DRIVER_ATTR(poll_mode_io, S_IRUGO|S_IWUSR,
bo yangad84db22007-11-09 04:40:16 -05004974 megasas_sysfs_show_poll_mode_io,
4975 megasas_sysfs_set_poll_mode_io);
Sumant Patro658dced2006-10-03 13:09:14 -07004976
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004977/**
4978 * megasas_init - Driver load entry point
4979 */
4980static int __init megasas_init(void)
4981{
4982 int rval;
4983
4984 /*
4985 * Announce driver version and other information
4986 */
4987 printk(KERN_INFO "megasas: %s %s\n", MEGASAS_VERSION,
4988 MEGASAS_EXT_VERSION);
4989
Yang, Bo72c4fd32009-10-06 14:20:59 -06004990 support_poll_for_event = 2;
Yang, Bo837f5fe2010-10-11 06:59:20 -06004991 support_device_change = 1;
Yang, Bo72c4fd32009-10-06 14:20:59 -06004992
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004993 memset(&megasas_mgmt_info, 0, sizeof(megasas_mgmt_info));
4994
4995 /*
4996 * Register character device node
4997 */
4998 rval = register_chrdev(0, "megaraid_sas_ioctl", &megasas_mgmt_fops);
4999
5000 if (rval < 0) {
5001 printk(KERN_DEBUG "megasas: failed to open device node\n");
5002 return rval;
5003 }
5004
5005 megasas_mgmt_majorno = rval;
5006
5007 /*
5008 * Register ourselves as PCI hotplug module
5009 */
Michal Piotrowski4041b9c2006-08-17 13:28:22 +00005010 rval = pci_register_driver(&megasas_pci_driver);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04005011
5012 if (rval) {
5013 printk(KERN_DEBUG "megasas: PCI hotplug regisration failed \n");
Jeff Garzik83aabc12006-10-04 06:34:03 -04005014 goto err_pcidrv;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04005015 }
5016
Jeff Garzik83aabc12006-10-04 06:34:03 -04005017 rval = driver_create_file(&megasas_pci_driver.driver,
5018 &driver_attr_version);
5019 if (rval)
5020 goto err_dcf_attr_ver;
5021 rval = driver_create_file(&megasas_pci_driver.driver,
5022 &driver_attr_release_date);
5023 if (rval)
5024 goto err_dcf_rel_date;
Yang, Bo72c4fd32009-10-06 14:20:59 -06005025
5026 rval = driver_create_file(&megasas_pci_driver.driver,
5027 &driver_attr_support_poll_for_event);
5028 if (rval)
5029 goto err_dcf_support_poll_for_event;
5030
Jeff Garzik83aabc12006-10-04 06:34:03 -04005031 rval = driver_create_file(&megasas_pci_driver.driver,
5032 &driver_attr_dbg_lvl);
5033 if (rval)
5034 goto err_dcf_dbg_lvl;
bo yangad84db22007-11-09 04:40:16 -05005035 rval = driver_create_file(&megasas_pci_driver.driver,
5036 &driver_attr_poll_mode_io);
5037 if (rval)
5038 goto err_dcf_poll_mode_io;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04005039
Yang, Bo837f5fe2010-10-11 06:59:20 -06005040 rval = driver_create_file(&megasas_pci_driver.driver,
5041 &driver_attr_support_device_change);
5042 if (rval)
5043 goto err_dcf_support_device_change;
5044
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04005045 return rval;
bo yangad84db22007-11-09 04:40:16 -05005046
Yang, Bo837f5fe2010-10-11 06:59:20 -06005047err_dcf_support_device_change:
5048 driver_remove_file(&megasas_pci_driver.driver,
5049 &driver_attr_poll_mode_io);
5050
bo yangad84db22007-11-09 04:40:16 -05005051err_dcf_poll_mode_io:
5052 driver_remove_file(&megasas_pci_driver.driver,
5053 &driver_attr_dbg_lvl);
Jeff Garzik83aabc12006-10-04 06:34:03 -04005054err_dcf_dbg_lvl:
5055 driver_remove_file(&megasas_pci_driver.driver,
Yang, Bo72c4fd32009-10-06 14:20:59 -06005056 &driver_attr_support_poll_for_event);
5057
5058err_dcf_support_poll_for_event:
5059 driver_remove_file(&megasas_pci_driver.driver,
Jeff Garzik83aabc12006-10-04 06:34:03 -04005060 &driver_attr_release_date);
Yang, Bo72c4fd32009-10-06 14:20:59 -06005061
Jeff Garzik83aabc12006-10-04 06:34:03 -04005062err_dcf_rel_date:
5063 driver_remove_file(&megasas_pci_driver.driver, &driver_attr_version);
5064err_dcf_attr_ver:
5065 pci_unregister_driver(&megasas_pci_driver);
5066err_pcidrv:
5067 unregister_chrdev(megasas_mgmt_majorno, "megaraid_sas_ioctl");
5068 return rval;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04005069}
5070
5071/**
5072 * megasas_exit - Driver unload entry point
5073 */
5074static void __exit megasas_exit(void)
5075{
Sumant Patro658dced2006-10-03 13:09:14 -07005076 driver_remove_file(&megasas_pci_driver.driver,
bo yangad84db22007-11-09 04:40:16 -05005077 &driver_attr_poll_mode_io);
5078 driver_remove_file(&megasas_pci_driver.driver,
Sumant Patro658dced2006-10-03 13:09:14 -07005079 &driver_attr_dbg_lvl);
Jeff Garzik83aabc12006-10-04 06:34:03 -04005080 driver_remove_file(&megasas_pci_driver.driver,
Yang, Bo837f5fe2010-10-11 06:59:20 -06005081 &driver_attr_support_poll_for_event);
5082 driver_remove_file(&megasas_pci_driver.driver,
5083 &driver_attr_support_device_change);
5084 driver_remove_file(&megasas_pci_driver.driver,
Jeff Garzik83aabc12006-10-04 06:34:03 -04005085 &driver_attr_release_date);
5086 driver_remove_file(&megasas_pci_driver.driver, &driver_attr_version);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04005087
5088 pci_unregister_driver(&megasas_pci_driver);
5089 unregister_chrdev(megasas_mgmt_majorno, "megaraid_sas_ioctl");
5090}
5091
5092module_init(megasas_init);
5093module_exit(megasas_exit);