1 /*-
2 * Copyright (c) 2011, 2012 LSI Corp.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24 * SUCH DAMAGE.
25 *
26 * LSI MPT-Fusion Host Adapter FreeBSD
27 */
28
29 #include <sys/cdefs.h>
30 __FBSDID("$FreeBSD: releng/8.4/sys/dev/mps/mps_mapping.c 237877 2012-07-01 05:23:59Z ken $");
31
32 /* TODO Move headers to mpsvar */
33 #include <sys/types.h>
34 #include <sys/param.h>
35 #include <sys/lock.h>
36 #include <sys/mutex.h>
37 #include <sys/systm.h>
38 #include <sys/kernel.h>
39 #include <sys/malloc.h>
40 #include <sys/kthread.h>
41 #include <sys/taskqueue.h>
42 #include <sys/bus.h>
43 #include <sys/endian.h>
44 #include <sys/sysctl.h>
45 #include <sys/eventhandler.h>
46 #include <sys/uio.h>
47 #include <machine/bus.h>
48 #include <machine/resource.h>
49 #include <dev/mps/mpi/mpi2_type.h>
50 #include <dev/mps/mpi/mpi2.h>
51 #include <dev/mps/mpi/mpi2_ioc.h>
52 #include <dev/mps/mpi/mpi2_sas.h>
53 #include <dev/mps/mpi/mpi2_cnfg.h>
54 #include <dev/mps/mpi/mpi2_init.h>
55 #include <dev/mps/mpi/mpi2_tool.h>
56 #include <dev/mps/mps_ioctl.h>
57 #include <dev/mps/mpsvar.h>
58 #include <dev/mps/mps_mapping.h>
59
60 /**
61 * _mapping_clear_entry - Clear a particular mapping entry.
62 * @map_entry: map table entry
63 *
64 * Returns nothing.
65 */
66 static inline void
67 _mapping_clear_map_entry(struct dev_mapping_table *map_entry)
68 {
69 map_entry->physical_id = 0;
70 map_entry->device_info = 0;
71 map_entry->phy_bits = 0;
72 map_entry->dpm_entry_num = MPS_DPM_BAD_IDX;
73 map_entry->dev_handle = 0;
74 map_entry->channel = -1;
75 map_entry->id = -1;
76 map_entry->missing_count = 0;
77 map_entry->init_complete = 0;
78 map_entry->TLR_bits = (u8)MPI2_SCSIIO_CONTROL_NO_TLR;
79 }
80
81 /**
82 * _mapping_clear_enc_entry - Clear a particular enclosure table entry.
83 * @enc_entry: enclosure table entry
84 *
85 * Returns nothing.
86 */
87 static inline void
88 _mapping_clear_enc_entry(struct enc_mapping_table *enc_entry)
89 {
90 enc_entry->enclosure_id = 0;
91 enc_entry->start_index = MPS_MAPTABLE_BAD_IDX;
92 enc_entry->phy_bits = 0;
93 enc_entry->dpm_entry_num = MPS_DPM_BAD_IDX;
94 enc_entry->enc_handle = 0;
95 enc_entry->num_slots = 0;
96 enc_entry->start_slot = 0;
97 enc_entry->missing_count = 0;
98 enc_entry->removal_flag = 0;
99 enc_entry->skip_search = 0;
100 enc_entry->init_complete = 0;
101 }
102
103 /**
104 * _mapping_commit_enc_entry - write a particular enc entry in DPM page0.
105 * @sc: per adapter object
106 * @enc_entry: enclosure table entry
107 *
108 * Returns 0 for success, non-zero for failure.
109 */
110 static int
111 _mapping_commit_enc_entry(struct mps_softc *sc,
112 struct enc_mapping_table *et_entry)
113 {
114 Mpi2DriverMap0Entry_t *dpm_entry;
115 struct dev_mapping_table *mt_entry;
116 Mpi2ConfigReply_t mpi_reply;
117 Mpi2DriverMappingPage0_t config_page;
118
119 if (!sc->is_dpm_enable)
120 return 0;
121
122 memset(&config_page, 0, sizeof(Mpi2DriverMappingPage0_t));
123 memcpy(&config_page.Header, (u8 *) sc->dpm_pg0,
124 sizeof(MPI2_CONFIG_EXTENDED_PAGE_HEADER));
125 dpm_entry = (Mpi2DriverMap0Entry_t *)((u8 *)sc->dpm_pg0 +
126 sizeof(MPI2_CONFIG_EXTENDED_PAGE_HEADER));
127 dpm_entry += et_entry->dpm_entry_num;
128 dpm_entry->PhysicalIdentifier.Low =
129 ( 0xFFFFFFFF & et_entry->enclosure_id);
130 dpm_entry->PhysicalIdentifier.High =
131 ( et_entry->enclosure_id >> 32);
132 mt_entry = &sc->mapping_table[et_entry->start_index];
133 dpm_entry->DeviceIndex = htole16(mt_entry->id);
134 dpm_entry->MappingInformation = et_entry->num_slots;
135 dpm_entry->MappingInformation <<= MPI2_DRVMAP0_MAPINFO_SLOT_SHIFT;
136 dpm_entry->MappingInformation |= et_entry->missing_count;
137 dpm_entry->MappingInformation = htole16(dpm_entry->MappingInformation);
138 dpm_entry->PhysicalBitsMapping = htole32(et_entry->phy_bits);
139 dpm_entry->Reserved1 = 0;
140
141 memcpy(&config_page.Entry, (u8 *)dpm_entry,
142 sizeof(Mpi2DriverMap0Entry_t));
143 if (mps_config_set_dpm_pg0(sc, &mpi_reply, &config_page,
144 et_entry->dpm_entry_num)) {
145 printf("%s: write of dpm entry %d for enclosure failed\n",
146 __func__, et_entry->dpm_entry_num);
147 dpm_entry->MappingInformation = le16toh(dpm_entry->
148 MappingInformation);
149 dpm_entry->DeviceIndex = le16toh(dpm_entry->DeviceIndex);
150 dpm_entry->PhysicalBitsMapping =
151 le32toh(dpm_entry->PhysicalBitsMapping);
152 return -1;
153 }
154 dpm_entry->MappingInformation = le16toh(dpm_entry->
155 MappingInformation);
156 dpm_entry->DeviceIndex = le16toh(dpm_entry->DeviceIndex);
157 dpm_entry->PhysicalBitsMapping =
158 le32toh(dpm_entry->PhysicalBitsMapping);
159 return 0;
160 }
161
162 /**
163 * _mapping_commit_map_entry - write a particular map table entry in DPM page0.
164 * @sc: per adapter object
165 * @enc_entry: enclosure table entry
166 *
167 * Returns 0 for success, non-zero for failure.
168 */
169
170 static int
171 _mapping_commit_map_entry(struct mps_softc *sc,
172 struct dev_mapping_table *mt_entry)
173 {
174 Mpi2DriverMap0Entry_t *dpm_entry;
175 Mpi2ConfigReply_t mpi_reply;
176 Mpi2DriverMappingPage0_t config_page;
177
178 if (!sc->is_dpm_enable)
179 return 0;
180
181 memset(&config_page, 0, sizeof(Mpi2DriverMappingPage0_t));
182 memcpy(&config_page.Header, (u8 *)sc->dpm_pg0,
183 sizeof(MPI2_CONFIG_EXTENDED_PAGE_HEADER));
184 dpm_entry = (Mpi2DriverMap0Entry_t *)((u8 *) sc->dpm_pg0 +
185 sizeof(MPI2_CONFIG_EXTENDED_PAGE_HEADER));
186 dpm_entry = dpm_entry + mt_entry->dpm_entry_num;
187 dpm_entry->PhysicalIdentifier.Low = (0xFFFFFFFF &
188 mt_entry->physical_id);
189 dpm_entry->PhysicalIdentifier.High = (mt_entry->physical_id >> 32);
190 dpm_entry->DeviceIndex = htole16(mt_entry->id);
191 dpm_entry->MappingInformation = htole16(mt_entry->missing_count);
192 dpm_entry->PhysicalBitsMapping = 0;
193 dpm_entry->Reserved1 = 0;
194 dpm_entry->MappingInformation = htole16(dpm_entry->MappingInformation);
195 memcpy(&config_page.Entry, (u8 *)dpm_entry,
196 sizeof(Mpi2DriverMap0Entry_t));
197 if (mps_config_set_dpm_pg0(sc, &mpi_reply, &config_page,
198 mt_entry->dpm_entry_num)) {
199 printf("%s: write of dpm entry %d for device failed\n",
200 __func__, mt_entry->dpm_entry_num);
201 dpm_entry->MappingInformation = le16toh(dpm_entry->
202 MappingInformation);
203 dpm_entry->DeviceIndex = le16toh(dpm_entry->DeviceIndex);
204 return -1;
205 }
206
207 dpm_entry->MappingInformation = le16toh(dpm_entry->MappingInformation);
208 dpm_entry->DeviceIndex = le16toh(dpm_entry->DeviceIndex);
209 return 0;
210 }
211
212 /**
213 * _mapping_get_ir_maprange - get start and end index for IR map range.
214 * @sc: per adapter object
215 * @start_idx: place holder for start index
216 * @end_idx: place holder for end index
217 *
218 * The IR volumes can be mapped either at start or end of the mapping table
219 * this function gets the detail of where IR volume mapping starts and ends
220 * in the device mapping table
221 *
222 * Returns nothing.
223 */
224 static void
225 _mapping_get_ir_maprange(struct mps_softc *sc, u32 *start_idx, u32 *end_idx)
226 {
227 u16 volume_mapping_flags;
228 u16 ioc_pg8_flags = le16toh(sc->ioc_pg8.Flags);
229
230 volume_mapping_flags = le16toh(sc->ioc_pg8.IRVolumeMappingFlags) &
231 MPI2_IOCPAGE8_IRFLAGS_MASK_VOLUME_MAPPING_MODE;
232 if (volume_mapping_flags == MPI2_IOCPAGE8_IRFLAGS_LOW_VOLUME_MAPPING) {
233 *start_idx = 0;
234 if (ioc_pg8_flags & MPI2_IOCPAGE8_FLAGS_RESERVED_TARGETID_0)
235 *start_idx = 1;
236 } else
237 *start_idx = sc->max_devices - sc->max_volumes;
238 *end_idx = *start_idx + sc->max_volumes - 1;
239 }
240
241 /**
242 * _mapping_get_enc_idx_from_id - get enclosure index from enclosure ID
243 * @sc: per adapter object
244 * @enc_id: enclosure logical identifier
245 *
246 * Returns the index of enclosure entry on success or bad index.
247 */
248 static u8
249 _mapping_get_enc_idx_from_id(struct mps_softc *sc, u64 enc_id,
250 u64 phy_bits)
251 {
252 struct enc_mapping_table *et_entry;
253 u8 enc_idx = 0;
254
255 for (enc_idx = 0; enc_idx < sc->num_enc_table_entries; enc_idx++) {
256 et_entry = &sc->enclosure_table[enc_idx];
257 if ((et_entry->enclosure_id == le64toh(enc_id)) &&
258 (!et_entry->phy_bits || (et_entry->phy_bits &
259 le32toh(phy_bits))))
260 return enc_idx;
261 }
262 return MPS_ENCTABLE_BAD_IDX;
263 }
264
265 /**
266 * _mapping_get_enc_idx_from_handle - get enclosure index from handle
267 * @sc: per adapter object
268 * @enc_id: enclosure handle
269 *
270 * Returns the index of enclosure entry on success or bad index.
271 */
272 static u8
273 _mapping_get_enc_idx_from_handle(struct mps_softc *sc, u16 handle)
274 {
275 struct enc_mapping_table *et_entry;
276 u8 enc_idx = 0;
277
278 for (enc_idx = 0; enc_idx < sc->num_enc_table_entries; enc_idx++) {
279 et_entry = &sc->enclosure_table[enc_idx];
280 if (et_entry->missing_count)
281 continue;
282 if (et_entry->enc_handle == handle)
283 return enc_idx;
284 }
285 return MPS_ENCTABLE_BAD_IDX;
286 }
287
288 /**
289 * _mapping_get_high_missing_et_idx - get missing enclosure index
290 * @sc: per adapter object
291 *
292 * Search through the enclosure table and identifies the enclosure entry
293 * with high missing count and returns it's index
294 *
295 * Returns the index of enclosure entry on success or bad index.
296 */
297 static u8
298 _mapping_get_high_missing_et_idx(struct mps_softc *sc)
299 {
300 struct enc_mapping_table *et_entry;
301 u8 high_missing_count = 0;
302 u8 enc_idx, high_idx = MPS_ENCTABLE_BAD_IDX;
303
304 for (enc_idx = 0; enc_idx < sc->num_enc_table_entries; enc_idx++) {
305 et_entry = &sc->enclosure_table[enc_idx];
306 if ((et_entry->missing_count > high_missing_count) &&
307 !et_entry->skip_search) {
308 high_missing_count = et_entry->missing_count;
309 high_idx = enc_idx;
310 }
311 }
312 return high_idx;
313 }
314
315 /**
316 * _mapping_get_high_missing_mt_idx - get missing map table index
317 * @sc: per adapter object
318 *
319 * Search through the map table and identifies the device entry
320 * with high missing count and returns it's index
321 *
322 * Returns the index of map table entry on success or bad index.
323 */
324 static u32
325 _mapping_get_high_missing_mt_idx(struct mps_softc *sc)
326 {
327 u32 map_idx, high_idx = MPS_ENCTABLE_BAD_IDX;
328 u8 high_missing_count = 0;
329 u32 start_idx, end_idx, start_idx_ir, end_idx_ir;
330 struct dev_mapping_table *mt_entry;
331 u16 ioc_pg8_flags = le16toh(sc->ioc_pg8.Flags);
332
333 start_idx = 0;
334 end_idx = sc->max_devices;
335 if (ioc_pg8_flags & MPI2_IOCPAGE8_FLAGS_RESERVED_TARGETID_0)
336 start_idx = 1;
337 if (sc->ir_firmware)
338 _mapping_get_ir_maprange(sc, &start_idx_ir, &end_idx_ir);
339 if (start_idx == start_idx_ir)
340 start_idx = end_idx_ir + 1;
341 else
342 end_idx = start_idx_ir;
343 mt_entry = &sc->mapping_table[start_idx];
344 for (map_idx = start_idx; map_idx < end_idx; map_idx++, mt_entry++) {
345 if (mt_entry->missing_count > high_missing_count) {
346 high_missing_count = mt_entry->missing_count;
347 high_idx = map_idx;
348 }
349 }
350 return high_idx;
351 }
352
353 /**
354 * _mapping_get_ir_mt_idx_from_wwid - get map table index from volume WWID
355 * @sc: per adapter object
356 * @wwid: world wide unique ID of the volume
357 *
358 * Returns the index of map table entry on success or bad index.
359 */
360 static u32
361 _mapping_get_ir_mt_idx_from_wwid(struct mps_softc *sc, u64 wwid)
362 {
363 u32 start_idx, end_idx, map_idx;
364 struct dev_mapping_table *mt_entry;
365
366 _mapping_get_ir_maprange(sc, &start_idx, &end_idx);
367 mt_entry = &sc->mapping_table[start_idx];
368 for (map_idx = start_idx; map_idx <= end_idx; map_idx++, mt_entry++)
369 if (mt_entry->physical_id == wwid)
370 return map_idx;
371
372 return MPS_MAPTABLE_BAD_IDX;
373 }
374
375 /**
376 * _mapping_get_mt_idx_from_id - get map table index from a device ID
377 * @sc: per adapter object
378 * @dev_id: device identifer (SAS Address)
379 *
380 * Returns the index of map table entry on success or bad index.
381 */
382 static u32
383 _mapping_get_mt_idx_from_id(struct mps_softc *sc, u64 dev_id)
384 {
385 u32 map_idx;
386 struct dev_mapping_table *mt_entry;
387
388 for (map_idx = 0; map_idx < sc->max_devices; map_idx++) {
389 mt_entry = &sc->mapping_table[map_idx];
390 if (mt_entry->physical_id == dev_id)
391 return map_idx;
392 }
393 return MPS_MAPTABLE_BAD_IDX;
394 }
395
396 /**
397 * _mapping_get_ir_mt_idx_from_handle - get map table index from volume handle
398 * @sc: per adapter object
399 * @wwid: volume device handle
400 *
401 * Returns the index of map table entry on success or bad index.
402 */
403 static u32
404 _mapping_get_ir_mt_idx_from_handle(struct mps_softc *sc, u16 volHandle)
405 {
406 u32 start_idx, end_idx, map_idx;
407 struct dev_mapping_table *mt_entry;
408
409 _mapping_get_ir_maprange(sc, &start_idx, &end_idx);
410 mt_entry = &sc->mapping_table[start_idx];
411 for (map_idx = start_idx; map_idx <= end_idx; map_idx++, mt_entry++)
412 if (mt_entry->dev_handle == volHandle)
413 return map_idx;
414
415 return MPS_MAPTABLE_BAD_IDX;
416 }
417
418 /**
419 * _mapping_get_mt_idx_from_handle - get map table index from handle
420 * @sc: per adapter object
421 * @dev_id: device handle
422 *
423 * Returns the index of map table entry on success or bad index.
424 */
425 static u32
426 _mapping_get_mt_idx_from_handle(struct mps_softc *sc, u16 handle)
427 {
428 u32 map_idx;
429 struct dev_mapping_table *mt_entry;
430
431 for (map_idx = 0; map_idx < sc->max_devices; map_idx++) {
432 mt_entry = &sc->mapping_table[map_idx];
433 if (mt_entry->dev_handle == handle)
434 return map_idx;
435 }
436 return MPS_MAPTABLE_BAD_IDX;
437 }
438
439 /**
440 * _mapping_get_free_ir_mt_idx - get first free index for a volume
441 * @sc: per adapter object
442 *
443 * Search through mapping table for free index for a volume and if no free
444 * index then looks for a volume with high mapping index
445 *
446 * Returns the index of map table entry on success or bad index.
447 */
448 static u32
449 _mapping_get_free_ir_mt_idx(struct mps_softc *sc)
450 {
451 u8 high_missing_count = 0;
452 u32 start_idx, end_idx, map_idx;
453 u32 high_idx = MPS_MAPTABLE_BAD_IDX;
454 struct dev_mapping_table *mt_entry;
455
456 _mapping_get_ir_maprange(sc, &start_idx, &end_idx);
457
458 mt_entry = &sc->mapping_table[start_idx];
459 for (map_idx = start_idx; map_idx <= end_idx; map_idx++, mt_entry++)
460 if (!(mt_entry->device_info & MPS_MAP_IN_USE))
461 return map_idx;
462
463 mt_entry = &sc->mapping_table[start_idx];
464 for (map_idx = start_idx; map_idx <= end_idx; map_idx++, mt_entry++) {
465 if (mt_entry->missing_count > high_missing_count) {
466 high_missing_count = mt_entry->missing_count;
467 high_idx = map_idx;
468 }
469 }
470 return high_idx;
471 }
472
473 /**
474 * _mapping_get_free_mt_idx - get first free index for a device
475 * @sc: per adapter object
476 * @start_idx: offset in the table to start search
477 *
478 * Returns the index of map table entry on success or bad index.
479 */
480 static u32
481 _mapping_get_free_mt_idx(struct mps_softc *sc, u32 start_idx)
482 {
483 u32 map_idx, max_idx = sc->max_devices;
484 struct dev_mapping_table *mt_entry = &sc->mapping_table[start_idx];
485 u16 volume_mapping_flags;
486
487 volume_mapping_flags = le16toh(sc->ioc_pg8.IRVolumeMappingFlags) &
488 MPI2_IOCPAGE8_IRFLAGS_MASK_VOLUME_MAPPING_MODE;
489 if (sc->ir_firmware && (volume_mapping_flags ==
490 MPI2_IOCPAGE8_IRFLAGS_HIGH_VOLUME_MAPPING))
491 max_idx -= sc->max_volumes;
492 for (map_idx = start_idx; map_idx < max_idx; map_idx++, mt_entry++)
493 if (!(mt_entry->device_info & (MPS_MAP_IN_USE |
494 MPS_DEV_RESERVED)))
495 return map_idx;
496
497 return MPS_MAPTABLE_BAD_IDX;
498 }
499
500 /**
501 * _mapping_get_dpm_idx_from_id - get DPM index from ID
502 * @sc: per adapter object
503 * @id: volume WWID or enclosure ID or device ID
504 *
505 * Returns the index of DPM entry on success or bad index.
506 */
507 static u16
508 _mapping_get_dpm_idx_from_id(struct mps_softc *sc, u64 id, u32 phy_bits)
509 {
510 u16 entry_num;
511 uint64_t PhysicalIdentifier;
512 Mpi2DriverMap0Entry_t *dpm_entry;
513
514 dpm_entry = (Mpi2DriverMap0Entry_t *)((u8 *)sc->dpm_pg0 +
515 sizeof(MPI2_CONFIG_EXTENDED_PAGE_HEADER));
516 PhysicalIdentifier = dpm_entry->PhysicalIdentifier.High;
517 PhysicalIdentifier = (PhysicalIdentifier << 32) |
518 dpm_entry->PhysicalIdentifier.Low;
519 for (entry_num = 0; entry_num < sc->max_dpm_entries; entry_num++,
520 dpm_entry++)
521 if ((id == PhysicalIdentifier) &&
522 (!phy_bits || !dpm_entry->PhysicalBitsMapping ||
523 (phy_bits & dpm_entry->PhysicalBitsMapping)))
524 return entry_num;
525
526 return MPS_DPM_BAD_IDX;
527 }
528
529
530 /**
531 * _mapping_get_free_dpm_idx - get first available DPM index
532 * @sc: per adapter object
533 *
534 * Returns the index of DPM entry on success or bad index.
535 */
536 static u32
537 _mapping_get_free_dpm_idx(struct mps_softc *sc)
538 {
539 u16 entry_num;
540
541 for (entry_num = 0; entry_num < sc->max_dpm_entries; entry_num++) {
542 if (!sc->dpm_entry_used[entry_num])
543 return entry_num;
544 }
545 return MPS_DPM_BAD_IDX;
546 }
547
548 /**
549 * _mapping_update_ir_missing_cnt - Updates missing count for a volume
550 * @sc: per adapter object
551 * @map_idx: map table index of the volume
552 * @element: IR configuration change element
553 * @wwid: IR volume ID.
554 *
555 * Updates the missing count in the map table and in the DPM entry for a volume
556 *
557 * Returns nothing.
558 */
559 static void
560 _mapping_update_ir_missing_cnt(struct mps_softc *sc, u32 map_idx,
561 Mpi2EventIrConfigElement_t *element, u64 wwid)
562 {
563 struct dev_mapping_table *mt_entry;
564 u8 missing_cnt, reason = element->ReasonCode;
565 u16 dpm_idx;
566 Mpi2DriverMap0Entry_t *dpm_entry;
567
568 if (!sc->is_dpm_enable)
569 return;
570 mt_entry = &sc->mapping_table[map_idx];
571 if (reason == MPI2_EVENT_IR_CHANGE_RC_ADDED) {
572 mt_entry->missing_count = 0;
573 } else if (reason == MPI2_EVENT_IR_CHANGE_RC_VOLUME_CREATED) {
574 mt_entry->missing_count = 0;
575 mt_entry->init_complete = 0;
576 } else if ((reason == MPI2_EVENT_IR_CHANGE_RC_REMOVED) ||
577 (reason == MPI2_EVENT_IR_CHANGE_RC_VOLUME_DELETED)) {
578 if (!mt_entry->init_complete) {
579 if (mt_entry->missing_count < MPS_MAX_MISSING_COUNT)
580 mt_entry->missing_count++;
581 else
582 mt_entry->init_complete = 1;
583 }
584 if (!mt_entry->missing_count)
585 mt_entry->missing_count++;
586 mt_entry->dev_handle = 0;
587 }
588
589 dpm_idx = mt_entry->dpm_entry_num;
590 if (dpm_idx == MPS_DPM_BAD_IDX) {
591 if ((reason == MPI2_EVENT_IR_CHANGE_RC_ADDED) ||
592 (reason == MPI2_EVENT_IR_CHANGE_RC_REMOVED))
593 dpm_idx = _mapping_get_dpm_idx_from_id(sc,
594 mt_entry->physical_id, 0);
595 else if (reason == MPI2_EVENT_IR_CHANGE_RC_VOLUME_DELETED)
596 return;
597 }
598 if (dpm_idx != MPS_DPM_BAD_IDX) {
599 dpm_entry = (Mpi2DriverMap0Entry_t *)((u8 *)sc->dpm_pg0 +
600 sizeof(MPI2_CONFIG_EXTENDED_PAGE_HEADER));
601 dpm_entry += dpm_idx;
602 missing_cnt = dpm_entry->MappingInformation &
603 MPI2_DRVMAP0_MAPINFO_MISSING_MASK;
604 if ((mt_entry->physical_id ==
605 le64toh((u64)dpm_entry->PhysicalIdentifier.High |
606 dpm_entry->PhysicalIdentifier.Low)) && (missing_cnt ==
607 mt_entry->missing_count))
608 mt_entry->init_complete = 1;
609 } else {
610 dpm_idx = _mapping_get_free_dpm_idx(sc);
611 mt_entry->init_complete = 0;
612 }
613
614 if ((dpm_idx != MPS_DPM_BAD_IDX) && !mt_entry->init_complete) {
615 mt_entry->init_complete = 1;
616 mt_entry->dpm_entry_num = dpm_idx;
617 dpm_entry = (Mpi2DriverMap0Entry_t *)((u8 *)sc->dpm_pg0 +
618 sizeof(MPI2_CONFIG_EXTENDED_PAGE_HEADER));
619 dpm_entry += dpm_idx;
620 dpm_entry->PhysicalIdentifier.Low =
621 (0xFFFFFFFF & mt_entry->physical_id);
622 dpm_entry->PhysicalIdentifier.High =
623 (mt_entry->physical_id >> 32);
624 dpm_entry->DeviceIndex = map_idx;
625 dpm_entry->MappingInformation = mt_entry->missing_count;
626 dpm_entry->PhysicalBitsMapping = 0;
627 dpm_entry->Reserved1 = 0;
628 sc->dpm_flush_entry[dpm_idx] = 1;
629 sc->dpm_entry_used[dpm_idx] = 1;
630 } else if (dpm_idx == MPS_DPM_BAD_IDX) {
631 printf("%s: no space to add entry in DPM table\n", __func__);
632 mt_entry->init_complete = 1;
633 }
634 }
635
636 /**
637 * _mapping_add_to_removal_table - mark an entry for removal
638 * @sc: per adapter object
639 * @handle: Handle of enclosures/device/volume
640 *
641 * Adds the handle or DPM entry number in removal table.
642 *
643 * Returns nothing.
644 */
645 static void
646 _mapping_add_to_removal_table(struct mps_softc *sc, u16 handle,
647 u16 dpm_idx)
648 {
649 struct map_removal_table *remove_entry;
650 u32 i;
651 u16 ioc_pg8_flags = le16toh(sc->ioc_pg8.Flags);
652
653 remove_entry = sc->removal_table;
654
655 for (i = 0; i < sc->max_devices; i++, remove_entry++) {
656 if (remove_entry->dev_handle || remove_entry->dpm_entry_num !=
657 MPS_DPM_BAD_IDX)
658 continue;
659 if ((ioc_pg8_flags & MPI2_IOCPAGE8_FLAGS_MASK_MAPPING_MODE) ==
660 MPI2_IOCPAGE8_FLAGS_ENCLOSURE_SLOT_MAPPING) {
661 if (dpm_idx)
662 remove_entry->dpm_entry_num = dpm_idx;
663 if (remove_entry->dpm_entry_num == MPS_DPM_BAD_IDX)
664 remove_entry->dev_handle = handle;
665 } else if ((ioc_pg8_flags &
666 MPI2_IOCPAGE8_FLAGS_MASK_MAPPING_MODE) ==
667 MPI2_IOCPAGE8_FLAGS_DEVICE_PERSISTENCE_MAPPING)
668 remove_entry->dev_handle = handle;
669 break;
670 }
671
672 }
673
674 /**
675 * _mapping_update_missing_count - Update missing count for a device
676 * @sc: per adapter object
677 * @topo_change: Topology change event entry
678 *
679 * Search through the topology change list and if any device is found not
680 * responding it's associated map table entry and DPM entry is updated
681 *
682 * Returns nothing.
683 */
684 static void
685 _mapping_update_missing_count(struct mps_softc *sc,
686 struct _map_topology_change *topo_change)
687 {
688 u16 ioc_pg8_flags = le16toh(sc->ioc_pg8.Flags);
689 u8 entry;
690 struct _map_phy_change *phy_change;
691 u32 map_idx;
692 struct dev_mapping_table *mt_entry;
693 Mpi2DriverMap0Entry_t *dpm_entry;
694
695 for (entry = 0; entry < topo_change->num_entries; entry++) {
696 phy_change = &topo_change->phy_details[entry];
697 if (!phy_change->dev_handle || (phy_change->reason !=
698 MPI2_EVENT_SAS_TOPO_RC_TARG_NOT_RESPONDING))
699 continue;
700 map_idx = _mapping_get_mt_idx_from_handle(sc, phy_change->
701 dev_handle);
702 phy_change->is_processed = 1;
703 if (map_idx == MPS_MAPTABLE_BAD_IDX) {
704 printf("%s: device is already removed from mapping "
705 "table\n", __func__);
706 continue;
707 }
708 mt_entry = &sc->mapping_table[map_idx];
709 if (!mt_entry->init_complete) {
710 if (mt_entry->missing_count < MPS_MAX_MISSING_COUNT)
711 mt_entry->missing_count++;
712 else
713 mt_entry->init_complete = 1;
714 }
715 if (!mt_entry->missing_count)
716 mt_entry->missing_count++;
717 _mapping_add_to_removal_table(sc, mt_entry->dev_handle, 0);
718 mt_entry->dev_handle = 0;
719
720 if (((ioc_pg8_flags & MPI2_IOCPAGE8_FLAGS_MASK_MAPPING_MODE) ==
721 MPI2_IOCPAGE8_FLAGS_DEVICE_PERSISTENCE_MAPPING) &&
722 sc->is_dpm_enable && !mt_entry->init_complete &&
723 mt_entry->dpm_entry_num != MPS_DPM_BAD_IDX) {
724 dpm_entry =
725 (Mpi2DriverMap0Entry_t *) ((u8 *)sc->dpm_pg0 +
726 sizeof(MPI2_CONFIG_EXTENDED_PAGE_HEADER));
727 dpm_entry += mt_entry->dpm_entry_num;
728 dpm_entry->MappingInformation = mt_entry->missing_count;
729 sc->dpm_flush_entry[mt_entry->dpm_entry_num] = 1;
730 }
731 mt_entry->init_complete = 1;
732 }
733 }
734
735 /**
736 * _mapping_find_enc_map_space -find map table entries for enclosure
737 * @sc: per adapter object
738 * @et_entry: enclosure entry
739 *
740 * Search through the mapping table defragment it and provide contiguous
741 * space in map table for a particular enclosure entry
742 *
743 * Returns start index in map table or bad index.
744 */
745 static u32
746 _mapping_find_enc_map_space(struct mps_softc *sc,
747 struct enc_mapping_table *et_entry)
748 {
749 u16 vol_mapping_flags;
750 u32 skip_count, end_of_table, map_idx, enc_idx;
751 u16 num_found;
752 u32 start_idx = MPS_MAPTABLE_BAD_IDX;
753 struct dev_mapping_table *mt_entry;
754 struct enc_mapping_table *enc_entry;
755 unsigned char done_flag = 0, found_space;
756 u16 max_num_phy_ids = le16toh(sc->ioc_pg8.MaxNumPhysicalMappedIDs);
757
758 skip_count = sc->num_rsvd_entries;
759 num_found = 0;
760
761 vol_mapping_flags = le16toh(sc->ioc_pg8.IRVolumeMappingFlags) &
762 MPI2_IOCPAGE8_IRFLAGS_MASK_VOLUME_MAPPING_MODE;
763
764 if (!sc->ir_firmware)
765 end_of_table = sc->max_devices;
766 else if (vol_mapping_flags == MPI2_IOCPAGE8_IRFLAGS_LOW_VOLUME_MAPPING)
767 end_of_table = sc->max_devices;
768 else
769 end_of_table = sc->max_devices - sc->max_volumes;
770
771 for (map_idx = (max_num_phy_ids + skip_count);
772 map_idx < end_of_table; map_idx++) {
773 mt_entry = &sc->mapping_table[map_idx];
774 if ((et_entry->enclosure_id == mt_entry->physical_id) &&
775 (!mt_entry->phy_bits || (mt_entry->phy_bits &
776 et_entry->phy_bits))) {
777 num_found += 1;
778 if (num_found == et_entry->num_slots) {
779 start_idx = (map_idx - num_found) + 1;
780 return start_idx;
781 }
782 } else
783 num_found = 0;
784 }
785 for (map_idx = (max_num_phy_ids + skip_count);
786 map_idx < end_of_table; map_idx++) {
787 mt_entry = &sc->mapping_table[map_idx];
788 if (!(mt_entry->device_info & MPS_DEV_RESERVED)) {
789 num_found += 1;
790 if (num_found == et_entry->num_slots) {
791 start_idx = (map_idx - num_found) + 1;
792 return start_idx;
793 }
794 } else
795 num_found = 0;
796 }
797
798 while (!done_flag) {
799 enc_idx = _mapping_get_high_missing_et_idx(sc);
800 if (enc_idx == MPS_ENCTABLE_BAD_IDX)
801 return MPS_MAPTABLE_BAD_IDX;
802 enc_entry = &sc->enclosure_table[enc_idx];
803 /*VSP FIXME*/
804 enc_entry->skip_search = 1;
805 mt_entry = &sc->mapping_table[enc_entry->start_index];
806 for (map_idx = enc_entry->start_index; map_idx <
807 (enc_entry->start_index + enc_entry->num_slots); map_idx++,
808 mt_entry++)
809 mt_entry->device_info &= ~MPS_DEV_RESERVED;
810 found_space = 0;
811 for (map_idx = (max_num_phy_ids +
812 skip_count); map_idx < end_of_table; map_idx++) {
813 mt_entry = &sc->mapping_table[map_idx];
814 if (!(mt_entry->device_info & MPS_DEV_RESERVED)) {
815 num_found += 1;
816 if (num_found == et_entry->num_slots) {
817 start_idx = (map_idx - num_found) + 1;
818 found_space = 1;
819 }
820 } else
821 num_found = 0;
822 }
823
824 if (!found_space)
825 continue;
826 for (map_idx = start_idx; map_idx < (start_idx + num_found);
827 map_idx++) {
828 enc_entry = sc->enclosure_table;
829 for (enc_idx = 0; enc_idx < sc->num_enc_table_entries;
830 enc_idx++, enc_entry++) {
831 if (map_idx < enc_entry->start_index ||
832 map_idx > (enc_entry->start_index +
833 enc_entry->num_slots))
834 continue;
835 if (!enc_entry->removal_flag) {
836 enc_entry->removal_flag = 1;
837 _mapping_add_to_removal_table(sc, 0,
838 enc_entry->dpm_entry_num);
839 }
840 mt_entry = &sc->mapping_table[map_idx];
841 if (mt_entry->device_info &
842 MPS_MAP_IN_USE) {
843 _mapping_add_to_removal_table(sc,
844 mt_entry->dev_handle, 0);
845 _mapping_clear_map_entry(mt_entry);
846 }
847 if (map_idx == (enc_entry->start_index +
848 enc_entry->num_slots - 1))
849 _mapping_clear_enc_entry(et_entry);
850 }
851 }
852 enc_entry = sc->enclosure_table;
853 for (enc_idx = 0; enc_idx < sc->num_enc_table_entries;
854 enc_idx++, enc_entry++) {
855 if (!enc_entry->removal_flag) {
856 mt_entry = &sc->mapping_table[enc_entry->
857 start_index];
858 for (map_idx = enc_entry->start_index; map_idx <
859 (enc_entry->start_index +
860 enc_entry->num_slots); map_idx++,
861 mt_entry++)
862 mt_entry->device_info |=
863 MPS_DEV_RESERVED;
864 et_entry->skip_search = 0;
865 }
866 }
867 done_flag = 1;
868 }
869 return start_idx;
870 }
871
872 /**
873 * _mapping_get_dev_info -get information about newly added devices
874 * @sc: per adapter object
875 * @topo_change: Topology change event entry
876 *
877 * Search through the topology change event list and issues sas device pg0
878 * requests for the newly added device and reserved entries in tables
879 *
880 * Returns nothing
881 */
882 static void
883 _mapping_get_dev_info(struct mps_softc *sc,
884 struct _map_topology_change *topo_change)
885 {
886 u16 ioc_pg8_flags = le16toh(sc->ioc_pg8.Flags);
887 Mpi2ConfigReply_t mpi_reply;
888 Mpi2SasDevicePage0_t sas_device_pg0;
889 u8 entry, enc_idx, phy_idx;
890 u32 map_idx, index, device_info;
891 struct _map_phy_change *phy_change, *tmp_phy_change;
892 uint64_t sas_address;
893 struct enc_mapping_table *et_entry;
894 struct dev_mapping_table *mt_entry;
895 u8 add_code = MPI2_EVENT_SAS_TOPO_RC_TARG_ADDED;
896 int rc;
897
898 for (entry = 0; entry < topo_change->num_entries; entry++) {
899 phy_change = &topo_change->phy_details[entry];
900 if (phy_change->is_processed || !phy_change->dev_handle ||
901 phy_change->reason != MPI2_EVENT_SAS_TOPO_RC_TARG_ADDED)
902 continue;
903 if (mps_config_get_sas_device_pg0(sc, &mpi_reply,
904 &sas_device_pg0, MPI2_SAS_DEVICE_PGAD_FORM_HANDLE,
905 phy_change->dev_handle)) {
906 phy_change->is_processed = 1;
907 continue;
908 }
909
910 device_info = le32toh(sas_device_pg0.DeviceInfo);
911 if ((ioc_pg8_flags & MPI2_IOCPAGE8_FLAGS_MASK_MAPPING_MODE) ==
912 MPI2_IOCPAGE8_FLAGS_DEVICE_PERSISTENCE_MAPPING) {
913 if ((device_info & MPI2_SAS_DEVICE_INFO_END_DEVICE) &&
914 (device_info & MPI2_SAS_DEVICE_INFO_SATA_DEVICE)) {
915 rc = mpssas_get_sas_address_for_sata_disk(sc,
916 &sas_address, phy_change->dev_handle,
917 device_info);
918 if (rc) {
919 printf("%s: failed to compute the "
920 "hashed SAS Address for SATA "
921 "device with handle 0x%04x\n",
922 __func__, phy_change->dev_handle);
923 sas_address =
924 sas_device_pg0.SASAddress.High;
925 sas_address = (sas_address << 32) |
926 sas_device_pg0.SASAddress.Low;
927 }
928 mps_dprint(sc, MPS_INFO, "SAS Address for SATA "
929 "device = %jx\n", sas_address);
930 } else {
931 sas_address =
932 sas_device_pg0.SASAddress.High;
933 sas_address = (sas_address << 32) |
934 sas_device_pg0.SASAddress.Low;
935 }
936 } else {
937 sas_address = sas_device_pg0.SASAddress.High;
938 sas_address = (sas_address << 32) |
939 sas_device_pg0.SASAddress.Low;
940 }
941 phy_change->physical_id = sas_address;
942 phy_change->slot = le16toh(sas_device_pg0.Slot);
943 phy_change->device_info =
944 le32toh(sas_device_pg0.DeviceInfo);
945
946 if ((ioc_pg8_flags & MPI2_IOCPAGE8_FLAGS_MASK_MAPPING_MODE) ==
947 MPI2_IOCPAGE8_FLAGS_ENCLOSURE_SLOT_MAPPING) {
948 enc_idx = _mapping_get_enc_idx_from_handle(sc,
949 topo_change->enc_handle);
950 if (enc_idx == MPS_ENCTABLE_BAD_IDX) {
951 phy_change->is_processed = 1;
952 printf("%s: failed to add the device with "
953 "handle 0x%04x because the enclosure is "
954 "not in the mapping table\n", __func__,
955 phy_change->dev_handle);
956 continue;
957 }
958 if (!((phy_change->device_info &
959 MPI2_SAS_DEVICE_INFO_END_DEVICE) &&
960 (phy_change->device_info &
961 (MPI2_SAS_DEVICE_INFO_SSP_TARGET |
962 MPI2_SAS_DEVICE_INFO_STP_TARGET |
963 MPI2_SAS_DEVICE_INFO_SATA_DEVICE)))) {
964 phy_change->is_processed = 1;
965 continue;
966 }
967 et_entry = &sc->enclosure_table[enc_idx];
968 if (et_entry->start_index != MPS_MAPTABLE_BAD_IDX)
969 continue;
970 if (!topo_change->exp_handle) {
971 map_idx = sc->num_rsvd_entries;
972 et_entry->start_index = map_idx;
973 } else {
974 map_idx = _mapping_find_enc_map_space(sc,
975 et_entry);
976 et_entry->start_index = map_idx;
977 if (et_entry->start_index ==
978 MPS_MAPTABLE_BAD_IDX) {
979 phy_change->is_processed = 1;
980 for (phy_idx = 0; phy_idx <
981 topo_change->num_entries;
982 phy_idx++) {
983 tmp_phy_change =
984 &topo_change->phy_details
985 [phy_idx];
986 if (tmp_phy_change->reason ==
987 add_code)
988 tmp_phy_change->
989 is_processed = 1;
990 }
991 break;
992 }
993 }
994 mt_entry = &sc->mapping_table[map_idx];
995 for (index = map_idx; index < (et_entry->num_slots
996 + map_idx); index++, mt_entry++) {
997 mt_entry->device_info = MPS_DEV_RESERVED;
998 mt_entry->physical_id = et_entry->enclosure_id;
999 mt_entry->phy_bits = et_entry->phy_bits;
1000 }
1001 }
1002 }
1003 }
1004
1005 /**
1006 * _mapping_set_mid_to_eid -set map table data from enclosure table
1007 * @sc: per adapter object
1008 * @et_entry: enclosure entry
1009 *
1010 * Returns nothing
1011 */
1012 static inline void
1013 _mapping_set_mid_to_eid(struct mps_softc *sc,
1014 struct enc_mapping_table *et_entry)
1015 {
1016 struct dev_mapping_table *mt_entry;
1017 u16 slots = et_entry->num_slots, map_idx;
1018 u32 start_idx = et_entry->start_index;
1019 if (start_idx != MPS_MAPTABLE_BAD_IDX) {
1020 mt_entry = &sc->mapping_table[start_idx];
1021 for (map_idx = 0; map_idx < slots; map_idx++, mt_entry++)
1022 mt_entry->physical_id = et_entry->enclosure_id;
1023 }
1024 }
1025
1026 /**
1027 * _mapping_clear_removed_entries - mark the entries to be cleared
1028 * @sc: per adapter object
1029 *
1030 * Search through the removal table and mark the entries which needs to be
1031 * flushed to DPM and also updates the map table and enclosure table by
1032 * clearing the corresponding entries.
1033 *
1034 * Returns nothing
1035 */
1036 static void
1037 _mapping_clear_removed_entries(struct mps_softc *sc)
1038 {
1039 u32 remove_idx;
1040 struct map_removal_table *remove_entry;
1041 Mpi2DriverMap0Entry_t *dpm_entry;
1042 u8 done_flag = 0, num_entries, m, i;
1043 struct enc_mapping_table *et_entry, *from, *to;
1044 u16 ioc_pg8_flags = le16toh(sc->ioc_pg8.Flags);
1045
1046 if (sc->is_dpm_enable) {
1047 remove_entry = sc->removal_table;
1048 for (remove_idx = 0; remove_idx < sc->max_devices;
1049 remove_idx++, remove_entry++) {
1050 if (remove_entry->dpm_entry_num != MPS_DPM_BAD_IDX) {
1051 dpm_entry = (Mpi2DriverMap0Entry_t *)
1052 ((u8 *) sc->dpm_pg0 +
1053 sizeof(MPI2_CONFIG_EXTENDED_PAGE_HEADER));
1054 dpm_entry += remove_entry->dpm_entry_num;
1055 dpm_entry->PhysicalIdentifier.Low = 0;
1056 dpm_entry->PhysicalIdentifier.High = 0;
1057 dpm_entry->DeviceIndex = 0;
1058 dpm_entry->MappingInformation = 0;
1059 dpm_entry->PhysicalBitsMapping = 0;
1060 sc->dpm_flush_entry[remove_entry->
1061 dpm_entry_num] = 1;
1062 sc->dpm_entry_used[remove_entry->dpm_entry_num]
1063 = 0;
1064 remove_entry->dpm_entry_num = MPS_DPM_BAD_IDX;
1065 }
1066 }
1067 }
1068 if ((ioc_pg8_flags & MPI2_IOCPAGE8_FLAGS_MASK_MAPPING_MODE) ==
1069 MPI2_IOCPAGE8_FLAGS_ENCLOSURE_SLOT_MAPPING) {
1070 num_entries = sc->num_enc_table_entries;
1071 while (!done_flag) {
1072 done_flag = 1;
1073 et_entry = sc->enclosure_table;
1074 for (i = 0; i < num_entries; i++, et_entry++) {
1075 if (!et_entry->enc_handle && et_entry->
1076 init_complete) {
1077 done_flag = 0;
1078 if (i != (num_entries - 1)) {
1079 from = &sc->enclosure_table
1080 [i+1];
1081 to = &sc->enclosure_table[i];
1082 for (m = i; m < (num_entries -
1083 1); m++, from++, to++) {
1084 _mapping_set_mid_to_eid
1085 (sc, to);
1086 *to = *from;
1087 }
1088 _mapping_clear_enc_entry(to);
1089 sc->num_enc_table_entries--;
1090 num_entries =
1091 sc->num_enc_table_entries;
1092 } else {
1093 _mapping_clear_enc_entry
1094 (et_entry);
1095 sc->num_enc_table_entries--;
1096 num_entries =
1097 sc->num_enc_table_entries;
1098 }
1099 }
1100 }
1101 }
1102 }
1103 }
1104
1105 /**
1106 * _mapping_add_new_device -Add the new device into mapping table
1107 * @sc: per adapter object
1108 * @topo_change: Topology change event entry
1109 *
1110 * Search through the topology change event list and updates map table,
1111 * enclosure table and DPM pages for for the newly added devices.
1112 *
1113 * Returns nothing
1114 */
1115 static void
1116 _mapping_add_new_device(struct mps_softc *sc,
1117 struct _map_topology_change *topo_change)
1118 {
1119 u8 enc_idx, missing_cnt, is_removed = 0;
1120 u16 dpm_idx;
1121 u32 search_idx, map_idx;
1122 u32 entry;
1123 struct dev_mapping_table *mt_entry;
1124 struct enc_mapping_table *et_entry;
1125 struct _map_phy_change *phy_change;
1126 u16 ioc_pg8_flags = le16toh(sc->ioc_pg8.Flags);
1127 Mpi2DriverMap0Entry_t *dpm_entry;
1128 uint64_t temp64_var;
1129 u8 map_shift = MPI2_DRVMAP0_MAPINFO_SLOT_SHIFT;
1130 u8 hdr_sz = sizeof(MPI2_CONFIG_EXTENDED_PAGE_HEADER);
1131 u16 max_num_phy_ids = le16toh(sc->ioc_pg8.MaxNumPhysicalMappedIDs);
1132
1133 for (entry = 0; entry < topo_change->num_entries; entry++) {
1134 phy_change = &topo_change->phy_details[entry];
1135 if (phy_change->is_processed)
1136 continue;
1137 if (phy_change->reason != MPI2_EVENT_SAS_TOPO_RC_TARG_ADDED ||
1138 !phy_change->dev_handle) {
1139 phy_change->is_processed = 1;
1140 continue;
1141 }
1142 if ((ioc_pg8_flags & MPI2_IOCPAGE8_FLAGS_MASK_MAPPING_MODE) ==
1143 MPI2_IOCPAGE8_FLAGS_ENCLOSURE_SLOT_MAPPING) {
1144 enc_idx = _mapping_get_enc_idx_from_handle
1145 (sc, topo_change->enc_handle);
1146 if (enc_idx == MPS_ENCTABLE_BAD_IDX) {
1147 phy_change->is_processed = 1;
1148 printf("%s: failed to add the device with "
1149 "handle 0x%04x because the enclosure is "
1150 "not in the mapping table\n", __func__,
1151 phy_change->dev_handle);
1152 continue;
1153 }
1154 et_entry = &sc->enclosure_table[enc_idx];
1155 if (et_entry->start_index == MPS_MAPTABLE_BAD_IDX) {
1156 phy_change->is_processed = 1;
1157 if (!sc->mt_full_retry) {
1158 sc->mt_add_device_failed = 1;
1159 continue;
1160 }
1161 printf("%s: failed to add the device with "
1162 "handle 0x%04x because there is no free "
1163 "space available in the mapping table\n",
1164 __func__, phy_change->dev_handle);
1165 continue;
1166 }
1167 map_idx = et_entry->start_index + phy_change->slot -
1168 et_entry->start_slot;
1169 mt_entry = &sc->mapping_table[map_idx];
1170 mt_entry->physical_id = phy_change->physical_id;
1171 mt_entry->channel = 0;
1172 mt_entry->id = map_idx;
1173 mt_entry->dev_handle = phy_change->dev_handle;
1174 mt_entry->missing_count = 0;
1175 mt_entry->dpm_entry_num = et_entry->dpm_entry_num;
1176 mt_entry->device_info = phy_change->device_info |
1177 (MPS_DEV_RESERVED | MPS_MAP_IN_USE);
1178 if (sc->is_dpm_enable) {
1179 dpm_idx = et_entry->dpm_entry_num;
1180 if (dpm_idx == MPS_DPM_BAD_IDX)
1181 dpm_idx = _mapping_get_dpm_idx_from_id
1182 (sc, et_entry->enclosure_id,
1183 et_entry->phy_bits);
1184 if (dpm_idx == MPS_DPM_BAD_IDX) {
1185 dpm_idx = _mapping_get_free_dpm_idx(sc);
1186 if (dpm_idx != MPS_DPM_BAD_IDX) {
1187 dpm_entry =
1188 (Mpi2DriverMap0Entry_t *)
1189 ((u8 *) sc->dpm_pg0 +
1190 hdr_sz);
1191 dpm_entry += dpm_idx;
1192 dpm_entry->
1193 PhysicalIdentifier.Low =
1194 (0xFFFFFFFF &
1195 et_entry->enclosure_id);
1196 dpm_entry->
1197 PhysicalIdentifier.High =
1198 ( et_entry->enclosure_id
1199 >> 32);
1200 dpm_entry->DeviceIndex =
1201 (U16)et_entry->start_index;
1202 dpm_entry->MappingInformation =
1203 et_entry->num_slots;
1204 dpm_entry->MappingInformation
1205 <<= map_shift;
1206 dpm_entry->PhysicalBitsMapping
1207 = et_entry->phy_bits;
1208 et_entry->dpm_entry_num =
1209 dpm_idx;
1210 /* FIXME Do I need to set the dpm_idxin mt_entry too */
1211 sc->dpm_entry_used[dpm_idx] = 1;
1212 sc->dpm_flush_entry[dpm_idx] =
1213 1;
1214 phy_change->is_processed = 1;
1215 } else {
1216 phy_change->is_processed = 1;
1217 printf("%s: failed to add the "
1218 "device with handle 0x%04x "
1219 "to persistent table "
1220 "because there is no free "
1221 "space available\n",
1222 __func__,
1223 phy_change->dev_handle);
1224 }
1225 } else {
1226 et_entry->dpm_entry_num = dpm_idx;
1227 mt_entry->dpm_entry_num = dpm_idx;
1228 }
1229 }
1230 /* FIXME Why not mt_entry too? */
1231 et_entry->init_complete = 1;
1232 } else if ((ioc_pg8_flags &
1233 MPI2_IOCPAGE8_FLAGS_MASK_MAPPING_MODE) ==
1234 MPI2_IOCPAGE8_FLAGS_DEVICE_PERSISTENCE_MAPPING) {
1235 map_idx = _mapping_get_mt_idx_from_id
1236 (sc, phy_change->physical_id);
1237 if (map_idx == MPS_MAPTABLE_BAD_IDX) {
1238 search_idx = sc->num_rsvd_entries;
1239 if (topo_change->exp_handle)
1240 search_idx += max_num_phy_ids;
1241 map_idx = _mapping_get_free_mt_idx(sc,
1242 search_idx);
1243 }
1244 if (map_idx == MPS_MAPTABLE_BAD_IDX) {
1245 map_idx = _mapping_get_high_missing_mt_idx(sc);
1246 if (map_idx != MPS_MAPTABLE_BAD_IDX) {
1247 mt_entry = &sc->mapping_table[map_idx];
1248 if (mt_entry->dev_handle) {
1249 _mapping_add_to_removal_table
1250 (sc, mt_entry->dev_handle,
1251 0);
1252 is_removed = 1;
1253 }
1254 mt_entry->init_complete = 0;
1255 }
1256 }
1257 if (map_idx != MPS_MAPTABLE_BAD_IDX) {
1258 mt_entry = &sc->mapping_table[map_idx];
1259 mt_entry->physical_id = phy_change->physical_id;
1260 mt_entry->channel = 0;
1261 mt_entry->id = map_idx;
1262 mt_entry->dev_handle = phy_change->dev_handle;
1263 mt_entry->missing_count = 0;
1264 mt_entry->device_info = phy_change->device_info
1265 | (MPS_DEV_RESERVED | MPS_MAP_IN_USE);
1266 } else {
1267 phy_change->is_processed = 1;
1268 if (!sc->mt_full_retry) {
1269 sc->mt_add_device_failed = 1;
1270 continue;
1271 }
1272 printf("%s: failed to add the device with "
1273 "handle 0x%04x because there is no free "
1274 "space available in the mapping table\n",
1275 __func__, phy_change->dev_handle);
1276 continue;
1277 }
1278 if (sc->is_dpm_enable) {
1279 if (mt_entry->dpm_entry_num !=
1280 MPS_DPM_BAD_IDX) {
1281 dpm_idx = mt_entry->dpm_entry_num;
1282 dpm_entry = (Mpi2DriverMap0Entry_t *)
1283 ((u8 *)sc->dpm_pg0 + hdr_sz);
1284 dpm_entry += dpm_idx;
1285 missing_cnt = dpm_entry->
1286 MappingInformation &
1287 MPI2_DRVMAP0_MAPINFO_MISSING_MASK;
1288 temp64_var = dpm_entry->
1289 PhysicalIdentifier.High;
1290 temp64_var = (temp64_var << 32) |
1291 dpm_entry->PhysicalIdentifier.Low;
1292 if ((mt_entry->physical_id ==
1293 temp64_var) && !missing_cnt)
1294 mt_entry->init_complete = 1;
1295 } else {
1296 dpm_idx = _mapping_get_free_dpm_idx(sc);
1297 mt_entry->init_complete = 0;
1298 }
1299 if (dpm_idx != MPS_DPM_BAD_IDX &&
1300 !mt_entry->init_complete) {
1301 mt_entry->init_complete = 1;
1302 mt_entry->dpm_entry_num = dpm_idx;
1303 dpm_entry = (Mpi2DriverMap0Entry_t *)
1304 ((u8 *)sc->dpm_pg0 + hdr_sz);
1305 dpm_entry += dpm_idx;
1306 dpm_entry->PhysicalIdentifier.Low =
1307 (0xFFFFFFFF &
1308 mt_entry->physical_id);
1309 dpm_entry->PhysicalIdentifier.High =
1310 (mt_entry->physical_id >> 32);
1311 dpm_entry->DeviceIndex = (U16) map_idx;
1312 dpm_entry->MappingInformation = 0;
1313 dpm_entry->PhysicalBitsMapping = 0;
1314 sc->dpm_entry_used[dpm_idx] = 1;
1315 sc->dpm_flush_entry[dpm_idx] = 1;
1316 phy_change->is_processed = 1;
1317 } else if (dpm_idx == MPS_DPM_BAD_IDX) {
1318 phy_change->is_processed = 1;
1319 printf("%s: failed to add the "
1320 "device with handle 0x%04x "
1321 "to persistent table "
1322 "because there is no free "
1323 "space available\n",
1324 __func__,
1325 phy_change->dev_handle);
1326 }
1327 }
1328 mt_entry->init_complete = 1;
1329 }
1330
1331 phy_change->is_processed = 1;
1332 }
1333 if (is_removed)
1334 _mapping_clear_removed_entries(sc);
1335 }
1336
1337 /**
1338 * _mapping_flush_dpm_pages -Flush the DPM pages to NVRAM
1339 * @sc: per adapter object
1340 *
1341 * Returns nothing
1342 */
1343 static void
1344 _mapping_flush_dpm_pages(struct mps_softc *sc)
1345 {
1346 Mpi2DriverMap0Entry_t *dpm_entry;
1347 Mpi2ConfigReply_t mpi_reply;
1348 Mpi2DriverMappingPage0_t config_page;
1349 u16 entry_num;
1350
1351 for (entry_num = 0; entry_num < sc->max_dpm_entries; entry_num++) {
1352 if (!sc->dpm_flush_entry[entry_num])
1353 continue;
1354 memset(&config_page, 0, sizeof(Mpi2DriverMappingPage0_t));
1355 memcpy(&config_page.Header, (u8 *)sc->dpm_pg0,
1356 sizeof(MPI2_CONFIG_EXTENDED_PAGE_HEADER));
1357 dpm_entry = (Mpi2DriverMap0Entry_t *) ((u8 *)sc->dpm_pg0 +
1358 sizeof(MPI2_CONFIG_EXTENDED_PAGE_HEADER));
1359 dpm_entry += entry_num;
1360 dpm_entry->MappingInformation = htole16(dpm_entry->
1361 MappingInformation);
1362 dpm_entry->DeviceIndex = htole16(dpm_entry->DeviceIndex);
1363 dpm_entry->PhysicalBitsMapping = htole32(dpm_entry->
1364 PhysicalBitsMapping);
1365 memcpy(&config_page.Entry, (u8 *)dpm_entry,
1366 sizeof(Mpi2DriverMap0Entry_t));
1367 /* TODO-How to handle failed writes? */
1368 if (mps_config_set_dpm_pg0(sc, &mpi_reply, &config_page,
1369 entry_num)) {
1370 printf("%s: write of dpm entry %d for device failed\n",
1371 __func__, entry_num);
1372 } else
1373 sc->dpm_flush_entry[entry_num] = 0;
1374 dpm_entry->MappingInformation = le16toh(dpm_entry->
1375 MappingInformation);
1376 dpm_entry->DeviceIndex = le16toh(dpm_entry->DeviceIndex);
1377 dpm_entry->PhysicalBitsMapping = le32toh(dpm_entry->
1378 PhysicalBitsMapping);
1379 }
1380 }
1381
1382 /**
1383 * _mapping_allocate_memory- allocates the memory required for mapping tables
1384 * @sc: per adapter object
1385 *
1386 * Allocates the memory for all the tables required for host mapping
1387 *
1388 * Return 0 on success or non-zero on failure.
1389 */
1390 int
1391 mps_mapping_allocate_memory(struct mps_softc *sc)
1392 {
1393 uint32_t dpm_pg0_sz;
1394
1395 sc->mapping_table = malloc((sizeof(struct dev_mapping_table) *
1396 sc->max_devices), M_MPT2, M_ZERO|M_NOWAIT);
1397 if (!sc->mapping_table)
1398 goto free_resources;
1399
1400 sc->removal_table = malloc((sizeof(struct map_removal_table) *
1401 sc->max_devices), M_MPT2, M_ZERO|M_NOWAIT);
1402 if (!sc->removal_table)
1403 goto free_resources;
1404
1405 sc->enclosure_table = malloc((sizeof(struct enc_mapping_table) *
1406 sc->max_enclosures), M_MPT2, M_ZERO|M_NOWAIT);
1407 if (!sc->enclosure_table)
1408 goto free_resources;
1409
1410 sc->dpm_entry_used = malloc((sizeof(u8) * sc->max_dpm_entries),
1411 M_MPT2, M_ZERO|M_NOWAIT);
1412 if (!sc->dpm_entry_used)
1413 goto free_resources;
1414
1415 sc->dpm_flush_entry = malloc((sizeof(u8) * sc->max_dpm_entries),
1416 M_MPT2, M_ZERO|M_NOWAIT);
1417 if (!sc->dpm_flush_entry)
1418 goto free_resources;
1419
1420 dpm_pg0_sz = sizeof(MPI2_CONFIG_EXTENDED_PAGE_HEADER) +
1421 (sc->max_dpm_entries * sizeof(MPI2_CONFIG_PAGE_DRIVER_MAP0_ENTRY));
1422
1423 sc->dpm_pg0 = malloc(dpm_pg0_sz, M_MPT2, M_ZERO|M_NOWAIT);
1424 if (!sc->dpm_pg0) {
1425 printf("%s: memory alloc failed for dpm page; disabling dpm\n",
1426 __func__);
1427 sc->is_dpm_enable = 0;
1428 }
1429
1430 return 0;
1431
1432 free_resources:
1433 free(sc->mapping_table, M_MPT2);
1434 free(sc->removal_table, M_MPT2);
1435 free(sc->enclosure_table, M_MPT2);
1436 free(sc->dpm_entry_used, M_MPT2);
1437 free(sc->dpm_flush_entry, M_MPT2);
1438 free(sc->dpm_pg0, M_MPT2);
1439 printf("%s: device initialization failed due to failure in mapping "
1440 "table memory allocation\n", __func__);
1441 return -1;
1442 }
1443
1444 /**
1445 * mps_mapping_free_memory- frees the memory allocated for mapping tables
1446 * @sc: per adapter object
1447 *
1448 * Returns nothing.
1449 */
1450 void
1451 mps_mapping_free_memory(struct mps_softc *sc)
1452 {
1453 free(sc->mapping_table, M_MPT2);
1454 free(sc->removal_table, M_MPT2);
1455 free(sc->enclosure_table, M_MPT2);
1456 free(sc->dpm_entry_used, M_MPT2);
1457 free(sc->dpm_flush_entry, M_MPT2);
1458 free(sc->dpm_pg0, M_MPT2);
1459 }
1460
1461
1462 static void
1463 _mapping_process_dpm_pg0(struct mps_softc *sc)
1464 {
1465 u8 missing_cnt, enc_idx;
1466 u16 slot_id, entry_num, num_slots;
1467 u32 map_idx, dev_idx, start_idx, end_idx;
1468 struct dev_mapping_table *mt_entry;
1469 Mpi2DriverMap0Entry_t *dpm_entry;
1470 u16 ioc_pg8_flags = le16toh(sc->ioc_pg8.Flags);
1471 u16 max_num_phy_ids = le16toh(sc->ioc_pg8.MaxNumPhysicalMappedIDs);
1472 struct enc_mapping_table *et_entry;
1473 u64 physical_id;
1474 u32 phy_bits = 0;
1475
1476 if (sc->ir_firmware)
1477 _mapping_get_ir_maprange(sc, &start_idx, &end_idx);
1478
1479 dpm_entry = (Mpi2DriverMap0Entry_t *) ((uint8_t *) sc->dpm_pg0 +
1480 sizeof(MPI2_CONFIG_EXTENDED_PAGE_HEADER));
1481 for (entry_num = 0; entry_num < sc->max_dpm_entries; entry_num++,
1482 dpm_entry++) {
1483 physical_id = dpm_entry->PhysicalIdentifier.High;
1484 physical_id = (physical_id << 32) |
1485 dpm_entry->PhysicalIdentifier.Low;
1486 if (!physical_id) {
1487 sc->dpm_entry_used[entry_num] = 0;
1488 continue;
1489 }
1490 sc->dpm_entry_used[entry_num] = 1;
1491 dpm_entry->MappingInformation = le16toh(dpm_entry->
1492 MappingInformation);
1493 missing_cnt = dpm_entry->MappingInformation &
1494 MPI2_DRVMAP0_MAPINFO_MISSING_MASK;
1495 dev_idx = le16toh(dpm_entry->DeviceIndex);
1496 phy_bits = le32toh(dpm_entry->PhysicalBitsMapping);
1497 if (sc->ir_firmware && (dev_idx >= start_idx) &&
1498 (dev_idx <= end_idx)) {
1499 mt_entry = &sc->mapping_table[dev_idx];
1500 mt_entry->physical_id = dpm_entry->PhysicalIdentifier.High;
1501 mt_entry->physical_id = (mt_entry->physical_id << 32) |
1502 dpm_entry->PhysicalIdentifier.Low;
1503 mt_entry->channel = MPS_RAID_CHANNEL;
1504 mt_entry->id = dev_idx;
1505 mt_entry->missing_count = missing_cnt;
1506 mt_entry->dpm_entry_num = entry_num;
1507 mt_entry->device_info = MPS_DEV_RESERVED;
1508 continue;
1509 }
1510 if ((ioc_pg8_flags & MPI2_IOCPAGE8_FLAGS_MASK_MAPPING_MODE) ==
1511 MPI2_IOCPAGE8_FLAGS_ENCLOSURE_SLOT_MAPPING) {
1512 if (dev_idx < (sc->num_rsvd_entries +
1513 max_num_phy_ids)) {
1514 slot_id = 0;
1515 if (ioc_pg8_flags &
1516 MPI2_IOCPAGE8_FLAGS_DA_START_SLOT_1)
1517 slot_id = 1;
1518 num_slots = max_num_phy_ids;
1519 } else {
1520 slot_id = 0;
1521 num_slots = dpm_entry->MappingInformation &
1522 MPI2_DRVMAP0_MAPINFO_SLOT_MASK;
1523 num_slots >>= MPI2_DRVMAP0_MAPINFO_SLOT_SHIFT;
1524 }
1525 enc_idx = sc->num_enc_table_entries;
1526 if (enc_idx >= sc->max_enclosures) {
1527 printf("%s: enclosure entries exceed max "
1528 "enclosures of %d\n", __func__,
1529 sc->max_enclosures);
1530 break;
1531 }
1532 sc->num_enc_table_entries++;
1533 et_entry = &sc->enclosure_table[enc_idx];
1534 physical_id = dpm_entry->PhysicalIdentifier.High;
1535 et_entry->enclosure_id = (physical_id << 32) |
1536 dpm_entry->PhysicalIdentifier.Low;
1537 et_entry->start_index = dev_idx;
1538 et_entry->dpm_entry_num = entry_num;
1539 et_entry->num_slots = num_slots;
1540 et_entry->start_slot = slot_id;
1541 et_entry->missing_count = missing_cnt;
1542 et_entry->phy_bits = phy_bits;
1543
1544 mt_entry = &sc->mapping_table[dev_idx];
1545 for (map_idx = dev_idx; map_idx < (dev_idx + num_slots);
1546 map_idx++, mt_entry++) {
1547 if (mt_entry->dpm_entry_num !=
1548 MPS_DPM_BAD_IDX) {
1549 printf("%s: conflict in mapping table "
1550 "for enclosure %d\n", __func__,
1551 enc_idx);
1552 break;
1553 }
1554 physical_id = dpm_entry->PhysicalIdentifier.High;
1555 mt_entry->physical_id = (physical_id << 32) |
1556 dpm_entry->PhysicalIdentifier.Low;
1557 mt_entry->phy_bits = phy_bits;
1558 mt_entry->channel = 0;
1559 mt_entry->id = dev_idx;
1560 mt_entry->dpm_entry_num = entry_num;
1561 mt_entry->missing_count = missing_cnt;
1562 mt_entry->device_info = MPS_DEV_RESERVED;
1563 }
1564 } else if ((ioc_pg8_flags &
1565 MPI2_IOCPAGE8_FLAGS_MASK_MAPPING_MODE) ==
1566 MPI2_IOCPAGE8_FLAGS_DEVICE_PERSISTENCE_MAPPING) {
1567 map_idx = dev_idx;
1568 mt_entry = &sc->mapping_table[map_idx];
1569 if (mt_entry->dpm_entry_num != MPS_DPM_BAD_IDX) {
1570 printf("%s: conflict in mapping table for "
1571 "device %d\n", __func__, map_idx);
1572 break;
1573 }
1574 physical_id = dpm_entry->PhysicalIdentifier.High;
1575 mt_entry->physical_id = (physical_id << 32) |
1576 dpm_entry->PhysicalIdentifier.Low;
1577 mt_entry->phy_bits = phy_bits;
1578 mt_entry->channel = 0;
1579 mt_entry->id = dev_idx;
1580 mt_entry->missing_count = missing_cnt;
1581 mt_entry->dpm_entry_num = entry_num;
1582 mt_entry->device_info = MPS_DEV_RESERVED;
1583 }
1584 } /*close the loop for DPM table */
1585 }
1586
1587 /*
1588 * mps_mapping_check_devices - start of the day check for device availabilty
1589 * @sc: per adapter object
1590 * @sleep_flag: Flag indicating whether this function can sleep or not
1591 *
1592 * Returns nothing.
1593 */
1594 void
1595 mps_mapping_check_devices(struct mps_softc *sc, int sleep_flag)
1596 {
1597 u32 i;
1598 /* u32 cntdn, i;
1599 u32 timeout = 60;*/
1600 struct dev_mapping_table *mt_entry;
1601 u16 ioc_pg8_flags = le16toh(sc->ioc_pg8.Flags);
1602 struct enc_mapping_table *et_entry;
1603 u32 start_idx, end_idx;
1604
1605 /* We need to ucomment this when this function is called
1606 * from the port enable complete */
1607 #if 0
1608 sc->track_mapping_events = 0;
1609 cntdn = (sleep_flag == CAN_SLEEP) ? 1000*timeout : 2000*timeout;
1610 do {
1611 if (!sc->pending_map_events)
1612 break;
1613 if (sleep_flag == CAN_SLEEP)
1614 pause("mps_pause", (hz/1000));/* 1msec sleep */
1615 else
1616 DELAY(500); /* 500 useconds delay */
1617 } while (--cntdn);
1618
1619
1620 if (!cntdn)
1621 printf("%s: there are %d"
1622 " pending events after %d seconds of delay\n",
1623 __func__, sc->pending_map_events, timeout);
1624 #endif
1625 sc->pending_map_events = 0;
1626
1627 if ((ioc_pg8_flags & MPI2_IOCPAGE8_FLAGS_MASK_MAPPING_MODE) ==
1628 MPI2_IOCPAGE8_FLAGS_ENCLOSURE_SLOT_MAPPING) {
1629 et_entry = sc->enclosure_table;
1630 for (i = 0; i < sc->num_enc_table_entries; i++, et_entry++) {
1631 if (!et_entry->init_complete) {
1632 if (et_entry->missing_count <
1633 MPS_MAX_MISSING_COUNT) {
1634 et_entry->missing_count++;
1635 if (et_entry->dpm_entry_num !=
1636 MPS_DPM_BAD_IDX)
1637 _mapping_commit_enc_entry(sc,
1638 et_entry);
1639 }
1640 et_entry->init_complete = 1;
1641 }
1642 }
1643 if (!sc->ir_firmware)
1644 return;
1645 _mapping_get_ir_maprange(sc, &start_idx, &end_idx);
1646 mt_entry = &sc->mapping_table[start_idx];
1647 for (i = start_idx; i < (end_idx + 1); i++, mt_entry++) {
1648 if (mt_entry->device_info & MPS_DEV_RESERVED
1649 && !mt_entry->physical_id)
1650 mt_entry->init_complete = 1;
1651 else if (mt_entry->device_info & MPS_DEV_RESERVED) {
1652 if (!mt_entry->init_complete) {
1653 if (mt_entry->missing_count <
1654 MPS_MAX_MISSING_COUNT) {
1655 mt_entry->missing_count++;
1656 if (mt_entry->dpm_entry_num !=
1657 MPS_DPM_BAD_IDX)
1658 _mapping_commit_map_entry(sc,
1659 mt_entry);
1660 }
1661 mt_entry->init_complete = 1;
1662 }
1663 }
1664 }
1665 } else if ((ioc_pg8_flags & MPI2_IOCPAGE8_FLAGS_MASK_MAPPING_MODE) ==
1666 MPI2_IOCPAGE8_FLAGS_DEVICE_PERSISTENCE_MAPPING) {
1667 mt_entry = sc->mapping_table;
1668 for (i = 0; i < sc->max_devices; i++, mt_entry++) {
1669 if (mt_entry->device_info & MPS_DEV_RESERVED
1670 && !mt_entry->physical_id)
1671 mt_entry->init_complete = 1;
1672 else if (mt_entry->device_info & MPS_DEV_RESERVED) {
1673 if (!mt_entry->init_complete) {
1674 if (mt_entry->missing_count <
1675 MPS_MAX_MISSING_COUNT) {
1676 mt_entry->missing_count++;
1677 if (mt_entry->dpm_entry_num !=
1678 MPS_DPM_BAD_IDX)
1679 _mapping_commit_map_entry(sc,
1680 mt_entry);
1681 }
1682 mt_entry->init_complete = 1;
1683 }
1684 }
1685 }
1686 }
1687 }
1688
1689
1690 /**
1691 * mps_mapping_is_reinit_required - check whether event replay required
1692 * @sc: per adapter object
1693 *
1694 * Checks the per ioc flags and decide whether reinit of events required
1695 *
1696 * Returns 1 for reinit of ioc 0 for not.
1697 */
1698 int mps_mapping_is_reinit_required(struct mps_softc *sc)
1699 {
1700 if (!sc->mt_full_retry && sc->mt_add_device_failed) {
1701 sc->mt_full_retry = 1;
1702 sc->mt_add_device_failed = 0;
1703 _mapping_flush_dpm_pages(sc);
1704 return 1;
1705 }
1706 sc->mt_full_retry = 1;
1707 return 0;
1708 }
1709
1710 /**
1711 * mps_mapping_initialize - initialize mapping tables
1712 * @sc: per adapter object
1713 *
1714 * Read controller persitant mapping tables into internal data area.
1715 *
1716 * Return 0 for success or non-zero for failure.
1717 */
1718 int
1719 mps_mapping_initialize(struct mps_softc *sc)
1720 {
1721 uint16_t volume_mapping_flags, dpm_pg0_sz;
1722 uint32_t i;
1723 Mpi2ConfigReply_t mpi_reply;
1724 int error;
1725 uint8_t retry_count;
1726 uint16_t ioc_pg8_flags = le16toh(sc->ioc_pg8.Flags);
1727
1728 /* The additional 1 accounts for the virtual enclosure
1729 * created for the controller
1730 */
1731 sc->max_enclosures = sc->facts->MaxEnclosures + 1;
1732 sc->max_expanders = sc->facts->MaxSasExpanders;
1733 sc->max_volumes = sc->facts->MaxVolumes;
1734 sc->max_devices = sc->facts->MaxTargets + sc->max_volumes;
1735 sc->pending_map_events = 0;
1736 sc->num_enc_table_entries = 0;
1737 sc->num_rsvd_entries = 0;
1738 sc->num_channels = 1;
1739 sc->max_dpm_entries = sc->ioc_pg8.MaxPersistentEntries;
1740 sc->is_dpm_enable = (sc->max_dpm_entries) ? 1 : 0;
1741 sc->track_mapping_events = 0;
1742
1743 if (ioc_pg8_flags & MPI2_IOCPAGE8_FLAGS_DISABLE_PERSISTENT_MAPPING)
1744 sc->is_dpm_enable = 0;
1745
1746 if (ioc_pg8_flags & MPI2_IOCPAGE8_FLAGS_RESERVED_TARGETID_0)
1747 sc->num_rsvd_entries = 1;
1748
1749 volume_mapping_flags = sc->ioc_pg8.IRVolumeMappingFlags &
1750 MPI2_IOCPAGE8_IRFLAGS_MASK_VOLUME_MAPPING_MODE;
1751 if (sc->ir_firmware && (volume_mapping_flags ==
1752 MPI2_IOCPAGE8_IRFLAGS_LOW_VOLUME_MAPPING))
1753 sc->num_rsvd_entries += sc->max_volumes;
1754
1755 error = mps_mapping_allocate_memory(sc);
1756 if (error)
1757 return (error);
1758
1759 for (i = 0; i < sc->max_devices; i++)
1760 _mapping_clear_map_entry(sc->mapping_table + i);
1761
1762 for (i = 0; i < sc->max_enclosures; i++)
1763 _mapping_clear_enc_entry(sc->enclosure_table + i);
1764
1765 for (i = 0; i < sc->max_devices; i++) {
1766 sc->removal_table[i].dev_handle = 0;
1767 sc->removal_table[i].dpm_entry_num = MPS_DPM_BAD_IDX;
1768 }
1769
1770 memset(sc->dpm_entry_used, 0, sc->max_dpm_entries);
1771 memset(sc->dpm_flush_entry, 0, sc->max_dpm_entries);
1772
1773 if (sc->is_dpm_enable) {
1774 dpm_pg0_sz = sizeof(MPI2_CONFIG_EXTENDED_PAGE_HEADER) +
1775 (sc->max_dpm_entries *
1776 sizeof(MPI2_CONFIG_PAGE_DRIVER_MAP0_ENTRY));
1777 retry_count = 0;
1778
1779 retry_read_dpm:
1780 if (mps_config_get_dpm_pg0(sc, &mpi_reply, sc->dpm_pg0,
1781 dpm_pg0_sz)) {
1782 printf("%s: dpm page read failed; disabling dpm\n",
1783 __func__);
1784 if (retry_count < 3) {
1785 retry_count++;
1786 goto retry_read_dpm;
1787 }
1788 sc->is_dpm_enable = 0;
1789 }
1790 }
1791
1792 if (sc->is_dpm_enable)
1793 _mapping_process_dpm_pg0(sc);
1794
1795 sc->track_mapping_events = 1;
1796 return 0;
1797 }
1798
1799 /**
1800 * mps_mapping_exit - clear mapping table and associated memory
1801 * @sc: per adapter object
1802 *
1803 * Returns nothing.
1804 */
1805 void
1806 mps_mapping_exit(struct mps_softc *sc)
1807 {
1808 _mapping_flush_dpm_pages(sc);
1809 mps_mapping_free_memory(sc);
1810 }
1811
1812 /**
1813 * mps_mapping_get_sas_id - assign a target id for sas device
1814 * @sc: per adapter object
1815 * @sas_address: sas address of the device
1816 * @handle: device handle
1817 *
1818 * Returns valid ID on success or BAD_ID.
1819 */
1820 unsigned int
1821 mps_mapping_get_sas_id(struct mps_softc *sc, uint64_t sas_address, u16 handle)
1822 {
1823 u32 map_idx;
1824 struct dev_mapping_table *mt_entry;
1825
1826 for (map_idx = 0; map_idx < sc->max_devices; map_idx++) {
1827 mt_entry = &sc->mapping_table[map_idx];
1828 if (mt_entry->dev_handle == handle && mt_entry->physical_id ==
1829 sas_address)
1830 return mt_entry->id;
1831 }
1832
1833 return MPS_MAP_BAD_ID;
1834 }
1835
1836 /**
1837 * mps_mapping_get_sas_id_from_handle - find a target id in mapping table using
1838 * only the dev handle. This is just a wrapper function for the local function
1839 * _mapping_get_mt_idx_from_handle.
1840 * @sc: per adapter object
1841 * @handle: device handle
1842 *
1843 * Returns valid ID on success or BAD_ID.
1844 */
1845 unsigned int
1846 mps_mapping_get_sas_id_from_handle(struct mps_softc *sc, u16 handle)
1847 {
1848 return (_mapping_get_mt_idx_from_handle(sc, handle));
1849 }
1850
1851 /**
1852 * mps_mapping_get_raid_id - assign a target id for raid device
1853 * @sc: per adapter object
1854 * @wwid: world wide identifier for raid volume
1855 * @handle: device handle
1856 *
1857 * Returns valid ID on success or BAD_ID.
1858 */
1859 unsigned int
1860 mps_mapping_get_raid_id(struct mps_softc *sc, u64 wwid, u16 handle)
1861 {
1862 u32 map_idx;
1863 struct dev_mapping_table *mt_entry;
1864
1865 for (map_idx = 0; map_idx < sc->max_devices; map_idx++) {
1866 mt_entry = &sc->mapping_table[map_idx];
1867 if (mt_entry->dev_handle == handle && mt_entry->physical_id ==
1868 wwid)
1869 return mt_entry->id;
1870 }
1871
1872 return MPS_MAP_BAD_ID;
1873 }
1874
1875 /**
1876 * mps_mapping_get_raid_id_from_handle - find raid device in mapping table
1877 * using only the volume dev handle. This is just a wrapper function for the
1878 * local function _mapping_get_ir_mt_idx_from_handle.
1879 * @sc: per adapter object
1880 * @volHandle: volume device handle
1881 *
1882 * Returns valid ID on success or BAD_ID.
1883 */
1884 unsigned int
1885 mps_mapping_get_raid_id_from_handle(struct mps_softc *sc, u16 volHandle)
1886 {
1887 return (_mapping_get_ir_mt_idx_from_handle(sc, volHandle));
1888 }
1889
1890 /**
1891 * mps_mapping_enclosure_dev_status_change_event - handle enclosure events
1892 * @sc: per adapter object
1893 * @event_data: event data payload
1894 *
1895 * Return nothing.
1896 */
1897 void
1898 mps_mapping_enclosure_dev_status_change_event(struct mps_softc *sc,
1899 Mpi2EventDataSasEnclDevStatusChange_t *event_data)
1900 {
1901 u8 enc_idx, missing_count;
1902 struct enc_mapping_table *et_entry;
1903 Mpi2DriverMap0Entry_t *dpm_entry;
1904 u16 ioc_pg8_flags = le16toh(sc->ioc_pg8.Flags);
1905 u8 map_shift = MPI2_DRVMAP0_MAPINFO_SLOT_SHIFT;
1906 u8 update_phy_bits = 0;
1907 u32 saved_phy_bits;
1908 uint64_t temp64_var;
1909
1910 if ((ioc_pg8_flags & MPI2_IOCPAGE8_FLAGS_MASK_MAPPING_MODE) !=
1911 MPI2_IOCPAGE8_FLAGS_ENCLOSURE_SLOT_MAPPING)
1912 goto out;
1913
1914 dpm_entry = (Mpi2DriverMap0Entry_t *)((u8 *)sc->dpm_pg0 +
1915 sizeof(MPI2_CONFIG_EXTENDED_PAGE_HEADER));
1916
1917 if (event_data->ReasonCode == MPI2_EVENT_SAS_ENCL_RC_ADDED) {
1918 if (!event_data->NumSlots) {
1919 printf("%s: enclosure with handle = 0x%x reported 0 "
1920 "slots\n", __func__,
1921 le16toh(event_data->EnclosureHandle));
1922 goto out;
1923 }
1924 temp64_var = event_data->EnclosureLogicalID.High;
1925 temp64_var = (temp64_var << 32) |
1926 event_data->EnclosureLogicalID.Low;
1927 enc_idx = _mapping_get_enc_idx_from_id(sc, temp64_var,
1928 event_data->PhyBits);
1929 if (enc_idx != MPS_ENCTABLE_BAD_IDX) {
1930 et_entry = &sc->enclosure_table[enc_idx];
1931 if (et_entry->init_complete &&
1932 !et_entry->missing_count) {
1933 printf("%s: enclosure %d is already present "
1934 "with handle = 0x%x\n",__func__, enc_idx,
1935 et_entry->enc_handle);
1936 goto out;
1937 }
1938 et_entry->enc_handle = le16toh(event_data->
1939 EnclosureHandle);
1940 et_entry->start_slot = le16toh(event_data->StartSlot);
1941 saved_phy_bits = et_entry->phy_bits;
1942 et_entry->phy_bits |= le32toh(event_data->PhyBits);
1943 if (saved_phy_bits != et_entry->phy_bits)
1944 update_phy_bits = 1;
1945 if (et_entry->missing_count || update_phy_bits) {
1946 et_entry->missing_count = 0;
1947 if (sc->is_dpm_enable &&
1948 et_entry->dpm_entry_num !=
1949 MPS_DPM_BAD_IDX) {
1950 dpm_entry += et_entry->dpm_entry_num;
1951 missing_count =
1952 (u8)(dpm_entry->MappingInformation &
1953 MPI2_DRVMAP0_MAPINFO_MISSING_MASK);
1954 if (!et_entry->init_complete && (
1955 missing_count || update_phy_bits)) {
1956 dpm_entry->MappingInformation
1957 = et_entry->num_slots;
1958 dpm_entry->MappingInformation
1959 <<= map_shift;
1960 dpm_entry->PhysicalBitsMapping
1961 = et_entry->phy_bits;
1962 sc->dpm_flush_entry[et_entry->
1963 dpm_entry_num] = 1;
1964 }
1965 }
1966 }
1967 } else {
1968 enc_idx = sc->num_enc_table_entries;
1969 if (enc_idx >= sc->max_enclosures) {
1970 printf("%s: enclosure can not be added; "
1971 "mapping table is full\n", __func__);
1972 goto out;
1973 }
1974 sc->num_enc_table_entries++;
1975 et_entry = &sc->enclosure_table[enc_idx];
1976 et_entry->enc_handle = le16toh(event_data->
1977 EnclosureHandle);
1978 et_entry->enclosure_id = event_data->
1979 EnclosureLogicalID.High;
1980 et_entry->enclosure_id = ( et_entry->enclosure_id <<
1981 32) | event_data->EnclosureLogicalID.Low;
1982 et_entry->start_index = MPS_MAPTABLE_BAD_IDX;
1983 et_entry->dpm_entry_num = MPS_DPM_BAD_IDX;
1984 et_entry->num_slots = le16toh(event_data->NumSlots);
1985 et_entry->start_slot = le16toh(event_data->StartSlot);
1986 et_entry->phy_bits = le32toh(event_data->PhyBits);
1987 }
1988 et_entry->init_complete = 1;
1989 } else if (event_data->ReasonCode ==
1990 MPI2_EVENT_SAS_ENCL_RC_NOT_RESPONDING) {
1991 enc_idx = _mapping_get_enc_idx_from_handle(sc,
1992 le16toh(event_data->EnclosureHandle));
1993 if (enc_idx == MPS_ENCTABLE_BAD_IDX) {
1994 printf("%s: cannot unmap enclosure %d because it has "
1995 "already been deleted", __func__, enc_idx);
1996 goto out;
1997 }
1998 et_entry = &sc->enclosure_table[enc_idx];
1999 if (!et_entry->init_complete) {
2000 if (et_entry->missing_count < MPS_MAX_MISSING_COUNT)
2001 et_entry->missing_count++;
2002 else
2003 et_entry->init_complete = 1;
2004 }
2005 if (!et_entry->missing_count)
2006 et_entry->missing_count++;
2007 if (sc->is_dpm_enable && !et_entry->init_complete &&
2008 et_entry->dpm_entry_num != MPS_DPM_BAD_IDX) {
2009 dpm_entry += et_entry->dpm_entry_num;
2010 dpm_entry->MappingInformation = et_entry->num_slots;
2011 dpm_entry->MappingInformation <<= map_shift;
2012 dpm_entry->MappingInformation |=
2013 et_entry->missing_count;
2014 sc->dpm_flush_entry[et_entry->dpm_entry_num] = 1;
2015 }
2016 et_entry->init_complete = 1;
2017 }
2018
2019 out:
2020 _mapping_flush_dpm_pages(sc);
2021 if (sc->pending_map_events)
2022 sc->pending_map_events--;
2023 }
2024
2025 /**
2026 * mps_mapping_topology_change_event - handle topology change events
2027 * @sc: per adapter object
2028 * @event_data: event data payload
2029 *
2030 * Returns nothing.
2031 */
2032 void
2033 mps_mapping_topology_change_event(struct mps_softc *sc,
2034 Mpi2EventDataSasTopologyChangeList_t *event_data)
2035 {
2036 struct _map_topology_change topo_change;
2037 struct _map_phy_change *phy_change;
2038 Mpi2EventSasTopoPhyEntry_t *event_phy_change;
2039 u8 i, num_entries;
2040
2041 topo_change.enc_handle = le16toh(event_data->EnclosureHandle);
2042 topo_change.exp_handle = le16toh(event_data->ExpanderDevHandle);
2043 num_entries = event_data->NumEntries;
2044 topo_change.num_entries = num_entries;
2045 topo_change.start_phy_num = event_data->StartPhyNum;
2046 topo_change.num_phys = event_data->NumPhys;
2047 topo_change.exp_status = event_data->ExpStatus;
2048 event_phy_change = event_data->PHY;
2049 topo_change.phy_details = NULL;
2050
2051 if (!num_entries)
2052 goto out;
2053 phy_change = malloc(sizeof(struct _map_phy_change) * num_entries,
2054 M_MPT2, M_NOWAIT|M_ZERO);
2055 topo_change.phy_details = phy_change;
2056 if (!phy_change)
2057 goto out;
2058 for (i = 0; i < num_entries; i++, event_phy_change++, phy_change++) {
2059 phy_change->dev_handle = le16toh(event_phy_change->
2060 AttachedDevHandle);
2061 phy_change->reason = event_phy_change->PhyStatus &
2062 MPI2_EVENT_SAS_TOPO_RC_MASK;
2063 }
2064 _mapping_update_missing_count(sc, &topo_change);
2065 _mapping_get_dev_info(sc, &topo_change);
2066 _mapping_clear_removed_entries(sc);
2067 _mapping_add_new_device(sc, &topo_change);
2068
2069 out:
2070 free(topo_change.phy_details, M_MPT2);
2071 _mapping_flush_dpm_pages(sc);
2072 if (sc->pending_map_events)
2073 sc->pending_map_events--;
2074 }
2075
2076 /**
2077 * _mapping_check_update_ir_mt_idx - Check and update IR map table index
2078 * @sc: per adapter object
2079 * @event_data: event data payload
2080 * @evt_idx: current event index
2081 * @map_idx: current index and the place holder for new map table index
2082 * @wwid_table: world wide name for volumes in the element table
2083 *
2084 * pass through IR events and find whether any events matches and if so
2085 * tries to find new index if not returns failure
2086 *
2087 * Returns 0 on success and 1 on failure
2088 */
2089 static int
2090 _mapping_check_update_ir_mt_idx(struct mps_softc *sc,
2091 Mpi2EventDataIrConfigChangeList_t *event_data, int evt_idx, u32 *map_idx,
2092 u64 *wwid_table)
2093 {
2094 struct dev_mapping_table *mt_entry;
2095 u32 st_idx, end_idx, mt_idx = *map_idx;
2096 u8 match = 0;
2097 Mpi2EventIrConfigElement_t *element;
2098 u16 element_flags;
2099 int i;
2100
2101 mt_entry = &sc->mapping_table[mt_idx];
2102 _mapping_get_ir_maprange(sc, &st_idx, &end_idx);
2103 search_again:
2104 match = 0;
2105 for (i = evt_idx + 1; i < event_data->NumElements; i++) {
2106 element = (Mpi2EventIrConfigElement_t *)
2107 &event_data->ConfigElement[i];
2108 element_flags = le16toh(element->ElementFlags);
2109 if ((element_flags &
2110 MPI2_EVENT_IR_CHANGE_EFLAGS_ELEMENT_TYPE_MASK) !=
2111 MPI2_EVENT_IR_CHANGE_EFLAGS_VOLUME_ELEMENT)
2112 continue;
2113 if (element->ReasonCode == MPI2_EVENT_IR_CHANGE_RC_ADDED ||
2114 element->ReasonCode ==
2115 MPI2_EVENT_IR_CHANGE_RC_VOLUME_CREATED) {
2116 if (mt_entry->physical_id == wwid_table[i]) {
2117 match = 1;
2118 break;
2119 }
2120 }
2121 }
2122
2123 if (match) {
2124 do {
2125 mt_idx++;
2126 if (mt_idx > end_idx)
2127 return 1;
2128 mt_entry = &sc->mapping_table[mt_idx];
2129 } while (mt_entry->device_info & MPS_MAP_IN_USE);
2130 goto search_again;
2131 }
2132 *map_idx = mt_idx;
2133 return 0;
2134 }
2135
2136 /**
2137 * mps_mapping_ir_config_change_event - handle IR config change list events
2138 * @sc: per adapter object
2139 * @event_data: event data payload
2140 *
2141 * Returns nothing.
2142 */
2143 void
2144 mps_mapping_ir_config_change_event(struct mps_softc *sc,
2145 Mpi2EventDataIrConfigChangeList_t *event_data)
2146 {
2147 Mpi2EventIrConfigElement_t *element;
2148 int i;
2149 u64 *wwid_table;
2150 u32 map_idx, flags;
2151 struct dev_mapping_table *mt_entry;
2152 u16 element_flags;
2153 u8 log_full_error = 0;
2154
2155 wwid_table = malloc(sizeof(u64) * event_data->NumElements, M_MPT2,
2156 M_NOWAIT | M_ZERO);
2157 if (!wwid_table)
2158 goto out;
2159 element = (Mpi2EventIrConfigElement_t *)&event_data->ConfigElement[0];
2160 flags = le32toh(event_data->Flags);
2161 for (i = 0; i < event_data->NumElements; i++, element++) {
2162 element_flags = le16toh(element->ElementFlags);
2163 if ((element->ReasonCode != MPI2_EVENT_IR_CHANGE_RC_ADDED) &&
2164 (element->ReasonCode != MPI2_EVENT_IR_CHANGE_RC_REMOVED) &&
2165 (element->ReasonCode != MPI2_EVENT_IR_CHANGE_RC_NO_CHANGE)
2166 && (element->ReasonCode !=
2167 MPI2_EVENT_IR_CHANGE_RC_VOLUME_CREATED))
2168 continue;
2169 if ((element_flags &
2170 MPI2_EVENT_IR_CHANGE_EFLAGS_ELEMENT_TYPE_MASK) ==
2171 MPI2_EVENT_IR_CHANGE_EFLAGS_VOLUME_ELEMENT) {
2172 mps_config_get_volume_wwid(sc,
2173 le16toh(element->VolDevHandle), &wwid_table[i]);
2174 map_idx = _mapping_get_ir_mt_idx_from_wwid(sc,
2175 wwid_table[i]);
2176 if (map_idx != MPS_MAPTABLE_BAD_IDX) {
2177 mt_entry = &sc->mapping_table[map_idx];
2178 mt_entry->device_info |= MPS_MAP_IN_USE;
2179 }
2180 }
2181 }
2182 if (flags == MPI2_EVENT_IR_CHANGE_FLAGS_FOREIGN_CONFIG)
2183 goto out;
2184 else {
2185 element = (Mpi2EventIrConfigElement_t *)&event_data->
2186 ConfigElement[0];
2187 for (i = 0; i < event_data->NumElements; i++, element++) {
2188 if (element->ReasonCode ==
2189 MPI2_EVENT_IR_CHANGE_RC_ADDED ||
2190 element->ReasonCode ==
2191 MPI2_EVENT_IR_CHANGE_RC_VOLUME_CREATED) {
2192 map_idx = _mapping_get_ir_mt_idx_from_wwid
2193 (sc, wwid_table[i]);
2194 if (map_idx != MPS_MAPTABLE_BAD_IDX) {
2195 mt_entry = &sc->mapping_table[map_idx];
2196 mt_entry->channel = MPS_RAID_CHANNEL;
2197 mt_entry->id = map_idx;
2198 mt_entry->dev_handle = le16toh
2199 (element->VolDevHandle);
2200 mt_entry->device_info =
2201 MPS_DEV_RESERVED | MPS_MAP_IN_USE;
2202 _mapping_update_ir_missing_cnt(sc,
2203 map_idx, element, wwid_table[i]);
2204 continue;
2205 }
2206 map_idx = _mapping_get_free_ir_mt_idx(sc);
2207 if (map_idx == MPS_MAPTABLE_BAD_IDX)
2208 log_full_error = 1;
2209 else if (i < (event_data->NumElements - 1)) {
2210 log_full_error =
2211 _mapping_check_update_ir_mt_idx
2212 (sc, event_data, i, &map_idx,
2213 wwid_table);
2214 }
2215 if (log_full_error) {
2216 printf("%s: no space to add the RAID "
2217 "volume with handle 0x%04x in "
2218 "mapping table\n", __func__, le16toh
2219 (element->VolDevHandle));
2220 continue;
2221 }
2222 mt_entry = &sc->mapping_table[map_idx];
2223 mt_entry->physical_id = wwid_table[i];
2224 mt_entry->channel = MPS_RAID_CHANNEL;
2225 mt_entry->id = map_idx;
2226 mt_entry->dev_handle = le16toh(element->
2227 VolDevHandle);
2228 mt_entry->device_info = MPS_DEV_RESERVED |
2229 MPS_MAP_IN_USE;
2230 mt_entry->init_complete = 0;
2231 _mapping_update_ir_missing_cnt(sc, map_idx,
2232 element, wwid_table[i]);
2233 } else if (element->ReasonCode ==
2234 MPI2_EVENT_IR_CHANGE_RC_REMOVED) {
2235 map_idx = _mapping_get_ir_mt_idx_from_wwid(sc,
2236 wwid_table[i]);
2237 if (map_idx == MPS_MAPTABLE_BAD_IDX) {
2238 printf("%s: failed to remove a volume "
2239 "because it has already been "
2240 "removed\n", __func__);
2241 continue;
2242 }
2243 _mapping_update_ir_missing_cnt(sc, map_idx,
2244 element, wwid_table[i]);
2245 } else if (element->ReasonCode ==
2246 MPI2_EVENT_IR_CHANGE_RC_VOLUME_DELETED) {
2247 map_idx = _mapping_get_mt_idx_from_handle(sc,
2248 le16toh(element->VolDevHandle));
2249 if (map_idx == MPS_MAPTABLE_BAD_IDX) {
2250 printf("%s: failed to remove volume "
2251 "with handle 0x%04x because it has "
2252 "already been removed\n", __func__,
2253 le16toh(element->VolDevHandle));
2254 continue;
2255 }
2256 mt_entry = &sc->mapping_table[map_idx];
2257 _mapping_update_ir_missing_cnt(sc, map_idx,
2258 element, mt_entry->physical_id);
2259 }
2260 }
2261 }
2262
2263 out:
2264 _mapping_flush_dpm_pages(sc);
2265 free(wwid_table, M_MPT2);
2266 if (sc->pending_map_events)
2267 sc->pending_map_events--;
2268 }
Cache object: b88d06b4929491e58248ed8c0194174c
|