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