forked from Minki/linux
[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: Matthew Wilcox <matthew@wil.cx> Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
This commit is contained in:
parent
760c9de589
commit
84e203a279
@ -563,10 +563,7 @@ int sym_setup_data_and_start(struct sym_hcb *np, struct scsi_cmnd *cmd, struct s
|
||||
/*
|
||||
* activate this job.
|
||||
*/
|
||||
if (lp)
|
||||
sym_start_next_ccbs(np, lp, 2);
|
||||
else
|
||||
sym_put_start_queue(np, cp);
|
||||
sym_start_next_ccbs(np, lp, 2);
|
||||
return 0;
|
||||
|
||||
out_abort:
|
||||
@ -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)
|
||||
{
|
||||
struct sym_hcb *np;
|
||||
struct sym_tcb *tp;
|
||||
struct sym_hcb *np = sym_get_hcb(sdev->host);
|
||||
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)
|
||||
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
|
||||
* the NVRAM. This may speed up boot and maintain coherency with
|
||||
@ -1005,6 +1000,10 @@ static int sym53c8xx_slave_alloc(struct scsi_device *sdev)
|
||||
return -ENXIO;
|
||||
}
|
||||
|
||||
lp = sym_alloc_lcb(np, sdev->id, sdev->lun);
|
||||
if (!lp)
|
||||
return -ENOMEM;
|
||||
|
||||
tp->starget = sdev->sdev_target;
|
||||
return 0;
|
||||
}
|
||||
@ -1012,21 +1011,13 @@ static int sym53c8xx_slave_alloc(struct scsi_device *sdev)
|
||||
/*
|
||||
* 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_tcb *tp = &np->target[device->id];
|
||||
struct sym_lcb *lp;
|
||||
struct sym_hcb *np = sym_get_hcb(sdev->host);
|
||||
struct sym_tcb *tp = &np->target[sdev->id];
|
||||
struct sym_lcb *lp = sym_lp(tp, sdev->lun);
|
||||
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.
|
||||
*/
|
||||
@ -1038,10 +1029,10 @@ static int sym53c8xx_slave_configure(struct scsi_device *device)
|
||||
* Use at least 2.
|
||||
* 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)
|
||||
reqtags = tp->usrtags;
|
||||
if (!device->tagged_supported)
|
||||
if (!sdev->tagged_supported)
|
||||
reqtags = 0;
|
||||
#if 1 /* Avoid to locally queue commands for no good reasons */
|
||||
if (reqtags > SYM_CONF_MAX_TAG)
|
||||
@ -1050,19 +1041,30 @@ static int sym53c8xx_slave_configure(struct scsi_device *device)
|
||||
#else
|
||||
depth_to_use = (reqtags ? SYM_CONF_MAX_TAG : 2);
|
||||
#endif
|
||||
scsi_adjust_queue_depth(device,
|
||||
(device->tagged_supported ?
|
||||
scsi_adjust_queue_depth(sdev,
|
||||
(sdev->tagged_supported ?
|
||||
MSG_SIMPLE_TAG : 0),
|
||||
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))
|
||||
spi_dv_device(device);
|
||||
if (!spi_initial_dv(sdev->sdev_target))
|
||||
spi_dv_device(sdev);
|
||||
|
||||
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
|
||||
*/
|
||||
@ -1926,6 +1928,7 @@ static struct scsi_host_template sym2_template = {
|
||||
.queuecommand = sym53c8xx_queue_command,
|
||||
.slave_alloc = sym53c8xx_slave_alloc,
|
||||
.slave_configure = sym53c8xx_slave_configure,
|
||||
.slave_destroy = sym53c8xx_slave_destroy,
|
||||
.eh_abort_handler = sym53c8xx_eh_abort_handler,
|
||||
.eh_device_reset_handler = sym53c8xx_eh_device_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
|
||||
/*
|
||||
* 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;
|
||||
|
||||
@ -4664,30 +4664,7 @@ struct sym_ccb *sym_get_ccb (struct sym_hcb *np, struct scsi_cmnd *cmd, u_char t
|
||||
goto out;
|
||||
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.
|
||||
*/
|
||||
@ -4840,12 +4817,6 @@ void sym_free_ccb (struct sym_hcb *np, struct sym_ccb *cp)
|
||||
lp->head.resel_sa =
|
||||
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
|
||||
@ -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_tcb *tp = &np->target[tn];
|
||||
struct sym_lcb *lp = sym_lp(tp, ln);
|
||||
|
||||
/*
|
||||
* 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;
|
||||
struct sym_lcb *lp = NULL;
|
||||
|
||||
/*
|
||||
* 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)
|
||||
lp->started_max = SYM_CONF_MAX_TASK;
|
||||
lp->started_limit = SYM_CONF_MAX_TASK;
|
||||
#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:
|
||||
return lp;
|
||||
}
|
||||
@ -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);
|
||||
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
|
||||
* circular buffer. We want both or none.
|
||||
@ -5481,8 +5427,7 @@ finish:
|
||||
/*
|
||||
* 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
|
||||
}
|
||||
|
||||
@ -5520,12 +5465,6 @@ void sym_complete_ok (struct sym_hcb *np, struct sym_ccb *cp)
|
||||
tp = &np->target[cp->target];
|
||||
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
|
||||
* extended error did occur, there is no residual.
|
||||
@ -5578,7 +5517,7 @@ if (resid)
|
||||
/*
|
||||
* 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);
|
||||
#endif
|
||||
/*
|
||||
@ -5821,8 +5760,7 @@ void sym_hcb_free(struct sym_hcb *np)
|
||||
SYM_QUEHEAD *qp;
|
||||
struct sym_ccb *cp;
|
||||
struct sym_tcb *tp;
|
||||
struct sym_lcb *lp;
|
||||
int target, lun;
|
||||
int target;
|
||||
|
||||
if (np->scriptz0)
|
||||
sym_mfree_dma(np->scriptz0, np->scriptz_sz, "SCRIPTZ0");
|
||||
@ -5848,16 +5786,6 @@ void sym_hcb_free(struct sym_hcb *np)
|
||||
|
||||
for (target = 0; target < SYM_CONF_MAX_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
|
||||
kfree(tp->lunmp);
|
||||
#endif
|
||||
|
@ -416,19 +416,6 @@ struct sym_tcb {
|
||||
struct sym_lcb **lunmp; /* Other LCBs [1..MAX_LUN] */
|
||||
#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
|
||||
/*
|
||||
* O/S specific data structure.
|
||||
@ -1077,7 +1064,6 @@ char *sym_driver_name(void);
|
||||
void sym_print_xerr(struct scsi_cmnd *cmd, int x_status);
|
||||
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);
|
||||
void sym_put_start_queue(struct sym_hcb *np, struct sym_ccb *cp);
|
||||
#ifdef SYM_OPT_HANDLE_DEVICE_QUEUEING
|
||||
void sym_start_next_ccbs(struct sym_hcb *np, struct sym_lcb *lp, int maxn);
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user