]>
Commit | Line | Data |
---|---|---|
00e5a55c BS |
1 | From: Hannes Reinecke <hare@suse.de> |
2 | Subject: qla4xxx driver fixes for SLES11 | |
3 | Date: Tue Oct 7 12:59:55 2008 +0200: | |
4 | References: bnc#432976 | |
5 | ||
6 | The upstream qla4xxx driver requires some fixes for SLES11. | |
7 | ||
8 | Signed-off-by: David Wagner <david.wagner@qlogic.com> | |
9 | Signed-off-by: Hannes Reinecke <hare@suse.de> | |
10 | ||
11 | diff --git a/drivers/scsi/qla4xxx/Kconfig b/drivers/scsi/qla4xxx/Kconfig | |
12 | index 69cbff3..4eda26a 100644 | |
13 | --- a/drivers/scsi/qla4xxx/Kconfig | |
14 | +++ b/drivers/scsi/qla4xxx/Kconfig | |
15 | @@ -1,7 +1,7 @@ | |
16 | config SCSI_QLA_ISCSI | |
17 | tristate "QLogic ISP4XXX host adapter family support" | |
18 | - depends on PCI && SCSI && NET | |
19 | + depends on PCI && SCSI | |
20 | select SCSI_ISCSI_ATTRS | |
21 | ---help--- | |
22 | - This driver supports the QLogic 40xx (ISP4XXX) iSCSI host | |
23 | + This driver supports the QLogic 40xx (ISP4XXX) iSCSI host | |
24 | adapter family. | |
25 | diff --git a/drivers/scsi/qla4xxx/ql4_dbg.c b/drivers/scsi/qla4xxx/ql4_dbg.c | |
26 | index fcc184c..171a342 100644 | |
27 | --- a/drivers/scsi/qla4xxx/ql4_dbg.c | |
28 | +++ b/drivers/scsi/qla4xxx/ql4_dbg.c | |
29 | @@ -6,10 +6,162 @@ | |
30 | */ | |
31 | ||
32 | #include "ql4_def.h" | |
33 | +#include "ql4_version.h" | |
34 | #include "ql4_glbl.h" | |
35 | #include "ql4_dbg.h" | |
36 | #include "ql4_inline.h" | |
37 | ||
38 | +#include <scsi/scsi_dbg.h> | |
39 | + | |
40 | +static void qla4xxx_print_srb_info(struct srb * srb) | |
41 | +{ | |
42 | + printk("%s: srb = 0x%p, flags=0x%02x\n", __func__, srb, srb->flags); | |
43 | + printk("%s: cmd = 0x%p, saved_dma_handle = 0x%lx\n", | |
44 | + __func__, srb->cmd, (unsigned long) srb->dma_handle); | |
45 | + printk("%s: fw_ddb_index = %d, lun = %d\n", | |
46 | + __func__, srb->fw_ddb_index, srb->cmd->device->lun); | |
47 | + printk("%s: iocb_tov = %d\n", | |
48 | + __func__, srb->iocb_tov); | |
49 | + printk("%s: cc_stat = 0x%x\n", __func__, srb->cc_stat); | |
50 | +} | |
51 | + | |
52 | +void qla4xxx_print_scsi_cmd(struct scsi_cmnd *cmd) | |
53 | +{ | |
54 | + printk("SCSI Command = 0x%p, Handle=0x%p\n", cmd, cmd->host_scribble); | |
55 | + printk(" b=%d, t=%02xh, l=%02xh, cmd_len = %02xh\n", | |
56 | + cmd->device->channel, cmd->device->id, cmd->device->lun, | |
57 | + cmd->cmd_len); | |
58 | + scsi_print_command(cmd); | |
59 | + qla4xxx_print_srb_info((struct srb *) cmd->SCp.ptr); | |
60 | +} | |
61 | + | |
62 | +void __dump_registers(struct scsi_qla_host *ha) | |
63 | +{ | |
64 | + uint8_t i; | |
65 | + for (i = 0; i < MBOX_REG_COUNT; i++) { | |
66 | + printk(KERN_INFO "0x%02X mailbox[%d] = 0x%08X\n", | |
67 | + (uint8_t) offsetof(struct isp_reg, mailbox[i]), i, | |
68 | + readw(&ha->reg->mailbox[i])); | |
69 | + } | |
70 | + printk(KERN_INFO "0x%02X flash_address = 0x%08X\n", | |
71 | + (uint8_t) offsetof(struct isp_reg, flash_address), | |
72 | + readw(&ha->reg->flash_address)); | |
73 | + printk(KERN_INFO "0x%02X flash_data = 0x%08X\n", | |
74 | + (uint8_t) offsetof(struct isp_reg, flash_data), | |
75 | + readw(&ha->reg->flash_data)); | |
76 | + printk(KERN_INFO "0x%02X ctrl_status = 0x%08X\n", | |
77 | + (uint8_t) offsetof(struct isp_reg, ctrl_status), | |
78 | + readw(&ha->reg->ctrl_status)); | |
79 | + if (is_qla4010(ha)) { | |
80 | + printk(KERN_INFO "0x%02X nvram = 0x%08X\n", | |
81 | + (uint8_t) offsetof(struct isp_reg, u1.isp4010.nvram), | |
82 | + readw(&ha->reg->u1.isp4010.nvram)); | |
83 | + } | |
84 | + | |
85 | + else if (is_qla4022(ha) | is_qla4032(ha)) { | |
86 | + printk(KERN_INFO "0x%02X intr_mask = 0x%08X\n", | |
87 | + (uint8_t) offsetof(struct isp_reg, | |
88 | + u1.isp4022.intr_mask), | |
89 | + readw(&ha->reg->u1.isp4022.intr_mask)); | |
90 | + printk(KERN_INFO "0x%02X nvram = 0x%08X\n", | |
91 | + (uint8_t) offsetof(struct isp_reg, u1.isp4022.nvram), | |
92 | + readw(&ha->reg->u1.isp4022.nvram)); | |
93 | + printk(KERN_INFO "0x%02X semaphore = 0x%08X\n", | |
94 | + (uint8_t) offsetof(struct isp_reg, | |
95 | + u1.isp4022.semaphore), | |
96 | + readw(&ha->reg->u1.isp4022.semaphore)); | |
97 | + } | |
98 | + printk(KERN_INFO "0x%02X req_q_in = 0x%08X\n", | |
99 | + (uint8_t) offsetof(struct isp_reg, req_q_in), | |
100 | + readw(&ha->reg->req_q_in)); | |
101 | + printk(KERN_INFO "0x%02X rsp_q_out = 0x%08X\n", | |
102 | + (uint8_t) offsetof(struct isp_reg, rsp_q_out), | |
103 | + readw(&ha->reg->rsp_q_out)); | |
104 | + if (is_qla4010(ha)) { | |
105 | + printk(KERN_INFO "0x%02X ext_hw_conf = 0x%08X\n", | |
106 | + (uint8_t) offsetof(struct isp_reg, | |
107 | + u2.isp4010.ext_hw_conf), | |
108 | + readw(&ha->reg->u2.isp4010.ext_hw_conf)); | |
109 | + printk(KERN_INFO "0x%02X port_ctrl = 0x%08X\n", | |
110 | + (uint8_t) offsetof(struct isp_reg, | |
111 | + u2.isp4010.port_ctrl), | |
112 | + readw(&ha->reg->u2.isp4010.port_ctrl)); | |
113 | + printk(KERN_INFO "0x%02X port_status = 0x%08X\n", | |
114 | + (uint8_t) offsetof(struct isp_reg, | |
115 | + u2.isp4010.port_status), | |
116 | + readw(&ha->reg->u2.isp4010.port_status)); | |
117 | + printk(KERN_INFO "0x%02X req_q_out = 0x%08X\n", | |
118 | + (uint8_t) offsetof(struct isp_reg, | |
119 | + u2.isp4010.req_q_out), | |
120 | + readw(&ha->reg->u2.isp4010.req_q_out)); | |
121 | + printk(KERN_INFO "0x%02X gp_out = 0x%08X\n", | |
122 | + (uint8_t) offsetof(struct isp_reg, u2.isp4010.gp_out), | |
123 | + readw(&ha->reg->u2.isp4010.gp_out)); | |
124 | + printk(KERN_INFO "0x%02X gp_in = 0x%08X\n", | |
125 | + (uint8_t) offsetof(struct isp_reg, u2.isp4010.gp_in), | |
126 | + readw(&ha->reg->u2.isp4010.gp_in)); | |
127 | + printk(KERN_INFO "0x%02X port_err_status = 0x%08X\n", | |
128 | + (uint8_t) offsetof(struct isp_reg, | |
129 | + u2.isp4010.port_err_status), | |
130 | + readw(&ha->reg->u2.isp4010.port_err_status)); | |
131 | + } | |
132 | + | |
133 | + else if (is_qla4022(ha) | is_qla4032(ha)) { | |
134 | + printk(KERN_INFO "Page 0 Registers:\n"); | |
135 | + printk(KERN_INFO "0x%02X ext_hw_conf = 0x%08X\n", | |
136 | + (uint8_t) offsetof(struct isp_reg, | |
137 | + u2.isp4022.p0.ext_hw_conf), | |
138 | + readw(&ha->reg->u2.isp4022.p0.ext_hw_conf)); | |
139 | + printk(KERN_INFO "0x%02X port_ctrl = 0x%08X\n", | |
140 | + (uint8_t) offsetof(struct isp_reg, | |
141 | + u2.isp4022.p0.port_ctrl), | |
142 | + readw(&ha->reg->u2.isp4022.p0.port_ctrl)); | |
143 | + printk(KERN_INFO "0x%02X port_status = 0x%08X\n", | |
144 | + (uint8_t) offsetof(struct isp_reg, | |
145 | + u2.isp4022.p0.port_status), | |
146 | + readw(&ha->reg->u2.isp4022.p0.port_status)); | |
147 | + printk(KERN_INFO "0x%02X gp_out = 0x%08X\n", | |
148 | + (uint8_t) offsetof(struct isp_reg, | |
149 | + u2.isp4022.p0.gp_out), | |
150 | + readw(&ha->reg->u2.isp4022.p0.gp_out)); | |
151 | + printk(KERN_INFO "0x%02X gp_in = 0x%08X\n", | |
152 | + (uint8_t) offsetof(struct isp_reg, u2.isp4022.p0.gp_in), | |
153 | + readw(&ha->reg->u2.isp4022.p0.gp_in)); | |
154 | + printk(KERN_INFO "0x%02X port_err_status = 0x%08X\n", | |
155 | + (uint8_t) offsetof(struct isp_reg, | |
156 | + u2.isp4022.p0.port_err_status), | |
157 | + readw(&ha->reg->u2.isp4022.p0.port_err_status)); | |
158 | + printk(KERN_INFO "Page 1 Registers:\n"); | |
159 | + writel(HOST_MEM_CFG_PAGE & set_rmask(CSR_SCSI_PAGE_SELECT), | |
160 | + &ha->reg->ctrl_status); | |
161 | + printk(KERN_INFO "0x%02X req_q_out = 0x%08X\n", | |
162 | + (uint8_t) offsetof(struct isp_reg, | |
163 | + u2.isp4022.p1.req_q_out), | |
164 | + readw(&ha->reg->u2.isp4022.p1.req_q_out)); | |
165 | + writel(PORT_CTRL_STAT_PAGE & set_rmask(CSR_SCSI_PAGE_SELECT), | |
166 | + &ha->reg->ctrl_status); | |
167 | + } | |
168 | +} | |
169 | + | |
170 | +void qla4xxx_dump_mbox_registers(struct scsi_qla_host *ha) | |
171 | +{ | |
172 | + unsigned long flags = 0; | |
173 | + int i = 0; | |
174 | + spin_lock_irqsave(&ha->hardware_lock, flags); | |
175 | + for (i = 1; i < MBOX_REG_COUNT; i++) | |
176 | + printk(KERN_INFO " Mailbox[%d] = %08x\n", i, | |
177 | + readw(&ha->reg->mailbox[i])); | |
178 | + spin_unlock_irqrestore(&ha->hardware_lock, flags); | |
179 | +} | |
180 | + | |
181 | +void qla4xxx_dump_registers(struct scsi_qla_host *ha) | |
182 | +{ | |
183 | + unsigned long flags = 0; | |
184 | + spin_lock_irqsave(&ha->hardware_lock, flags); | |
185 | + __dump_registers(ha); | |
186 | + spin_unlock_irqrestore(&ha->hardware_lock, flags); | |
187 | +} | |
188 | + | |
189 | void qla4xxx_dump_buffer(void *b, uint32_t size) | |
190 | { | |
191 | uint32_t cnt; | |
192 | @@ -30,4 +182,3 @@ void qla4xxx_dump_buffer(void *b, uint32_t size) | |
193 | if (cnt % 16) | |
194 | printk(KERN_DEBUG "\n"); | |
195 | } | |
196 | - | |
197 | diff --git a/drivers/scsi/qla4xxx/ql4_dbg.h b/drivers/scsi/qla4xxx/ql4_dbg.h | |
198 | index d861c3b..20dfe4a 100644 | |
199 | --- a/drivers/scsi/qla4xxx/ql4_dbg.h | |
200 | +++ b/drivers/scsi/qla4xxx/ql4_dbg.h | |
201 | @@ -12,6 +12,7 @@ | |
202 | /* #define QL_DEBUG_LEVEL_3 */ /* Output function tracing */ | |
203 | /* #define QL_DEBUG_LEVEL_4 */ | |
204 | /* #define QL_DEBUG_LEVEL_5 */ | |
205 | +/* #define QL_DEBUG_LEVEL_6 */ | |
206 | /* #define QL_DEBUG_LEVEL_9 */ | |
207 | ||
208 | #define QL_DEBUG_LEVEL_2 /* ALways enable error messagess */ | |
209 | @@ -22,14 +23,14 @@ | |
210 | #endif | |
211 | ||
212 | #if defined(QL_DEBUG_LEVEL_2) | |
213 | -#define DEBUG2(x) do {if(ql4xextended_error_logging == 2) x;} while (0); | |
214 | +#define DEBUG2(x) do {if(extended_error_logging == 2) x;} while (0); | |
215 | #define DEBUG2_3(x) do {x;} while (0); | |
216 | #else /* */ | |
217 | #define DEBUG2(x) do {} while (0); | |
218 | #endif /* */ | |
219 | ||
220 | #if defined(QL_DEBUG_LEVEL_3) | |
221 | -#define DEBUG3(x) do {if(ql4xextended_error_logging == 3) x;} while (0); | |
222 | +#define DEBUG3(x) do {if(extended_error_logging == 3) x;} while (0); | |
223 | #else /* */ | |
224 | #define DEBUG3(x) do {} while (0); | |
225 | #if !defined(QL_DEBUG_LEVEL_2) | |
226 | @@ -48,6 +49,12 @@ | |
227 | #define DEBUG5(x) do {} while (0); | |
228 | #endif /* */ | |
229 | ||
230 | +#if defined(QL_DEBUG_LEVEL_6) | |
231 | +#define DEBUG6(x) do {x;} while (0); | |
232 | +#else /* */ | |
233 | +#define DEBUG6(x) do {} while (0); | |
234 | +#endif /* */ | |
235 | + | |
236 | #if defined(QL_DEBUG_LEVEL_9) | |
237 | #define DEBUG9(x) do {x;} while (0); | |
238 | #else /* */ | |
239 | diff --git a/drivers/scsi/qla4xxx/ql4_def.h b/drivers/scsi/qla4xxx/ql4_def.h | |
240 | index d6be076..52d36b2 100644 | |
241 | --- a/drivers/scsi/qla4xxx/ql4_def.h | |
242 | +++ b/drivers/scsi/qla4xxx/ql4_def.h | |
243 | @@ -90,10 +90,10 @@ | |
244 | ***********************************/ | |
245 | #define MAX_HBAS 16 | |
246 | #define MAX_BUSES 1 | |
247 | -#define MAX_TARGETS (MAX_PRST_DEV_DB_ENTRIES + MAX_DEV_DB_ENTRIES) | |
248 | +#define MAX_TARGETS MAX_DEV_DB_ENTRIES | |
249 | #define MAX_LUNS 0xffff | |
250 | #define MAX_AEN_ENTRIES 256 /* should be > EXT_DEF_MAX_AEN_QUEUE */ | |
251 | -#define MAX_DDB_ENTRIES (MAX_PRST_DEV_DB_ENTRIES + MAX_DEV_DB_ENTRIES) | |
252 | +#define MAX_DDB_ENTRIES MAX_DEV_DB_ENTRIES | |
253 | #define MAX_PDU_ENTRIES 32 | |
254 | #define INVALID_ENTRY 0xFFFF | |
255 | #define MAX_CMDS_TO_RISC 1024 | |
256 | @@ -121,8 +121,9 @@ | |
257 | #define MAX_REQS_SERVICED_PER_INTR 16 | |
258 | ||
259 | #define ISCSI_IPADDR_SIZE 4 /* IP address size */ | |
260 | -#define ISCSI_ALIAS_SIZE 32 /* ISCSI Alias name size */ | |
261 | -#define ISCSI_NAME_SIZE 0xE0 /* ISCSI Name size */ | |
262 | +#define ISCSI_ALIAS_SIZE 32 /* ISCSI Alais name size */ | |
263 | +#define ISCSI_NAME_SIZE 0xE0 /* ISCSI Name size - | |
264 | + * usually a string */ | |
265 | ||
266 | #define LSDW(x) ((u32)((u64)(x))) | |
267 | #define MSDW(x) ((u32)((((u64)(x)) >> 16) >> 16)) | |
268 | @@ -158,6 +159,7 @@ struct srb { | |
269 | struct ddb_entry *ddb; | |
270 | uint16_t flags; /* (1) Status flags. */ | |
271 | ||
272 | +#define SRB_SCSI_PASSTHRU BIT_2 /* for scsi passthru cmds */ | |
273 | #define SRB_DMA_VALID BIT_3 /* DMA Buffer mapped. */ | |
274 | #define SRB_GOT_SENSE BIT_4 /* sense data recieved. */ | |
275 | uint8_t state; /* (1) Status flags. */ | |
276 | @@ -182,25 +184,12 @@ struct srb { | |
277 | uint16_t iocb_tov; | |
278 | uint16_t iocb_cnt; /* Number of used iocbs */ | |
279 | uint16_t cc_stat; | |
280 | - u_long r_start; /* Time we recieve a cmd from OS */ | |
281 | - u_long u_start; /* Time when we handed the cmd to F/W */ | |
282 | + uint32_t dma_len; | |
283 | }; | |
284 | ||
285 | -/* | |
286 | - * Asynchronous Event Queue structure | |
287 | - */ | |
288 | -struct aen { | |
289 | - uint32_t mbox_sts[MBOX_AEN_REG_COUNT]; | |
290 | -}; | |
291 | - | |
292 | -struct ql4_aen_log { | |
293 | - int count; | |
294 | - struct aen entry[MAX_AEN_ENTRIES]; | |
295 | -}; | |
296 | - | |
297 | -/* | |
298 | - * Device Database (DDB) structure | |
299 | - */ | |
300 | + /* | |
301 | + * Device Database (DDB) structure | |
302 | + */ | |
303 | struct ddb_entry { | |
304 | struct list_head list; /* ddb list */ | |
305 | struct scsi_qla_host *ha; | |
306 | @@ -262,9 +251,19 @@ struct ddb_entry { | |
307 | #define DF_RELOGIN 0 /* Relogin to device */ | |
308 | #define DF_NO_RELOGIN 1 /* Do not relogin if IOCTL | |
309 | * logged it out */ | |
310 | -#define DF_ISNS_DISCOVERED 2 /* Device was discovered via iSNS */ | |
311 | -#define DF_FO_MASKED 3 | |
312 | +#define DF_SCAN_ISSUED 2 | |
313 | + | |
314 | +/* | |
315 | + * Asynchronous Event Queue structure | |
316 | + */ | |
317 | +struct aen { | |
318 | + uint32_t mbox_sts[MBOX_AEN_REG_COUNT]; | |
319 | +}; | |
320 | ||
321 | +struct ql4_aen_log { | |
322 | + int count; | |
323 | + struct aen entry[MAX_AEN_ENTRIES]; | |
324 | +}; | |
325 | ||
326 | #include "ql4_fw.h" | |
327 | #include "ql4_nvram.h" | |
328 | @@ -273,16 +272,29 @@ struct ddb_entry { | |
329 | * Linux Host Adapter structure | |
330 | */ | |
331 | struct scsi_qla_host { | |
332 | + struct klist_node node; | |
333 | + uint16_t instance; | |
334 | + uint16_t rsvd0; | |
335 | + | |
336 | + /* exported functions */ | |
337 | + int (*ql4cmd)(struct scsi_qla_host *ha, struct srb * srb); | |
338 | + int (*ql4mbx)(struct scsi_qla_host *ha, uint8_t inCount, | |
339 | + uint8_t outCount, uint32_t *mbx_cmd, uint32_t *mbx_sts); | |
340 | + | |
341 | /* Linux adapter configuration data */ | |
342 | + struct Scsi_Host *host; /* pointer to host data */ | |
343 | + uint32_t tot_ddbs; | |
344 | unsigned long flags; | |
345 | ||
346 | +#define AF_ISNS_CMD_DONE 13 /* 0x00002000 */ | |
347 | #define AF_ONLINE 0 /* 0x00000001 */ | |
348 | #define AF_INIT_DONE 1 /* 0x00000002 */ | |
349 | #define AF_MBOX_COMMAND 2 /* 0x00000004 */ | |
350 | #define AF_MBOX_COMMAND_DONE 3 /* 0x00000008 */ | |
351 | -#define AF_INTERRUPTS_ON 6 /* 0x00000040 */ | |
352 | +#define AF_INTERRUPTS_ON 6 /* 0x00000040 Not Used */ | |
353 | #define AF_GET_CRASH_RECORD 7 /* 0x00000080 */ | |
354 | #define AF_LINK_UP 8 /* 0x00000100 */ | |
355 | +#define AF_TOPCAT_CHIP_PRESENT 9 /* 0x00000200 */ | |
356 | #define AF_IRQ_ATTACHED 10 /* 0x00000400 */ | |
357 | #define AF_DISABLE_ACB_COMPLETE 11 /* 0x00000800 */ | |
358 | ||
359 | @@ -297,9 +309,6 @@ struct scsi_qla_host { | |
360 | #define DPC_AEN 9 /* 0x00000200 */ | |
361 | #define DPC_GET_DHCP_IP_ADDR 15 /* 0x00008000 */ | |
362 | ||
363 | - struct Scsi_Host *host; /* pointer to host data */ | |
364 | - uint32_t tot_ddbs; | |
365 | - | |
366 | uint16_t iocb_cnt; | |
367 | uint16_t iocb_hiwat; | |
368 | ||
369 | @@ -324,6 +333,7 @@ struct scsi_qla_host { | |
370 | /* NVRAM registers */ | |
371 | struct eeprom_data *nvram; | |
372 | spinlock_t hardware_lock ____cacheline_aligned; | |
373 | + spinlock_t list_lock; | |
374 | uint32_t eeprom_cmd_data; | |
375 | ||
376 | /* Counters for general statistics */ | |
377 | @@ -348,7 +358,6 @@ struct scsi_qla_host { | |
378 | uint32_t firmware_version[2]; | |
379 | uint32_t patch_number; | |
380 | uint32_t build_number; | |
381 | - uint32_t board_id; | |
382 | ||
383 | /* --- From Init_FW --- */ | |
384 | /* init_cb_t *init_cb; */ | |
385 | @@ -368,6 +377,7 @@ struct scsi_qla_host { | |
386 | ||
387 | /* --- From GetFwState --- */ | |
388 | uint32_t firmware_state; | |
389 | + uint32_t board_id; | |
390 | uint32_t addl_fw_state; | |
391 | ||
392 | /* Linux kernel thread */ | |
393 | @@ -390,6 +400,10 @@ struct scsi_qla_host { | |
394 | uint16_t free_srb_q_count; | |
395 | uint16_t num_srbs_allocated; | |
396 | ||
397 | + /* Active array */ | |
398 | + struct srb *active_srb_array[MAX_SRBS]; | |
399 | + uint16_t current_active_index; | |
400 | + | |
401 | /* DMA Memory Block */ | |
402 | void *queues; | |
403 | dma_addr_t queues_dma; | |
404 | @@ -418,12 +432,20 @@ struct scsi_qla_host { | |
405 | uint16_t aen_out; | |
406 | struct aen aen_q[MAX_AEN_ENTRIES]; | |
407 | ||
408 | - struct ql4_aen_log aen_log;/* tracks all aens */ | |
409 | + /* pdu variables */ | |
410 | + uint16_t pdu_count; /* Number of available aen_q entries */ | |
411 | + uint16_t pdu_in; /* Current indexes */ | |
412 | + uint16_t pdu_out; | |
413 | + uint16_t pdu_active; | |
414 | + struct pdu_entry *free_pdu_top; | |
415 | + struct pdu_entry *free_pdu_bottom; | |
416 | + struct pdu_entry pdu_queue[MAX_PDU_ENTRIES]; | |
417 | ||
418 | /* This mutex protects several threads to do mailbox commands | |
419 | * concurrently. | |
420 | */ | |
421 | struct mutex mbox_sem; | |
422 | + wait_queue_head_t mailbox_wait_queue; | |
423 | ||
424 | /* temporary mailbox status registers */ | |
425 | volatile uint8_t mbox_status_count; | |
426 | @@ -434,7 +456,11 @@ struct scsi_qla_host { | |
427 | ||
428 | /* Map ddb_list entry by FW ddb index */ | |
429 | struct ddb_entry *fw_ddb_index_map[MAX_DDB_ENTRIES]; | |
430 | - | |
431 | + struct ql4_aen_log aen_log; | |
432 | + void (*ql4getaenlog)(struct scsi_qla_host *ha, struct ql4_aen_log *aenl); | |
433 | +#define QL_INDICES_PER_ENTRY 32 | |
434 | +#define QL_OSINDEX_ENTRIES (MAX_DDB_ENTRIES/QL_INDICES_PER_ENTRY) | |
435 | + volatile uint32_t os_map[QL_OSINDEX_ENTRIES]; | |
436 | }; | |
437 | ||
438 | static inline int is_qla4010(struct scsi_qla_host *ha) | |
439 | @@ -512,6 +538,20 @@ static inline void __iomem * isp_gp_out(struct scsi_qla_host *ha) | |
440 | &ha->reg->u2.isp4022.p0.gp_out); | |
441 | } | |
442 | ||
443 | +static inline void __iomem * isp_probe_mux_addr(struct scsi_qla_host *ha) | |
444 | +{ | |
445 | + return (is_qla4010(ha) ? | |
446 | + &ha->reg->u2.isp4010.probe_mux_addr : | |
447 | + &ha->reg->u2.isp4022.p0.probe_mux_addr); | |
448 | +} | |
449 | + | |
450 | +static inline void __iomem * isp_probe_mux_data(struct scsi_qla_host *ha) | |
451 | +{ | |
452 | + return (is_qla4010(ha) ? | |
453 | + &ha->reg->u2.isp4010.probe_mux_data : | |
454 | + &ha->reg->u2.isp4022.p0.probe_mux_data); | |
455 | +} | |
456 | + | |
457 | static inline int eeprom_ext_hw_conf_offset(struct scsi_qla_host *ha) | |
458 | { | |
459 | return (is_qla4010(ha) ? | |
460 | @@ -590,5 +630,6 @@ static inline void ql4xxx_unlock_drvr(struct scsi_qla_host *a) | |
461 | #define PROCESS_ALL_AENS 0 | |
462 | #define FLUSH_DDB_CHANGED_AENS 1 | |
463 | #define RELOGIN_DDB_CHANGED_AENS 2 | |
464 | +#define PROCESS_FOR_PROBE 3 | |
465 | ||
466 | #endif /*_QLA4XXX_H */ | |
467 | diff --git a/drivers/scsi/qla4xxx/ql4_fw.h b/drivers/scsi/qla4xxx/ql4_fw.h | |
468 | index 1b667a7..3fb3658 100644 | |
469 | --- a/drivers/scsi/qla4xxx/ql4_fw.h | |
470 | +++ b/drivers/scsi/qla4xxx/ql4_fw.h | |
471 | @@ -27,7 +27,11 @@ struct port_ctrl_stat_regs { | |
472 | __le32 rsrvd1[32]; /* 0x60-0xdf */ | |
473 | __le32 gp_out; /* 0xe0 */ | |
474 | __le32 gp_in; /* 0xe4 */ | |
475 | - __le32 rsrvd2[5]; /* 0xe8-0xfb */ | |
476 | + __le32 probe_mux_addr; /* 0xe8 */ | |
477 | + __le32 probe_mux_data; /* 0xec */ | |
478 | + __le32 stats_index; /* 0xf0 */ | |
479 | + __le32 stats_read_data_inc; /* 0xf4 */ | |
480 | + __le32 stats_read_data_noinc; /* 0xf8 */ | |
481 | __le32 port_err_status; /* 0xfc */ | |
482 | }; | |
483 | ||
484 | @@ -61,7 +65,9 @@ struct isp_reg { | |
485 | __le32 req_q_in; /* SCSI Request Queue Producer Index */ | |
486 | __le32 rsp_q_out; /* SCSI Completion Queue Consumer Index */ | |
487 | ||
488 | - __le32 reserved2[4]; /* 0x40 */ | |
489 | + __le32 reserved2[2]; /* 0x40 */ | |
490 | + __le32 arc_madi_cmd; | |
491 | + __le32 arc_madi_data; | |
492 | ||
493 | union { | |
494 | struct { | |
495 | @@ -79,7 +85,10 @@ struct isp_reg { | |
496 | __le32 gp_out; /* 0xe0 */ | |
497 | __le32 gp_in; | |
498 | ||
499 | - __le32 reserved5[5]; | |
500 | + __le32 probe_mux_addr; | |
501 | + __le32 probe_mux_data; | |
502 | + | |
503 | + __le32 reserved5[3]; | |
504 | ||
505 | __le32 port_err_status; /* 0xfc */ | |
506 | } __attribute__ ((packed)) isp4010; | |
507 | @@ -216,7 +225,6 @@ union external_hw_config_reg { | |
508 | #define MBOX_CMD_ABOUT_FW 0x0009 | |
509 | #define MBOX_CMD_PING 0x000B | |
510 | #define MBOX_CMD_LUN_RESET 0x0016 | |
511 | -#define MBOX_CMD_TARGET_WARM_RESET 0x0017 | |
512 | #define MBOX_CMD_GET_MANAGEMENT_DATA 0x001E | |
513 | #define MBOX_CMD_GET_FW_STATUS 0x001F | |
514 | #define MBOX_CMD_SET_ISNS_SERVICE 0x0021 | |
515 | @@ -431,8 +439,9 @@ struct init_fw_ctrl_blk { | |
516 | ||
517 | struct dev_db_entry { | |
518 | uint16_t options; /* 00-01 */ | |
519 | -#define DDB_OPT_DISC_SESSION 0x10 | |
520 | -#define DDB_OPT_TARGET 0x02 /* device is a target */ | |
521 | +#define DDB_OPT_DISC_SESSION 0x10 | |
522 | +#define DDB_OPT_TARGET 0x02 /* device is a target */ | |
523 | +#define DDB_OPT_IPV6_DEVICE 0x100 | |
524 | ||
525 | uint16_t exec_throttle; /* 02-03 */ | |
526 | uint16_t exec_count; /* 04-05 */ | |
527 | @@ -672,14 +681,13 @@ struct continuation_t1_entry { | |
528 | #define ET_CONTINUE ET_CONT_T1 | |
529 | ||
530 | /* Marker entry structure*/ | |
531 | -struct qla4_marker_entry { | |
532 | +struct marker_entry { | |
533 | struct qla4_header hdr; /* 00-03 */ | |
534 | ||
535 | uint32_t system_defined; /* 04-07 */ | |
536 | uint16_t target; /* 08-09 */ | |
537 | uint16_t modifier; /* 0A-0B */ | |
538 | -#define MM_LUN_RESET 0 | |
539 | -#define MM_TGT_WARM_RESET 1 | |
540 | +#define MM_LUN_RESET 0 | |
541 | ||
542 | uint16_t flags; /* 0C-0D */ | |
543 | uint16_t reserved1; /* 0E-0F */ | |
544 | @@ -733,6 +741,15 @@ struct status_entry { | |
545 | ||
546 | }; | |
547 | ||
548 | +struct pdu_entry { | |
549 | + uint8_t *Buff; | |
550 | + uint32_t BuffLen; | |
551 | + uint32_t SendBuffLen; | |
552 | + uint32_t RecvBuffLen; | |
553 | + struct pdu_entry *Next; | |
554 | + dma_addr_t DmaBuff; | |
555 | +}; | |
556 | + | |
557 | struct passthru0 { | |
558 | struct qla4_header hdr; /* 00-03 */ | |
559 | uint32_t handle; /* 04-07 */ | |
560 | diff --git a/drivers/scsi/qla4xxx/ql4_glbl.h b/drivers/scsi/qla4xxx/ql4_glbl.h | |
561 | index 96ebfb0..f948b9a 100644 | |
562 | --- a/drivers/scsi/qla4xxx/ql4_glbl.h | |
563 | +++ b/drivers/scsi/qla4xxx/ql4_glbl.h | |
564 | @@ -12,6 +12,7 @@ struct iscsi_cls_conn; | |
565 | ||
566 | void qla4xxx_hw_reset(struct scsi_qla_host *ha); | |
567 | int ql4xxx_lock_drvr_wait(struct scsi_qla_host *a); | |
568 | +int qla4xxx_conn_start(struct iscsi_cls_conn *conn); | |
569 | int qla4xxx_send_tgts(struct scsi_qla_host *ha, char *ip, uint16_t port); | |
570 | int qla4xxx_send_command_to_isp(struct scsi_qla_host *ha, struct srb * srb); | |
571 | int qla4xxx_initialize_adapter(struct scsi_qla_host * ha, | |
572 | @@ -27,8 +28,6 @@ int qla4xxx_relogin_device(struct scsi_qla_host * ha, | |
573 | struct ddb_entry * ddb_entry); | |
574 | int qla4xxx_reset_lun(struct scsi_qla_host * ha, struct ddb_entry * ddb_entry, | |
575 | int lun); | |
576 | -int qla4xxx_reset_target(struct scsi_qla_host * ha, | |
577 | - struct ddb_entry * ddb_entry); | |
578 | int qla4xxx_get_flash(struct scsi_qla_host * ha, dma_addr_t dma_addr, | |
579 | uint32_t offset, uint32_t len); | |
580 | int qla4xxx_get_firmware_status(struct scsi_qla_host * ha); | |
581 | @@ -56,25 +55,35 @@ void qla4xxx_mark_device_missing(struct scsi_qla_host *ha, | |
582 | u16 rd_nvram_word(struct scsi_qla_host * ha, int offset); | |
583 | void qla4xxx_get_crash_record(struct scsi_qla_host * ha); | |
584 | struct ddb_entry *qla4xxx_alloc_sess(struct scsi_qla_host *ha); | |
585 | -int qla4xxx_add_sess(struct ddb_entry *); | |
586 | +int qla4xxx_add_sess(struct ddb_entry *, int); | |
587 | void qla4xxx_destroy_sess(struct ddb_entry *ddb_entry); | |
588 | +int qla4xxx_conn_close_sess_logout(struct scsi_qla_host * ha, | |
589 | + uint16_t fw_ddb_index, | |
590 | + uint16_t connection_id, | |
591 | + uint16_t option); | |
592 | +int qla4xxx_clear_database_entry(struct scsi_qla_host * ha, | |
593 | + uint16_t fw_ddb_index); | |
594 | int qla4xxx_is_nvram_configuration_valid(struct scsi_qla_host * ha); | |
595 | int qla4xxx_get_fw_version(struct scsi_qla_host * ha); | |
596 | void qla4xxx_interrupt_service_routine(struct scsi_qla_host * ha, | |
597 | uint32_t intr_status); | |
598 | int qla4xxx_init_rings(struct scsi_qla_host * ha); | |
599 | -struct srb * qla4xxx_del_from_active_array(struct scsi_qla_host *ha, | |
600 | - uint32_t index); | |
601 | +void qla4xxx_dump_buffer(void *b, uint32_t size); | |
602 | +struct srb * qla4xxx_del_from_active_array(struct scsi_qla_host *ha, uint32_t index); | |
603 | void qla4xxx_srb_compl(struct scsi_qla_host *ha, struct srb *srb); | |
604 | int qla4xxx_reinitialize_ddb_list(struct scsi_qla_host * ha); | |
605 | int qla4xxx_process_ddb_changed(struct scsi_qla_host * ha, | |
606 | - uint32_t fw_ddb_index, uint32_t state); | |
607 | -void qla4xxx_dump_buffer(void *b, uint32_t size); | |
608 | + uint32_t fw_ddb_index, uint32_t state, uint32_t probe); | |
609 | + | |
610 | +int qla4xxx_mailbox_command(struct scsi_qla_host *ha, uint8_t inCount, | |
611 | + uint8_t outCount, uint32_t *mbx_cmd, uint32_t *mbx_sts); | |
612 | int qla4xxx_send_marker_iocb(struct scsi_qla_host *ha, | |
613 | - struct ddb_entry *ddb_entry, int lun, uint16_t mrkr_mod); | |
614 | + struct ddb_entry *ddb_entry, int lun); | |
615 | + | |
616 | + | |
617 | ||
618 | -extern int ql4xextended_error_logging; | |
619 | +extern int extended_error_logging; | |
620 | extern int ql4xdiscoverywait; | |
621 | extern int ql4xdontresethba; | |
622 | extern int ql4_mod_unload; | |
623 | -#endif /* _QLA4x_GBL_H */ | |
624 | +#endif /* _QLA4x_GBL_H */ | |
625 | diff --git a/drivers/scsi/qla4xxx/ql4_init.c b/drivers/scsi/qla4xxx/ql4_init.c | |
626 | index 109c5f5..6e83198 100644 | |
627 | --- a/drivers/scsi/qla4xxx/ql4_init.c | |
628 | +++ b/drivers/scsi/qla4xxx/ql4_init.c | |
629 | @@ -5,12 +5,20 @@ | |
630 | * See LICENSE.qla4xxx for copyright and licensing details. | |
631 | */ | |
632 | ||
633 | -#include <scsi/iscsi_if.h> | |
634 | #include "ql4_def.h" | |
635 | +#include "ql4_version.h" | |
636 | #include "ql4_glbl.h" | |
637 | #include "ql4_dbg.h" | |
638 | #include "ql4_inline.h" | |
639 | ||
640 | +/* link auto negotiation normally takes roughly 2s. */ | |
641 | +/* If we don't have link in 3 times that period quit. */ | |
642 | +#define QLA4XXX_LINK_UP_DELAY 6 | |
643 | + | |
644 | +/* | |
645 | + * QLogic ISP4xxx Hardware Support Function Prototypes. | |
646 | + */ | |
647 | + | |
648 | static struct ddb_entry * qla4xxx_alloc_ddb(struct scsi_qla_host *ha, | |
649 | uint32_t fw_ddb_index); | |
650 | ||
651 | @@ -44,7 +52,7 @@ static void ql4xxx_set_mac_number(struct scsi_qla_host *ha) | |
652 | } | |
653 | ||
654 | /** | |
655 | - * qla4xxx_free_ddb - deallocate ddb | |
656 | + * qla4xxx_free_ddb - deallocate ddb | |
657 | * @ha: pointer to host adapter structure. | |
658 | * @ddb_entry: pointer to device database entry | |
659 | * | |
660 | @@ -58,8 +66,7 @@ static void qla4xxx_free_ddb(struct scsi_qla_host *ha, | |
661 | list_del_init(&ddb_entry->list); | |
662 | ||
663 | /* Remove device pointer from index mapping arrays */ | |
664 | - ha->fw_ddb_index_map[ddb_entry->fw_ddb_index] = | |
665 | - (struct ddb_entry *) INVALID_ENTRY; | |
666 | + ha->fw_ddb_index_map[ddb_entry->fw_ddb_index] = NULL; | |
667 | ha->tot_ddbs--; | |
668 | ||
669 | /* Free memory and scsi-ml struct for device entry */ | |
670 | @@ -95,6 +102,7 @@ void qla4xxx_free_ddb_list(struct scsi_qla_host *ha) | |
671 | **/ | |
672 | int qla4xxx_init_rings(struct scsi_qla_host *ha) | |
673 | { | |
674 | + uint16_t i; | |
675 | unsigned long flags = 0; | |
676 | ||
677 | /* Initialize request queue. */ | |
678 | @@ -123,6 +131,10 @@ int qla4xxx_init_rings(struct scsi_qla_host *ha) | |
679 | writel(0, &ha->reg->rsp_q_out); | |
680 | readl(&ha->reg->rsp_q_out); | |
681 | ||
682 | + /* Initialize active array */ | |
683 | + for (i = 0; i < MAX_SRBS; i++) | |
684 | + ha->active_srb_array[i] = NULL; | |
685 | + | |
686 | spin_unlock_irqrestore(&ha->hardware_lock, flags); | |
687 | ||
688 | return QLA_SUCCESS; | |
689 | @@ -183,6 +195,16 @@ static int qla4xxx_validate_mac_address(struct scsi_qla_host *ha) | |
690 | **/ | |
691 | static int qla4xxx_init_local_data(struct scsi_qla_host *ha) | |
692 | { | |
693 | + int i; | |
694 | + | |
695 | + /* Initialize passthru PDU list */ | |
696 | + for (i = 0; i < (MAX_PDU_ENTRIES - 1); i++) | |
697 | + ha->pdu_queue[i].Next = &ha->pdu_queue[i + 1]; | |
698 | + ha->free_pdu_top = &ha->pdu_queue[0]; | |
699 | + ha->free_pdu_bottom = &ha->pdu_queue[MAX_PDU_ENTRIES - 1]; | |
700 | + ha->free_pdu_bottom->Next = NULL; | |
701 | + ha->pdu_active = 0; | |
702 | + | |
703 | /* Initilize aen queue */ | |
704 | ha->aen_q_count = MAX_AEN_ENTRIES; | |
705 | ||
706 | @@ -263,12 +285,10 @@ static int qla4xxx_fw_ready(struct scsi_qla_host *ha) | |
707 | "seconds expired= %d\n", ha->host_no, __func__, | |
708 | ha->firmware_state, ha->addl_fw_state, | |
709 | timeout_count)); | |
710 | - if (is_qla4032(ha) && | |
711 | - !(ha->addl_fw_state & FW_ADDSTATE_LINK_UP) && | |
712 | + if (!(ha->addl_fw_state & FW_ADDSTATE_LINK_UP) && | |
713 | (timeout_count < ADAPTER_INIT_TOV - 5)) { | |
714 | break; | |
715 | } | |
716 | - | |
717 | msleep(1000); | |
718 | } /* end of for */ | |
719 | ||
720 | @@ -276,7 +296,8 @@ static int qla4xxx_fw_ready(struct scsi_qla_host *ha) | |
721 | DEBUG2(printk("scsi%ld: %s: FW Initialization timed out!\n", | |
722 | ha->host_no, __func__)); | |
723 | ||
724 | - if (ha->firmware_state & FW_STATE_DHCP_IN_PROGRESS) { | |
725 | + if ((ha->firmware_state & FW_STATE_DHCP_IN_PROGRESS)|| | |
726 | + !(ha->addl_fw_state & FW_ADDSTATE_LINK_UP)) { | |
727 | DEBUG2(printk("scsi%ld: %s: FW is reporting its waiting to" | |
728 | " grab an IP address from DHCP server\n", | |
729 | ha->host_no, __func__)); | |
730 | @@ -307,145 +328,27 @@ static int qla4xxx_init_firmware(struct scsi_qla_host *ha) | |
731 | return qla4xxx_get_firmware_status(ha); | |
732 | } | |
733 | ||
734 | -static struct ddb_entry* qla4xxx_get_ddb_entry(struct scsi_qla_host *ha, | |
735 | - uint32_t fw_ddb_index, | |
736 | - uint32_t *new_tgt) | |
737 | +static void qla4xxx_fill_ddb(struct ddb_entry *ddb_entry, | |
738 | + struct dev_db_entry *fw_ddb_entry) | |
739 | { | |
740 | - struct dev_db_entry *fw_ddb_entry = NULL; | |
741 | - dma_addr_t fw_ddb_entry_dma; | |
742 | - struct ddb_entry *ddb_entry = NULL; | |
743 | - int found = 0; | |
744 | - uint32_t device_state; | |
745 | - | |
746 | - *new_tgt = 0; | |
747 | - /* Make sure the dma buffer is valid */ | |
748 | - fw_ddb_entry = dma_alloc_coherent(&ha->pdev->dev, | |
749 | - sizeof(*fw_ddb_entry), | |
750 | - &fw_ddb_entry_dma, GFP_KERNEL); | |
751 | - if (fw_ddb_entry == NULL) { | |
752 | - DEBUG2(printk("scsi%ld: %s: Unable to allocate dma buffer.\n", | |
753 | - ha->host_no, __func__)); | |
754 | - return NULL; | |
755 | - } | |
756 | - | |
757 | - if (qla4xxx_get_fwddb_entry(ha, fw_ddb_index, fw_ddb_entry, | |
758 | - fw_ddb_entry_dma, NULL, NULL, | |
759 | - &device_state, NULL, NULL, NULL) == | |
760 | - QLA_ERROR) { | |
761 | - DEBUG2(printk("scsi%ld: %s: failed get_ddb_entry for " | |
762 | - "fw_ddb_index %d\n", ha->host_no, __func__, | |
763 | - fw_ddb_index)); | |
764 | - return NULL; | |
765 | - } | |
766 | - | |
767 | - /* Allocate DDB if not already allocated. */ | |
768 | - DEBUG2(printk("scsi%ld: %s: Looking for ddb[%d]\n", ha->host_no, | |
769 | - __func__, fw_ddb_index)); | |
770 | - list_for_each_entry(ddb_entry, &ha->ddb_list, list) { | |
771 | - if (memcmp(ddb_entry->iscsi_name, fw_ddb_entry->iscsi_name, | |
772 | - ISCSI_NAME_SIZE) == 0) { | |
773 | - found++; | |
774 | - break; | |
775 | - } | |
776 | - } | |
777 | - | |
778 | - if (!found) { | |
779 | - DEBUG2(printk("scsi%ld: %s: ddb[%d] not found - allocating " | |
780 | - "new ddb\n", ha->host_no, __func__, | |
781 | - fw_ddb_index)); | |
782 | - *new_tgt = 1; | |
783 | - ddb_entry = qla4xxx_alloc_ddb(ha, fw_ddb_index); | |
784 | - } | |
785 | - | |
786 | - /* if not found allocate new ddb */ | |
787 | - dma_free_coherent(&ha->pdev->dev, sizeof(*fw_ddb_entry), fw_ddb_entry, | |
788 | - fw_ddb_entry_dma); | |
789 | - | |
790 | - return ddb_entry; | |
791 | -} | |
792 | - | |
793 | -/** | |
794 | - * qla4xxx_update_ddb_entry - update driver's internal ddb | |
795 | - * @ha: pointer to host adapter structure. | |
796 | - * @ddb_entry: pointer to device database structure to be filled | |
797 | - * @fw_ddb_index: index of the ddb entry in fw ddb table | |
798 | - * | |
799 | - * This routine updates the driver's internal device database entry | |
800 | - * with information retrieved from the firmware's device database | |
801 | - * entry for the specified device. The ddb_entry->fw_ddb_index field | |
802 | - * must be initialized prior to calling this routine | |
803 | - * | |
804 | - **/ | |
805 | -static int qla4xxx_update_ddb_entry(struct scsi_qla_host *ha, | |
806 | - struct ddb_entry *ddb_entry, | |
807 | - uint32_t fw_ddb_index) | |
808 | -{ | |
809 | - struct dev_db_entry *fw_ddb_entry = NULL; | |
810 | - dma_addr_t fw_ddb_entry_dma; | |
811 | - int status = QLA_ERROR; | |
812 | - | |
813 | - if (ddb_entry == NULL) { | |
814 | - DEBUG2(printk("scsi%ld: %s: ddb_entry is NULL\n", ha->host_no, | |
815 | - __func__)); | |
816 | - goto exit_update_ddb; | |
817 | - } | |
818 | - | |
819 | - /* Make sure the dma buffer is valid */ | |
820 | - fw_ddb_entry = dma_alloc_coherent(&ha->pdev->dev, | |
821 | - sizeof(*fw_ddb_entry), | |
822 | - &fw_ddb_entry_dma, GFP_KERNEL); | |
823 | - if (fw_ddb_entry == NULL) { | |
824 | - DEBUG2(printk("scsi%ld: %s: Unable to allocate dma buffer.\n", | |
825 | - ha->host_no, __func__)); | |
826 | - | |
827 | - goto exit_update_ddb; | |
828 | - } | |
829 | - | |
830 | - if (qla4xxx_get_fwddb_entry(ha, fw_ddb_index, fw_ddb_entry, | |
831 | - fw_ddb_entry_dma, NULL, NULL, | |
832 | - &ddb_entry->fw_ddb_device_state, NULL, | |
833 | - &ddb_entry->tcp_source_port_num, | |
834 | - &ddb_entry->connection_id) == | |
835 | - QLA_ERROR) { | |
836 | - DEBUG2(printk("scsi%ld: %s: failed get_ddb_entry for " | |
837 | - "fw_ddb_index %d\n", ha->host_no, __func__, | |
838 | - fw_ddb_index)); | |
839 | - | |
840 | - goto exit_update_ddb; | |
841 | - } | |
842 | - | |
843 | - status = QLA_SUCCESS; | |
844 | ddb_entry->target_session_id = le16_to_cpu(fw_ddb_entry->tsid); | |
845 | ddb_entry->task_mgmt_timeout = | |
846 | le16_to_cpu(fw_ddb_entry->def_timeout); | |
847 | ddb_entry->CmdSn = 0; | |
848 | ddb_entry->exe_throttle = le16_to_cpu(fw_ddb_entry->exec_throttle); | |
849 | + | |
850 | ddb_entry->default_relogin_timeout = | |
851 | le16_to_cpu(fw_ddb_entry->def_timeout); | |
852 | - ddb_entry->default_time2wait = le16_to_cpu(fw_ddb_entry->iscsi_def_time2wait); | |
853 | - | |
854 | - /* Update index in case it changed */ | |
855 | - ddb_entry->fw_ddb_index = fw_ddb_index; | |
856 | - ha->fw_ddb_index_map[fw_ddb_index] = ddb_entry; | |
857 | + ddb_entry->default_time2wait = | |
858 | + le16_to_cpu(fw_ddb_entry->iscsi_def_time2wait); | |
859 | ||
860 | ddb_entry->port = le16_to_cpu(fw_ddb_entry->port); | |
861 | ddb_entry->tpgt = le32_to_cpu(fw_ddb_entry->tgt_portal_grp); | |
862 | memcpy(&ddb_entry->iscsi_name[0], &fw_ddb_entry->iscsi_name[0], | |
863 | - min(sizeof(ddb_entry->iscsi_name), | |
864 | - sizeof(fw_ddb_entry->iscsi_name))); | |
865 | + min(sizeof(ddb_entry->iscsi_name), | |
866 | + sizeof(fw_ddb_entry->iscsi_name))); | |
867 | memcpy(&ddb_entry->ip_addr[0], &fw_ddb_entry->ip_addr[0], | |
868 | - min(sizeof(ddb_entry->ip_addr), sizeof(fw_ddb_entry->ip_addr))); | |
869 | - | |
870 | - DEBUG2(printk("scsi%ld: %s: ddb[%d] - State= %x status= %d.\n", | |
871 | - ha->host_no, __func__, fw_ddb_index, | |
872 | - ddb_entry->fw_ddb_device_state, status)); | |
873 | - | |
874 | - exit_update_ddb: | |
875 | - if (fw_ddb_entry) | |
876 | - dma_free_coherent(&ha->pdev->dev, sizeof(*fw_ddb_entry), | |
877 | - fw_ddb_entry, fw_ddb_entry_dma); | |
878 | - | |
879 | - return status; | |
880 | + min(sizeof(ddb_entry->ip_addr), sizeof(fw_ddb_entry->ip_addr))); | |
881 | } | |
882 | ||
883 | /** | |
884 | @@ -478,6 +381,12 @@ static struct ddb_entry * qla4xxx_alloc_ddb(struct scsi_qla_host *ha, | |
885 | atomic_set(&ddb_entry->relogin_timer, 0); | |
886 | atomic_set(&ddb_entry->relogin_retry_count, 0); | |
887 | atomic_set(&ddb_entry->state, DDB_STATE_ONLINE); | |
888 | + | |
889 | + dev_info(&ha->pdev->dev, | |
890 | + "scsi%ld: %s: ddb[%d] os[%d] marked ONLINE\n", | |
891 | + ha->host_no, __func__, ddb_entry->fw_ddb_index, | |
892 | + ddb_entry->os_target_id); | |
893 | + | |
894 | list_add_tail(&ddb_entry->list, &ha->ddb_list); | |
895 | ha->fw_ddb_index_map[fw_ddb_index] = ddb_entry; | |
896 | ha->tot_ddbs++; | |
897 | @@ -490,7 +399,7 @@ static struct ddb_entry * qla4xxx_alloc_ddb(struct scsi_qla_host *ha, | |
898 | * @ha: Pointer to host adapter structure. | |
899 | * | |
900 | * This routine searches for all valid firmware ddb entries and builds | |
901 | - * an internal ddb list. Ddbs that are considered valid are those with | |
902 | + * an internal ddb list. Ddbs that are considered valid are those with | |
903 | * a device state of SESSION_ACTIVE. | |
904 | **/ | |
905 | static int qla4xxx_build_ddb_list(struct scsi_qla_host *ha) | |
906 | @@ -501,90 +410,116 @@ static int qla4xxx_build_ddb_list(struct scsi_qla_host *ha) | |
907 | uint32_t ddb_state; | |
908 | uint32_t conn_err, err_code; | |
909 | struct ddb_entry *ddb_entry; | |
910 | - uint32_t new_tgt; | |
911 | + struct dev_db_entry *fw_ddb_entry = NULL; | |
912 | + dma_addr_t fw_ddb_entry_dma; | |
913 | + uint16_t src_port, conn_id; | |
914 | + uint32_t ipv6_device; | |
915 | ||
916 | dev_info(&ha->pdev->dev, "Initializing DDBs ...\n"); | |
917 | + | |
918 | + fw_ddb_entry = dma_alloc_coherent(&ha->pdev->dev, sizeof(*fw_ddb_entry), | |
919 | + &fw_ddb_entry_dma, GFP_KERNEL); | |
920 | + | |
921 | + if (fw_ddb_entry == NULL) { | |
922 | + DEBUG2(dev_info(&ha->pdev->dev, "%s: DMA alloc failed\n", | |
923 | + __func__)); | |
924 | + return QLA_ERROR; | |
925 | + } | |
926 | + | |
927 | for (fw_ddb_index = 0; fw_ddb_index < MAX_DDB_ENTRIES; | |
928 | fw_ddb_index = next_fw_ddb_index) { | |
929 | /* First, let's see if a device exists here */ | |
930 | - if (qla4xxx_get_fwddb_entry(ha, fw_ddb_index, NULL, 0, NULL, | |
931 | - &next_fw_ddb_index, &ddb_state, | |
932 | - &conn_err, NULL, NULL) == | |
933 | - QLA_ERROR) { | |
934 | - DEBUG2(printk("scsi%ld: %s: get_ddb_entry, " | |
935 | - "fw_ddb_index %d failed", ha->host_no, | |
936 | - __func__, fw_ddb_index)); | |
937 | - return QLA_ERROR; | |
938 | + if (qla4xxx_get_fwddb_entry(ha, fw_ddb_index, fw_ddb_entry, | |
939 | + fw_ddb_entry_dma, NULL, &next_fw_ddb_index, | |
940 | + &ddb_state, &conn_err, &src_port, | |
941 | + &conn_id) == QLA_ERROR) { | |
942 | + DEBUG2(dev_info(&ha->pdev->dev, "%s: get_ddb_entry," | |
943 | + " fw_ddb_index %d failed", __func__, | |
944 | + fw_ddb_index)); | |
945 | + goto exit_ddb_list; | |
946 | } | |
947 | ||
948 | - DEBUG2(printk("scsi%ld: %s: Getting DDB[%d] ddbstate=0x%x, " | |
949 | - "next_fw_ddb_index=%d.\n", ha->host_no, __func__, | |
950 | + DEBUG2(dev_info(&ha->pdev->dev, "%s: DDB[%d] ddbstate=0x%x, " | |
951 | + "next_fw_ddb_index=%d.\n", __func__, | |
952 | fw_ddb_index, ddb_state, next_fw_ddb_index)); | |
953 | ||
954 | /* Issue relogin, if necessary. */ | |
955 | if (ddb_state == DDB_DS_SESSION_FAILED || | |
956 | ddb_state == DDB_DS_NO_CONNECTION_ACTIVE) { | |
957 | + ipv6_device = le16_to_cpu(fw_ddb_entry->options) & | |
958 | + DDB_OPT_IPV6_DEVICE; | |
959 | /* Try and login to device */ | |
960 | - DEBUG2(printk("scsi%ld: %s: Login to DDB[%d]\n", | |
961 | - ha->host_no, __func__, fw_ddb_index)); | |
962 | + DEBUG2(dev_info(&ha->pdev->dev, "%s: Login DDB[%d]\n", | |
963 | + __func__, fw_ddb_index)); | |
964 | err_code = ((conn_err & 0x00ff0000) >> 16); | |
965 | if (err_code == 0x1c || err_code == 0x06) { | |
966 | - DEBUG2(printk("scsi%ld: %s send target " | |
967 | - "completed " | |
968 | - "or access denied failure\n", | |
969 | - ha->host_no, __func__)); | |
970 | - } else { | |
971 | + DEBUG2(dev_info(&ha->pdev->dev, | |
972 | + ": %s send target completed or access" | |
973 | + " denied failure\n", __func__)); | |
974 | + } else if ((!ipv6_device && | |
975 | + *((uint32_t *)fw_ddb_entry->ip_addr)) || | |
976 | + ipv6_device) { | |
977 | qla4xxx_set_ddb_entry(ha, fw_ddb_index, 0); | |
978 | if (qla4xxx_get_fwddb_entry(ha, fw_ddb_index, | |
979 | - NULL, 0, NULL, &next_fw_ddb_index, | |
980 | - &ddb_state, &conn_err, NULL, NULL) | |
981 | - == QLA_ERROR) { | |
982 | - DEBUG2(printk("scsi%ld: %s:" | |
983 | - "get_ddb_entry %d failed\n", | |
984 | - ha->host_no, | |
985 | + fw_ddb_entry, fw_ddb_entry_dma, NULL, | |
986 | + &next_fw_ddb_index, &ddb_state, | |
987 | + &conn_err, &src_port, | |
988 | + &conn_id) == QLA_ERROR) { | |
989 | + DEBUG2(dev_info(&ha->pdev->dev, | |
990 | + "%s: get_fwddb %d failed\n", | |
991 | __func__, fw_ddb_index)); | |
992 | - return QLA_ERROR; | |
993 | + goto exit_ddb_list; | |
994 | } | |
995 | } | |
996 | } | |
997 | ||
998 | - if (ddb_state != DDB_DS_SESSION_ACTIVE) | |
999 | - goto next_one; | |
1000 | - /* | |
1001 | - * if fw_ddb with session active state found, | |
1002 | - * add to ddb_list | |
1003 | - */ | |
1004 | - DEBUG2(printk("scsi%ld: %s: DDB[%d] added to list\n", | |
1005 | - ha->host_no, __func__, fw_ddb_index)); | |
1006 | - | |
1007 | - /* Add DDB to internal our ddb list. */ | |
1008 | - ddb_entry = qla4xxx_get_ddb_entry(ha, fw_ddb_index, &new_tgt); | |
1009 | - if (ddb_entry == NULL) { | |
1010 | - DEBUG2(printk("scsi%ld: %s: Unable to allocate memory " | |
1011 | - "for device at fw_ddb_index %d\n", | |
1012 | - ha->host_no, __func__, fw_ddb_index)); | |
1013 | - return QLA_ERROR; | |
1014 | - } | |
1015 | - /* Fill in the device structure */ | |
1016 | - if (qla4xxx_update_ddb_entry(ha, ddb_entry, fw_ddb_index) == | |
1017 | - QLA_ERROR) { | |
1018 | - ha->fw_ddb_index_map[fw_ddb_index] = | |
1019 | - (struct ddb_entry *)INVALID_ENTRY; | |
1020 | - | |
1021 | - | |
1022 | - DEBUG2(printk("scsi%ld: %s: update_ddb_entry failed " | |
1023 | - "for fw_ddb_index %d.\n", | |
1024 | - ha->host_no, __func__, fw_ddb_index)); | |
1025 | - return QLA_ERROR; | |
1026 | + if (!(le16_to_cpu(fw_ddb_entry->options) & DDB_OPT_DISC_SESSION) && | |
1027 | + (ddb_state != DDB_DS_UNASSIGNED) && | |
1028 | + (strlen(fw_ddb_entry->iscsi_name) != 0)){ | |
1029 | + ddb_entry = qla4xxx_alloc_ddb(ha, fw_ddb_index); | |
1030 | + if (ddb_entry == NULL) { | |
1031 | + DEBUG2(dev_info(&ha->pdev->dev,"%s alloc_ddb %d " | |
1032 | + "failed\n", __func__, fw_ddb_index)); | |
1033 | + goto exit_ddb_list; | |
1034 | + } | |
1035 | + ddb_entry->fw_ddb_index = fw_ddb_index; | |
1036 | + ha->fw_ddb_index_map[fw_ddb_index] = ddb_entry; | |
1037 | + ddb_entry->tcp_source_port_num = src_port; | |
1038 | + ddb_entry->connection_id = conn_id; | |
1039 | + qla4xxx_fill_ddb(ddb_entry, fw_ddb_entry); | |
1040 | + ddb_entry->fw_ddb_device_state = ddb_state; | |
1041 | + | |
1042 | + if (ddb_entry->fw_ddb_device_state == DDB_DS_SESSION_ACTIVE) { | |
1043 | + atomic_set(&ddb_entry->state, DDB_STATE_ONLINE); | |
1044 | + dev_info(&ha->pdev->dev, | |
1045 | + "scsi%ld: %s: ddb[%d] os[%d] marked ONLINE\n", | |
1046 | + ha->host_no, __func__, ddb_entry->fw_ddb_index, | |
1047 | + ddb_entry->os_target_id); | |
1048 | + } else { | |
1049 | + atomic_set(&ddb_entry->state, DDB_STATE_MISSING); | |
1050 | + dev_info(&ha->pdev->dev, | |
1051 | + "scsi%ld: %s: ddb[%d] os[%d] marked MISSING\n", | |
1052 | + ha->host_no, __func__, ddb_entry->fw_ddb_index, | |
1053 | + ddb_entry->os_target_id); | |
1054 | + } | |
1055 | + DEBUG6(dev_info(&ha->pdev->dev, "%s: DDB[%d] osIdx = %d State %04x" | |
1056 | + " ConnErr %08x %d.%d.%d.%d:%04d \"%s\"\n", __func__, | |
1057 | + fw_ddb_index, ddb_entry->os_target_id, ddb_state, conn_err, | |
1058 | + fw_ddb_entry->ip_addr[0], fw_ddb_entry->ip_addr[1], | |
1059 | + fw_ddb_entry->ip_addr[2], fw_ddb_entry->ip_addr[3], | |
1060 | + le16_to_cpu(fw_ddb_entry->port), | |
1061 | + fw_ddb_entry->iscsi_name)); | |
1062 | } | |
1063 | ||
1064 | -next_one: | |
1065 | /* We know we've reached the last device when | |
1066 | * next_fw_ddb_index is 0 */ | |
1067 | if (next_fw_ddb_index == 0) | |
1068 | break; | |
1069 | } | |
1070 | ||
1071 | +exit_ddb_list: | |
1072 | + dma_free_coherent(&ha->pdev->dev, sizeof(*fw_ddb_entry), fw_ddb_entry, | |
1073 | + fw_ddb_entry_dma); | |
1074 | dev_info(&ha->pdev->dev, "DDB list done..\n"); | |
1075 | ||
1076 | return status; | |
1077 | @@ -682,15 +617,18 @@ static int qla4_scan_for_relogin(struct scsi_qla_host *ha, | |
1078 | static int qla4xxx_devices_ready(struct scsi_qla_host *ha) | |
1079 | { | |
1080 | int error; | |
1081 | - unsigned long discovery_wtime; | |
1082 | + unsigned long discovery_wtime = 0; | |
1083 | struct qla4_relog_scan rs; | |
1084 | ||
1085 | - discovery_wtime = jiffies + (ql4xdiscoverywait * HZ); | |
1086 | - | |
1087 | DEBUG(printk("Waiting (%d) for devices ...\n", ql4xdiscoverywait)); | |
1088 | do { | |
1089 | /* poll for AEN. */ | |
1090 | qla4xxx_get_firmware_state(ha); | |
1091 | + | |
1092 | + if(!(ha->addl_fw_state & FW_ADDSTATE_LINK_UP) && | |
1093 | + (discovery_wtime > QLA4XXX_LINK_UP_DELAY)) | |
1094 | + break; | |
1095 | + | |
1096 | if (test_and_clear_bit(DPC_AEN, &ha->dpc_flags)) { | |
1097 | /* Set time-between-relogin timer */ | |
1098 | qla4xxx_process_aen(ha, RELOGIN_DDB_CHANGED_AENS); | |
1099 | @@ -708,7 +646,8 @@ static int qla4xxx_devices_ready(struct scsi_qla_host *ha) | |
1100 | } | |
1101 | ||
1102 | msleep(2000); | |
1103 | - } while (!time_after_eq(jiffies, discovery_wtime)); | |
1104 | + discovery_wtime += 2; | |
1105 | + } while (discovery_wtime < ql4xdiscoverywait); | |
1106 | ||
1107 | DEBUG3(qla4xxx_get_conn_event_log(ha)); | |
1108 | ||
1109 | @@ -750,13 +689,13 @@ static int qla4xxx_initialize_ddb_list(struct scsi_qla_host *ha) | |
1110 | qla4xxx_free_ddb_list(ha); | |
1111 | ||
1112 | for (fw_ddb_index = 0; fw_ddb_index < MAX_DDB_ENTRIES; fw_ddb_index++) | |
1113 | - ha->fw_ddb_index_map[fw_ddb_index] = | |
1114 | - (struct ddb_entry *)INVALID_ENTRY; | |
1115 | + ha->fw_ddb_index_map[fw_ddb_index] = NULL; | |
1116 | ||
1117 | ha->tot_ddbs = 0; | |
1118 | ||
1119 | qla4xxx_flush_AENS(ha); | |
1120 | ||
1121 | + | |
1122 | /* | |
1123 | * First perform device discovery for active | |
1124 | * fw ddb indexes and build | |
1125 | @@ -773,7 +712,7 @@ static int qla4xxx_initialize_ddb_list(struct scsi_qla_host *ha) | |
1126 | * the aens here will catch them. | |
1127 | */ | |
1128 | if (test_and_clear_bit(DPC_AEN, &ha->dpc_flags)) | |
1129 | - qla4xxx_process_aen(ha, PROCESS_ALL_AENS); | |
1130 | + qla4xxx_process_aen(ha, PROCESS_FOR_PROBE); | |
1131 | ||
1132 | return status; | |
1133 | } | |
1134 | @@ -789,19 +728,37 @@ int qla4xxx_reinitialize_ddb_list(struct scsi_qla_host *ha) | |
1135 | { | |
1136 | int status = QLA_SUCCESS; | |
1137 | struct ddb_entry *ddb_entry, *detemp; | |
1138 | + struct dev_db_entry *fw_ddb_entry = NULL; | |
1139 | + dma_addr_t fw_ddb_entry_dma; | |
1140 | + | |
1141 | + fw_ddb_entry = dma_alloc_coherent(&ha->pdev->dev, | |
1142 | + sizeof(*fw_ddb_entry), &fw_ddb_entry_dma, | |
1143 | + GFP_KERNEL); | |
1144 | + if (fw_ddb_entry == NULL) | |
1145 | + return QLA_ERROR; | |
1146 | ||
1147 | /* Update the device information for all devices. */ | |
1148 | list_for_each_entry_safe(ddb_entry, detemp, &ha->ddb_list, list) { | |
1149 | - qla4xxx_update_ddb_entry(ha, ddb_entry, | |
1150 | - ddb_entry->fw_ddb_index); | |
1151 | - if (ddb_entry->fw_ddb_device_state == DDB_DS_SESSION_ACTIVE) { | |
1152 | - atomic_set(&ddb_entry->state, DDB_STATE_ONLINE); | |
1153 | - DEBUG2(printk ("scsi%ld: %s: ddb index [%d] marked " | |
1154 | - "ONLINE\n", ha->host_no, __func__, | |
1155 | - ddb_entry->fw_ddb_index)); | |
1156 | - } else if (atomic_read(&ddb_entry->state) == DDB_STATE_ONLINE) | |
1157 | - qla4xxx_mark_device_missing(ha, ddb_entry); | |
1158 | + if (qla4xxx_get_fwddb_entry(ha, ddb_entry->fw_ddb_index, | |
1159 | + fw_ddb_entry, fw_ddb_entry_dma, NULL, NULL, | |
1160 | + &ddb_entry->fw_ddb_device_state, NULL, | |
1161 | + &ddb_entry->tcp_source_port_num, | |
1162 | + &ddb_entry->connection_id) == QLA_SUCCESS) { | |
1163 | + | |
1164 | + qla4xxx_fill_ddb(ddb_entry, fw_ddb_entry); | |
1165 | + | |
1166 | + if (ddb_entry->fw_ddb_device_state == DDB_DS_SESSION_ACTIVE) { | |
1167 | + atomic_set(&ddb_entry->state, DDB_STATE_ONLINE); | |
1168 | + dev_info(&ha->pdev->dev, | |
1169 | + "scsi%ld: %s: ddb[%d] os[%d] marked ONLINE\n", | |
1170 | + ha->host_no, __func__, ddb_entry->fw_ddb_index, | |
1171 | + ddb_entry->os_target_id); | |
1172 | + } else if (atomic_read(&ddb_entry->state) == DDB_STATE_ONLINE) | |
1173 | + qla4xxx_mark_device_missing(ha, ddb_entry); | |
1174 | + } | |
1175 | } | |
1176 | + dma_free_coherent(&ha->pdev->dev, sizeof(*fw_ddb_entry), | |
1177 | + fw_ddb_entry, fw_ddb_entry_dma); | |
1178 | return status; | |
1179 | } | |
1180 | ||
1181 | @@ -884,12 +841,11 @@ static int qla4xxx_config_nvram(struct scsi_qla_host *ha) | |
1182 | static void qla4x00_pci_config(struct scsi_qla_host *ha) | |
1183 | { | |
1184 | uint16_t w; | |
1185 | - int status; | |
1186 | ||
1187 | dev_info(&ha->pdev->dev, "Configuring PCI space...\n"); | |
1188 | ||
1189 | pci_set_master(ha->pdev); | |
1190 | - status = pci_set_mwi(ha->pdev); | |
1191 | + pci_set_mwi(ha->pdev); | |
1192 | /* | |
1193 | * We want to respect framework's setting of PCI configuration space | |
1194 | * command register and also want to make sure that all bits of | |
1195 | @@ -1007,7 +963,7 @@ int ql4xxx_lock_drvr_wait(struct scsi_qla_host *a) | |
1196 | * qla4xxx_start_firmware - starts qla4xxx firmware | |
1197 | * @ha: Pointer to host adapter structure. | |
1198 | * | |
1199 | - * This routine performs the necessary steps to start the firmware for | |
1200 | + * This routine performs the neccessary steps to start the firmware for | |
1201 | * the QLA4010 adapter. | |
1202 | **/ | |
1203 | static int qla4xxx_start_firmware(struct scsi_qla_host *ha) | |
1204 | @@ -1127,7 +1083,7 @@ static int qla4xxx_start_firmware(struct scsi_qla_host *ha) | |
1205 | * @renew_ddb_list: Indicates what to do with the adapter's ddb list | |
1206 | * after adapter recovery has completed. | |
1207 | * 0=preserve ddb list, 1=destroy and rebuild ddb list | |
1208 | - * | |
1209 | + * | |
1210 | * This routine parforms all of the steps necessary to initialize the adapter. | |
1211 | * | |
1212 | **/ | |
1213 | @@ -1211,51 +1167,81 @@ exit_init_hba: | |
1214 | * This routine processes adds a device as a result of an 8014h AEN. | |
1215 | **/ | |
1216 | static void qla4xxx_add_device_dynamically(struct scsi_qla_host *ha, | |
1217 | - uint32_t fw_ddb_index) | |
1218 | + uint32_t fw_ddb_index, uint32_t probe) | |
1219 | { | |
1220 | - struct ddb_entry * ddb_entry; | |
1221 | - uint32_t new_tgt; | |
1222 | + struct dev_db_entry *fw_ddb_entry = NULL; | |
1223 | + dma_addr_t fw_ddb_entry_dma; | |
1224 | + uint16_t src_port, conn_id; | |
1225 | + struct ddb_entry *ddb_entry = NULL; | |
1226 | + uint32_t ddb_state, found = 0; | |
1227 | ||
1228 | - /* First allocate a device structure */ | |
1229 | - ddb_entry = qla4xxx_get_ddb_entry(ha, fw_ddb_index, &new_tgt); | |
1230 | - if (ddb_entry == NULL) { | |
1231 | - DEBUG2(printk(KERN_WARNING | |
1232 | - "scsi%ld: Unable to allocate memory to add " | |
1233 | - "fw_ddb_index %d\n", ha->host_no, fw_ddb_index)); | |
1234 | + fw_ddb_entry = dma_alloc_coherent(&ha->pdev->dev, sizeof(*fw_ddb_entry), | |
1235 | + &fw_ddb_entry_dma, GFP_KERNEL); | |
1236 | + | |
1237 | + if (fw_ddb_entry == NULL) { | |
1238 | + DEBUG2(dev_info(&ha->pdev->dev, "%s dmaalloc failed\n", __func__)); | |
1239 | return; | |
1240 | } | |
1241 | ||
1242 | - if (!new_tgt && (ddb_entry->fw_ddb_index != fw_ddb_index)) { | |
1243 | + if (qla4xxx_get_fwddb_entry(ha, fw_ddb_index, fw_ddb_entry, | |
1244 | + fw_ddb_entry_dma, NULL, NULL, &ddb_state, NULL, &src_port, | |
1245 | + &conn_id) == QLA_ERROR) { | |
1246 | + DEBUG2(dev_info(&ha->pdev->dev, "%s getddb %d failed\n", | |
1247 | + __func__, fw_ddb_index)); | |
1248 | + return; | |
1249 | + } | |
1250 | + | |
1251 | + list_for_each_entry(ddb_entry, &ha->ddb_list, list) { | |
1252 | + if (memcmp(ddb_entry->iscsi_name, fw_ddb_entry->iscsi_name, | |
1253 | + ISCSI_NAME_SIZE) == 0) { | |
1254 | + found = 1; | |
1255 | + | |
1256 | + DEBUG6(dev_info(&ha->pdev->dev, "%s found target ddb = 0x%p" | |
1257 | + " sess 0x%p conn 0x%p state 0x%x nidx 0x%x oidx 0x%x\n", | |
1258 | + __func__, ddb_entry, ddb_entry->sess, ddb_entry->conn, | |
1259 | + ddb_entry->state, fw_ddb_index, ddb_entry->fw_ddb_index)); | |
1260 | + break; | |
1261 | + } | |
1262 | + } | |
1263 | + | |
1264 | + if (!found) | |
1265 | + ddb_entry = qla4xxx_alloc_ddb(ha, fw_ddb_index); | |
1266 | + else if (ddb_entry->fw_ddb_index != fw_ddb_index) { | |
1267 | /* Target has been bound to a new fw_ddb_index */ | |
1268 | qla4xxx_free_ddb(ha, ddb_entry); | |
1269 | ddb_entry = qla4xxx_alloc_ddb(ha, fw_ddb_index); | |
1270 | - if (ddb_entry == NULL) { | |
1271 | - DEBUG2(printk(KERN_WARNING | |
1272 | - "scsi%ld: Unable to allocate memory" | |
1273 | - " to add fw_ddb_index %d\n", | |
1274 | - ha->host_no, fw_ddb_index)); | |
1275 | - return; | |
1276 | - } | |
1277 | } | |
1278 | - if (qla4xxx_update_ddb_entry(ha, ddb_entry, fw_ddb_index) == | |
1279 | - QLA_ERROR) { | |
1280 | - ha->fw_ddb_index_map[fw_ddb_index] = | |
1281 | - (struct ddb_entry *)INVALID_ENTRY; | |
1282 | - DEBUG2(printk(KERN_WARNING | |
1283 | - "scsi%ld: failed to add new device at index " | |
1284 | - "[%d]\n Unable to retrieve fw ddb entry\n", | |
1285 | - ha->host_no, fw_ddb_index)); | |
1286 | - qla4xxx_free_ddb(ha, ddb_entry); | |
1287 | - return; | |
1288 | + | |
1289 | + if (ddb_entry == NULL) { | |
1290 | + DEBUG2(dev_info(&ha->pdev->dev, "%s NULL DDB %d\n", | |
1291 | + __func__, fw_ddb_index)); | |
1292 | + goto exit_dyn_add; | |
1293 | } | |
1294 | ||
1295 | - if (qla4xxx_add_sess(ddb_entry)) { | |
1296 | - DEBUG2(printk(KERN_WARNING | |
1297 | + ddb_entry->fw_ddb_index = fw_ddb_index; | |
1298 | + ha->fw_ddb_index_map[fw_ddb_index] = ddb_entry; | |
1299 | + ddb_entry->tcp_source_port_num = src_port; | |
1300 | + ddb_entry->connection_id = conn_id; | |
1301 | + qla4xxx_fill_ddb(ddb_entry, fw_ddb_entry); | |
1302 | + ddb_entry->fw_ddb_device_state = ddb_state; | |
1303 | + | |
1304 | + if (!probe) { | |
1305 | + if (qla4xxx_add_sess(ddb_entry, 1)) { | |
1306 | + DEBUG2(printk(KERN_WARNING | |
1307 | "scsi%ld: failed to add new device at index " | |
1308 | "[%d]\n Unable to add connection and session\n", | |
1309 | ha->host_no, fw_ddb_index)); | |
1310 | - qla4xxx_free_ddb(ha, ddb_entry); | |
1311 | + qla4xxx_free_ddb(ha, ddb_entry); | |
1312 | + } | |
1313 | } | |
1314 | + | |
1315 | + DEBUG6(dev_info(&ha->pdev->dev, "%s added ddb 0x%p sess 0x%p conn 0x%p" | |
1316 | + " state 0x%x\n", __func__, ddb_entry, ddb_entry->sess, | |
1317 | + ddb_entry->conn, ddb_entry->state)); | |
1318 | +exit_dyn_add: | |
1319 | + dma_free_coherent(&ha->pdev->dev, sizeof(*fw_ddb_entry), fw_ddb_entry, | |
1320 | + fw_ddb_entry_dma); | |
1321 | + return; | |
1322 | } | |
1323 | ||
1324 | /** | |
1325 | @@ -1267,11 +1253,13 @@ static void qla4xxx_add_device_dynamically(struct scsi_qla_host *ha, | |
1326 | * This routine processes a Decive Database Changed AEN Event. | |
1327 | **/ | |
1328 | int qla4xxx_process_ddb_changed(struct scsi_qla_host *ha, | |
1329 | - uint32_t fw_ddb_index, uint32_t state) | |
1330 | + uint32_t fw_ddb_index, uint32_t state, uint32_t probe) | |
1331 | { | |
1332 | struct ddb_entry * ddb_entry; | |
1333 | uint32_t old_fw_ddb_device_state; | |
1334 | ||
1335 | + DEBUG6(dev_info(&ha->pdev->dev, "%s idx %d nstate 0x%x\n", | |
1336 | + __func__, fw_ddb_index, state)); | |
1337 | /* check for out of range index */ | |
1338 | if (fw_ddb_index >= MAX_DDB_ENTRIES) | |
1339 | return QLA_ERROR; | |
1340 | @@ -1281,9 +1269,12 @@ int qla4xxx_process_ddb_changed(struct scsi_qla_host *ha, | |
1341 | /* Device does not currently exist in our database. */ | |
1342 | if (ddb_entry == NULL) { | |
1343 | if (state == DDB_DS_SESSION_ACTIVE) | |
1344 | - qla4xxx_add_device_dynamically(ha, fw_ddb_index); | |
1345 | + qla4xxx_add_device_dynamically(ha, fw_ddb_index, probe); | |
1346 | return QLA_SUCCESS; | |
1347 | } | |
1348 | + DEBUG6(dev_info(&ha->pdev->dev, "%s ddb_entry 0x%p ostate 0x%x" | |
1349 | + " sess 0x%p conn 0x%p\n", __func__, ddb_entry, | |
1350 | + ddb_entry->state, ddb_entry->sess, ddb_entry->conn)); | |
1351 | ||
1352 | /* Device already exists in our database. */ | |
1353 | old_fw_ddb_device_state = ddb_entry->fw_ddb_device_state; | |
1354 | @@ -1297,25 +1288,43 @@ int qla4xxx_process_ddb_changed(struct scsi_qla_host *ha, | |
1355 | } | |
1356 | ||
1357 | ddb_entry->fw_ddb_device_state = state; | |
1358 | + | |
1359 | + if (probe) | |
1360 | + return QLA_SUCCESS; | |
1361 | + | |
1362 | /* Device is back online. */ | |
1363 | if (ddb_entry->fw_ddb_device_state == DDB_DS_SESSION_ACTIVE) { | |
1364 | - atomic_set(&ddb_entry->state, DDB_STATE_ONLINE); | |
1365 | atomic_set(&ddb_entry->port_down_timer, | |
1366 | ha->port_down_retry_count); | |
1367 | + atomic_set(&ddb_entry->state, DDB_STATE_ONLINE); | |
1368 | atomic_set(&ddb_entry->relogin_retry_count, 0); | |
1369 | atomic_set(&ddb_entry->relogin_timer, 0); | |
1370 | clear_bit(DF_RELOGIN, &ddb_entry->flags); | |
1371 | clear_bit(DF_NO_RELOGIN, &ddb_entry->flags); | |
1372 | - iscsi_unblock_session(ddb_entry->sess); | |
1373 | - iscsi_session_event(ddb_entry->sess, | |
1374 | - ISCSI_KEVENT_CREATE_SESSION); | |
1375 | - /* | |
1376 | - * Change the lun state to READY in case the lun TIMEOUT before | |
1377 | - * the device came back. | |
1378 | - */ | |
1379 | + | |
1380 | + DEBUG6(dev_info(&ha->pdev->dev, "%s conn startddb_entry 0x%p" | |
1381 | + " sess 0x%p conn 0x%p\n", | |
1382 | + __func__, ddb_entry, ddb_entry->sess, ddb_entry->conn)); | |
1383 | + | |
1384 | + qla4xxx_conn_start(ddb_entry->conn); | |
1385 | + | |
1386 | + DEBUG6(dev_info(&ha->pdev->dev, "%s conn start done " | |
1387 | + "ddb_entry 0x%p sess 0x%p conn 0x%p\n", | |
1388 | + __func__, ddb_entry, ddb_entry->sess, ddb_entry->conn)); | |
1389 | + | |
1390 | + if (!test_bit(DF_SCAN_ISSUED, &ddb_entry->flags)) { | |
1391 | + scsi_scan_target(&ddb_entry->sess->dev, 0, | |
1392 | + ddb_entry->sess->target_id, | |
1393 | + SCAN_WILD_CARD, 0); | |
1394 | + set_bit(DF_SCAN_ISSUED, &ddb_entry->flags); | |
1395 | + } | |
1396 | } else { | |
1397 | /* Device went away, try to relogin. */ | |
1398 | /* Mark device missing */ | |
1399 | + DEBUG6(dev_info(&ha->pdev->dev, "%s mark missing ddb_entry 0x%p" | |
1400 | + " sess 0x%p conn 0x%p\n", __func__, ddb_entry, | |
1401 | + ddb_entry->sess, ddb_entry->conn)); | |
1402 | + | |
1403 | if (atomic_read(&ddb_entry->state) == DDB_STATE_ONLINE) | |
1404 | qla4xxx_mark_device_missing(ha, ddb_entry); | |
1405 | /* | |
1406 | @@ -1325,8 +1334,7 @@ int qla4xxx_process_ddb_changed(struct scsi_qla_host *ha, | |
1407 | */ | |
1408 | if (ddb_entry->fw_ddb_device_state == DDB_DS_SESSION_FAILED && | |
1409 | !test_bit(DF_RELOGIN, &ddb_entry->flags) && | |
1410 | - !test_bit(DF_NO_RELOGIN, &ddb_entry->flags) && | |
1411 | - !test_bit(DF_ISNS_DISCOVERED, &ddb_entry->flags)) { | |
1412 | + !test_bit(DF_NO_RELOGIN, &ddb_entry->flags)) { | |
1413 | /* | |
1414 | * This triggers a relogin. After the relogin_timer | |
1415 | * expires, the relogin gets scheduled. We must wait a | |
1416 | diff --git a/drivers/scsi/qla4xxx/ql4_inline.h b/drivers/scsi/qla4xxx/ql4_inline.h | |
1417 | index 6375eb0..3cf28aa 100644 | |
1418 | --- a/drivers/scsi/qla4xxx/ql4_inline.h | |
1419 | +++ b/drivers/scsi/qla4xxx/ql4_inline.h | |
1420 | @@ -24,8 +24,7 @@ qla4xxx_lookup_ddb_by_fw_index(struct scsi_qla_host *ha, uint32_t fw_ddb_index) | |
1421 | struct ddb_entry *ddb_entry = NULL; | |
1422 | ||
1423 | if ((fw_ddb_index < MAX_DDB_ENTRIES) && | |
1424 | - (ha->fw_ddb_index_map[fw_ddb_index] != | |
1425 | - (struct ddb_entry *) INVALID_ENTRY)) { | |
1426 | + (ha->fw_ddb_index_map[fw_ddb_index] != NULL)) { | |
1427 | ddb_entry = ha->fw_ddb_index_map[fw_ddb_index]; | |
1428 | } | |
1429 | ||
1430 | diff --git a/drivers/scsi/qla4xxx/ql4_iocb.c b/drivers/scsi/qla4xxx/ql4_iocb.c | |
1431 | index 912a674..d387386 100644 | |
1432 | --- a/drivers/scsi/qla4xxx/ql4_iocb.c | |
1433 | +++ b/drivers/scsi/qla4xxx/ql4_iocb.c | |
1434 | @@ -6,11 +6,12 @@ | |
1435 | */ | |
1436 | ||
1437 | #include "ql4_def.h" | |
1438 | +#include "ql4_version.h" | |
1439 | #include "ql4_glbl.h" | |
1440 | #include "ql4_dbg.h" | |
1441 | #include "ql4_inline.h" | |
1442 | ||
1443 | - | |
1444 | +#define VMWARE_CMD_TIMEOUT 30 | |
1445 | #include <scsi/scsi_tcq.h> | |
1446 | ||
1447 | /** | |
1448 | @@ -67,9 +68,9 @@ static int qla4xxx_get_req_pkt(struct scsi_qla_host *ha, | |
1449 | * This routine issues a marker IOCB. | |
1450 | **/ | |
1451 | int qla4xxx_send_marker_iocb(struct scsi_qla_host *ha, | |
1452 | - struct ddb_entry *ddb_entry, int lun, uint16_t mrkr_mod) | |
1453 | + struct ddb_entry *ddb_entry, int lun) | |
1454 | { | |
1455 | - struct qla4_marker_entry *marker_entry; | |
1456 | + struct marker_entry *marker_entry; | |
1457 | unsigned long flags = 0; | |
1458 | uint8_t status = QLA_SUCCESS; | |
1459 | ||
1460 | @@ -87,7 +88,7 @@ int qla4xxx_send_marker_iocb(struct scsi_qla_host *ha, | |
1461 | marker_entry->hdr.entryType = ET_MARKER; | |
1462 | marker_entry->hdr.entryCount = 1; | |
1463 | marker_entry->target = cpu_to_le16(ddb_entry->fw_ddb_index); | |
1464 | - marker_entry->modifier = cpu_to_le16(mrkr_mod); | |
1465 | + marker_entry->modifier = cpu_to_le16(MM_LUN_RESET); | |
1466 | int_to_scsilun(lun, &marker_entry->lun); | |
1467 | wmb(); | |
1468 | ||
1469 | @@ -160,6 +161,13 @@ static void qla4xxx_build_scsi_iocbs(struct srb *srb, | |
1470 | avail_dsds = COMMAND_SEG; | |
1471 | cur_dsd = (struct data_seg_a64 *) & (cmd_entry->dataseg[0]); | |
1472 | ||
1473 | + if (srb->flags & SRB_SCSI_PASSTHRU) { | |
1474 | + cur_dsd->base.addrLow = cpu_to_le32(LSDW(srb->dma_handle)); | |
1475 | + cur_dsd->base.addrHigh = cpu_to_le32(MSDW(srb->dma_handle)); | |
1476 | + cur_dsd->count = cpu_to_le32(srb->dma_len); | |
1477 | + return; | |
1478 | + } | |
1479 | + | |
1480 | scsi_for_each_sg(cmd, sg, tot_dsds, i) { | |
1481 | dma_addr_t sle_dma; | |
1482 | ||
1483 | @@ -204,6 +212,7 @@ int qla4xxx_send_command_to_isp(struct scsi_qla_host *ha, struct srb * srb) | |
1484 | ||
1485 | unsigned long flags; | |
1486 | uint16_t cnt; | |
1487 | + uint16_t i; | |
1488 | uint32_t index; | |
1489 | char tag[2]; | |
1490 | ||
1491 | @@ -215,7 +224,22 @@ int qla4xxx_send_command_to_isp(struct scsi_qla_host *ha, struct srb * srb) | |
1492 | /* Acquire hardware specific lock */ | |
1493 | spin_lock_irqsave(&ha->hardware_lock, flags); | |
1494 | ||
1495 | - index = (uint32_t)cmd->request->tag; | |
1496 | + index = ha->current_active_index; | |
1497 | + for (i = 0; i < MAX_SRBS; i++) { | |
1498 | + index++; | |
1499 | + if (index == MAX_SRBS) | |
1500 | + index = 1; | |
1501 | + if (ha->active_srb_array[index] == 0) { | |
1502 | + ha->current_active_index = index; | |
1503 | + break; | |
1504 | + } | |
1505 | + } | |
1506 | + if (i >= MAX_SRBS) { | |
1507 | + printk(KERN_INFO "scsi%ld: %s: NO more SRB entries used " | |
1508 | + "iocbs=%d, \n reqs remaining=%d\n", ha->host_no, | |
1509 | + __func__, ha->iocb_cnt, ha->req_q_count); | |
1510 | + goto queuing_error; | |
1511 | + } | |
1512 | ||
1513 | /* Calculate the number of request entries needed. */ | |
1514 | nseg = scsi_dma_map(cmd); | |
1515 | @@ -258,8 +282,8 @@ int qla4xxx_send_command_to_isp(struct scsi_qla_host *ha, struct srb * srb) | |
1516 | ||
1517 | /* Set data transfer direction control flags | |
1518 | * NOTE: Look at data_direction bits iff there is data to be | |
1519 | - * transferred, as the data direction bit is sometimed filled | |
1520 | - * in when there is no data to be transferred */ | |
1521 | + * transferred, as the data direction bit is sometimed filled | |
1522 | + * in when there is no data to be transferred */ | |
1523 | cmd_entry->control_flags = CF_NO_DATA; | |
1524 | if (scsi_bufflen(cmd)) { | |
1525 | if (cmd->sc_data_direction == DMA_TO_DEVICE) | |
1526 | @@ -286,7 +310,6 @@ int qla4xxx_send_command_to_isp(struct scsi_qla_host *ha, struct srb * srb) | |
1527 | break; | |
1528 | } | |
1529 | ||
1530 | - | |
1531 | /* Advance request queue pointer */ | |
1532 | ha->request_in++; | |
1533 | if (ha->request_in == REQUEST_QUEUE_DEPTH) { | |
1534 | @@ -313,6 +336,7 @@ int qla4xxx_send_command_to_isp(struct scsi_qla_host *ha, struct srb * srb) | |
1535 | } | |
1536 | ||
1537 | srb->cmd->host_scribble = (unsigned char *)srb; | |
1538 | + ha->active_srb_array[index] = srb; | |
1539 | ||
1540 | /* update counters */ | |
1541 | srb->state = SRB_ACTIVE_STATE; | |
1542 | @@ -331,6 +355,9 @@ int qla4xxx_send_command_to_isp(struct scsi_qla_host *ha, struct srb * srb) | |
1543 | return QLA_SUCCESS; | |
1544 | ||
1545 | queuing_error: | |
1546 | + if (srb->flags & SRB_SCSI_PASSTHRU) | |
1547 | + return QLA_ERROR; | |
1548 | + | |
1549 | if (tot_dsds) | |
1550 | scsi_dma_unmap(cmd); | |
1551 | ||
1552 | @@ -338,4 +365,3 @@ queuing_error: | |
1553 | ||
1554 | return QLA_ERROR; | |
1555 | } | |
1556 | - | |
1557 | diff --git a/drivers/scsi/qla4xxx/ql4_isr.c b/drivers/scsi/qla4xxx/ql4_isr.c | |
1558 | index 799120f..dfe985b 100644 | |
1559 | --- a/drivers/scsi/qla4xxx/ql4_isr.c | |
1560 | +++ b/drivers/scsi/qla4xxx/ql4_isr.c | |
1561 | @@ -6,6 +6,7 @@ | |
1562 | */ | |
1563 | ||
1564 | #include "ql4_def.h" | |
1565 | +#include "ql4_version.h" | |
1566 | #include "ql4_glbl.h" | |
1567 | #include "ql4_dbg.h" | |
1568 | #include "ql4_inline.h" | |
1569 | @@ -27,11 +28,6 @@ static void qla4xxx_status_entry(struct scsi_qla_host *ha, | |
1570 | ||
1571 | srb = qla4xxx_del_from_active_array(ha, le32_to_cpu(sts_entry->handle)); | |
1572 | if (!srb) { | |
1573 | - /* FIXMEdg: Don't we need to reset ISP in this case??? */ | |
1574 | - DEBUG2(printk(KERN_WARNING "scsi%ld: %s: Status Entry invalid " | |
1575 | - "handle 0x%x, sp=%p. This cmd may have already " | |
1576 | - "been completed.\n", ha->host_no, __func__, | |
1577 | - le32_to_cpu(sts_entry->handle), srb)); | |
1578 | dev_warn(&ha->pdev->dev, "%s invalid status entry:" | |
1579 | " handle=0x%0x\n", __func__, sts_entry->handle); | |
1580 | set_bit(DPC_RESET_HA, &ha->dpc_flags); | |
1581 | @@ -40,12 +36,9 @@ static void qla4xxx_status_entry(struct scsi_qla_host *ha, | |
1582 | ||
1583 | cmd = srb->cmd; | |
1584 | if (cmd == NULL) { | |
1585 | - DEBUG2(printk("scsi%ld: %s: Command already returned back to " | |
1586 | - "OS pkt->handle=%d srb=%p srb->state:%d\n", | |
1587 | - ha->host_no, __func__, sts_entry->handle, | |
1588 | - srb, srb->state)); | |
1589 | - dev_warn(&ha->pdev->dev, "Command is NULL:" | |
1590 | - " already returned to OS (srb=%p)\n", srb); | |
1591 | + dev_warn(&ha->pdev->dev, "%s Command is NULL: srb=%p" | |
1592 | + " sts_handle=0x%0x srb_state=0x%0x\n", __func__, | |
1593 | + srb, sts_entry->handle, srb->state); | |
1594 | return; | |
1595 | } | |
1596 | ||
1597 | @@ -61,27 +54,15 @@ static void qla4xxx_status_entry(struct scsi_qla_host *ha, | |
1598 | scsi_status = sts_entry->scsiStatus; | |
1599 | switch (sts_entry->completionStatus) { | |
1600 | case SCS_COMPLETE: | |
1601 | - | |
1602 | if (sts_entry->iscsiFlags & ISCSI_FLAG_RESIDUAL_OVER) { | |
1603 | cmd->result = DID_ERROR << 16; | |
1604 | break; | |
1605 | } | |
1606 | - | |
1607 | - if (sts_entry->iscsiFlags &ISCSI_FLAG_RESIDUAL_UNDER) { | |
1608 | + if (sts_entry->iscsiFlags & ISCSI_FLAG_RESIDUAL_UNDER) { | |
1609 | scsi_set_resid(cmd, residual); | |
1610 | if (!scsi_status && ((scsi_bufflen(cmd) - residual) < | |
1611 | - cmd->underflow)) { | |
1612 | - | |
1613 | + cmd->underflow)) { | |
1614 | cmd->result = DID_ERROR << 16; | |
1615 | - | |
1616 | - DEBUG2(printk("scsi%ld:%d:%d:%d: %s: " | |
1617 | - "Mid-layer Data underrun0, " | |
1618 | - "xferlen = 0x%x, " | |
1619 | - "residual = 0x%x\n", ha->host_no, | |
1620 | - cmd->device->channel, | |
1621 | - cmd->device->id, | |
1622 | - cmd->device->lun, __func__, | |
1623 | - scsi_bufflen(cmd), residual)); | |
1624 | break; | |
1625 | } | |
1626 | } | |
1627 | @@ -218,13 +202,13 @@ static void qla4xxx_status_entry(struct scsi_qla_host *ha, | |
1628 | * will return DID_ERROR. | |
1629 | */ | |
1630 | DEBUG2(printk("scsi%ld:%d:%d:%d: %s: " | |
1631 | - "Mid-layer Data underrun1, " | |
1632 | - "xferlen = 0x%x, " | |
1633 | - "residual = 0x%x\n", ha->host_no, | |
1634 | - cmd->device->channel, | |
1635 | - cmd->device->id, | |
1636 | - cmd->device->lun, __func__, | |
1637 | - scsi_bufflen(cmd), residual)); | |
1638 | + "Mid-layer Data underrun len = 0x%x, " | |
1639 | + "resid = 0x%x, compstat = 0x%x\n", | |
1640 | + ha->host_no, cmd->device->channel, | |
1641 | + cmd->device->id, cmd->device->lun, | |
1642 | + __func__, scsi_bufflen(cmd), | |
1643 | + residual, | |
1644 | + sts_entry->completionStatus)); | |
1645 | ||
1646 | cmd->result = DID_ERROR << 16; | |
1647 | } else { | |
1648 | @@ -414,6 +398,15 @@ static void qla4xxx_isr_decode_mailbox(struct scsi_qla_host * ha, | |
1649 | } else if (mbox_status >> 12 == MBOX_ASYNC_EVENT_STATUS) { | |
1650 | /* Immediately process the AENs that don't require much work. | |
1651 | * Only queue the database_changed AENs */ | |
1652 | + | |
1653 | + dev_info(&ha->pdev->dev, "%s mbx0 0x%08x mbx1 0x%08x" | |
1654 | + " mbx2 0x%08x mbx3 0x%08x mbx4 0x%08x mbx5 0x%08x " | |
1655 | + "mbx6 0x%08x mbx7 0x%08x\n", __func__, | |
1656 | + readl(&ha->reg->mailbox[0]), readl(&ha->reg->mailbox[1]), | |
1657 | + readl(&ha->reg->mailbox[2]), readl(&ha->reg->mailbox[3]), | |
1658 | + readl(&ha->reg->mailbox[4]), readl(&ha->reg->mailbox[5]), | |
1659 | + readl(&ha->reg->mailbox[6]), readl(&ha->reg->mailbox[7])); | |
1660 | + | |
1661 | if (ha->aen_log.count < MAX_AEN_ENTRIES) { | |
1662 | for (i = 0; i < MBOX_AEN_REG_COUNT; i++) | |
1663 | ha->aen_log.entry[ha->aen_log.count].mbox_sts[i] = | |
1664 | @@ -480,9 +473,9 @@ static void qla4xxx_isr_decode_mailbox(struct scsi_qla_host * ha, | |
1665 | mbox_stat2 = readl(&ha->reg->mailbox[2]); | |
1666 | mbox_stat3 = readl(&ha->reg->mailbox[3]); | |
1667 | ||
1668 | - if ((mbox_stat3 == 5) && (mbox_stat2 == 3)) | |
1669 | + if ((mbox_stat3 == 5) && (mbox_stat2 == 3)) | |
1670 | set_bit(DPC_GET_DHCP_IP_ADDR, &ha->dpc_flags); | |
1671 | - else if ((mbox_stat3 == 2) && (mbox_stat2 == 5)) | |
1672 | + else if ((mbox_stat3 == 2) && (mbox_stat2 == 5)) | |
1673 | set_bit(DPC_RESET_HA, &ha->dpc_flags); | |
1674 | break; | |
1675 | ||
1676 | @@ -604,6 +597,7 @@ void qla4xxx_interrupt_service_routine(struct scsi_qla_host * ha, | |
1677 | **/ | |
1678 | irqreturn_t qla4xxx_intr_handler(int irq, void *dev_id) | |
1679 | { | |
1680 | + | |
1681 | struct scsi_qla_host *ha; | |
1682 | uint32_t intr_status; | |
1683 | unsigned long flags = 0; | |
1684 | @@ -714,7 +708,17 @@ void qla4xxx_process_aen(struct scsi_qla_host * ha, uint8_t process_aen) | |
1685 | int i; | |
1686 | unsigned long flags; | |
1687 | ||
1688 | + DEBUG6(dev_info(&ha->pdev->dev, "%s proc_aen 0x%x\n", | |
1689 | + __func__, process_aen)); | |
1690 | + | |
1691 | spin_lock_irqsave(&ha->hardware_lock, flags); | |
1692 | + if (process_aen == FLUSH_DDB_CHANGED_AENS) { | |
1693 | + ha->aen_q_count = MAX_AEN_ENTRIES; | |
1694 | + ha->aen_out = ha->aen_in = 0; | |
1695 | + spin_unlock_irqrestore(&ha->hardware_lock, flags); | |
1696 | + return; | |
1697 | + } | |
1698 | + | |
1699 | while (ha->aen_out != ha->aen_in) { | |
1700 | aen = &ha->aen_q[ha->aen_out]; | |
1701 | /* copy aen information to local structure */ | |
1702 | @@ -727,60 +731,46 @@ void qla4xxx_process_aen(struct scsi_qla_host * ha, uint8_t process_aen) | |
1703 | if (ha->aen_out == MAX_AEN_ENTRIES) | |
1704 | ha->aen_out = 0; | |
1705 | ||
1706 | - spin_unlock_irqrestore(&ha->hardware_lock, flags); | |
1707 | + DEBUG6(dev_info(&ha->pdev->dev, "%s mbx0 0x%x mbx1 0x%x mbx2 " | |
1708 | + "0x%x mbx3 0x%x ddb 0x%p\n", __func__, mbox_sts[0], | |
1709 | + mbox_sts[1], mbox_sts[2], mbox_sts[3], | |
1710 | + qla4xxx_lookup_ddb_by_fw_index(ha, mbox_sts[2]))); | |
1711 | ||
1712 | - DEBUG2(printk("qla4xxx(%ld): AEN[%d]=0x%08x, mbx1=0x%08x mbx2=0x%08x" | |
1713 | - " mbx3=0x%08x mbx4=0x%08x\n", ha->host_no, | |
1714 | - (ha->aen_out ? (ha->aen_out-1): (MAX_AEN_ENTRIES-1)), | |
1715 | - mbox_sts[0], mbox_sts[1], mbox_sts[2], | |
1716 | - mbox_sts[3], mbox_sts[4])); | |
1717 | + if (process_aen == RELOGIN_DDB_CHANGED_AENS) { | |
1718 | + /* for use during init time, we only want to | |
1719 | + * relogin non-active ddbs */ | |
1720 | + struct ddb_entry *ddb_entry; | |
1721 | ||
1722 | - switch (mbox_sts[0]) { | |
1723 | - case MBOX_ASTS_DATABASE_CHANGED: | |
1724 | - if (process_aen == FLUSH_DDB_CHANGED_AENS) { | |
1725 | - DEBUG2(printk("scsi%ld: AEN[%d] %04x, index " | |
1726 | - "[%d] state=%04x FLUSHED!\n", | |
1727 | - ha->host_no, ha->aen_out, | |
1728 | - mbox_sts[0], mbox_sts[2], | |
1729 | - mbox_sts[3])); | |
1730 | - break; | |
1731 | - } else if (process_aen == RELOGIN_DDB_CHANGED_AENS) { | |
1732 | - /* for use during init time, we only want to | |
1733 | - * relogin non-active ddbs */ | |
1734 | - struct ddb_entry *ddb_entry; | |
1735 | - | |
1736 | - ddb_entry = | |
1737 | - /* FIXME: name length? */ | |
1738 | - qla4xxx_lookup_ddb_by_fw_index(ha, | |
1739 | - mbox_sts[2]); | |
1740 | - if (!ddb_entry) | |
1741 | - break; | |
1742 | - | |
1743 | - ddb_entry->dev_scan_wait_to_complete_relogin = | |
1744 | - 0; | |
1745 | + ddb_entry = qla4xxx_lookup_ddb_by_fw_index(ha, mbox_sts[2]); | |
1746 | + | |
1747 | + if (ddb_entry) { | |
1748 | + | |
1749 | + DEBUG6(dev_info(&ha->pdev->dev, "%s ddb 0x%p " | |
1750 | + "sess 0x%p conn 0x%p state 0x%x\n", | |
1751 | + __func__, ddb_entry, ddb_entry->sess, | |
1752 | + ddb_entry->conn, ddb_entry->state)); | |
1753 | + | |
1754 | + ddb_entry->dev_scan_wait_to_complete_relogin = 0; | |
1755 | ddb_entry->dev_scan_wait_to_start_relogin = | |
1756 | jiffies + | |
1757 | - ((ddb_entry->default_time2wait + | |
1758 | - 4) * HZ); | |
1759 | + ((ddb_entry->default_time2wait + 4) * HZ); | |
1760 | ||
1761 | DEBUG2(printk("scsi%ld: ddb index [%d] initate" | |
1762 | - " RELOGIN after %d seconds\n", | |
1763 | - ha->host_no, | |
1764 | - ddb_entry->fw_ddb_index, | |
1765 | - ddb_entry->default_time2wait + | |
1766 | - 4)); | |
1767 | - break; | |
1768 | + " RELOGIN after %d seconds\n", ha->host_no, | |
1769 | + ddb_entry->fw_ddb_index, | |
1770 | + ddb_entry->default_time2wait + 4)); | |
1771 | } | |
1772 | - | |
1773 | + } else if (mbox_sts[0] == MBOX_ASTS_DATABASE_CHANGED) { | |
1774 | + spin_unlock_irqrestore(&ha->hardware_lock, flags); | |
1775 | if (mbox_sts[1] == 0) { /* Global DB change. */ | |
1776 | qla4xxx_reinitialize_ddb_list(ha); | |
1777 | } else if (mbox_sts[1] == 1) { /* Specific device. */ | |
1778 | qla4xxx_process_ddb_changed(ha, mbox_sts[2], | |
1779 | - mbox_sts[3]); | |
1780 | + mbox_sts[3], | |
1781 | + ((process_aen == PROCESS_FOR_PROBE) ? 1 : 0 )); | |
1782 | } | |
1783 | - break; | |
1784 | + spin_lock_irqsave(&ha->hardware_lock, flags); | |
1785 | } | |
1786 | - spin_lock_irqsave(&ha->hardware_lock, flags); | |
1787 | } | |
1788 | spin_unlock_irqrestore(&ha->hardware_lock, flags); | |
1789 | } | |
1790 | diff --git a/drivers/scsi/qla4xxx/ql4_mbx.c b/drivers/scsi/qla4xxx/ql4_mbx.c | |
1791 | index c577d79..dbd7218 100644 | |
1792 | --- a/drivers/scsi/qla4xxx/ql4_mbx.c | |
1793 | +++ b/drivers/scsi/qla4xxx/ql4_mbx.c | |
1794 | @@ -6,6 +6,7 @@ | |
1795 | */ | |
1796 | ||
1797 | #include "ql4_def.h" | |
1798 | +#include "ql4_version.h" | |
1799 | #include "ql4_glbl.h" | |
1800 | #include "ql4_dbg.h" | |
1801 | #include "ql4_inline.h" | |
1802 | @@ -23,9 +24,9 @@ | |
1803 | * If outCount is 0, this routine completes successfully WITHOUT waiting | |
1804 | * for the mailbox command to complete. | |
1805 | **/ | |
1806 | -static int qla4xxx_mailbox_command(struct scsi_qla_host *ha, uint8_t inCount, | |
1807 | - uint8_t outCount, uint32_t *mbx_cmd, | |
1808 | - uint32_t *mbx_sts) | |
1809 | +int qla4xxx_mailbox_command(struct scsi_qla_host *ha, uint8_t inCount, | |
1810 | + uint8_t outCount, uint32_t *mbx_cmd, | |
1811 | + uint32_t *mbx_sts) | |
1812 | { | |
1813 | int status = QLA_ERROR; | |
1814 | uint8_t i; | |
1815 | @@ -39,9 +40,9 @@ static int qla4xxx_mailbox_command(struct scsi_qla_host *ha, uint8_t inCount, | |
1816 | "pointer\n", ha->host_no, __func__)); | |
1817 | return status; | |
1818 | } | |
1819 | + | |
1820 | /* Mailbox code active */ | |
1821 | wait_count = MBOX_TOV * 100; | |
1822 | - | |
1823 | while (wait_count--) { | |
1824 | mutex_lock(&ha->mbox_sem); | |
1825 | if (!test_bit(AF_MBOX_COMMAND, &ha->flags)) { | |
1826 | @@ -87,8 +88,6 @@ static int qla4xxx_mailbox_command(struct scsi_qla_host *ha, uint8_t inCount, | |
1827 | readl(&ha->reg->ctrl_status); | |
1828 | spin_unlock_irqrestore(&ha->hardware_lock, flags); | |
1829 | ||
1830 | - /* Wait for completion */ | |
1831 | - | |
1832 | /* | |
1833 | * If we don't want status, don't wait for the mailbox command to | |
1834 | * complete. For example, MBOX_CMD_RESET_FW doesn't return status, | |
1835 | @@ -98,6 +97,8 @@ static int qla4xxx_mailbox_command(struct scsi_qla_host *ha, uint8_t inCount, | |
1836 | status = QLA_SUCCESS; | |
1837 | goto mbox_exit; | |
1838 | } | |
1839 | + /* Wait for completion */ | |
1840 | + set_current_state(TASK_UNINTERRUPTIBLE); | |
1841 | /* Wait for command to complete */ | |
1842 | wait_count = jiffies + MBOX_TOV * HZ; | |
1843 | while (test_bit(AF_MBOX_COMMAND_DONE, &ha->flags) == 0) { | |
1844 | @@ -119,6 +120,7 @@ static int qla4xxx_mailbox_command(struct scsi_qla_host *ha, uint8_t inCount, | |
1845 | spin_unlock_irqrestore(&ha->hardware_lock, flags); | |
1846 | msleep(10); | |
1847 | } | |
1848 | + set_current_state(TASK_RUNNING); | |
1849 | ||
1850 | /* Check for mailbox timeout. */ | |
1851 | if (!test_bit(AF_MBOX_COMMAND_DONE, &ha->flags)) { | |
1852 | @@ -172,6 +174,86 @@ mbox_exit: | |
1853 | return status; | |
1854 | } | |
1855 | ||
1856 | + | |
1857 | +/** | |
1858 | + * qla4xxx_issue_iocb - issue mailbox iocb command | |
1859 | + * @ha: adapter state pointer. | |
1860 | + * @buffer: buffer pointer. | |
1861 | + * @phys_addr: physical address of buffer. | |
1862 | + * @size: size of buffer. | |
1863 | + * | |
1864 | + * Issues iocbs via mailbox commands. | |
1865 | + * TARGET_QUEUE_LOCK must be released. | |
1866 | + * ADAPTER_STATE_LOCK must be released. | |
1867 | + **/ | |
1868 | +int | |
1869 | +qla4xxx_issue_iocb(struct scsi_qla_host * ha, void *buffer, | |
1870 | + dma_addr_t phys_addr, size_t size) | |
1871 | +{ | |
1872 | + uint32_t mbox_cmd[MBOX_REG_COUNT]; | |
1873 | + uint32_t mbox_sts[MBOX_REG_COUNT]; | |
1874 | + int status; | |
1875 | + | |
1876 | + memset(&mbox_cmd, 0, sizeof(mbox_cmd)); | |
1877 | + memset(&mbox_sts, 0, sizeof(mbox_sts)); | |
1878 | + | |
1879 | + mbox_cmd[0] = MBOX_CMD_EXECUTE_IOCB_A64; | |
1880 | + mbox_cmd[1] = 0; | |
1881 | + mbox_cmd[2] = LSDW(phys_addr); | |
1882 | + mbox_cmd[3] = MSDW(phys_addr); | |
1883 | + | |
1884 | + status = qla4xxx_mailbox_command(ha, MBOX_REG_COUNT, 1, &mbox_cmd[0], &mbox_sts[0]); | |
1885 | + return status; | |
1886 | +} | |
1887 | + | |
1888 | +int qla4xxx_conn_close_sess_logout(struct scsi_qla_host * ha, | |
1889 | + uint16_t fw_ddb_index, | |
1890 | + uint16_t connection_id, | |
1891 | + uint16_t option) | |
1892 | +{ | |
1893 | + uint32_t mbox_cmd[MBOX_REG_COUNT]; | |
1894 | + uint32_t mbox_sts[MBOX_REG_COUNT]; | |
1895 | + | |
1896 | + memset(&mbox_cmd, 0, sizeof(mbox_cmd)); | |
1897 | + memset(&mbox_sts, 0, sizeof(mbox_sts)); | |
1898 | + | |
1899 | + mbox_cmd[0] = MBOX_CMD_CONN_CLOSE_SESS_LOGOUT; | |
1900 | + mbox_cmd[1] = fw_ddb_index; | |
1901 | + mbox_cmd[2] = connection_id; | |
1902 | + mbox_cmd[3] = LOGOUT_OPTION_RELOGIN; | |
1903 | + | |
1904 | + if (qla4xxx_mailbox_command(ha, MBOX_REG_COUNT, 2, &mbox_cmd[0], &mbox_sts[0]) != | |
1905 | + QLA_SUCCESS) { | |
1906 | + DEBUG2(printk("scsi%ld: %s: MBOX_CMD_CONN_CLOSE_SESS_LOGOUT " | |
1907 | + "option %04x failed sts %04X %04X", | |
1908 | + ha->host_no, __func__, | |
1909 | + option, mbox_sts[0], mbox_sts[1])); | |
1910 | + if (mbox_sts[0] == 0x4005) | |
1911 | + DEBUG2(printk("%s reason %04X\n", __func__, | |
1912 | + mbox_sts[1])); | |
1913 | + } | |
1914 | + return QLA_SUCCESS; | |
1915 | +} | |
1916 | + | |
1917 | +int qla4xxx_clear_database_entry(struct scsi_qla_host * ha, | |
1918 | + uint16_t fw_ddb_index) | |
1919 | +{ | |
1920 | + uint32_t mbox_cmd[MBOX_REG_COUNT]; | |
1921 | + uint32_t mbox_sts[MBOX_REG_COUNT]; | |
1922 | + | |
1923 | + memset(&mbox_cmd, 0, sizeof(mbox_cmd)); | |
1924 | + memset(&mbox_sts, 0, sizeof(mbox_sts)); | |
1925 | + | |
1926 | + mbox_cmd[0] = MBOX_CMD_CLEAR_DATABASE_ENTRY; | |
1927 | + mbox_cmd[1] = fw_ddb_index; | |
1928 | + | |
1929 | + if (qla4xxx_mailbox_command(ha, MBOX_REG_COUNT, 5, &mbox_cmd[0], &mbox_sts[0]) != | |
1930 | + QLA_SUCCESS) | |
1931 | + return QLA_ERROR; | |
1932 | + | |
1933 | + return QLA_SUCCESS; | |
1934 | +} | |
1935 | + | |
1936 | /** | |
1937 | * qla4xxx_initialize_fw_cb - initializes firmware control block. | |
1938 | * @ha: Pointer to host adapter structure. | |
1939 | @@ -450,15 +532,16 @@ int qla4xxx_get_fwddb_entry(struct scsi_qla_host *ha, | |
1940 | mbox_sts[1])); | |
1941 | goto exit_get_fwddb; | |
1942 | } | |
1943 | + | |
1944 | if (fw_ddb_entry) { | |
1945 | - dev_info(&ha->pdev->dev, "DDB[%d] MB0 %04x Tot %d Next %d " | |
1946 | - "State %04x ConnErr %08x %d.%d.%d.%d:%04d \"%s\"\n", | |
1947 | + DEBUG6(dev_info(&ha->pdev->dev, "%s: DDB[%d] MB0 %04x Tot %d Next %d " | |
1948 | + "State %04x ConnErr %08x %d.%d.%d.%d:%04d \"%s\"\n", __func__, | |
1949 | fw_ddb_index, mbox_sts[0], mbox_sts[2], mbox_sts[3], | |
1950 | mbox_sts[4], mbox_sts[5], fw_ddb_entry->ip_addr[0], | |
1951 | fw_ddb_entry->ip_addr[1], fw_ddb_entry->ip_addr[2], | |
1952 | fw_ddb_entry->ip_addr[3], | |
1953 | le16_to_cpu(fw_ddb_entry->port), | |
1954 | - fw_ddb_entry->iscsi_name); | |
1955 | + fw_ddb_entry->iscsi_name)); | |
1956 | } | |
1957 | if (num_valid_ddb_entries) | |
1958 | *num_valid_ddb_entries = mbox_sts[2]; | |
1959 | @@ -518,6 +601,31 @@ int qla4xxx_set_ddb_entry(struct scsi_qla_host * ha, uint16_t fw_ddb_index, | |
1960 | return qla4xxx_mailbox_command(ha, MBOX_REG_COUNT, 1, &mbox_cmd[0], &mbox_sts[0]); | |
1961 | } | |
1962 | ||
1963 | +int qla4xxx_conn_open_session_login(struct scsi_qla_host * ha, | |
1964 | + uint16_t fw_ddb_index) | |
1965 | +{ | |
1966 | + int status = QLA_ERROR; | |
1967 | + uint32_t mbox_cmd[MBOX_REG_COUNT]; | |
1968 | + uint32_t mbox_sts[MBOX_REG_COUNT]; | |
1969 | + | |
1970 | + /* Do not wait for completion. The firmware will send us an | |
1971 | + * ASTS_DATABASE_CHANGED (0x8014) to notify us of the login status. | |
1972 | + */ | |
1973 | + memset(&mbox_cmd, 0, sizeof(mbox_cmd)); | |
1974 | + memset(&mbox_sts, 0, sizeof(mbox_sts)); | |
1975 | + | |
1976 | + mbox_cmd[0] = MBOX_CMD_CONN_OPEN_SESS_LOGIN; | |
1977 | + mbox_cmd[1] = (uint32_t) fw_ddb_index; | |
1978 | + mbox_cmd[6] = 1; | |
1979 | + | |
1980 | + status = qla4xxx_mailbox_command(ha, MBOX_REG_COUNT, 0, &mbox_cmd[0], &mbox_sts[0]); | |
1981 | + DEBUG2(printk("%s fw_ddb_index=%d status=%d mbx0_1=0x%x :0x%x\n", | |
1982 | + __func__, fw_ddb_index, status, mbox_sts[0], | |
1983 | + mbox_sts[1]);) | |
1984 | + | |
1985 | + return status; | |
1986 | +} | |
1987 | + | |
1988 | /** | |
1989 | * qla4xxx_get_crash_record - retrieves crash record. | |
1990 | * @ha: Pointer to host adapter structure. | |
1991 | @@ -642,7 +750,7 @@ void qla4xxx_get_conn_event_log(struct scsi_qla_host * ha) | |
1992 | DEBUG3(printk("scsi%ld: Connection Event Log Dump (%d entries):\n", | |
1993 | ha->host_no, num_valid_entries)); | |
1994 | ||
1995 | - if (ql4xextended_error_logging == 3) { | |
1996 | + if (extended_error_logging == 3) { | |
1997 | if (oldest_entry == 0) { | |
1998 | /* Circular Buffer has not wrapped around */ | |
1999 | for (i=0; i < num_valid_entries; i++) { | |
2000 | @@ -713,45 +821,6 @@ int qla4xxx_reset_lun(struct scsi_qla_host * ha, struct ddb_entry * ddb_entry, | |
2001 | return status; | |
2002 | } | |
2003 | ||
2004 | -/** | |
2005 | - * qla4xxx_reset_target - issues target Reset | |
2006 | - * @ha: Pointer to host adapter structure. | |
2007 | - * @db_entry: Pointer to device database entry | |
2008 | - * @un_entry: Pointer to lun entry structure | |
2009 | - * | |
2010 | - * This routine performs a TARGET RESET on the specified target. | |
2011 | - * The caller must ensure that the ddb_entry pointers | |
2012 | - * are valid before calling this routine. | |
2013 | - **/ | |
2014 | -int qla4xxx_reset_target(struct scsi_qla_host *ha, | |
2015 | - struct ddb_entry *ddb_entry) | |
2016 | -{ | |
2017 | - uint32_t mbox_cmd[MBOX_REG_COUNT]; | |
2018 | - uint32_t mbox_sts[MBOX_REG_COUNT]; | |
2019 | - int status = QLA_SUCCESS; | |
2020 | - | |
2021 | - DEBUG2(printk("scsi%ld:%d: target reset issued\n", ha->host_no, | |
2022 | - ddb_entry->os_target_id)); | |
2023 | - | |
2024 | - /* | |
2025 | - * Send target reset command to ISP, so that the ISP will return all | |
2026 | - * outstanding requests with RESET status | |
2027 | - */ | |
2028 | - memset(&mbox_cmd, 0, sizeof(mbox_cmd)); | |
2029 | - memset(&mbox_sts, 0, sizeof(mbox_sts)); | |
2030 | - | |
2031 | - mbox_cmd[0] = MBOX_CMD_TARGET_WARM_RESET; | |
2032 | - mbox_cmd[1] = ddb_entry->fw_ddb_index; | |
2033 | - mbox_cmd[5] = 0x01; /* Immediate Command Enable */ | |
2034 | - | |
2035 | - qla4xxx_mailbox_command(ha, MBOX_REG_COUNT, 1, &mbox_cmd[0], | |
2036 | - &mbox_sts[0]); | |
2037 | - if (mbox_sts[0] != MBOX_STS_COMMAND_COMPLETE && | |
2038 | - mbox_sts[0] != MBOX_STS_COMMAND_ERROR) | |
2039 | - status = QLA_ERROR; | |
2040 | - | |
2041 | - return status; | |
2042 | -} | |
2043 | ||
2044 | int qla4xxx_get_flash(struct scsi_qla_host * ha, dma_addr_t dma_addr, | |
2045 | uint32_t offset, uint32_t len) | |
2046 | @@ -782,8 +851,8 @@ int qla4xxx_get_flash(struct scsi_qla_host * ha, dma_addr_t dma_addr, | |
2047 | * qla4xxx_get_fw_version - gets firmware version | |
2048 | * @ha: Pointer to host adapter structure. | |
2049 | * | |
2050 | - * Retrieves the firmware version on HBA. In QLA4010, mailboxes 2 & 3 may | |
2051 | - * hold an address for data. Make sure that we write 0 to those mailboxes, | |
2052 | + * Retrieves the firmware version on HBA. In QLA4010, mailboxes 2 & 3 may | |
2053 | + * hold an address for data. Make sure that we write 0 to those mailboxes, | |
2054 | * if unused. | |
2055 | **/ | |
2056 | int qla4xxx_get_fw_version(struct scsi_qla_host * ha) | |
2057 | @@ -835,7 +904,7 @@ static int qla4xxx_get_default_ddb(struct scsi_qla_host *ha, | |
2058 | return QLA_SUCCESS; | |
2059 | } | |
2060 | ||
2061 | -static int qla4xxx_req_ddb_entry(struct scsi_qla_host *ha, uint32_t *ddb_index) | |
2062 | +int qla4xxx_req_ddb_entry(struct scsi_qla_host *ha, uint32_t *ddb_index) | |
2063 | { | |
2064 | uint32_t mbox_cmd[MBOX_REG_COUNT]; | |
2065 | uint32_t mbox_sts[MBOX_REG_COUNT]; | |
2066 | @@ -889,14 +958,14 @@ int qla4xxx_send_tgts(struct scsi_qla_host *ha, char *ip, uint16_t port) | |
2067 | if (ret_val != QLA_SUCCESS) | |
2068 | goto qla4xxx_send_tgts_exit; | |
2069 | ||
2070 | - memset(fw_ddb_entry->iscsi_alias, 0, | |
2071 | + memset((void *)fw_ddb_entry->iscsi_alias, 0, | |
2072 | sizeof(fw_ddb_entry->iscsi_alias)); | |
2073 | ||
2074 | - memset(fw_ddb_entry->iscsi_name, 0, | |
2075 | + memset((void *)fw_ddb_entry->iscsi_name, 0, | |
2076 | sizeof(fw_ddb_entry->iscsi_name)); | |
2077 | ||
2078 | - memset(fw_ddb_entry->ip_addr, 0, sizeof(fw_ddb_entry->ip_addr)); | |
2079 | - memset(fw_ddb_entry->tgt_addr, 0, | |
2080 | + memset((void *)fw_ddb_entry->ip_addr, 0, sizeof(fw_ddb_entry->ip_addr)); | |
2081 | + memset((void *)fw_ddb_entry->tgt_addr, 0, | |
2082 | sizeof(fw_ddb_entry->tgt_addr)); | |
2083 | ||
2084 | fw_ddb_entry->options = (DDB_OPT_DISC_SESSION | DDB_OPT_TARGET); | |
2085 | diff --git a/drivers/scsi/qla4xxx/ql4_nvram.c b/drivers/scsi/qla4xxx/ql4_nvram.c | |
2086 | index 7fe0482..67cfd0a 100644 | |
2087 | --- a/drivers/scsi/qla4xxx/ql4_nvram.c | |
2088 | +++ b/drivers/scsi/qla4xxx/ql4_nvram.c | |
2089 | @@ -6,6 +6,7 @@ | |
2090 | */ | |
2091 | ||
2092 | #include "ql4_def.h" | |
2093 | +#include "ql4_version.h" | |
2094 | #include "ql4_glbl.h" | |
2095 | #include "ql4_dbg.h" | |
2096 | #include "ql4_inline.h" | |
2097 | diff --git a/drivers/scsi/qla4xxx/ql4_nvram.h b/drivers/scsi/qla4xxx/ql4_nvram.h | |
2098 | index b47b4fc..08e2aed 100644 | |
2099 | --- a/drivers/scsi/qla4xxx/ql4_nvram.h | |
2100 | +++ b/drivers/scsi/qla4xxx/ql4_nvram.h | |
2101 | @@ -134,7 +134,9 @@ struct eeprom_data { | |
2102 | u16 phyConfig; /* x36 */ | |
2103 | #define PHY_CONFIG_PHY_ADDR_MASK 0x1f | |
2104 | #define PHY_CONFIG_ENABLE_FW_MANAGEMENT_MASK 0x20 | |
2105 | - u16 reserved_56; /* x38 */ | |
2106 | + u16 topcat; /* x38 */ | |
2107 | +#define TOPCAT_PRESENT 0x0100 | |
2108 | +#define TOPCAT_MASK 0xFF00 | |
2109 | ||
2110 | #define EEPROM_UNUSED_1_SIZE 2 | |
2111 | u8 unused_1[EEPROM_UNUSED_1_SIZE]; /* x3A */ | |
2112 | diff --git a/drivers/scsi/qla4xxx/ql4_os.c b/drivers/scsi/qla4xxx/ql4_os.c | |
2113 | index 4255b36..a62188b 100644 | |
2114 | --- a/drivers/scsi/qla4xxx/ql4_os.c | |
2115 | +++ b/drivers/scsi/qla4xxx/ql4_os.c | |
2116 | @@ -1,6 +1,6 @@ | |
2117 | /* | |
2118 | * QLogic iSCSI HBA Driver | |
2119 | - * Copyright (c) 2003-2006 QLogic Corporation | |
2120 | + * Copyright (c) 2003-2006 QLogic Corporation | |
2121 | * | |
2122 | * See LICENSE.qla4xxx for copyright and licensing details. | |
2123 | */ | |
2124 | @@ -9,6 +9,7 @@ | |
2125 | #include <scsi/scsi_tcq.h> | |
2126 | #include <scsi/scsicam.h> | |
2127 | ||
2128 | +#include <linux/klist.h> | |
2129 | #include "ql4_def.h" | |
2130 | #include "ql4_version.h" | |
2131 | #include "ql4_glbl.h" | |
2132 | @@ -18,7 +19,18 @@ | |
2133 | /* | |
2134 | * Driver version | |
2135 | */ | |
2136 | -static char qla4xxx_version_str[40]; | |
2137 | +char qla4xxx_version_str[40]; | |
2138 | +EXPORT_SYMBOL_GPL(qla4xxx_version_str); | |
2139 | + | |
2140 | +/* | |
2141 | + * List of host adapters | |
2142 | + */ | |
2143 | +struct klist qla4xxx_hostlist; | |
2144 | + | |
2145 | +struct klist *qla4xxx_hostlist_ptr = &qla4xxx_hostlist; | |
2146 | +EXPORT_SYMBOL_GPL(qla4xxx_hostlist_ptr); | |
2147 | + | |
2148 | +static atomic_t qla4xxx_hba_count; | |
2149 | ||
2150 | /* | |
2151 | * SRB allocation cache | |
2152 | @@ -38,16 +50,13 @@ MODULE_PARM_DESC(ql4xdontresethba, | |
2153 | " default it will reset hba :0" | |
2154 | " set to 1 to avoid resetting HBA"); | |
2155 | ||
2156 | -int ql4xextended_error_logging = 0; /* 0 = off, 1 = log errors */ | |
2157 | -module_param(ql4xextended_error_logging, int, S_IRUGO | S_IRUSR); | |
2158 | -MODULE_PARM_DESC(ql4xextended_error_logging, | |
2159 | +int extended_error_logging = 0; /* 0 = off, 1 = log errors */ | |
2160 | +module_param(extended_error_logging, int, S_IRUGO | S_IRUSR); | |
2161 | +MODULE_PARM_DESC(extended_error_logging, | |
2162 | "Option to enable extended error logging, " | |
2163 | "Default is 0 - no logging, 1 - debug logging"); | |
2164 | ||
2165 | int ql4_mod_unload = 0; | |
2166 | - | |
2167 | -#define QL4_DEF_QDEPTH 32 | |
2168 | - | |
2169 | /* | |
2170 | * SCSI host template entry points | |
2171 | */ | |
2172 | @@ -73,12 +82,9 @@ static void qla4xxx_recovery_timedout(struct iscsi_cls_session *session); | |
2173 | static int qla4xxx_queuecommand(struct scsi_cmnd *cmd, | |
2174 | void (*done) (struct scsi_cmnd *)); | |
2175 | static int qla4xxx_eh_device_reset(struct scsi_cmnd *cmd); | |
2176 | -static int qla4xxx_eh_target_reset(struct scsi_cmnd *cmd); | |
2177 | static int qla4xxx_eh_host_reset(struct scsi_cmnd *cmd); | |
2178 | static int qla4xxx_slave_alloc(struct scsi_device *device); | |
2179 | static int qla4xxx_slave_configure(struct scsi_device *device); | |
2180 | -static void qla4xxx_slave_destroy(struct scsi_device *sdev); | |
2181 | -static void qla4xxx_scan_start(struct Scsi_Host *shost); | |
2182 | ||
2183 | static struct scsi_host_template qla4xxx_driver_template = { | |
2184 | .module = THIS_MODULE, | |
2185 | @@ -87,15 +93,10 @@ static struct scsi_host_template qla4xxx_driver_template = { | |
2186 | .queuecommand = qla4xxx_queuecommand, | |
2187 | ||
2188 | .eh_device_reset_handler = qla4xxx_eh_device_reset, | |
2189 | - .eh_target_reset_handler = qla4xxx_eh_target_reset, | |
2190 | .eh_host_reset_handler = qla4xxx_eh_host_reset, | |
2191 | ||
2192 | .slave_configure = qla4xxx_slave_configure, | |
2193 | .slave_alloc = qla4xxx_slave_alloc, | |
2194 | - .slave_destroy = qla4xxx_slave_destroy, | |
2195 | - | |
2196 | - .scan_finished = iscsi_scan_finished, | |
2197 | - .scan_start = qla4xxx_scan_start, | |
2198 | ||
2199 | .this_id = -1, | |
2200 | .cmd_per_lun = 3, | |
2201 | @@ -108,13 +109,10 @@ static struct scsi_host_template qla4xxx_driver_template = { | |
2202 | static struct iscsi_transport qla4xxx_iscsi_transport = { | |
2203 | .owner = THIS_MODULE, | |
2204 | .name = DRIVER_NAME, | |
2205 | - .caps = CAP_FW_DB | CAP_SENDTARGETS_OFFLOAD | | |
2206 | - CAP_DATA_PATH_OFFLOAD, | |
2207 | - .param_mask = ISCSI_CONN_PORT | ISCSI_CONN_ADDRESS | | |
2208 | - ISCSI_TARGET_NAME | ISCSI_TPGT, | |
2209 | - .host_param_mask = ISCSI_HOST_HWADDRESS | | |
2210 | - ISCSI_HOST_IPADDRESS | | |
2211 | - ISCSI_HOST_INITIATOR_NAME, | |
2212 | + .param_mask = ISCSI_CONN_PORT | | |
2213 | + ISCSI_CONN_ADDRESS | | |
2214 | + ISCSI_TARGET_NAME | | |
2215 | + ISCSI_TPGT, | |
2216 | .tgt_dscvr = qla4xxx_tgt_dscvr, | |
2217 | .get_conn_param = qla4xxx_conn_get_param, | |
2218 | .get_session_param = qla4xxx_sess_get_param, | |
2219 | @@ -129,19 +127,16 @@ static void qla4xxx_recovery_timedout(struct iscsi_cls_session *session) | |
2220 | struct ddb_entry *ddb_entry = session->dd_data; | |
2221 | struct scsi_qla_host *ha = ddb_entry->ha; | |
2222 | ||
2223 | - if (atomic_read(&ddb_entry->state) != DDB_STATE_ONLINE) { | |
2224 | - atomic_set(&ddb_entry->state, DDB_STATE_DEAD); | |
2225 | + atomic_set(&ddb_entry->state, DDB_STATE_DEAD); | |
2226 | ||
2227 | - DEBUG2(printk("scsi%ld: %s: index [%d] port down retry count " | |
2228 | - "of (%d) secs exhausted, marking device DEAD.\n", | |
2229 | - ha->host_no, __func__, ddb_entry->fw_ddb_index, | |
2230 | - ha->port_down_retry_count)); | |
2231 | + dev_info(&ha->pdev->dev, "%s: ddb[%d] os[%d] marked DEAD" | |
2232 | + " - retry count of (%d)\n", __func__, | |
2233 | + ddb_entry->fw_ddb_index, ddb_entry->os_target_id, | |
2234 | + ha->port_down_retry_count); | |
2235 | ||
2236 | - DEBUG2(printk("scsi%ld: %s: scheduling dpc routine - dpc " | |
2237 | - "flags = 0x%lx\n", | |
2238 | - ha->host_no, __func__, ha->dpc_flags)); | |
2239 | - queue_work(ha->dpc_thread, &ha->dpc_work); | |
2240 | - } | |
2241 | + DEBUG2(printk("scsi%ld: %s: scheduling dpc routine - dpc flags = " | |
2242 | + "0x%lx\n", ha->host_no, __func__, ha->dpc_flags)); | |
2243 | + queue_work(ha->dpc_thread, &ha->dpc_work); | |
2244 | } | |
2245 | ||
2246 | static int qla4xxx_host_get_param(struct Scsi_Host *shost, | |
2247 | @@ -151,16 +146,13 @@ static int qla4xxx_host_get_param(struct Scsi_Host *shost, | |
2248 | int len; | |
2249 | ||
2250 | switch (param) { | |
2251 | - case ISCSI_HOST_PARAM_HWADDRESS: | |
2252 | - len = sysfs_format_mac(buf, ha->my_mac, MAC_ADDR_LEN); | |
2253 | - break; | |
2254 | case ISCSI_HOST_PARAM_IPADDRESS: | |
2255 | - len = sprintf(buf, "%d.%d.%d.%d\n", ha->ip_address[0], | |
2256 | - ha->ip_address[1], ha->ip_address[2], | |
2257 | - ha->ip_address[3]); | |
2258 | + len = sprintf(buf, "%d.%d.%d.%d", ha->ip_address[0], | |
2259 | + ha->ip_address[1], ha->ip_address[2], | |
2260 | + ha->ip_address[3]); | |
2261 | break; | |
2262 | case ISCSI_HOST_PARAM_INITIATOR_NAME: | |
2263 | - len = sprintf(buf, "%s\n", ha->name_string); | |
2264 | + len = sprintf(buf, "%s", ha->name_string); | |
2265 | break; | |
2266 | default: | |
2267 | return -ENOSYS; | |
2268 | @@ -169,6 +161,38 @@ static int qla4xxx_host_get_param(struct Scsi_Host *shost, | |
2269 | return len; | |
2270 | } | |
2271 | ||
2272 | +int qla4xxx_conn_start(struct iscsi_cls_conn *conn) | |
2273 | +{ | |
2274 | + struct iscsi_cls_session *session; | |
2275 | + struct ddb_entry *ddb_entry; | |
2276 | + | |
2277 | + session = iscsi_dev_to_session(conn->dev.parent); | |
2278 | + ddb_entry = session->dd_data; | |
2279 | + | |
2280 | + DEBUG2(printk("scsi%ld: %s: index [%d] starting conn\n", | |
2281 | + ddb_entry->ha->host_no, __func__, | |
2282 | + ddb_entry->fw_ddb_index)); | |
2283 | + iscsi_unblock_session(session); | |
2284 | + return 0; | |
2285 | +} | |
2286 | + | |
2287 | +static void qla4xxx_conn_stop(struct iscsi_cls_conn *conn, int flag) | |
2288 | +{ | |
2289 | + struct iscsi_cls_session *session; | |
2290 | + struct ddb_entry *ddb_entry; | |
2291 | + | |
2292 | + session = iscsi_dev_to_session(conn->dev.parent); | |
2293 | + ddb_entry = session->dd_data; | |
2294 | + | |
2295 | + DEBUG2(printk("scsi%ld: %s: index [%d] stopping conn\n", | |
2296 | + ddb_entry->ha->host_no, __func__, | |
2297 | + ddb_entry->fw_ddb_index)); | |
2298 | + if (flag == STOP_CONN_RECOVER) | |
2299 | + iscsi_block_session(session); | |
2300 | + else | |
2301 | + printk(KERN_ERR "iscsi: invalid stop flag %d\n", flag); | |
2302 | +} | |
2303 | + | |
2304 | static int qla4xxx_sess_get_param(struct iscsi_cls_session *sess, | |
2305 | enum iscsi_param param, char *buf) | |
2306 | { | |
2307 | @@ -177,11 +201,11 @@ static int qla4xxx_sess_get_param(struct iscsi_cls_session *sess, | |
2308 | ||
2309 | switch (param) { | |
2310 | case ISCSI_PARAM_TARGET_NAME: | |
2311 | - len = snprintf(buf, PAGE_SIZE - 1, "%s\n", | |
2312 | - ddb_entry->iscsi_name); | |
2313 | + len = snprintf(buf, PAGE_SIZE - 1, "%s", | |
2314 | + ddb_entry->iscsi_name); | |
2315 | break; | |
2316 | case ISCSI_PARAM_TPGT: | |
2317 | - len = sprintf(buf, "%u\n", ddb_entry->tpgt); | |
2318 | + len = sprintf(buf, "%u", ddb_entry->tpgt); | |
2319 | break; | |
2320 | default: | |
2321 | return -ENOSYS; | |
2322 | @@ -202,12 +226,12 @@ static int qla4xxx_conn_get_param(struct iscsi_cls_conn *conn, | |
2323 | ||
2324 | switch (param) { | |
2325 | case ISCSI_PARAM_CONN_PORT: | |
2326 | - len = sprintf(buf, "%hu\n", ddb_entry->port); | |
2327 | + len = sprintf(buf, "%u", (uint32_t)ddb_entry->port); | |
2328 | break; | |
2329 | case ISCSI_PARAM_CONN_ADDRESS: | |
2330 | /* TODO: what are the ipv6 bits */ | |
2331 | - len = sprintf(buf, "%u.%u.%u.%u\n", | |
2332 | - NIPQUAD(ddb_entry->ip_addr)); | |
2333 | + len = sprintf(buf, "%u.%u.%u.%u", | |
2334 | + NIPQUAD(ddb_entry->ip_addr)); | |
2335 | break; | |
2336 | default: | |
2337 | return -ENOSYS; | |
2338 | @@ -257,17 +281,15 @@ void qla4xxx_destroy_sess(struct ddb_entry *ddb_entry) | |
2339 | return; | |
2340 | ||
2341 | if (ddb_entry->conn) { | |
2342 | - atomic_set(&ddb_entry->state, DDB_STATE_DEAD); | |
2343 | iscsi_remove_session(ddb_entry->sess); | |
2344 | } | |
2345 | iscsi_free_session(ddb_entry->sess); | |
2346 | } | |
2347 | ||
2348 | -int qla4xxx_add_sess(struct ddb_entry *ddb_entry) | |
2349 | +int qla4xxx_add_sess(struct ddb_entry *ddb_entry, int scan) | |
2350 | { | |
2351 | int err; | |
2352 | ||
2353 | - ddb_entry->sess->recovery_tmo = ddb_entry->ha->port_down_retry_count; | |
2354 | err = iscsi_add_session(ddb_entry->sess, ddb_entry->fw_ddb_index); | |
2355 | if (err) { | |
2356 | DEBUG2(printk(KERN_ERR "Could not add session.\n")); | |
2357 | @@ -281,7 +303,11 @@ int qla4xxx_add_sess(struct ddb_entry *ddb_entry) | |
2358 | return -ENOMEM; | |
2359 | } | |
2360 | ||
2361 | - /* finally ready to go */ | |
2362 | + ddb_entry->sess->recovery_tmo = ddb_entry->ha->port_down_retry_count; | |
2363 | + if (scan) | |
2364 | + scsi_scan_target(&ddb_entry->sess->dev, 0, | |
2365 | + ddb_entry->sess->target_id, | |
2366 | + SCAN_WILD_CARD, 0); | |
2367 | iscsi_unblock_session(ddb_entry->sess); | |
2368 | return 0; | |
2369 | } | |
2370 | @@ -292,7 +318,7 @@ struct ddb_entry *qla4xxx_alloc_sess(struct scsi_qla_host *ha) | |
2371 | struct iscsi_cls_session *sess; | |
2372 | ||
2373 | sess = iscsi_alloc_session(ha->host, &qla4xxx_iscsi_transport, | |
2374 | - sizeof(struct ddb_entry)); | |
2375 | + sizeof(struct ddb_entry)); | |
2376 | if (!sess) | |
2377 | return NULL; | |
2378 | ||
2379 | @@ -303,18 +329,6 @@ struct ddb_entry *qla4xxx_alloc_sess(struct scsi_qla_host *ha) | |
2380 | return ddb_entry; | |
2381 | } | |
2382 | ||
2383 | -static void qla4xxx_scan_start(struct Scsi_Host *shost) | |
2384 | -{ | |
2385 | - struct scsi_qla_host *ha = shost_priv(shost); | |
2386 | - struct ddb_entry *ddb_entry, *ddbtemp; | |
2387 | - | |
2388 | - /* finish setup of sessions that were already setup in firmware */ | |
2389 | - list_for_each_entry_safe(ddb_entry, ddbtemp, &ha->ddb_list, list) { | |
2390 | - if (ddb_entry->fw_ddb_device_state == DDB_DS_SESSION_ACTIVE) | |
2391 | - qla4xxx_add_sess(ddb_entry); | |
2392 | - } | |
2393 | -} | |
2394 | - | |
2395 | /* | |
2396 | * Timer routines | |
2397 | */ | |
2398 | @@ -323,7 +337,7 @@ static void qla4xxx_start_timer(struct scsi_qla_host *ha, void *func, | |
2399 | unsigned long interval) | |
2400 | { | |
2401 | DEBUG(printk("scsi: %s: Starting timer thread for adapter %d\n", | |
2402 | - __func__, ha->host->host_no)); | |
2403 | + __func__, ha->host->host_no)); | |
2404 | init_timer(&ha->timer); | |
2405 | ha->timer.expires = jiffies + interval * HZ; | |
2406 | ha->timer.data = (unsigned long)ha; | |
2407 | @@ -349,11 +363,11 @@ void qla4xxx_mark_device_missing(struct scsi_qla_host *ha, | |
2408 | struct ddb_entry *ddb_entry) | |
2409 | { | |
2410 | atomic_set(&ddb_entry->state, DDB_STATE_MISSING); | |
2411 | - DEBUG3(printk("scsi%d:%d:%d: index [%d] marked MISSING\n", | |
2412 | - ha->host_no, ddb_entry->bus, ddb_entry->target, | |
2413 | - ddb_entry->fw_ddb_index)); | |
2414 | - iscsi_block_session(ddb_entry->sess); | |
2415 | - iscsi_conn_error(ddb_entry->conn, ISCSI_ERR_CONN_FAILED); | |
2416 | + | |
2417 | + dev_info(&ha->pdev->dev, "%s: ddb[%d] os[%d] marked MISSING\n", | |
2418 | + __func__, ddb_entry->fw_ddb_index, ddb_entry->os_target_id); | |
2419 | + | |
2420 | + qla4xxx_conn_stop(ddb_entry->conn, STOP_CONN_RECOVER); | |
2421 | } | |
2422 | ||
2423 | static struct srb* qla4xxx_get_new_srb(struct scsi_qla_host *ha, | |
2424 | @@ -393,10 +407,10 @@ void qla4xxx_srb_compl(struct scsi_qla_host *ha, struct srb *srb) | |
2425 | { | |
2426 | struct scsi_cmnd *cmd = srb->cmd; | |
2427 | ||
2428 | - qla4xxx_srb_free_dma(ha, srb); | |
2429 | - | |
2430 | - mempool_free(srb, ha->srb_mempool); | |
2431 | - | |
2432 | + if (!(srb->flags & SRB_SCSI_PASSTHRU)) { | |
2433 | + qla4xxx_srb_free_dma(ha, srb); | |
2434 | + mempool_free(srb, ha->srb_mempool); | |
2435 | + } | |
2436 | cmd->scsi_done(cmd); | |
2437 | } | |
2438 | ||
2439 | @@ -404,7 +418,7 @@ void qla4xxx_srb_compl(struct scsi_qla_host *ha, struct srb *srb) | |
2440 | * qla4xxx_queuecommand - scsi layer issues scsi command to driver. | |
2441 | * @cmd: Pointer to Linux's SCSI command structure | |
2442 | * @done_fn: Function that the driver calls to notify the SCSI mid-layer | |
2443 | - * that the command has been processed. | |
2444 | + * that the command has been processed. | |
2445 | * | |
2446 | * Remarks: | |
2447 | * This routine is invoked by Linux to send a SCSI command to the driver. | |
2448 | @@ -419,30 +433,20 @@ static int qla4xxx_queuecommand(struct scsi_cmnd *cmd, | |
2449 | { | |
2450 | struct scsi_qla_host *ha = to_qla_host(cmd->device->host); | |
2451 | struct ddb_entry *ddb_entry = cmd->device->hostdata; | |
2452 | - struct iscsi_cls_session *sess = ddb_entry->sess; | |
2453 | struct srb *srb; | |
2454 | int rval; | |
2455 | ||
2456 | - if (!sess) { | |
2457 | - cmd->result = DID_IMM_RETRY << 16; | |
2458 | - goto qc_fail_command; | |
2459 | - } | |
2460 | - | |
2461 | - rval = iscsi_session_chkready(sess); | |
2462 | - if (rval) { | |
2463 | - cmd->result = rval; | |
2464 | - goto qc_fail_command; | |
2465 | - } | |
2466 | - | |
2467 | if (atomic_read(&ddb_entry->state) != DDB_STATE_ONLINE) { | |
2468 | if (atomic_read(&ddb_entry->state) == DDB_STATE_DEAD) { | |
2469 | cmd->result = DID_NO_CONNECT << 16; | |
2470 | goto qc_fail_command; | |
2471 | } | |
2472 | - return SCSI_MLQUEUE_TARGET_BUSY; | |
2473 | + goto qc_host_busy; | |
2474 | } | |
2475 | ||
2476 | - if (test_bit(DPC_RESET_HA_INTR, &ha->dpc_flags)) | |
2477 | + if (test_bit(DPC_RESET_HA_INTR, &ha->dpc_flags) || | |
2478 | + test_bit(DPC_RESET_HA, &ha->dpc_flags) || | |
2479 | + test_bit(DPC_RESET_HA_DESTROY_DDB_LIST, &ha->dpc_flags)) | |
2480 | goto qc_host_busy; | |
2481 | ||
2482 | spin_unlock_irq(ha->host->host_lock); | |
2483 | @@ -596,7 +600,7 @@ static void qla4xxx_timer(struct scsi_qla_host *ha) | |
2484 | if (atomic_read(&ddb_entry->retry_relogin_timer) != | |
2485 | INVALID_ENTRY) { | |
2486 | if (atomic_read(&ddb_entry->retry_relogin_timer) | |
2487 | - == 0) { | |
2488 | + == 0) { | |
2489 | atomic_set(&ddb_entry-> | |
2490 | retry_relogin_timer, | |
2491 | INVALID_ENTRY); | |
2492 | @@ -669,7 +673,7 @@ static void qla4xxx_timer(struct scsi_qla_host *ha) | |
2493 | test_bit(DPC_RESET_HA_INTR, &ha->dpc_flags) || | |
2494 | test_bit(DPC_GET_DHCP_IP_ADDR, &ha->dpc_flags) || | |
2495 | test_bit(DPC_AEN, &ha->dpc_flags)) && | |
2496 | - ha->dpc_thread) { | |
2497 | + ha->dpc_thread) { | |
2498 | DEBUG2(printk("scsi%ld: %s: scheduling dpc routine" | |
2499 | " - dpc flags = 0x%lx\n", | |
2500 | ha->host_no, __func__, ha->dpc_flags)); | |
2501 | @@ -694,7 +698,6 @@ static int qla4xxx_cmd_wait(struct scsi_qla_host *ha) | |
2502 | uint32_t index = 0; | |
2503 | int stat = QLA_SUCCESS; | |
2504 | unsigned long flags; | |
2505 | - struct scsi_cmnd *cmd; | |
2506 | int wait_cnt = WAIT_CMD_TOV; /* | |
2507 | * Initialized for 30 seconds as we | |
2508 | * expect all commands to retuned | |
2509 | @@ -704,15 +707,14 @@ static int qla4xxx_cmd_wait(struct scsi_qla_host *ha) | |
2510 | while (wait_cnt) { | |
2511 | spin_lock_irqsave(&ha->hardware_lock, flags); | |
2512 | /* Find a command that hasn't completed. */ | |
2513 | - for (index = 0; index < ha->host->can_queue; index++) { | |
2514 | - cmd = scsi_host_find_tag(ha->host, index); | |
2515 | - if (cmd != NULL) | |
2516 | + for (index = 1; index < MAX_SRBS; index++) { | |
2517 | + if (ha->active_srb_array[index] != NULL) | |
2518 | break; | |
2519 | } | |
2520 | spin_unlock_irqrestore(&ha->hardware_lock, flags); | |
2521 | ||
2522 | /* If No Commands are pending, wait is complete */ | |
2523 | - if (index == ha->host->can_queue) { | |
2524 | + if (index == MAX_SRBS) { | |
2525 | break; | |
2526 | } | |
2527 | ||
2528 | @@ -738,7 +740,6 @@ void qla4xxx_hw_reset(struct scsi_qla_host *ha) | |
2529 | DEBUG2(printk(KERN_ERR "scsi%ld: %s\n", ha->host_no, __func__)); | |
2530 | ||
2531 | spin_lock_irqsave(&ha->hardware_lock, flags); | |
2532 | - | |
2533 | /* | |
2534 | * If the SCSI Reset Interrupt bit is set, clear it. | |
2535 | * Otherwise, the Soft Reset won't work. | |
2536 | @@ -865,9 +866,9 @@ static void qla4xxx_flush_active_srbs(struct scsi_qla_host *ha) | |
2537 | unsigned long flags; | |
2538 | ||
2539 | spin_lock_irqsave(&ha->hardware_lock, flags); | |
2540 | - for (i = 0; i < ha->host->can_queue; i++) { | |
2541 | - srb = qla4xxx_del_from_active_array(ha, i); | |
2542 | - if (srb != NULL) { | |
2543 | + for (i = 1; i < MAX_SRBS; i++) { | |
2544 | + if ((srb = ha->active_srb_array[i]) != NULL) { | |
2545 | + qla4xxx_del_from_active_array(ha, i); | |
2546 | srb->cmd->result = DID_RESET << 16; | |
2547 | qla4xxx_srb_compl(ha, srb); | |
2548 | } | |
2549 | @@ -879,19 +880,13 @@ static void qla4xxx_flush_active_srbs(struct scsi_qla_host *ha) | |
2550 | /** | |
2551 | * qla4xxx_recover_adapter - recovers adapter after a fatal error | |
2552 | * @ha: Pointer to host adapter structure. | |
2553 | - * @renew_ddb_list: Indicates what to do with the adapter's ddb list | |
2554 | - * | |
2555 | - * renew_ddb_list value can be 0=preserve ddb list, 1=destroy and rebuild | |
2556 | - * ddb list. | |
2557 | **/ | |
2558 | -static int qla4xxx_recover_adapter(struct scsi_qla_host *ha, | |
2559 | - uint8_t renew_ddb_list) | |
2560 | +static int qla4xxx_recover_adapter(struct scsi_qla_host *ha) | |
2561 | { | |
2562 | int status; | |
2563 | ||
2564 | /* Stall incoming I/O until we are done */ | |
2565 | clear_bit(AF_ONLINE, &ha->flags); | |
2566 | - | |
2567 | DEBUG2(printk("scsi%ld: %s calling qla4xxx_cmd_wait\n", ha->host_no, | |
2568 | __func__)); | |
2569 | ||
2570 | @@ -909,7 +904,7 @@ static int qla4xxx_recover_adapter(struct scsi_qla_host *ha, | |
2571 | * returns with ISP interrupts enabled. | |
2572 | */ | |
2573 | if (status == QLA_SUCCESS) { | |
2574 | - DEBUG2(printk("scsi%ld: %s - Performing soft reset..\n", | |
2575 | + DEBUG2(printk(KERN_ERR "scsi%ld: %s - Performing soft reset..\n", | |
2576 | ha->host_no, __func__)); | |
2577 | qla4xxx_flush_active_srbs(ha); | |
2578 | if (ql4xxx_lock_drvr_wait(ha) == QLA_SUCCESS) | |
2579 | @@ -929,7 +924,7 @@ static int qla4xxx_recover_adapter(struct scsi_qla_host *ha, | |
2580 | ||
2581 | /* If successful, AF_ONLINE flag set in | |
2582 | * qla4xxx_initialize_adapter */ | |
2583 | - status = qla4xxx_initialize_adapter(ha, renew_ddb_list); | |
2584 | + status = qla4xxx_initialize_adapter(ha, PRESERVE_DDB_LIST); | |
2585 | } | |
2586 | ||
2587 | /* Failed adapter initialization? | |
2588 | @@ -990,7 +985,7 @@ static int qla4xxx_recover_adapter(struct scsi_qla_host *ha, | |
2589 | * @data: in our case pointer to adapter structure | |
2590 | * | |
2591 | * This routine is a task that is schedule by the interrupt handler | |
2592 | - * to perform the background processing for interrupts. We put it | |
2593 | + * to perform the background processing for interrupts. We put it | |
2594 | * on a task queue that is consumed whenever the scheduler runs; that's | |
2595 | * so you can do anything (i.e. put the process to sleep etc). In fact, | |
2596 | * the mid-level tries to sleep when it reaches the driver threshold | |
2597 | @@ -1004,7 +999,8 @@ static void qla4xxx_do_dpc(struct work_struct *work) | |
2598 | int status = QLA_ERROR; | |
2599 | ||
2600 | DEBUG2(printk("scsi%ld: %s: DPC handler waking up." | |
2601 | - "flags = 0x%08lx, dpc_flags = 0x%08lx ctrl_stat = 0x%08x\n", | |
2602 | + "ha->flags=0x%08lx ha->dpc_flags=0x%08lx" | |
2603 | + " ctrl_status=0x%08x\n", | |
2604 | ha->host_no, __func__, ha->flags, ha->dpc_flags, | |
2605 | readw(&ha->reg->ctrl_status))); | |
2606 | ||
2607 | @@ -1017,8 +1013,8 @@ static void qla4xxx_do_dpc(struct work_struct *work) | |
2608 | test_bit(DPC_RESET_HA_INTR, &ha->dpc_flags) || | |
2609 | test_bit(DPC_RESET_HA_DESTROY_DDB_LIST, &ha->dpc_flags)) { | |
2610 | if (test_bit(DPC_RESET_HA_DESTROY_DDB_LIST, &ha->dpc_flags) || | |
2611 | - test_bit(DPC_RESET_HA, &ha->dpc_flags)) | |
2612 | - qla4xxx_recover_adapter(ha, PRESERVE_DDB_LIST); | |
2613 | + test_bit(DPC_RESET_HA, &ha->dpc_flags)) | |
2614 | + qla4xxx_recover_adapter(ha); | |
2615 | ||
2616 | if (test_bit(DPC_RESET_HA_INTR, &ha->dpc_flags)) { | |
2617 | uint8_t wait_time = RESET_INTR_TOV; | |
2618 | @@ -1036,7 +1032,7 @@ static void qla4xxx_do_dpc(struct work_struct *work) | |
2619 | qla4xxx_flush_active_srbs(ha); | |
2620 | if (ql4xxx_lock_drvr_wait(ha) == QLA_SUCCESS) { | |
2621 | qla4xxx_process_aen(ha, FLUSH_DDB_CHANGED_AENS); | |
2622 | - status = qla4xxx_initialize_adapter(ha, | |
2623 | + status = qla4xxx_initialize_adapter(ha, | |
2624 | PRESERVE_DDB_LIST); | |
2625 | } | |
2626 | clear_bit(DPC_RESET_HA_INTR, &ha->dpc_flags); | |
2627 | @@ -1070,8 +1066,8 @@ static void qla4xxx_do_dpc(struct work_struct *work) | |
2628 | */ | |
2629 | if (test_bit(DPC_RESET_HA, &ha->dpc_flags)) { | |
2630 | printk(KERN_WARNING "scsi%ld: %s: " | |
2631 | - "need to reset hba\n", | |
2632 | - ha->host_no, __func__); | |
2633 | + "need to reset hba\n", | |
2634 | + ha->host_no, __func__); | |
2635 | break; | |
2636 | } | |
2637 | } | |
2638 | @@ -1110,7 +1106,6 @@ static void qla4xxx_free_adapter(struct scsi_qla_host *ha) | |
2639 | qla4xxx_mem_free(ha); | |
2640 | ||
2641 | pci_disable_device(ha->pdev); | |
2642 | - | |
2643 | } | |
2644 | ||
2645 | /*** | |
2646 | @@ -1147,7 +1142,6 @@ static int qla4xxx_iospace_config(struct scsi_qla_host *ha) | |
2647 | if (!(mmio_flags & IORESOURCE_MEM)) { | |
2648 | dev_err(&ha->pdev->dev, | |
2649 | "region #0 not an MMIO resource, aborting\n"); | |
2650 | - | |
2651 | goto iospace_error_exit; | |
2652 | } | |
2653 | if (mmio_len < MIN_IOBASE_LEN) { | |
2654 | @@ -1179,6 +1173,14 @@ iospace_error_exit: | |
2655 | return -ENOMEM; | |
2656 | } | |
2657 | ||
2658 | +static void ql4_get_aen_log(struct scsi_qla_host *ha, struct ql4_aen_log *aenl) | |
2659 | +{ | |
2660 | + if (aenl) { | |
2661 | + memcpy(aenl, &ha->aen_log, sizeof (ha->aen_log)); | |
2662 | + ha->aen_log.count = 0; | |
2663 | + } | |
2664 | +} | |
2665 | + | |
2666 | /** | |
2667 | * qla4xxx_probe_adapter - callback function to probe HBA | |
2668 | * @pdev: pointer to pci_dev structure | |
2669 | @@ -1194,6 +1196,7 @@ static int __devinit qla4xxx_probe_adapter(struct pci_dev *pdev, | |
2670 | int ret = -ENODEV, status; | |
2671 | struct Scsi_Host *host; | |
2672 | struct scsi_qla_host *ha; | |
2673 | + struct ddb_entry *ddb_entry, *ddbtemp; | |
2674 | uint8_t init_retry_count = 0; | |
2675 | char buf[34]; | |
2676 | ||
2677 | @@ -1211,18 +1214,22 @@ static int __devinit qla4xxx_probe_adapter(struct pci_dev *pdev, | |
2678 | ha = (struct scsi_qla_host *) host->hostdata; | |
2679 | memset(ha, 0, sizeof(*ha)); | |
2680 | ||
2681 | - /* Save the information from PCI BIOS. */ | |
2682 | + /* Save the information from PCI BIOS. */ | |
2683 | ha->pdev = pdev; | |
2684 | ha->host = host; | |
2685 | ha->host_no = host->host_no; | |
2686 | ||
2687 | + ha->ql4mbx = qla4xxx_mailbox_command; | |
2688 | + ha->ql4cmd = qla4xxx_send_command_to_isp; | |
2689 | + ha->ql4getaenlog = ql4_get_aen_log; | |
2690 | + | |
2691 | /* Configure PCI I/O space. */ | |
2692 | ret = qla4xxx_iospace_config(ha); | |
2693 | if (ret) | |
2694 | goto probe_failed; | |
2695 | ||
2696 | dev_info(&ha->pdev->dev, "Found an ISP%04x, irq %d, iobase 0x%p\n", | |
2697 | - pdev->device, pdev->irq, ha->reg); | |
2698 | + pdev->device, pdev->irq, ha->reg); | |
2699 | ||
2700 | qla4xxx_config_dma_addressing(ha); | |
2701 | ||
2702 | @@ -1233,11 +1240,12 @@ static int __devinit qla4xxx_probe_adapter(struct pci_dev *pdev, | |
2703 | mutex_init(&ha->mbox_sem); | |
2704 | ||
2705 | spin_lock_init(&ha->hardware_lock); | |
2706 | + spin_lock_init(&ha->list_lock); | |
2707 | ||
2708 | /* Allocate dma buffers */ | |
2709 | if (qla4xxx_mem_alloc(ha)) { | |
2710 | dev_warn(&ha->pdev->dev, | |
2711 | - "[ERROR] Failed to allocate memory for adapter\n"); | |
2712 | + "[ERROR] Failed to allocate memory for adapter\n"); | |
2713 | ||
2714 | ret = -ENOMEM; | |
2715 | goto probe_failed; | |
2716 | @@ -1250,8 +1258,8 @@ static int __devinit qla4xxx_probe_adapter(struct pci_dev *pdev, | |
2717 | */ | |
2718 | status = qla4xxx_initialize_adapter(ha, REBUILD_DDB_LIST); | |
2719 | while (status == QLA_ERROR && init_retry_count++ < MAX_INIT_RETRIES) { | |
2720 | - DEBUG2(printk("scsi: %s: retrying adapter initialization " | |
2721 | - "(%d)\n", __func__, init_retry_count)); | |
2722 | + DEBUG2(printk(KERN_ERR "scsi%ld: %s: retrying adapter initialization " | |
2723 | + "(%d)\n", ha->host_no, __func__, init_retry_count)); | |
2724 | qla4xxx_soft_reset(ha); | |
2725 | status = qla4xxx_initialize_adapter(ha, REBUILD_DDB_LIST); | |
2726 | } | |
2727 | @@ -1267,15 +1275,9 @@ static int __devinit qla4xxx_probe_adapter(struct pci_dev *pdev, | |
2728 | host->max_lun = MAX_LUNS - 1; | |
2729 | host->max_id = MAX_TARGETS; | |
2730 | host->max_cmd_len = IOCB_MAX_CDB_LEN; | |
2731 | - host->can_queue = MAX_SRBS ; | |
2732 | + host->can_queue = REQUEST_QUEUE_DEPTH + 128; | |
2733 | host->transportt = qla4xxx_scsi_transport; | |
2734 | ||
2735 | - ret = scsi_init_shared_tag_map(host, MAX_SRBS); | |
2736 | - if (ret) { | |
2737 | - dev_warn(&ha->pdev->dev, "scsi_init_shared_tag_map failed\n"); | |
2738 | - goto probe_failed; | |
2739 | - } | |
2740 | - | |
2741 | /* Startup the kernel thread for this host adapter. */ | |
2742 | DEBUG2(printk("scsi: %s: Starting kernel thread for " | |
2743 | "qla4xxx_dpc\n", __func__)); | |
2744 | @@ -1287,9 +1289,8 @@ static int __devinit qla4xxx_probe_adapter(struct pci_dev *pdev, | |
2745 | goto probe_failed; | |
2746 | } | |
2747 | INIT_WORK(&ha->dpc_work, qla4xxx_do_dpc); | |
2748 | - | |
2749 | ret = request_irq(pdev->irq, qla4xxx_intr_handler, | |
2750 | - IRQF_DISABLED | IRQF_SHARED, "qla4xxx", ha); | |
2751 | + IRQF_DISABLED | IRQF_SHARED, "qla4xxx", ha); | |
2752 | if (ret) { | |
2753 | dev_warn(&ha->pdev->dev, "Failed to reserve interrupt %d" | |
2754 | " already in use.\n", pdev->irq); | |
2755 | @@ -1312,15 +1313,39 @@ static int __devinit qla4xxx_probe_adapter(struct pci_dev *pdev, | |
2756 | if (ret) | |
2757 | goto probe_failed; | |
2758 | ||
2759 | + /* Update transport device information for all devices. */ | |
2760 | + list_for_each_entry_safe(ddb_entry, ddbtemp, &ha->ddb_list, list) { | |
2761 | + | |
2762 | + if (ddb_entry->fw_ddb_device_state == DDB_DS_SESSION_ACTIVE) | |
2763 | + set_bit(DF_SCAN_ISSUED, &ddb_entry->flags); | |
2764 | + | |
2765 | + if (qla4xxx_add_sess(ddb_entry, | |
2766 | + test_bit(DF_SCAN_ISSUED, &ddb_entry->flags))) | |
2767 | + goto remove_host; | |
2768 | + if (!test_bit(DF_SCAN_ISSUED, &ddb_entry->flags)) | |
2769 | + qla4xxx_mark_device_missing(ha, ddb_entry); | |
2770 | + } | |
2771 | + | |
2772 | printk(KERN_INFO | |
2773 | " QLogic iSCSI HBA Driver version: %s\n" | |
2774 | - " QLogic ISP%04x @ %s, host#=%ld, fw=%02d.%02d.%02d.%02d\n", | |
2775 | - qla4xxx_version_str, ha->pdev->device, pci_name(ha->pdev), | |
2776 | + " QLogic ISP%04x @ %s, pdev = %p host#=%ld, fw=%02d.%02d.%02d.%02d\n", | |
2777 | + qla4xxx_version_str, ha->pdev->device, pci_name(ha->pdev), pdev, | |
2778 | ha->host_no, ha->firmware_version[0], ha->firmware_version[1], | |
2779 | ha->patch_number, ha->build_number); | |
2780 | - scsi_scan_host(host); | |
2781 | + | |
2782 | + /* Insert new entry into the list of adapters. */ | |
2783 | + klist_add_tail(&ha->node, &qla4xxx_hostlist); | |
2784 | + ha->instance = atomic_inc_return(&qla4xxx_hba_count) - 1; | |
2785 | + | |
2786 | + DEBUG2(printk("qla4xxx: listhead=%p, done adding ha=%p i=%d\n", | |
2787 | + &qla4xxx_hostlist, &ha->node, ha->instance)); | |
2788 | + | |
2789 | return 0; | |
2790 | ||
2791 | +remove_host: | |
2792 | + qla4xxx_free_ddb_list(ha); | |
2793 | + scsi_remove_host(host); | |
2794 | + | |
2795 | probe_failed: | |
2796 | qla4xxx_free_adapter(ha); | |
2797 | scsi_host_put(ha->host); | |
2798 | @@ -1346,6 +1371,9 @@ static void __devexit qla4xxx_remove_adapter(struct pci_dev *pdev) | |
2799 | while (test_bit(DPC_RESET_HA_INTR, &ha->dpc_flags)) | |
2800 | ssleep(1); | |
2801 | ||
2802 | + klist_remove(&ha->node); | |
2803 | + atomic_dec(&qla4xxx_hba_count); | |
2804 | + | |
2805 | /* remove devs from iscsi_sessions to scsi_devices */ | |
2806 | qla4xxx_free_ddb_list(ha); | |
2807 | ||
2808 | @@ -1374,7 +1402,7 @@ static void qla4xxx_config_dma_addressing(struct scsi_qla_host *ha) | |
2809 | if (pci_set_consistent_dma_mask(ha->pdev, DMA_64BIT_MASK)) { | |
2810 | dev_dbg(&ha->pdev->dev, | |
2811 | "Failed to set 64 bit PCI consistent mask; " | |
2812 | - "using 32 bit.\n"); | |
2813 | + "using 32 bit.\n"); | |
2814 | retval = pci_set_consistent_dma_mask(ha->pdev, | |
2815 | DMA_32BIT_MASK); | |
2816 | } | |
2817 | @@ -1385,23 +1413,22 @@ static void qla4xxx_config_dma_addressing(struct scsi_qla_host *ha) | |
2818 | static int qla4xxx_slave_alloc(struct scsi_device *sdev) | |
2819 | { | |
2820 | struct iscsi_cls_session *sess = starget_to_session(sdev->sdev_target); | |
2821 | - struct ddb_entry *ddb = sess->dd_data; | |
2822 | ||
2823 | - sdev->hostdata = ddb; | |
2824 | - sdev->tagged_supported = 1; | |
2825 | - scsi_activate_tcq(sdev, QL4_DEF_QDEPTH); | |
2826 | - return 0; | |
2827 | + if (sess) { | |
2828 | + sdev->hostdata = sess->dd_data; | |
2829 | + return 0; | |
2830 | + } | |
2831 | + return FAILED; | |
2832 | } | |
2833 | ||
2834 | static int qla4xxx_slave_configure(struct scsi_device *sdev) | |
2835 | { | |
2836 | - sdev->tagged_supported = 1; | |
2837 | - return 0; | |
2838 | -} | |
2839 | + if (sdev->tagged_supported) | |
2840 | + scsi_activate_tcq(sdev, 32); | |
2841 | + else | |
2842 | + scsi_deactivate_tcq(sdev, 32); | |
2843 | ||
2844 | -static void qla4xxx_slave_destroy(struct scsi_device *sdev) | |
2845 | -{ | |
2846 | - scsi_deactivate_tcq(sdev, 1); | |
2847 | + return 0; | |
2848 | } | |
2849 | ||
2850 | /** | |
2851 | @@ -1414,12 +1441,14 @@ static void qla4xxx_slave_destroy(struct scsi_device *sdev) | |
2852 | struct srb * qla4xxx_del_from_active_array(struct scsi_qla_host *ha, uint32_t index) | |
2853 | { | |
2854 | struct srb *srb = NULL; | |
2855 | - struct scsi_cmnd *cmd; | |
2856 | ||
2857 | - if (!(cmd = scsi_host_find_tag(ha->host, index))) | |
2858 | + /* validate handle and remove from active array */ | |
2859 | + if (index >= MAX_SRBS) | |
2860 | return srb; | |
2861 | ||
2862 | - if (!(srb = (struct srb *)cmd->host_scribble)) | |
2863 | + srb = ha->active_srb_array[index]; | |
2864 | + ha->active_srb_array[index] = NULL; | |
2865 | + if (!srb) | |
2866 | return srb; | |
2867 | ||
2868 | /* update counters */ | |
2869 | @@ -1467,24 +1496,18 @@ static int qla4xxx_eh_wait_on_command(struct scsi_qla_host *ha, | |
2870 | **/ | |
2871 | static int qla4xxx_wait_for_hba_online(struct scsi_qla_host *ha) | |
2872 | { | |
2873 | - unsigned long wait_online; | |
2874 | - | |
2875 | - wait_online = jiffies + (30 * HZ); | |
2876 | - while (time_before(jiffies, wait_online)) { | |
2877 | + unsigned long wait_online = 60; | |
2878 | ||
2879 | + while (wait_online--) { | |
2880 | if (adapter_up(ha)) | |
2881 | return QLA_SUCCESS; | |
2882 | - else if (ha->retry_reset_ha_cnt == 0) | |
2883 | - return QLA_ERROR; | |
2884 | - | |
2885 | - msleep(2000); | |
2886 | + ssleep(2); | |
2887 | } | |
2888 | - | |
2889 | return QLA_ERROR; | |
2890 | } | |
2891 | ||
2892 | /** | |
2893 | - * qla4xxx_eh_wait_for_commands - wait for active cmds to finish. | |
2894 | + * qla4xxx_eh_wait_for_active_target_commands - wait for active cmds to finish. | |
2895 | * @ha: pointer to to HBA | |
2896 | * @t: target id | |
2897 | * @l: lun id | |
2898 | @@ -1492,26 +1515,33 @@ static int qla4xxx_wait_for_hba_online(struct scsi_qla_host *ha) | |
2899 | * This function waits for all outstanding commands to a lun to complete. It | |
2900 | * returns 0 if all pending commands are returned and 1 otherwise. | |
2901 | **/ | |
2902 | -static int qla4xxx_eh_wait_for_commands(struct scsi_qla_host *ha, | |
2903 | - struct scsi_target *stgt, | |
2904 | - struct scsi_device *sdev) | |
2905 | +static int qla4xxx_eh_wait_for_active_target_commands(struct scsi_qla_host *ha, | |
2906 | + int t, int l) | |
2907 | { | |
2908 | int cnt; | |
2909 | - int status = 0; | |
2910 | + int status; | |
2911 | + struct srb *sp; | |
2912 | struct scsi_cmnd *cmd; | |
2913 | ||
2914 | /* | |
2915 | - * Waiting for all commands for the designated target or dev | |
2916 | - * in the active array | |
2917 | + * Waiting for all commands for the designated target in the active | |
2918 | + * array | |
2919 | */ | |
2920 | - for (cnt = 0; cnt < ha->host->can_queue; cnt++) { | |
2921 | - cmd = scsi_host_find_tag(ha->host, cnt); | |
2922 | - if (cmd && stgt == scsi_target(cmd->device) && | |
2923 | - (!sdev || sdev == cmd->device)) { | |
2924 | - if (!qla4xxx_eh_wait_on_command(ha, cmd)) { | |
2925 | - status++; | |
2926 | - break; | |
2927 | + status = 0; | |
2928 | + for (cnt = 1; cnt < MAX_SRBS; cnt++) { | |
2929 | + spin_lock(&ha->hardware_lock); | |
2930 | + sp = ha->active_srb_array[cnt]; | |
2931 | + if (sp) { | |
2932 | + cmd = sp->cmd; | |
2933 | + spin_unlock(&ha->hardware_lock); | |
2934 | + if (cmd->device->id == t && cmd->device->lun == l) { | |
2935 | + if (!qla4xxx_eh_wait_on_command(ha, cmd)) { | |
2936 | + status++; | |
2937 | + break; | |
2938 | + } | |
2939 | } | |
2940 | + } else { | |
2941 | + spin_unlock(&ha->hardware_lock); | |
2942 | } | |
2943 | } | |
2944 | return status; | |
2945 | @@ -1528,47 +1558,49 @@ static int qla4xxx_eh_device_reset(struct scsi_cmnd *cmd) | |
2946 | { | |
2947 | struct scsi_qla_host *ha = to_qla_host(cmd->device->host); | |
2948 | struct ddb_entry *ddb_entry = cmd->device->hostdata; | |
2949 | - struct srb *sp; | |
2950 | int ret = FAILED, stat; | |
2951 | ||
2952 | - sp = (struct srb *) cmd->SCp.ptr; | |
2953 | - if (!sp || !ddb_entry) | |
2954 | + if (!ddb_entry) | |
2955 | return ret; | |
2956 | ||
2957 | dev_info(&ha->pdev->dev, | |
2958 | - "scsi%ld:%d:%d:%d: DEVICE RESET ISSUED.\n", ha->host_no, | |
2959 | - cmd->device->channel, cmd->device->id, cmd->device->lun); | |
2960 | + "scsi%ld:%d:%d:%d: DEVICE RESET ISSUED.\n", ha->host_no, | |
2961 | + cmd->device->channel, cmd->device->id, cmd->device->lun); | |
2962 | ||
2963 | - DEBUG2(printk(KERN_INFO | |
2964 | - "scsi%ld: DEVICE_RESET cmd=%p jiffies = 0x%lx, to=%x," | |
2965 | - "dpc_flags=%lx, status=%x allowed=%d\n", ha->host_no, | |
2966 | - cmd, jiffies, cmd->request->timeout / HZ, | |
2967 | - ha->dpc_flags, cmd->result, cmd->allowed)); | |
2968 | + if (qla4xxx_wait_for_hba_online(ha) != QLA_SUCCESS) { | |
2969 | + dev_info(&ha->pdev->dev, "%s: HBA OFFLINE: FAILED\n", __func__); | |
2970 | + return FAILED; | |
2971 | + } | |
2972 | ||
2973 | - /* FIXME: wait for hba to go online */ | |
2974 | stat = qla4xxx_reset_lun(ha, ddb_entry, cmd->device->lun); | |
2975 | if (stat != QLA_SUCCESS) { | |
2976 | dev_info(&ha->pdev->dev, "DEVICE RESET FAILED. %d\n", stat); | |
2977 | goto eh_dev_reset_done; | |
2978 | } | |
2979 | ||
2980 | - if (qla4xxx_eh_wait_for_commands(ha, scsi_target(cmd->device), | |
2981 | - cmd->device)) { | |
2982 | - dev_info(&ha->pdev->dev, | |
2983 | - "DEVICE RESET FAILED - waiting for " | |
2984 | - "commands.\n"); | |
2985 | - goto eh_dev_reset_done; | |
2986 | + /* | |
2987 | + * If we are coming down the EH path, wait for all commands to complete | |
2988 | + * for the device. | |
2989 | + */ | |
2990 | + if (cmd->device->host->shost_state == SHOST_RECOVERY) { | |
2991 | + if (qla4xxx_eh_wait_for_active_target_commands(ha, | |
2992 | + cmd->device->id, | |
2993 | + cmd->device-> | |
2994 | + lun)) { | |
2995 | + dev_info(&ha->pdev->dev, | |
2996 | + "DEVICE RESET FAILED - waiting for " | |
2997 | + "commands.\n"); | |
2998 | + goto eh_dev_reset_done; | |
2999 | + } | |
3000 | } | |
3001 | - | |
3002 | - /* Send marker. */ | |
3003 | - if (qla4xxx_send_marker_iocb(ha, ddb_entry, cmd->device->lun, | |
3004 | - MM_LUN_RESET) != QLA_SUCCESS) | |
3005 | + if (qla4xxx_send_marker_iocb(ha, ddb_entry, cmd->device->lun) | |
3006 | + != QLA_SUCCESS) | |
3007 | goto eh_dev_reset_done; | |
3008 | ||
3009 | dev_info(&ha->pdev->dev, | |
3010 | - "scsi(%ld:%d:%d:%d): DEVICE RESET SUCCEEDED.\n", | |
3011 | - ha->host_no, cmd->device->channel, cmd->device->id, | |
3012 | - cmd->device->lun); | |
3013 | + "scsi(%ld:%d:%d:%d): DEVICE RESET SUCCEEDED.\n", | |
3014 | + ha->host_no, cmd->device->channel, cmd->device->id, | |
3015 | + cmd->device->lun); | |
3016 | ||
3017 | ret = SUCCESS; | |
3018 | ||
3019 | @@ -1578,59 +1610,6 @@ eh_dev_reset_done: | |
3020 | } | |
3021 | ||
3022 | /** | |
3023 | - * qla4xxx_eh_target_reset - callback for target reset. | |
3024 | - * @cmd: Pointer to Linux's SCSI command structure | |
3025 | - * | |
3026 | - * This routine is called by the Linux OS to reset the target. | |
3027 | - **/ | |
3028 | -static int qla4xxx_eh_target_reset(struct scsi_cmnd *cmd) | |
3029 | -{ | |
3030 | - struct scsi_qla_host *ha = to_qla_host(cmd->device->host); | |
3031 | - struct ddb_entry *ddb_entry = cmd->device->hostdata; | |
3032 | - int stat; | |
3033 | - | |
3034 | - if (!ddb_entry) | |
3035 | - return FAILED; | |
3036 | - | |
3037 | - starget_printk(KERN_INFO, scsi_target(cmd->device), | |
3038 | - "WARM TARGET RESET ISSUED.\n"); | |
3039 | - | |
3040 | - DEBUG2(printk(KERN_INFO | |
3041 | - "scsi%ld: TARGET_DEVICE_RESET cmd=%p jiffies = 0x%lx, " | |
3042 | - "to=%x,dpc_flags=%lx, status=%x allowed=%d\n", | |
3043 | - ha->host_no, cmd, jiffies, cmd->request->timeout / HZ, | |
3044 | - ha->dpc_flags, cmd->result, cmd->allowed)); | |
3045 | - | |
3046 | - stat = qla4xxx_reset_target(ha, ddb_entry); | |
3047 | - if (stat != QLA_SUCCESS) { | |
3048 | - starget_printk(KERN_INFO, scsi_target(cmd->device), | |
3049 | - "WARM TARGET RESET FAILED.\n"); | |
3050 | - return FAILED; | |
3051 | - } | |
3052 | - | |
3053 | - if (qla4xxx_eh_wait_for_commands(ha, scsi_target(cmd->device), | |
3054 | - NULL)) { | |
3055 | - starget_printk(KERN_INFO, scsi_target(cmd->device), | |
3056 | - "WARM TARGET DEVICE RESET FAILED - " | |
3057 | - "waiting for commands.\n"); | |
3058 | - return FAILED; | |
3059 | - } | |
3060 | - | |
3061 | - /* Send marker. */ | |
3062 | - if (qla4xxx_send_marker_iocb(ha, ddb_entry, cmd->device->lun, | |
3063 | - MM_TGT_WARM_RESET) != QLA_SUCCESS) { | |
3064 | - starget_printk(KERN_INFO, scsi_target(cmd->device), | |
3065 | - "WARM TARGET DEVICE RESET FAILED - " | |
3066 | - "marker iocb failed.\n"); | |
3067 | - return FAILED; | |
3068 | - } | |
3069 | - | |
3070 | - starget_printk(KERN_INFO, scsi_target(cmd->device), | |
3071 | - "WARM TARGET RESET SUCCEEDED.\n"); | |
3072 | - return SUCCESS; | |
3073 | -} | |
3074 | - | |
3075 | -/** | |
3076 | * qla4xxx_eh_host_reset - kernel callback | |
3077 | * @cmd: Pointer to Linux's SCSI command structure | |
3078 | * | |
3079 | @@ -1644,27 +1623,19 @@ static int qla4xxx_eh_host_reset(struct scsi_cmnd *cmd) | |
3080 | ||
3081 | ha = (struct scsi_qla_host *) cmd->device->host->hostdata; | |
3082 | ||
3083 | - dev_info(&ha->pdev->dev, | |
3084 | - "scsi(%ld:%d:%d:%d): ADAPTER RESET ISSUED.\n", ha->host_no, | |
3085 | - cmd->device->channel, cmd->device->id, cmd->device->lun); | |
3086 | + dev_info(&ha->pdev->dev, "%s: ADAPTER RESET ISSUED.\n", __func__); | |
3087 | ||
3088 | if (qla4xxx_wait_for_hba_online(ha) != QLA_SUCCESS) { | |
3089 | - DEBUG2(printk("scsi%ld:%d: %s: Unable to reset host. Adapter " | |
3090 | - "DEAD.\n", ha->host_no, cmd->device->channel, | |
3091 | - __func__)); | |
3092 | - | |
3093 | + dev_info(&ha->pdev->dev, "%s: HBA OFFLINE: FAILED\n", __func__); | |
3094 | return FAILED; | |
3095 | } | |
3096 | ||
3097 | - /* make sure the dpc thread is stopped while we reset the hba */ | |
3098 | - clear_bit(AF_ONLINE, &ha->flags); | |
3099 | - flush_workqueue(ha->dpc_thread); | |
3100 | - | |
3101 | - if (qla4xxx_recover_adapter(ha, PRESERVE_DDB_LIST) == QLA_SUCCESS) | |
3102 | + if (qla4xxx_recover_adapter(ha) == QLA_SUCCESS) { | |
3103 | return_status = SUCCESS; | |
3104 | + } | |
3105 | ||
3106 | dev_info(&ha->pdev->dev, "HOST RESET %s.\n", | |
3107 | - return_status == FAILED ? "FAILED" : "SUCCEDED"); | |
3108 | + return_status == FAILED ? "FAILED" : "SUCCEDED"); | |
3109 | ||
3110 | return return_status; | |
3111 | } | |
3112 | @@ -1704,9 +1675,11 @@ static int __init qla4xxx_module_init(void) | |
3113 | { | |
3114 | int ret; | |
3115 | ||
3116 | + atomic_set(&qla4xxx_hba_count, 0); | |
3117 | + klist_init(&qla4xxx_hostlist, NULL, NULL); | |
3118 | /* Allocate cache for SRBs. */ | |
3119 | srb_cachep = kmem_cache_create("qla4xxx_srbs", sizeof(struct srb), 0, | |
3120 | - SLAB_HWCACHE_ALIGN, NULL); | |
3121 | + SLAB_HWCACHE_ALIGN, NULL); | |
3122 | if (srb_cachep == NULL) { | |
3123 | printk(KERN_ERR | |
3124 | "%s: Unable to allocate SRB cache..." | |
3125 | @@ -1717,7 +1690,7 @@ static int __init qla4xxx_module_init(void) | |
3126 | ||
3127 | /* Derive version string. */ | |
3128 | strcpy(qla4xxx_version_str, QLA4XXX_DRIVER_VERSION); | |
3129 | - if (ql4xextended_error_logging) | |
3130 | + if (extended_error_logging) | |
3131 | strcat(qla4xxx_version_str, "-debug"); | |
3132 | ||
3133 | qla4xxx_scsi_transport = | |
3134 | @@ -1727,13 +1700,13 @@ static int __init qla4xxx_module_init(void) | |
3135 | goto release_srb_cache; | |
3136 | } | |
3137 | ||
3138 | + printk(KERN_INFO "QLogic iSCSI HBA Driver\n"); | |
3139 | ret = pci_register_driver(&qla4xxx_pci_driver); | |
3140 | if (ret) | |
3141 | goto unregister_transport; | |
3142 | ||
3143 | printk(KERN_INFO "QLogic iSCSI HBA Driver\n"); | |
3144 | return 0; | |
3145 | - | |
3146 | unregister_transport: | |
3147 | iscsi_unregister_transport(&qla4xxx_iscsi_transport); | |
3148 | release_srb_cache: | |
3149 | diff --git a/drivers/scsi/qla4xxx/ql4_version.h b/drivers/scsi/qla4xxx/ql4_version.h | |
3150 | index ab984cb..1cbfcbb 100644 | |
3151 | --- a/drivers/scsi/qla4xxx/ql4_version.h | |
3152 | +++ b/drivers/scsi/qla4xxx/ql4_version.h | |
3153 | @@ -5,5 +5,6 @@ | |
3154 | * See LICENSE.qla4xxx for copyright and licensing details. | |
3155 | */ | |
3156 | ||
3157 | -#define QLA4XXX_DRIVER_VERSION "5.01.00-k8" | |
3158 | +#define QLA4XXX_DRIVER_VERSION "5.01.00-k8_sles11-01" | |
3159 | + | |
3160 |