- sz = ioc->num_fw_frags * sizeof(void *);
- mem = kmalloc(sz, GFP_ATOMIC);
- if (mem == NULL)
- return NULL;
-
- memset(mem, 0, sz);
- cached_fw = (fw_image_t **)mem;
- alloc_total += sz;
-
- /* malloc fragment memory
- * fw_image_t struct and dma for fw data
- */
- bytes_left = size;
- ii = 0;
- num_frags = 0;
- bytes = bytes_left;
- while((bytes_left) && (num_frags < ioc->num_fw_frags)) {
- if (cached_fw[ii] == NULL) {
- mem = kmalloc(sizeof(fw_image_t), GFP_ATOMIC);
- if (mem == NULL)
- break;
-
- memset(mem, 0, sizeof(fw_image_t));
- cached_fw[ii] = (fw_image_t *)mem;
- alloc_total += sizeof(fw_image_t);
- }
-
- mem = pci_alloc_consistent(ioc->pcidev, bytes, &fw_dma);
- if (mem == NULL) {
- if (bytes > 0x10000)
- bytes = 0x10000;
- else if (bytes > 0x8000)
- bytes = 0x8000;
- else if (bytes > 0x4000)
- bytes = 0x4000;
- else if (bytes > 0x2000)
- bytes = 0x2000;
- else if (bytes > 0x1000)
- bytes = 0x1000;
- else
- break;
-
- continue;
- }
-
- cached_fw[ii]->fw = mem;
- cached_fw[ii]->fw_dma = fw_dma;
- cached_fw[ii]->size = bytes;
- memset(mem, 0, bytes);
- alloc_total += bytes;
-
- bytes_left -= bytes;
-
- num_frags++;
- ii++;
- }
-
- if (bytes_left ) {
- /* Major Failure.
- */
- mpt_free_fw_memory(ioc, cached_fw);
- return NULL;
- }
-
- *frags = num_frags;
- *alloc_sz = alloc_total;