diff options
author | Alexander Motin <mav@FreeBSD.org> | 2011-04-19 08:01:17 +0000 |
---|---|---|
committer | Alexander Motin <mav@FreeBSD.org> | 2011-04-19 08:01:17 +0000 |
commit | 6ac0befde2c5873a3cdae7fcec45facd817ae151 (patch) | |
tree | b127f1c0f2074a00cefb5b52a4696a36352ccb98 /sys/dev/ahci | |
parent | c819dfaeba2efc22541960dcf8aed0ce9e8bf19d (diff) | |
download | src-6ac0befde2c5873a3cdae7fcec45facd817ae151.tar.gz src-6ac0befde2c5873a3cdae7fcec45facd817ae151.zip |
Properly handle memory allocation errors during error recovery.
Notes
Notes:
svn path=/head/; revision=220822
Diffstat (limited to 'sys/dev/ahci')
-rw-r--r-- | sys/dev/ahci/ahci.c | 23 |
1 files changed, 18 insertions, 5 deletions
diff --git a/sys/dev/ahci/ahci.c b/sys/dev/ahci/ahci.c index e765a324c709..ac200cbad80b 100644 --- a/sys/dev/ahci/ahci.c +++ b/sys/dev/ahci/ahci.c @@ -2132,7 +2132,6 @@ ahci_issue_recovery(device_t dev) struct ccb_scsiio *csio; int i; - ch->recoverycmd = 1; /* Find some holden command. */ for (i = 0; i < ch->numslots; i++) { if (ch->hold[i]) @@ -2140,8 +2139,20 @@ ahci_issue_recovery(device_t dev) } ccb = xpt_alloc_ccb_nowait(); if (ccb == NULL) { - device_printf(dev, "Unable allocate READ LOG command"); - return; /* XXX */ + device_printf(dev, "Unable allocate recovery command\n"); +completeall: + /* We can't do anything -- complete holden commands. */ + for (i = 0; i < ch->numslots; i++) { + if (ch->hold[i] == NULL) + continue; + ch->hold[i]->ccb_h.status &= ~CAM_STATUS_MASK; + ch->hold[i]->ccb_h.status |= CAM_RESRC_UNAVAIL; + xpt_done(ch->hold[i]); + ch->hold[i] = NULL; + ch->numhslots--; + } + ahci_reset(dev); + return; } ccb->ccb_h = ch->hold[i]->ccb_h; /* Reuse old header. */ if (ccb->ccb_h.func_code == XPT_ATA_IO) { @@ -2154,8 +2165,9 @@ ahci_issue_recovery(device_t dev) ataio->data_ptr = malloc(512, M_AHCI, M_NOWAIT); if (ataio->data_ptr == NULL) { xpt_free_ccb(ccb); - device_printf(dev, "Unable allocate memory for READ LOG command"); - return; /* XXX */ + device_printf(dev, + "Unable allocate memory for READ LOG command\n"); + goto completeall; } ataio->dxfer_len = 512; bzero(&ataio->cmd, sizeof(ataio->cmd)); @@ -2183,6 +2195,7 @@ ahci_issue_recovery(device_t dev) csio->cdb_io.cdb_bytes[4] = csio->dxfer_len; } /* Freeze SIM while doing recovery. */ + ch->recoverycmd = 1; xpt_freeze_simq(ch->sim, 1); ahci_begin_transaction(dev, ccb); } |