Message ID | 20150416134827.30238.67380.stgit@brunhilda (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
On 04/16/2015 03:48 PM, Don Brace wrote: > From: Webb Scales <webbnh@hp.com> > > Increase the request size for ioaccel2 path. > > The error, if any, returned by hpsa_allocate_ioaccel2_sg_chain_blocks > to hpsa_alloc_ioaccel2_cmd_and_bft should be returned upstream rather > than assumed to be -ENOMEM. > > This differs slightly from hpsa_alloc_ioaccel1_cmd_and_bft, > which does not call another hpsa_allocate function and only > has -ENOMEM to return from some kmalloc calls. > > Reviewed-by: Scott Teel <scott.teel@pmcs.com> > Reviewed-by: Kevin Barnett <kevin.barnett@pmcs.com> > Signed-off-by: Robert Elliott <elliott@hp.com> > Signed-off-by: Don Brace <don.brace@pmcs.com> > --- > drivers/scsi/hpsa.c | 125 +++++++++++++++++++++++++++++++++++++++++++++++---- > drivers/scsi/hpsa.h | 1 > 2 files changed, 116 insertions(+), 10 deletions(-) > > diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c > index c9c42e9..1839761 100644 > --- a/drivers/scsi/hpsa.c > +++ b/drivers/scsi/hpsa.c > @@ -1704,6 +1704,46 @@ static void hpsa_slave_destroy(struct scsi_device *sdev) > /* nothing to do. */ > } > > +static void hpsa_free_ioaccel2_sg_chain_blocks(struct ctlr_info *h) > +{ > + int i; > + > + if (!h->ioaccel2_cmd_sg_list) > + return; > + for (i = 0; i < h->nr_cmds; i++) { > + kfree(h->ioaccel2_cmd_sg_list[i]); > + h->ioaccel2_cmd_sg_list[i] = NULL; > + } > + kfree(h->ioaccel2_cmd_sg_list); > + h->ioaccel2_cmd_sg_list = NULL; > +} > + > +static int hpsa_allocate_ioaccel2_sg_chain_blocks(struct ctlr_info *h) > +{ > + int i; > + > + if (h->chainsize <= 0) > + return 0; > + > + h->ioaccel2_cmd_sg_list = > + kzalloc(sizeof(*h->ioaccel2_cmd_sg_list) * h->nr_cmds, > + GFP_KERNEL); > + if (!h->ioaccel2_cmd_sg_list) > + return -ENOMEM; > + for (i = 0; i < h->nr_cmds; i++) { > + h->ioaccel2_cmd_sg_list[i] = > + kmalloc(sizeof(*h->ioaccel2_cmd_sg_list[i]) * > + h->maxsgentries, GFP_KERNEL); > + if (!h->ioaccel2_cmd_sg_list[i]) > + goto clean; > + } > + return 0; > + > +clean: > + hpsa_free_ioaccel2_sg_chain_blocks(h); > + return -ENOMEM; > +} > + > static void hpsa_free_sg_chain_blocks(struct ctlr_info *h) > { > int i; Any reason why you didn't use mempools here? Cheers, Hannes
VGhlIGxhc3QgSSByZWFkIGFib3V0IG1lbXBvb2xzIHdhcyBmcm9tOg0KTGludXggRGV2aWNlIERy aXZlcnMNCiBCeSBKb25hdGhhbiBDb3JiZXQsIEFsZXNzYW5kcm8gUnViaW5pLCBHcmVnIEtyb2Fo LUhhcnRtYW4NCg0KaHR0cHM6Ly9sd24ubmV0L2ltYWdlcy9wZGYvTEREMy9jaDA4LnBkZg0KDQoN CklmICB5b3UgIGFyZSAgY29uc2lkZXJpbmcgIHVzaW5nICBhICBtZW1wb29sICBpbiAgeW91ciAg ZHJpdmVyLCAgcGxlYXNlICBrZWVwICBvbmUgIHRoaW5nICBpbg0KbWluZDogbWVtcG9vbHMgYWxs b2NhdGUgYSBjaHVuayBvZiBtZW1vcnkgdGhhdCBzaXRzIGluIGEgbGlzdCwgaWRsZSBhbmQgdW5h dmFpbGFibGUNCmZvciBhbnkgcmVhbCB1c2UuIEl0IGlzIGVhc3kgdG8gY29uc3VtZSBhIGdyZWF0 IGRlYWwgb2YgbWVtb3J5IHdpdGggbWVtcG9vbHMuIEluDQphbG1vc3QgZXZlcnkgY2FzZSwgdGhl IHByZWZlcnJlZCBhbHRlcm5hdGl2ZSBpcyB0byBkbyB3aXRob3V0IHRoZSBtZW1wb29sIGFuZCBz aW1wbHkNCmRlYWwgd2l0aCB0aGUgcG9zc2liaWxpdHkgb2YgYWxsb2NhdGlvbiBmYWlsdXJlcyBp bnN0ZWFkLiBJZiB0aGVyZSBpcyBhbnkgd2F5IGZvciB5b3VyDQpkcml2ZXIgdG8gcmVzcG9uZCB0 byBhbiBhbGxvY2F0aW9uIGZhaWx1cmUgaW4gYSB3YXkgdGhhdCBkb2VzIG5vdCBlbmRhbmdlciB0 aGUgaW50ZWctDQpyaXR5IG9mIHRoZSBzeXN0ZW0sIGRvIHRoaW5ncyB0aGF0IHdheS4gVXNlIG9m IG1lbXBvb2xzIGluIGRyaXZlciBjb2RlIHNob3VsZCBiZQ0KcmFyZQ0KDQpCdXQgdGhpcyBib29r IGlzIG5vdyBxdWl0ZSBvbGQgaW4gTGludXggdGVybXMuDQoNClNvLCBJIGNhbiBpbnZlc3RpZ2F0 ZSB1c2luZyBtZW1wb29scy4gSG93ZXZlciwgSSB3b3VsZCBwcmVmZXIgdG8gY29udGludWUgdXNp bmcgdGhlIGV4aXN0aW5nIG1ldGhvZHMgaW4gdGhpcyBjdXJyZW50IHBhdGNoc2V0Lg0KDQpJIGhv cGUgdGhhdCBpcyBvayB3aXRoIHlvdS4uLg0KDQoNCj4gLS0tLS1PcmlnaW5hbCBNZXNzYWdlLS0t LS0NCj4gRnJvbTogSGFubmVzIFJlaW5lY2tlIFttYWlsdG86aGFyZUBzdXNlLmRlXQ0KPiBTZW50 OiBGcmlkYXksIEFwcmlsIDE3LCAyMDE1IDg6MTQgQU0NCj4gVG86IERvbiBCcmFjZTsgU2NvdHQg VGVlbDsgS2V2aW4gQmFybmV0dDsgamFtZXMuYm90dG9tbGV5QHBhcmFsbGVscy5jb207DQo+IGhj aEBpbmZyYWRlYWQub3JnOyBKdXN0aW4gTGluZGxleTsgYnJhY2UNCj4gQ2M6IGxpbnV4LXNjc2lA dmdlci5rZXJuZWwub3JnDQo+IFN1YmplY3Q6IFJlOiBbUEFUQ0ggdjQgMTkvNDNdIGhwc2E6IGFk ZCBpb2FjY2VsIHNnIGNoYWluaW5nIGZvciB0aGUgaW9hY2NlbDINCj4gcGF0aA0KPiANCj4gT24g MDQvMTYvMjAxNSAwMzo0OCBQTSwgRG9uIEJyYWNlIHdyb3RlOg0KPiA+IEZyb206IFdlYmIgU2Nh bGVzIDx3ZWJibmhAaHAuY29tPg0KPiA+DQo+ID4gSW5jcmVhc2UgdGhlIHJlcXVlc3Qgc2l6ZSBm b3IgaW9hY2NlbDIgcGF0aC4NCj4gPg0KPiA+IFRoZSBlcnJvciwgaWYgYW55LCByZXR1cm5lZCBi eSBocHNhX2FsbG9jYXRlX2lvYWNjZWwyX3NnX2NoYWluX2Jsb2Nrcw0KPiA+IHRvIGhwc2FfYWxs b2NfaW9hY2NlbDJfY21kX2FuZF9iZnQgc2hvdWxkIGJlIHJldHVybmVkIHVwc3RyZWFtIHJhdGhl cg0KPiA+IHRoYW4gYXNzdW1lZCB0byBiZSAtRU5PTUVNLg0KPiA+DQo+ID4gVGhpcyBkaWZmZXJz IHNsaWdodGx5IGZyb20gaHBzYV9hbGxvY19pb2FjY2VsMV9jbWRfYW5kX2JmdCwNCj4gPiB3aGlj aCBkb2VzIG5vdCBjYWxsIGFub3RoZXIgaHBzYV9hbGxvY2F0ZSBmdW5jdGlvbiBhbmQgb25seQ0K PiA+IGhhcyAtRU5PTUVNIHRvIHJldHVybiBmcm9tIHNvbWUga21hbGxvYyBjYWxscy4NCj4gPg0K PiA+IFJldmlld2VkLWJ5OiBTY290dCBUZWVsIDxzY290dC50ZWVsQHBtY3MuY29tPg0KPiA+IFJl dmlld2VkLWJ5OiBLZXZpbiBCYXJuZXR0IDxrZXZpbi5iYXJuZXR0QHBtY3MuY29tPg0KPiA+IFNp Z25lZC1vZmYtYnk6IFJvYmVydCBFbGxpb3R0IDxlbGxpb3R0QGhwLmNvbT4NCj4gPiBTaWduZWQt b2ZmLWJ5OiBEb24gQnJhY2UgPGRvbi5icmFjZUBwbWNzLmNvbT4NCj4gPiAtLS0NCj4gPiAgZHJp dmVycy9zY3NpL2hwc2EuYyB8ICAxMjUNCj4gKysrKysrKysrKysrKysrKysrKysrKysrKysrKysr KysrKysrKysrKysrKysrKystLS0tDQo+ID4gIGRyaXZlcnMvc2NzaS9ocHNhLmggfCAgICAxDQo+ ID4gIDIgZmlsZXMgY2hhbmdlZCwgMTE2IGluc2VydGlvbnMoKyksIDEwIGRlbGV0aW9ucygtKQ0K PiA+DQo+ID4gZGlmZiAtLWdpdCBhL2RyaXZlcnMvc2NzaS9ocHNhLmMgYi9kcml2ZXJzL3Njc2kv aHBzYS5jDQo+ID4gaW5kZXggYzljNDJlOS4uMTgzOTc2MSAxMDA2NDQNCj4gPiAtLS0gYS9kcml2 ZXJzL3Njc2kvaHBzYS5jDQo+ID4gKysrIGIvZHJpdmVycy9zY3NpL2hwc2EuYw0KPiA+IEBAIC0x NzA0LDYgKzE3MDQsNDYgQEAgc3RhdGljIHZvaWQgaHBzYV9zbGF2ZV9kZXN0cm95KHN0cnVjdCBz Y3NpX2RldmljZQ0KPiAqc2RldikNCj4gPiAgCS8qIG5vdGhpbmcgdG8gZG8uICovDQo+ID4gIH0N Cj4gPg0KPiA+ICtzdGF0aWMgdm9pZCBocHNhX2ZyZWVfaW9hY2NlbDJfc2dfY2hhaW5fYmxvY2tz KHN0cnVjdCBjdGxyX2luZm8gKmgpDQo+ID4gK3sNCj4gPiArCWludCBpOw0KPiA+ICsNCj4gPiAr CWlmICghaC0+aW9hY2NlbDJfY21kX3NnX2xpc3QpDQo+ID4gKwkJcmV0dXJuOw0KPiA+ICsJZm9y IChpID0gMDsgaSA8IGgtPm5yX2NtZHM7IGkrKykgew0KPiA+ICsJCWtmcmVlKGgtPmlvYWNjZWwy X2NtZF9zZ19saXN0W2ldKTsNCj4gPiArCQloLT5pb2FjY2VsMl9jbWRfc2dfbGlzdFtpXSA9IE5V TEw7DQo+ID4gKwl9DQo+ID4gKwlrZnJlZShoLT5pb2FjY2VsMl9jbWRfc2dfbGlzdCk7DQo+ID4g KwloLT5pb2FjY2VsMl9jbWRfc2dfbGlzdCA9IE5VTEw7DQo+ID4gK30NCj4gPiArDQo+ID4gK3N0 YXRpYyBpbnQgaHBzYV9hbGxvY2F0ZV9pb2FjY2VsMl9zZ19jaGFpbl9ibG9ja3Moc3RydWN0IGN0 bHJfaW5mbyAqaCkNCj4gPiArew0KPiA+ICsJaW50IGk7DQo+ID4gKw0KPiA+ICsJaWYgKGgtPmNo YWluc2l6ZSA8PSAwKQ0KPiA+ICsJCXJldHVybiAwOw0KPiA+ICsNCj4gPiArCWgtPmlvYWNjZWwy X2NtZF9zZ19saXN0ID0NCj4gPiArCQlremFsbG9jKHNpemVvZigqaC0+aW9hY2NlbDJfY21kX3Nn X2xpc3QpICogaC0+bnJfY21kcywNCj4gPiArCQkJCQlHRlBfS0VSTkVMKTsNCj4gPiArCWlmICgh aC0+aW9hY2NlbDJfY21kX3NnX2xpc3QpDQo+ID4gKwkJcmV0dXJuIC1FTk9NRU07DQo+ID4gKwlm b3IgKGkgPSAwOyBpIDwgaC0+bnJfY21kczsgaSsrKSB7DQo+ID4gKwkJaC0+aW9hY2NlbDJfY21k X3NnX2xpc3RbaV0gPQ0KPiA+ICsJCQlrbWFsbG9jKHNpemVvZigqaC0+aW9hY2NlbDJfY21kX3Nn X2xpc3RbaV0pICoNCj4gPiArCQkJCQloLT5tYXhzZ2VudHJpZXMsIEdGUF9LRVJORUwpOw0KPiA+ ICsJCWlmICghaC0+aW9hY2NlbDJfY21kX3NnX2xpc3RbaV0pDQo+ID4gKwkJCWdvdG8gY2xlYW47 DQo+ID4gKwl9DQo+ID4gKwlyZXR1cm4gMDsNCj4gPiArDQo+ID4gK2NsZWFuOg0KPiA+ICsJaHBz YV9mcmVlX2lvYWNjZWwyX3NnX2NoYWluX2Jsb2NrcyhoKTsNCj4gPiArCXJldHVybiAtRU5PTUVN Ow0KPiA+ICt9DQo+ID4gKw0KPiA+ICBzdGF0aWMgdm9pZCBocHNhX2ZyZWVfc2dfY2hhaW5fYmxv Y2tzKHN0cnVjdCBjdGxyX2luZm8gKmgpDQo+ID4gIHsNCj4gPiAgCWludCBpOw0KPiBBbnkgcmVh c29uIHdoeSB5b3UgZGlkbid0IHVzZSBtZW1wb29scyBoZXJlPw0KPiANCj4gQ2hlZXJzLA0KPiAN Cj4gSGFubmVzDQo+IC0tDQo+IERyLiBIYW5uZXMgUmVpbmVja2UJCSAgICAgICAgICAgICAgIHpT ZXJpZXMgJiBTdG9yYWdlDQo+IGhhcmVAc3VzZS5kZQkJCSAgICAgICAgICAgICAgICs0OSA5MTEg NzQwNTMgNjg4DQo+IFNVU0UgTElOVVggR21iSCwgTWF4ZmVsZHN0ci4gNSwgOTA0MDkgTsO8cm5i ZXJnDQo+IEdGOiBGLiBJbWVuZMO2cmZmZXIsIEouIFNtaXRoYXJkLCBKLiBHdWlsZCwgRC4gVXBt YW55dSwgRy4gTm9ydG9uDQo+IEhSQiAyMTI4NCAoQUcgTsO8cm5iZXJnKQ0K -- To unsubscribe from this list: send the line "unsubscribe linux-scsi" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
On 04/22/2015 09:12 PM, brace wrote: > The last I read about mempools was from: > Linux Device Drivers > By Jonathan Corbet, Alessandro Rubini, Greg Kroah-Hartman > > https://lwn.net/images/pdf/LDD3/ch08.pdf > > > If you are considering using a mempool in your driver, please keep one thing in > mind: mempools allocate a chunk of memory that sits in a list, idle and unavailable > for any real use. It is easy to consume a great deal of memory with mempools. In > almost every case, the preferred alternative is to do without the mempool and simply > deal with the possibility of allocation failures instead. If there is any way for your > driver to respond to an allocation failure in a way that does not endanger the integ- > rity of the system, do things that way. Use of mempools in driver code should be > rare > > But this book is now quite old in Linux terms. > > So, I can investigate using mempools. However, I would prefer to continue using the existing methods in this current patchset. > > I hope that is ok with you... > Yes, that's okay with me. Personally I would be using mempools when you need lots of small, frequently changed allocations (like sg elements), and kzalloc() for large or infrequently changed bits of memory. Reviewed-by: Hannes Reinecke <hare@suse.de> Cheers, Hannes
On Thu, Apr 23, 2015 at 07:50:41AM +0200, Hannes Reinecke wrote: > Yes, that's okay with me. > > Personally I would be using mempools when you need lots of small, > frequently changed allocations (like sg elements), and kzalloc() for > large or infrequently changed bits of memory. The array lookup is a small O(1) cost, so it's aways cheaper than a mempool for this case where we allocate on object per tag. Even better would be to use the command private data, but that needs the patches that allow the driver to initializse it that Jens is working on first. -- To unsubscribe from this list: send the line "unsubscribe linux-scsi" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c index c9c42e9..1839761 100644 --- a/drivers/scsi/hpsa.c +++ b/drivers/scsi/hpsa.c @@ -1704,6 +1704,46 @@ static void hpsa_slave_destroy(struct scsi_device *sdev) /* nothing to do. */ } +static void hpsa_free_ioaccel2_sg_chain_blocks(struct ctlr_info *h) +{ + int i; + + if (!h->ioaccel2_cmd_sg_list) + return; + for (i = 0; i < h->nr_cmds; i++) { + kfree(h->ioaccel2_cmd_sg_list[i]); + h->ioaccel2_cmd_sg_list[i] = NULL; + } + kfree(h->ioaccel2_cmd_sg_list); + h->ioaccel2_cmd_sg_list = NULL; +} + +static int hpsa_allocate_ioaccel2_sg_chain_blocks(struct ctlr_info *h) +{ + int i; + + if (h->chainsize <= 0) + return 0; + + h->ioaccel2_cmd_sg_list = + kzalloc(sizeof(*h->ioaccel2_cmd_sg_list) * h->nr_cmds, + GFP_KERNEL); + if (!h->ioaccel2_cmd_sg_list) + return -ENOMEM; + for (i = 0; i < h->nr_cmds; i++) { + h->ioaccel2_cmd_sg_list[i] = + kmalloc(sizeof(*h->ioaccel2_cmd_sg_list[i]) * + h->maxsgentries, GFP_KERNEL); + if (!h->ioaccel2_cmd_sg_list[i]) + goto clean; + } + return 0; + +clean: + hpsa_free_ioaccel2_sg_chain_blocks(h); + return -ENOMEM; +} + static void hpsa_free_sg_chain_blocks(struct ctlr_info *h) { int i; @@ -1746,6 +1786,39 @@ clean: return -ENOMEM; } +static int hpsa_map_ioaccel2_sg_chain_block(struct ctlr_info *h, + struct io_accel2_cmd *cp, struct CommandList *c) +{ + struct ioaccel2_sg_element *chain_block; + u64 temp64; + u32 chain_size; + + chain_block = h->ioaccel2_cmd_sg_list[c->cmdindex]; + chain_size = le32_to_cpu(cp->data_len); + temp64 = pci_map_single(h->pdev, chain_block, chain_size, + PCI_DMA_TODEVICE); + if (dma_mapping_error(&h->pdev->dev, temp64)) { + /* prevent subsequent unmapping */ + cp->sg->address = 0; + return -1; + } + cp->sg->address = cpu_to_le64(temp64); + return 0; +} + +static void hpsa_unmap_ioaccel2_sg_chain_block(struct ctlr_info *h, + struct io_accel2_cmd *cp) +{ + struct ioaccel2_sg_element *chain_sg; + u64 temp64; + u32 chain_size; + + chain_sg = cp->sg; + temp64 = le64_to_cpu(chain_sg->address); + chain_size = le32_to_cpu(cp->data_len); + pci_unmap_single(h->pdev, temp64, chain_size, PCI_DMA_TODEVICE); +} + static int hpsa_map_sg_chain_block(struct ctlr_info *h, struct CommandList *c) { @@ -1955,6 +2028,7 @@ static void complete_scsi_command(struct CommandList *cp) struct ctlr_info *h; struct ErrorInfo *ei; struct hpsa_scsi_dev_t *dev; + struct io_accel2_cmd *c2; int sense_key; int asc; /* additional sense code */ @@ -1965,12 +2039,17 @@ static void complete_scsi_command(struct CommandList *cp) cmd = cp->scsi_cmd; h = cp->h; dev = cmd->device->hostdata; + c2 = &h->ioaccel2_cmd_pool[cp->cmdindex]; scsi_dma_unmap(cmd); /* undo the DMA mappings */ if ((cp->cmd_type == CMD_SCSI) && (le16_to_cpu(cp->Header.SGTotal) > h->max_cmd_sg_entries)) hpsa_unmap_sg_chain_block(h, cp); + if ((cp->cmd_type == CMD_IOACCEL2) && + (c2->sg[0].chain_indicator == IOACCEL2_CHAIN)) + hpsa_unmap_ioaccel2_sg_chain_block(h, c2); + cmd->result = (DID_OK << 16); /* host byte */ cmd->result |= (COMMAND_COMPLETE << 8); /* msg byte */ @@ -3812,10 +3891,7 @@ static int hpsa_scsi_ioaccel2_queue_command(struct ctlr_info *h, u32 len; u32 total_len = 0; - if (scsi_sg_count(cmd) > h->ioaccel_maxsg) { - atomic_dec(&phys_disk->ioaccel_cmds_out); - return IO_ACCEL_INELIGIBLE; - } + BUG_ON(scsi_sg_count(cmd) > h->maxsgentries); if (fixup_ioaccel_cdb(cdb, &cdb_len)) { atomic_dec(&phys_disk->ioaccel_cmds_out); @@ -3838,8 +3914,19 @@ static int hpsa_scsi_ioaccel2_queue_command(struct ctlr_info *h, } if (use_sg) { - BUG_ON(use_sg > IOACCEL2_MAXSGENTRIES); curr_sg = cp->sg; + if (use_sg > h->ioaccel_maxsg) { + addr64 = le64_to_cpu( + h->ioaccel2_cmd_sg_list[c->cmdindex]->address); + curr_sg->address = cpu_to_le64(addr64); + curr_sg->length = 0; + curr_sg->reserved[0] = 0; + curr_sg->reserved[1] = 0; + curr_sg->reserved[2] = 0; + curr_sg->chain_indicator = 0x80; + + curr_sg = h->ioaccel2_cmd_sg_list[c->cmdindex]; + } scsi_for_each_sg(cmd, sg, use_sg, i) { addr64 = (u64) sg_dma_address(sg); len = sg_dma_len(sg); @@ -3884,14 +3971,22 @@ static int hpsa_scsi_ioaccel2_queue_command(struct ctlr_info *h, cp->Tag = cpu_to_le32(c->cmdindex << DIRECT_LOOKUP_SHIFT); memcpy(cp->cdb, cdb, sizeof(cp->cdb)); - /* fill in sg elements */ - cp->sg_count = (u8) use_sg; - cp->data_len = cpu_to_le32(total_len); cp->err_ptr = cpu_to_le64(c->busaddr + offsetof(struct io_accel2_cmd, error_data)); cp->err_len = cpu_to_le32(sizeof(cp->error_data)); + /* fill in sg elements */ + if (use_sg > h->ioaccel_maxsg) { + cp->sg_count = 1; + if (hpsa_map_ioaccel2_sg_chain_block(h, cp, c)) { + atomic_dec(&phys_disk->ioaccel_cmds_out); + scsi_dma_unmap(cmd); + return -1; + } + } else + cp->sg_count = (u8) use_sg; + enqueue_cmd_and_start_io(h, c); return 0; } @@ -7911,6 +8006,8 @@ clean_up: /* Free ioaccel2 mode command blocks and block fetch table */ static void hpsa_free_ioaccel2_cmd_and_bft(struct ctlr_info *h) { + hpsa_free_ioaccel2_sg_chain_blocks(h); + if (h->ioaccel2_cmd_pool) pci_free_consistent(h->pdev, h->nr_cmds * sizeof(*h->ioaccel2_cmd_pool), @@ -7922,6 +8019,8 @@ static void hpsa_free_ioaccel2_cmd_and_bft(struct ctlr_info *h) /* Allocate ioaccel2 mode command blocks and block fetch table */ static int hpsa_alloc_ioaccel2_cmd_and_bft(struct ctlr_info *h) { + int rc; + /* Allocate ioaccel2 mode command blocks and block fetch table */ h->ioaccel_maxsg = @@ -7941,7 +8040,13 @@ static int hpsa_alloc_ioaccel2_cmd_and_bft(struct ctlr_info *h) sizeof(u32)), GFP_KERNEL); if ((h->ioaccel2_cmd_pool == NULL) || - (h->ioaccel2_blockFetchTable == NULL)) + (h->ioaccel2_blockFetchTable == NULL)) { + rc = -ENOMEM; + goto clean_up; + } + + rc = hpsa_allocate_ioaccel2_sg_chain_blocks(h); + if (rc) goto clean_up; memset(h->ioaccel2_cmd_pool, 0, @@ -7950,7 +8055,7 @@ static int hpsa_alloc_ioaccel2_cmd_and_bft(struct ctlr_info *h) clean_up: hpsa_free_ioaccel2_cmd_and_bft(h); - return 1; + return rc; } static void hpsa_put_ctlr_into_performant_mode(struct ctlr_info *h) diff --git a/drivers/scsi/hpsa.h b/drivers/scsi/hpsa.h index 87a70b5..3acacf6 100644 --- a/drivers/scsi/hpsa.h +++ b/drivers/scsi/hpsa.h @@ -162,6 +162,7 @@ struct ctlr_info { u8 max_cmd_sg_entries; int chainsize; struct SGDescriptor **cmd_sg_list; + struct ioaccel2_sg_element **ioaccel2_cmd_sg_list; /* pointers to command and error info pool */ struct CommandList *cmd_pool;