} ahd_queue_alg;
void ahd_set_tags(struct ahd_softc *ahd,
+ struct scsi_cmnd *cmd,
struct ahd_devinfo *devinfo,
ahd_queue_alg alg);
/* Notify XPT */
ahd_send_async(ahd, devinfo.channel, devinfo.target,
- CAM_LUN_WILDCARD, AC_SENT_BDR, NULL);
+ CAM_LUN_WILDCARD, AC_SENT_BDR);
/*
* Allow the sequencer to continue with
tinfo->curr.ppr_options = ppr_options;
ahd_send_async(ahd, devinfo->channel, devinfo->target,
- CAM_LUN_WILDCARD, AC_TRANSFER_NEG, NULL);
+ CAM_LUN_WILDCARD, AC_TRANSFER_NEG);
if (bootverbose) {
if (offset != 0) {
int options;
tinfo->curr.width = width;
ahd_send_async(ahd, devinfo->channel, devinfo->target,
- CAM_LUN_WILDCARD, AC_TRANSFER_NEG, NULL);
+ CAM_LUN_WILDCARD, AC_TRANSFER_NEG);
if (bootverbose) {
printf("%s: target %d using %dbit transfers\n",
ahd_name(ahd), devinfo->target,
* Update the current state of tagged queuing for a given target.
*/
void
-ahd_set_tags(struct ahd_softc *ahd, struct ahd_devinfo *devinfo,
- ahd_queue_alg alg)
+ahd_set_tags(struct ahd_softc *ahd, struct scsi_cmnd *cmd,
+ struct ahd_devinfo *devinfo, ahd_queue_alg alg)
{
- ahd_platform_set_tags(ahd, devinfo, alg);
+ struct scsi_device *sdev = cmd->device;
+
+ ahd_platform_set_tags(ahd, sdev, devinfo, alg);
ahd_send_async(ahd, devinfo->channel, devinfo->target,
- devinfo->lun, AC_TRANSFER_NEG, &alg);
+ devinfo->lun, AC_TRANSFER_NEG);
}
static void
printf("(%s:%c:%d:%d): refuses tagged commands. "
"Performing non-tagged I/O\n", ahd_name(ahd),
devinfo->channel, devinfo->target, devinfo->lun);
- ahd_set_tags(ahd, devinfo, AHD_QUEUE_NONE);
+ ahd_set_tags(ahd, scb->io_ctx, devinfo, AHD_QUEUE_NONE);
mask = ~0x23;
} else {
printf("(%s:%c:%d:%d): refuses %s tagged commands. "
ahd_name(ahd), devinfo->channel, devinfo->target,
devinfo->lun, tag_type == MSG_ORDERED_TASK
? "ordered" : "head of queue");
- ahd_set_tags(ahd, devinfo, AHD_QUEUE_BASIC);
+ ahd_set_tags(ahd, scb->io_ctx, devinfo, AHD_QUEUE_BASIC);
mask = ~0x03;
}
if (status != CAM_SEL_TIMEOUT)
ahd_send_async(ahd, devinfo->channel, devinfo->target,
- CAM_LUN_WILDCARD, AC_SENT_BDR, NULL);
+ CAM_LUN_WILDCARD, AC_SENT_BDR);
if (message != NULL && bootverbose)
printf("%s: %s on %c:%d. %d SCBs aborted\n", ahd_name(ahd),
#endif
/* Notify the XPT that a bus reset occurred */
ahd_send_async(ahd, devinfo.channel, CAM_TARGET_WILDCARD,
- CAM_LUN_WILDCARD, AC_BUS_RESET, NULL);
+ CAM_LUN_WILDCARD, AC_BUS_RESET);
/*
* Revert to async/narrow transfers until we renegotiate.
struct seeprom_config *sc = ahd->seep_config;
unsigned long flags;
struct scsi_target **ahd_targp = ahd_linux_target_in_softc(starget);
- struct ahd_linux_target *targ = scsi_transport_target_data(starget);
struct ahd_devinfo devinfo;
struct ahd_initiator_tinfo *tinfo;
struct ahd_tmode_tstate *tstate;
BUG_ON(*ahd_targp != NULL);
*ahd_targp = starget;
- memset(targ, 0, sizeof(*targ));
if (sc) {
int flags = sc->device_flags[starget->id];
{
struct ahd_softc *ahd =
*((struct ahd_softc **)sdev->host->hostdata);
- struct scsi_target *starget = sdev->sdev_target;
- struct ahd_linux_target *targ = scsi_transport_target_data(starget);
struct ahd_linux_device *dev;
if (bootverbose)
printf("%s: Slave Alloc %d\n", ahd_name(ahd), sdev->id);
- BUG_ON(targ->sdev[sdev->lun] != NULL);
-
dev = scsi_transport_device_data(sdev);
memset(dev, 0, sizeof(*dev));
*/
dev->maxtags = 0;
- targ->sdev[sdev->lun] = sdev;
-
return (0);
}
return 0;
}
-static void
-ahd_linux_slave_destroy(struct scsi_device *sdev)
-{
- struct ahd_softc *ahd;
- struct ahd_linux_device *dev = scsi_transport_device_data(sdev);
- struct ahd_linux_target *targ = scsi_transport_target_data(sdev->sdev_target);
-
- ahd = *((struct ahd_softc **)sdev->host->hostdata);
- if (bootverbose)
- printf("%s: Slave Destroy %d\n", ahd_name(ahd), sdev->id);
-
- BUG_ON(dev->active);
-
- targ->sdev[sdev->lun] = NULL;
-
-}
-
#if defined(__i386__)
/*
* Return the disk geometry for the given SCSI device.
.use_clustering = ENABLE_CLUSTERING,
.slave_alloc = ahd_linux_slave_alloc,
.slave_configure = ahd_linux_slave_configure,
- .slave_destroy = ahd_linux_slave_destroy,
.target_alloc = ahd_linux_target_alloc,
.target_destroy = ahd_linux_target_destroy,
};
ahd_platform_free(struct ahd_softc *ahd)
{
struct scsi_target *starget;
- int i, j;
+ int i;
if (ahd->platform_data != NULL) {
/* destroy all of the device and target objects */
for (i = 0; i < AHD_NUM_TARGETS; i++) {
starget = ahd->platform_data->starget[i];
if (starget != NULL) {
- for (j = 0; j < AHD_NUM_LUNS; j++) {
- struct ahd_linux_target *targ =
- scsi_transport_target_data(starget);
- if (targ->sdev[j] == NULL)
- continue;
- targ->sdev[j] = NULL;
- }
ahd->platform_data->starget[i] = NULL;
}
}
}
void
-ahd_platform_set_tags(struct ahd_softc *ahd, struct ahd_devinfo *devinfo,
- ahd_queue_alg alg)
+ahd_platform_set_tags(struct ahd_softc *ahd, struct scsi_device *sdev,
+ struct ahd_devinfo *devinfo, ahd_queue_alg alg)
{
- struct scsi_target *starget;
- struct ahd_linux_target *targ;
struct ahd_linux_device *dev;
- struct scsi_device *sdev;
int was_queuing;
int now_queuing;
- starget = ahd->platform_data->starget[devinfo->target];
- targ = scsi_transport_target_data(starget);
- BUG_ON(targ == NULL);
- sdev = targ->sdev[devinfo->lun];
if (sdev == NULL)
return;
tags = ahd_linux_user_tagdepth(ahd, &devinfo);
if (tags != 0 && sdev->tagged_supported != 0) {
- ahd_set_tags(ahd, &devinfo, AHD_QUEUE_TAGGED);
+ ahd_platform_set_tags(ahd, sdev, &devinfo, AHD_QUEUE_TAGGED);
+ ahd_send_async(ahd, devinfo.channel, devinfo.target,
+ devinfo.lun, AC_TRANSFER_NEG);
ahd_print_devinfo(ahd, &devinfo);
printf("Tagged Queuing enabled. Depth %d\n", tags);
} else {
- ahd_set_tags(ahd, &devinfo, AHD_QUEUE_NONE);
+ ahd_platform_set_tags(ahd, sdev, &devinfo, AHD_QUEUE_NONE);
+ ahd_send_async(ahd, devinfo.channel, devinfo.target,
+ devinfo.lun, AC_TRANSFER_NEG);
}
}
void
ahd_send_async(struct ahd_softc *ahd, char channel,
- u_int target, u_int lun, ac_code code, void *arg)
+ u_int target, u_int lun, ac_code code)
{
switch (code) {
case AC_TRANSFER_NEG:
}
ahd_set_transaction_status(scb, CAM_REQUEUE_REQ);
ahd_set_scsi_status(scb, SCSI_STATUS_OK);
- ahd_platform_set_tags(ahd, &devinfo,
+ ahd_platform_set_tags(ahd, sdev, &devinfo,
(dev->flags & AHD_DEV_Q_BASIC)
? AHD_QUEUE_BASIC : AHD_QUEUE_TAGGED);
break;
* as if the target returned BUSY SCSI status.
*/
dev->openings = 1;
- ahd_platform_set_tags(ahd, &devinfo,
+ ahd_platform_set_tags(ahd, sdev, &devinfo,
(dev->flags & AHD_DEV_Q_BASIC)
? AHD_QUEUE_BASIC : AHD_QUEUE_TAGGED);
ahd_set_scsi_status(scb, SCSI_STATUS_BUSY);
if (!ahd_linux_transport_template)
return -ENODEV;
- scsi_transport_reserve_target(ahd_linux_transport_template,
- sizeof(struct ahd_linux_target));
scsi_transport_reserve_device(ahd_linux_transport_template,
sizeof(struct ahd_linux_device));
AHD_DEV_PERIODIC_OTAG = 0x40, /* Send OTAG to prevent starvation */
} ahd_linux_dev_flags;
-struct ahd_linux_target;
struct ahd_linux_device {
TAILQ_ENTRY(ahd_linux_device) links;
#define AHD_OTAG_THRESH 500
};
-struct ahd_linux_target {
- struct scsi_device *sdev[AHD_NUM_LUNS];
- struct ahd_transinfo last_tinfo;
- struct ahd_softc *ahd;
-};
-
/********************* Definitions Required by the Core ***********************/
/*
* Number of SG segments we require. So long as the S/G segments for
}
}
-void ahd_platform_set_tags(struct ahd_softc *ahd,
+void ahd_platform_set_tags(struct ahd_softc *ahd, struct scsi_device *sdev,
struct ahd_devinfo *devinfo, ahd_queue_alg);
int ahd_platform_abort_scbs(struct ahd_softc *ahd, int target,
char channel, int lun, u_int tag,
ahd_linux_isr(int irq, void *dev_id, struct pt_regs * regs);
void ahd_done(struct ahd_softc*, struct scb*);
void ahd_send_async(struct ahd_softc *, char channel,
- u_int target, u_int lun, ac_code, void *);
+ u_int target, u_int lun, ac_code);
void ahd_print_path(struct ahd_softc *, struct scb *);
#ifdef CONFIG_PCI
static void ahd_dump_target_state(struct ahd_softc *ahd,
struct info_str *info,
u_int our_id, char channel,
- u_int target_id, u_int target_offset);
+ u_int target_id);
static void ahd_dump_device_state(struct info_str *info,
struct scsi_device *sdev);
static int ahd_proc_write_seeprom(struct ahd_softc *ahd,
static void
ahd_dump_target_state(struct ahd_softc *ahd, struct info_str *info,
- u_int our_id, char channel, u_int target_id,
- u_int target_offset)
+ u_int our_id, char channel, u_int target_id)
{
- struct ahd_linux_target *targ;
struct scsi_target *starget;
struct ahd_initiator_tinfo *tinfo;
struct ahd_tmode_tstate *tstate;
copy_info(info, "Target %d Negotiation Settings\n", target_id);
copy_info(info, "\tUser: ");
ahd_format_transinfo(info, &tinfo->user);
- starget = ahd->platform_data->starget[target_offset];
+ starget = ahd->platform_data->starget[target_id];
if (starget == NULL)
return;
- targ = scsi_transport_target_data(starget);
copy_info(info, "\tGoal: ");
ahd_format_transinfo(info, &tinfo->goal);
for (lun = 0; lun < AHD_NUM_LUNS; lun++) {
struct scsi_device *dev;
- dev = targ->sdev[lun];
+ dev = scsi_device_lookup_by_target(starget, lun);
if (dev == NULL)
continue;
copy_info(&info, "Allocated SCBs: %d, SG List Length: %d\n\n",
ahd->scb_data.numscbs, AHD_NSEG);
- max_targ = 15;
+ max_targ = 16;
if (ahd->seep_config == NULL)
copy_info(&info, "No Serial EEPROM\n");
copy_info(&info, "\n");
if ((ahd->features & AHD_WIDE) == 0)
- max_targ = 7;
+ max_targ = 8;
- for (i = 0; i <= max_targ; i++) {
+ for (i = 0; i < max_targ; i++) {
ahd_dump_target_state(ahd, &info, ahd->our_id, 'A',
- /*target_id*/i, /*target_offset*/i);
+ /*target_id*/i);
}
retval = info.pos > info.offset ? info.pos - info.offset : 0;
done: