提交 84e203a2 编写于 作者: M Matthew Wilcox 提交者: James Bottomley

[SCSI] sym2: Manage sym_lcb properly

Allocate the lcb in slave_alloc and free it in slave_destroy.  This allows
us to remove all the code that checks to see if it's already been allocated.

From: Christoph Hellwig <hch@lst.de>
Signed-off-by: NMatthew Wilcox <matthew@wil.cx>
Signed-off-by: NJames Bottomley <James.Bottomley@SteelEye.com>
上级 760c9de5
...@@ -563,10 +563,7 @@ int sym_setup_data_and_start(struct sym_hcb *np, struct scsi_cmnd *cmd, struct s ...@@ -563,10 +563,7 @@ int sym_setup_data_and_start(struct sym_hcb *np, struct scsi_cmnd *cmd, struct s
/* /*
* activate this job. * activate this job.
*/ */
if (lp) sym_start_next_ccbs(np, lp, 2);
sym_start_next_ccbs(np, lp, 2);
else
sym_put_start_queue(np, cp);
return 0; return 0;
out_abort: out_abort:
...@@ -981,15 +978,13 @@ static int device_queue_depth(struct sym_hcb *np, int target, int lun) ...@@ -981,15 +978,13 @@ static int device_queue_depth(struct sym_hcb *np, int target, int lun)
static int sym53c8xx_slave_alloc(struct scsi_device *sdev) static int sym53c8xx_slave_alloc(struct scsi_device *sdev)
{ {
struct sym_hcb *np; struct sym_hcb *np = sym_get_hcb(sdev->host);
struct sym_tcb *tp; struct sym_tcb *tp = &np->target[sdev->id];
struct sym_lcb *lp;
if (sdev->id >= SYM_CONF_MAX_TARGET || sdev->lun >= SYM_CONF_MAX_LUN) if (sdev->id >= SYM_CONF_MAX_TARGET || sdev->lun >= SYM_CONF_MAX_LUN)
return -ENXIO; return -ENXIO;
np = sym_get_hcb(sdev->host);
tp = &np->target[sdev->id];
/* /*
* Fail the device init if the device is flagged NOSCAN at BOOT in * Fail the device init if the device is flagged NOSCAN at BOOT in
* the NVRAM. This may speed up boot and maintain coherency with * the NVRAM. This may speed up boot and maintain coherency with
...@@ -1005,6 +1000,10 @@ static int sym53c8xx_slave_alloc(struct scsi_device *sdev) ...@@ -1005,6 +1000,10 @@ static int sym53c8xx_slave_alloc(struct scsi_device *sdev)
return -ENXIO; return -ENXIO;
} }
lp = sym_alloc_lcb(np, sdev->id, sdev->lun);
if (!lp)
return -ENOMEM;
tp->starget = sdev->sdev_target; tp->starget = sdev->sdev_target;
return 0; return 0;
} }
...@@ -1012,21 +1011,13 @@ static int sym53c8xx_slave_alloc(struct scsi_device *sdev) ...@@ -1012,21 +1011,13 @@ static int sym53c8xx_slave_alloc(struct scsi_device *sdev)
/* /*
* Linux entry point for device queue sizing. * Linux entry point for device queue sizing.
*/ */
static int sym53c8xx_slave_configure(struct scsi_device *device) static int sym53c8xx_slave_configure(struct scsi_device *sdev)
{ {
struct sym_hcb *np = sym_get_hcb(device->host); struct sym_hcb *np = sym_get_hcb(sdev->host);
struct sym_tcb *tp = &np->target[device->id]; struct sym_tcb *tp = &np->target[sdev->id];
struct sym_lcb *lp; struct sym_lcb *lp = sym_lp(tp, sdev->lun);
int reqtags, depth_to_use; int reqtags, depth_to_use;
/*
* Allocate the LCB if not yet.
* If it fail, we may well be in the sh*t. :)
*/
lp = sym_alloc_lcb(np, device->id, device->lun);
if (!lp)
return -ENOMEM;
/* /*
* Get user flags. * Get user flags.
*/ */
...@@ -1038,10 +1029,10 @@ static int sym53c8xx_slave_configure(struct scsi_device *device) ...@@ -1038,10 +1029,10 @@ static int sym53c8xx_slave_configure(struct scsi_device *device)
* Use at least 2. * Use at least 2.
* Donnot use more than our maximum. * Donnot use more than our maximum.
*/ */
reqtags = device_queue_depth(np, device->id, device->lun); reqtags = device_queue_depth(np, sdev->id, sdev->lun);
if (reqtags > tp->usrtags) if (reqtags > tp->usrtags)
reqtags = tp->usrtags; reqtags = tp->usrtags;
if (!device->tagged_supported) if (!sdev->tagged_supported)
reqtags = 0; reqtags = 0;
#if 1 /* Avoid to locally queue commands for no good reasons */ #if 1 /* Avoid to locally queue commands for no good reasons */
if (reqtags > SYM_CONF_MAX_TAG) if (reqtags > SYM_CONF_MAX_TAG)
...@@ -1050,19 +1041,30 @@ static int sym53c8xx_slave_configure(struct scsi_device *device) ...@@ -1050,19 +1041,30 @@ static int sym53c8xx_slave_configure(struct scsi_device *device)
#else #else
depth_to_use = (reqtags ? SYM_CONF_MAX_TAG : 2); depth_to_use = (reqtags ? SYM_CONF_MAX_TAG : 2);
#endif #endif
scsi_adjust_queue_depth(device, scsi_adjust_queue_depth(sdev,
(device->tagged_supported ? (sdev->tagged_supported ?
MSG_SIMPLE_TAG : 0), MSG_SIMPLE_TAG : 0),
depth_to_use); depth_to_use);
lp->s.scdev_depth = depth_to_use; lp->s.scdev_depth = depth_to_use;
sym_tune_dev_queuing(tp, device->lun, reqtags); sym_tune_dev_queuing(tp, sdev->lun, reqtags);
if (!spi_initial_dv(device->sdev_target)) if (!spi_initial_dv(sdev->sdev_target))
spi_dv_device(device); spi_dv_device(sdev);
return 0; return 0;
} }
static void sym53c8xx_slave_destroy(struct scsi_device *sdev)
{
struct sym_hcb *np = sym_get_hcb(sdev->host);
struct sym_lcb *lp = sym_lp(&np->target[sdev->id], sdev->lun);
if (lp->itlq_tbl)
sym_mfree_dma(lp->itlq_tbl, SYM_CONF_MAX_TASK * 4, "ITLQ_TBL");
kfree(lp->cb_tags);
sym_mfree_dma(lp, sizeof(*lp), "LCB");
}
/* /*
* Linux entry point for info() function * Linux entry point for info() function
*/ */
...@@ -1926,6 +1928,7 @@ static struct scsi_host_template sym2_template = { ...@@ -1926,6 +1928,7 @@ static struct scsi_host_template sym2_template = {
.queuecommand = sym53c8xx_queue_command, .queuecommand = sym53c8xx_queue_command,
.slave_alloc = sym53c8xx_slave_alloc, .slave_alloc = sym53c8xx_slave_alloc,
.slave_configure = sym53c8xx_slave_configure, .slave_configure = sym53c8xx_slave_configure,
.slave_destroy = sym53c8xx_slave_destroy,
.eh_abort_handler = sym53c8xx_eh_abort_handler, .eh_abort_handler = sym53c8xx_eh_abort_handler,
.eh_device_reset_handler = sym53c8xx_eh_device_reset_handler, .eh_device_reset_handler = sym53c8xx_eh_device_reset_handler,
.eh_bus_reset_handler = sym53c8xx_eh_bus_reset_handler, .eh_bus_reset_handler = sym53c8xx_eh_bus_reset_handler,
......
...@@ -1523,7 +1523,7 @@ static int sym_prepare_nego(struct sym_hcb *np, struct sym_ccb *cp, u_char *msgp ...@@ -1523,7 +1523,7 @@ static int sym_prepare_nego(struct sym_hcb *np, struct sym_ccb *cp, u_char *msgp
/* /*
* Insert a job into the start queue. * Insert a job into the start queue.
*/ */
void sym_put_start_queue(struct sym_hcb *np, struct sym_ccb *cp) static void sym_put_start_queue(struct sym_hcb *np, struct sym_ccb *cp)
{ {
u_short qidx; u_short qidx;
...@@ -4664,30 +4664,7 @@ struct sym_ccb *sym_get_ccb (struct sym_hcb *np, struct scsi_cmnd *cmd, u_char t ...@@ -4664,30 +4664,7 @@ struct sym_ccb *sym_get_ccb (struct sym_hcb *np, struct scsi_cmnd *cmd, u_char t
goto out; goto out;
cp = sym_que_entry(qp, struct sym_ccb, link_ccbq); cp = sym_que_entry(qp, struct sym_ccb, link_ccbq);
#ifndef SYM_OPT_HANDLE_DEVICE_QUEUEING {
/*
* If the LCB is not yet available and the LUN
* has been probed ok, try to allocate the LCB.
*/
if (!lp && sym_is_bit(tp->lun_map, ln)) {
lp = sym_alloc_lcb(np, tn, ln);
if (!lp)
goto out_free;
}
#endif
/*
* If the LCB is not available here, then the
* logical unit is not yet discovered. For those
* ones only accept 1 SCSI IO per logical unit,
* since we cannot allow disconnections.
*/
if (!lp) {
if (!sym_is_bit(tp->busy0_map, ln))
sym_set_bit(tp->busy0_map, ln);
else
goto out_free;
} else {
/* /*
* If we have been asked for a tagged command. * If we have been asked for a tagged command.
*/ */
...@@ -4840,12 +4817,6 @@ void sym_free_ccb (struct sym_hcb *np, struct sym_ccb *cp) ...@@ -4840,12 +4817,6 @@ void sym_free_ccb (struct sym_hcb *np, struct sym_ccb *cp)
lp->head.resel_sa = lp->head.resel_sa =
cpu_to_scr(SCRIPTB_BA(np, resel_bad_lun)); cpu_to_scr(SCRIPTB_BA(np, resel_bad_lun));
} }
/*
* Otherwise, we only accept 1 IO per LUN.
* Clear the bit that keeps track of this IO.
*/
else
sym_clr_bit(tp->busy0_map, cp->lun);
/* /*
* We donnot queue more than 1 ccb per target * We donnot queue more than 1 ccb per target
...@@ -4997,20 +4968,7 @@ static void sym_init_tcb (struct sym_hcb *np, u_char tn) ...@@ -4997,20 +4968,7 @@ static void sym_init_tcb (struct sym_hcb *np, u_char tn)
struct sym_lcb *sym_alloc_lcb (struct sym_hcb *np, u_char tn, u_char ln) struct sym_lcb *sym_alloc_lcb (struct sym_hcb *np, u_char tn, u_char ln)
{ {
struct sym_tcb *tp = &np->target[tn]; struct sym_tcb *tp = &np->target[tn];
struct sym_lcb *lp = sym_lp(tp, ln); struct sym_lcb *lp = NULL;
/*
* Already done, just return.
*/
if (lp)
return lp;
/*
* Donnot allow LUN control block
* allocation for not probed LUNs.
*/
if (!sym_is_bit(tp->lun_map, ln))
return NULL;
/* /*
* Initialize the target control block if not yet. * Initialize the target control block if not yet.
...@@ -5082,13 +5040,7 @@ struct sym_lcb *sym_alloc_lcb (struct sym_hcb *np, u_char tn, u_char ln) ...@@ -5082,13 +5040,7 @@ struct sym_lcb *sym_alloc_lcb (struct sym_hcb *np, u_char tn, u_char ln)
lp->started_max = SYM_CONF_MAX_TASK; lp->started_max = SYM_CONF_MAX_TASK;
lp->started_limit = SYM_CONF_MAX_TASK; lp->started_limit = SYM_CONF_MAX_TASK;
#endif #endif
/*
* If we are busy, count the IO.
*/
if (sym_is_bit(tp->busy0_map, ln)) {
lp->busy_itl = 1;
sym_clr_bit(tp->busy0_map, ln);
}
fail: fail:
return lp; return lp;
} }
...@@ -5102,12 +5054,6 @@ static void sym_alloc_lcb_tags (struct sym_hcb *np, u_char tn, u_char ln) ...@@ -5102,12 +5054,6 @@ static void sym_alloc_lcb_tags (struct sym_hcb *np, u_char tn, u_char ln)
struct sym_lcb *lp = sym_lp(tp, ln); struct sym_lcb *lp = sym_lp(tp, ln);
int i; int i;
/*
* If LCB not available, try to allocate it.
*/
if (!lp && !(lp = sym_alloc_lcb(np, tn, ln)))
goto fail;
/* /*
* Allocate the task table and and the tag allocation * Allocate the task table and and the tag allocation
* circular buffer. We want both or none. * circular buffer. We want both or none.
...@@ -5481,8 +5427,7 @@ if (resid) ...@@ -5481,8 +5427,7 @@ if (resid)
/* /*
* Donnot start more than 1 command after an error. * Donnot start more than 1 command after an error.
*/ */
if (lp) sym_start_next_ccbs(np, lp, 1);
sym_start_next_ccbs(np, lp, 1);
#endif #endif
} }
...@@ -5520,12 +5465,6 @@ void sym_complete_ok (struct sym_hcb *np, struct sym_ccb *cp) ...@@ -5520,12 +5465,6 @@ void sym_complete_ok (struct sym_hcb *np, struct sym_ccb *cp)
tp = &np->target[cp->target]; tp = &np->target[cp->target];
lp = sym_lp(tp, cp->lun); lp = sym_lp(tp, cp->lun);
/*
* Assume device discovered on first success.
*/
if (!lp)
sym_set_bit(tp->lun_map, cp->lun);
/* /*
* If all data have been transferred, given than no * If all data have been transferred, given than no
* extended error did occur, there is no residual. * extended error did occur, there is no residual.
...@@ -5578,7 +5517,7 @@ if (resid) ...@@ -5578,7 +5517,7 @@ if (resid)
/* /*
* Requeue a couple of awaiting scsi commands. * Requeue a couple of awaiting scsi commands.
*/ */
if (lp && !sym_que_empty(&lp->waiting_ccbq)) if (!sym_que_empty(&lp->waiting_ccbq))
sym_start_next_ccbs(np, lp, 2); sym_start_next_ccbs(np, lp, 2);
#endif #endif
/* /*
...@@ -5821,8 +5760,7 @@ void sym_hcb_free(struct sym_hcb *np) ...@@ -5821,8 +5760,7 @@ void sym_hcb_free(struct sym_hcb *np)
SYM_QUEHEAD *qp; SYM_QUEHEAD *qp;
struct sym_ccb *cp; struct sym_ccb *cp;
struct sym_tcb *tp; struct sym_tcb *tp;
struct sym_lcb *lp; int target;
int target, lun;
if (np->scriptz0) if (np->scriptz0)
sym_mfree_dma(np->scriptz0, np->scriptz_sz, "SCRIPTZ0"); sym_mfree_dma(np->scriptz0, np->scriptz_sz, "SCRIPTZ0");
...@@ -5848,16 +5786,6 @@ void sym_hcb_free(struct sym_hcb *np) ...@@ -5848,16 +5786,6 @@ void sym_hcb_free(struct sym_hcb *np)
for (target = 0; target < SYM_CONF_MAX_TARGET ; target++) { for (target = 0; target < SYM_CONF_MAX_TARGET ; target++) {
tp = &np->target[target]; tp = &np->target[target];
for (lun = 0 ; lun < SYM_CONF_MAX_LUN ; lun++) {
lp = sym_lp(tp, lun);
if (!lp)
continue;
if (lp->itlq_tbl)
sym_mfree_dma(lp->itlq_tbl, SYM_CONF_MAX_TASK*4,
"ITLQ_TBL");
kfree(lp->cb_tags);
sym_mfree_dma(lp, sizeof(*lp), "LCB");
}
#if SYM_CONF_MAX_LUN > 1 #if SYM_CONF_MAX_LUN > 1
kfree(tp->lunmp); kfree(tp->lunmp);
#endif #endif
......
...@@ -416,19 +416,6 @@ struct sym_tcb { ...@@ -416,19 +416,6 @@ struct sym_tcb {
struct sym_lcb **lunmp; /* Other LCBs [1..MAX_LUN] */ struct sym_lcb **lunmp; /* Other LCBs [1..MAX_LUN] */
#endif #endif
/*
* Bitmap that tells about LUNs that succeeded at least
* 1 IO and therefore assumed to be a real device.
* Avoid useless allocation of the LCB structure.
*/
u32 lun_map[(SYM_CONF_MAX_LUN+31)/32];
/*
* Bitmap that tells about LUNs that haven't yet an LCB
* allocated (not discovered or LCB allocation failed).
*/
u32 busy0_map[(SYM_CONF_MAX_LUN+31)/32];
#ifdef SYM_HAVE_STCB #ifdef SYM_HAVE_STCB
/* /*
* O/S specific data structure. * O/S specific data structure.
...@@ -1077,7 +1064,6 @@ char *sym_driver_name(void); ...@@ -1077,7 +1064,6 @@ char *sym_driver_name(void);
void sym_print_xerr(struct scsi_cmnd *cmd, int x_status); void sym_print_xerr(struct scsi_cmnd *cmd, int x_status);
int sym_reset_scsi_bus(struct sym_hcb *np, int enab_int); int sym_reset_scsi_bus(struct sym_hcb *np, int enab_int);
struct sym_chip *sym_lookup_chip_table(u_short device_id, u_char revision); struct sym_chip *sym_lookup_chip_table(u_short device_id, u_char revision);
void sym_put_start_queue(struct sym_hcb *np, struct sym_ccb *cp);
#ifdef SYM_OPT_HANDLE_DEVICE_QUEUEING #ifdef SYM_OPT_HANDLE_DEVICE_QUEUEING
void sym_start_next_ccbs(struct sym_hcb *np, struct sym_lcb *lp, int maxn); void sym_start_next_ccbs(struct sym_hcb *np, struct sym_lcb *lp, int maxn);
#endif #endif
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册