Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
linux
Commits
b1b0a996
Commit
b1b0a996
authored
Dec 10, 2002
by
Justin T. Gibbs
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Enable highmem_io.
parent
b83302d7
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
22 additions
and
805 deletions
+22
-805
drivers/scsi/aic7xxx/aic79xx_host.h
drivers/scsi/aic7xxx/aic79xx_host.h
+9
-1
drivers/scsi/aic7xxx/aic79xx_osm.c
drivers/scsi/aic7xxx/aic79xx_osm.c
+2
-2
drivers/scsi/aic7xxx/aic7xxx_host.h
drivers/scsi/aic7xxx/aic7xxx_host.h
+9
-1
drivers/scsi/aic7xxx/aic7xxx_osm.c
drivers/scsi/aic7xxx/aic7xxx_osm.c
+2
-801
No files found.
drivers/scsi/aic7xxx/aic79xx_host.h
View file @
b1b0a996
...
...
@@ -36,7 +36,7 @@
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGES.
*
* $Id: //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_host.h#1
0
$
* $Id: //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_host.h#1
1
$
*/
#ifndef _AIC79XX_LINUX_HOST_H_
...
...
@@ -68,6 +68,13 @@ int ahd_linux_abort(Scsi_Cmnd *);
# define AIC79XX_BIOSPARAM NULL
#endif
#if defined BLK_BOUNCE_HIGH
#define AIC79XX_TEMPLATE_HIGHMEM_IO \
highmem_io: 1,
#else
#define AIC79XX_TEMPLATE_HIGHMEM_IO
#endif
/*
* Scsi_Host_Template (see hosts.h) for AIC-79xx - some fields
* to do with card config are filled in after the card is detected.
...
...
@@ -88,6 +95,7 @@ int ahd_linux_abort(Scsi_Cmnd *);
cmd_per_lun: 2,
/* cmds per lun */
\
present: 0,
/* number of 7xxx's present */
\
unchecked_isa_dma: 0,
/* no memory DMA restrictions*/
\
AIC79XX_TEMPLATE_HIGHMEM_IO \
use_clustering: ENABLE_CLUSTERING
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
...
...
drivers/scsi/aic7xxx/aic79xx_osm.c
View file @
b1b0a996
/*
* Adaptec AIC79xx device driver for Linux.
*
* $Id: //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.c#9
0
$
* $Id: //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.c#9
1
$
*
* --------------------------------------------------------------------------
* Copyright (c) 1994-2000 Justin T. Gibbs.
...
...
@@ -3005,11 +3005,11 @@ ahd_linux_fallback(struct ahd_softc *ahd, struct ahd_devinfo *devinfo)
fallback_speed
=
ahd_linux_calc_speed
(
width
,
period
+
1
,
offset
);
#ifdef AHD_DEBUG
if
(
ahd_debug
&
AHD_SHOW_DV
)
{
#endif
printf
(
"cur_speed= %d, wide_speed= %d, narrow_speed= %d, "
"fallback_speed= %d
\n
"
,
cur_speed
,
wide_speed
,
narrow_speed
,
fallback_speed
);
}
#endif
if
(
cur_speed
>
160000
)
{
/*
...
...
drivers/scsi/aic7xxx/aic7xxx_host.h
View file @
b1b0a996
...
...
@@ -36,7 +36,7 @@
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGES.
*
* $Id: //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_host.h#1
2
$
* $Id: //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_host.h#1
3
$
*/
#ifndef _AIC7XXX_HOST_H_
...
...
@@ -68,6 +68,13 @@ int ahc_linux_abort(Scsi_Cmnd *);
# define AIC7XXX_BIOSPARAM NULL
#endif
#if defined BLK_BOUNCE_HIGH
#define AIC7XXX_TEMPLATE_HIGHMEM_IO \
highmem_io: 1,
#else
#define AIC7XXX_TEMPLATE_HIGHMEM_IO
#endif
/*
* Scsi_Host_Template (see hosts.h) for AIC-7xxx - some fields
* to do with card config are filled in after the card is detected.
...
...
@@ -88,6 +95,7 @@ int ahc_linux_abort(Scsi_Cmnd *);
cmd_per_lun: 2,
/* cmds per lun */
\
present: 0,
/* number of 7xxx's present */
\
unchecked_isa_dma: 0,
/* no memory DMA restrictions*/
\
AIC7XXX_TEMPLATE_HIGHMEM_IO \
use_clustering: ENABLE_CLUSTERING
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
...
...
drivers/scsi/aic7xxx/aic7xxx_osm.c
View file @
b1b0a996
/*
* Adaptec AIC7xxx device driver for Linux.
*
* $Id: //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#15
8
$
* $Id: //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#15
9
$
*
* Copyright (c) 1994 John Aycock
* The University of Calgary Department of Computer Science.
...
...
@@ -2592,592 +2592,6 @@ ahc_linux_dv_transition(struct ahc_softc *ahc, struct scsi_cmnd *cmd,
}
}
#if 0
static void
ahc_linux_dv_target(struct ahc_softc *ahc, u_int target_offset)
{
struct ahc_devinfo devinfo;
struct ahc_linux_target *targ;
struct scsi_cmnd *cmd;
struct scsi_sense_data *sense;
uint8_t *buffer;
u_long s;
u_int timeout;
int echo_size;
sense = NULL;
buffer = NULL;
echo_size = 0;
ahc_lock(ahc, &s);
targ = ahc->platform_data->targets[target_offset];
if (targ == NULL || (targ->flags & AHC_DV_REQUIRED) == 0) {
ahc_unlock(ahc, &s);
return;
}
ahc_compile_devinfo(&devinfo,
targ->channel == 0 ? ahc->our_id : ahc->our_id_b,
targ->target, /*lun*/0, targ->channel + 'A',
ROLE_INITIATOR);
#ifdef AHC_DEBUG
if (ahc_debug & AHC_SHOW_DV) {
ahc_print_devinfo(ahc, &devinfo);
printf("Performing DV\n");
}
#endif
ahc_unlock(ahc, &s);
cmd = malloc(sizeof(struct scsi_cmnd), M_DEVBUF, M_WAITOK);
AHC_SET_DV_STATE(ahc, targ, AHC_DV_STATE_INQ_ASYNC);
while (targ->dv_state != AHC_DV_STATE_EXIT) {
timeout = AHC_LINUX_DV_TIMEOUT;
switch (targ->dv_state) {
case AHC_DV_STATE_INQ_ASYNC:
case AHC_DV_STATE_INQ_ASYNC_VERIFY:
/*
* Set things to async narrow to reduce the
* chance that the INQ will fail.
*/
ahc_lock(ahc, &s);
ahc_set_syncrate(ahc, &devinfo, NULL, 0, 0, 0,
AHC_TRANS_GOAL, /*paused*/FALSE);
ahc_set_width(ahc, &devinfo, MSG_EXT_WDTR_BUS_8_BIT,
AHC_TRANS_GOAL, /*paused*/FALSE);
ahc_unlock(ahc, &s);
timeout = 10 * HZ;
/* FALLTHROUGH */
case AHC_DV_STATE_INQ_VERIFY:
ahc_linux_dv_inq(ahc, cmd, &devinfo, targ);
break;
case AHC_DV_STATE_TUR:
case AHC_DV_STATE_BUSY:
ahc_linux_dv_tur(ahc, cmd, &devinfo);
break;
case AHC_DV_STATE_REBD:
ahc_linux_dv_rebd(ahc, cmd, &devinfo, targ);
break;
case AHC_DV_STATE_WEB:
ahc_linux_dv_web(ahc, cmd, &devinfo, targ);
break;
case AHC_DV_STATE_REB:
ahc_linux_dv_reb(ahc, cmd, &devinfo, targ);
break;
case AHC_DV_STATE_SU:
ahc_linux_dv_su(ahc, cmd, &devinfo, targ);
timeout = 50 * HZ;
break;
default:
ahc_print_devinfo(ahc, &devinfo);
printf("Unknown DV state %d\n", targ->dv_state);
goto out;
}
/* Queue the command and wait for it to complete */
/* Abuse eh_timeout in the scsi_cmnd struct for our purposes */
init_timer(&cmd->eh_timeout);
#ifdef AHC_DEBUG
if ((ahc_debug & AHC_SHOW_MESSAGES) != 0)
/*
* All of the printfs during negotiation
* really slow down the negotiation.
* Add a bit of time just to be safe.
*/
timeout += HZ;
#endif
scsi_add_timer(cmd, timeout, ahc_linux_dv_timeout);
/*
* In 2.5.X, it is assumed that all calls from the
* "midlayer" (which we are emulating) will have the
* ahc host lock held.
*/
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
ahc_lock(ahc, &s);
#endif
ahc_linux_queue(cmd, ahc_linux_dv_complete);
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
ahc_unlock(ahc, &s);
#endif
down(&ahc->platform_data->dv_cmd_sem);
/*
* Wait for the SIMQ to be released so that DV is the
* only reason the queue is frozen.
*/
ahc_lock(ahc, &s);
while (AHC_DV_SIMQ_FROZEN(ahc) == 0) {
ahc->platform_data->flags |= AHC_DV_WAIT_SIMQ_RELEASE;
ahc_unlock(ahc, &s);
down(&ahc->platform_data->dv_sem);
ahc_lock(ahc, &s);
}
ahc_unlock(ahc, &s);
ahc_linux_dv_transition(ahc, cmd, &devinfo, targ);
}
out:
if (cmd != NULL)
free(cmd, M_DEVBUF);
ahc_lock(ahc, &s);
if (targ->dv_buffer != NULL)
free(targ->dv_buffer, M_DEVBUF);
if (targ->dv_buffer1 != NULL)
free(targ->dv_buffer1, M_DEVBUF);
targ->flags &= ~AHC_DV_REQUIRED;
if (targ->refcount == 0)
ahc_linux_free_target(ahc, targ);
ahc_unlock(ahc, &s);
}
static void
ahc_linux_dv_transition(struct ahc_softc *ahc, struct scsi_cmnd *cmd,
struct ahc_devinfo *devinfo,
struct ahc_linux_target *targ)
{
u_int32_t status;
status = aic_dv_error_action(cmd, targ->inq_data);
#ifdef AHC_DEBUG
if (ahc_debug & AHC_SHOW_DV) {
ahc_print_devinfo(ahc, devinfo);
printf("Entering ahc_linux_dv_transition, state= %d, "
"status= 0x%x, cmd->result= 0x%x\n", targ->dv_state,
status, cmd->result);
}
#endif
switch (targ->dv_state) {
case AHC_DV_STATE_INQ_ASYNC:
switch (status & SS_MASK) {
case SS_NOP:
{
AHC_SET_DV_STATE(ahc, targ, AHC_DV_STATE_TUR);
break;
}
case SS_INQ_REFRESH:
AHC_SET_DV_STATE(ahc, targ, AHC_DV_STATE_INQ_ASYNC);
break;
case SS_TUR:
case SS_RETRY:
AHC_SET_DV_STATE(ahc, targ, targ->dv_state);
if (ahc_cmd_get_transaction_status(cmd)
== CAM_REQUEUE_REQ)
targ->dv_state_retry--;
if ((status & SS_ERRMASK) == EBUSY)
AHC_SET_DV_STATE(ahc, targ, AHC_DV_STATE_BUSY);
if (targ->dv_state_retry < 10)
break;
/* FALLTHROUGH */
default:
AHC_SET_DV_STATE(ahc, targ, AHC_DV_STATE_EXIT);
#ifdef AHC_DEBUG
if (ahc_debug & AHC_SHOW_DV) {
ahc_print_devinfo(ahc, devinfo);
printf("Failed DV inquiry, skipping\n");
}
#endif
break;
}
break;
case AHC_DV_STATE_INQ_ASYNC_VERIFY:
switch (status & SS_MASK) {
case SS_NOP:
{
u_int spi3data;
if (memcmp(targ->inq_data, targ->dv_buffer,
AHC_LINUX_DV_INQ_LEN) != 0) {
/*
* Inquiry data must have changed.
* Try from the top again.
*/
AHC_SET_DV_STATE(ahc, targ,
AHC_DV_STATE_INQ_ASYNC);
break;
}
if (ahc_linux_user_dv_setting(ahc) == 0) {
ahc_linux_filter_inquiry(ahc, devinfo);
AHC_SET_DV_STATE(ahc, targ, AHC_DV_STATE_EXIT);
break;
}
spi3data = targ->inq_data->spi3data;
switch (spi3data & SID_SPI_CLOCK_DT_ST) {
default:
case SID_SPI_CLOCK_ST:
/* Assume only basic DV is supported. */
ahc_linux_filter_inquiry(ahc, devinfo);
AHC_SET_DV_STATE(ahc, targ,
AHC_DV_STATE_INQ_VERIFY);
break;
case SID_SPI_CLOCK_DT:
case SID_SPI_CLOCK_DT_ST:
AHC_SET_DV_STATE(ahc, targ, AHC_DV_STATE_REBD);
break;
}
break;
}
case SS_INQ_REFRESH:
AHC_SET_DV_STATE(ahc, targ, AHC_DV_STATE_INQ_ASYNC);
break;
case SS_TUR:
case SS_RETRY:
AHC_SET_DV_STATE(ahc, targ, targ->dv_state);
if (ahc_cmd_get_transaction_status(cmd)
== CAM_REQUEUE_REQ)
targ->dv_state_retry--;
if ((status & SS_ERRMASK) == EBUSY)
AHC_SET_DV_STATE(ahc, targ, AHC_DV_STATE_BUSY);
if (targ->dv_state_retry < 10)
break;
/* FALLTHROUGH */
default:
AHC_SET_DV_STATE(ahc, targ, AHC_DV_STATE_EXIT);
#ifdef AHC_DEBUG
if (ahc_debug & AHC_SHOW_DV) {
ahc_print_devinfo(ahc, devinfo);
printf("Failed DV inquiry, skipping\n");
}
#endif
break;
}
break;
case AHC_DV_STATE_INQ_VERIFY:
switch (status & SS_MASK) {
case SS_NOP:
{
if (memcmp(targ->inq_data, targ->dv_buffer,
AHC_LINUX_DV_INQ_LEN) == 0) {
AHC_SET_DV_STATE(ahc, targ, AHC_DV_STATE_EXIT);
break;
}
if (ahc_linux_fallback(ahc, devinfo) != 0) {
AHC_SET_DV_STATE(ahc, targ, AHC_DV_STATE_EXIT);
break;
}
/*
* Do not count "falling back"
* against our retries.
*/
targ->dv_state_retry = 0;
AHC_SET_DV_STATE(ahc, targ, targ->dv_state);
break;
}
case SS_INQ_REFRESH:
AHC_SET_DV_STATE(ahc, targ, AHC_DV_STATE_INQ_ASYNC);
break;
case SS_TUR:
case SS_RETRY:
AHC_SET_DV_STATE(ahc, targ, targ->dv_state);
if (ahc_cmd_get_transaction_status(cmd)
== CAM_REQUEUE_REQ) {
targ->dv_state_retry--;
} else if ((status & SSQ_FALLBACK) != 0) {
if (ahc_linux_fallback(ahc, devinfo) != 0) {
AHC_SET_DV_STATE(ahc, targ,
AHC_DV_STATE_EXIT);
break;
}
/*
* Do not count "falling back"
* against our retries.
*/
targ->dv_state_retry = 0;
} else if ((status & SS_ERRMASK) == EBUSY)
AHC_SET_DV_STATE(ahc, targ, AHC_DV_STATE_BUSY);
if (targ->dv_state_retry < 10)
break;
/* FALLTHROUGH */
default:
AHC_SET_DV_STATE(ahc, targ, AHC_DV_STATE_EXIT);
#ifdef AHC_DEBUG
if (ahc_debug & AHC_SHOW_DV) {
ahc_print_devinfo(ahc, devinfo);
printf("Failed DV inquiry, skipping\n");
}
#endif
break;
}
break;
case AHC_DV_STATE_TUR:
switch (status & SS_MASK) {
case SS_NOP:
AHC_SET_DV_STATE(ahc, targ,
AHC_DV_STATE_INQ_ASYNC_VERIFY);
break;
case SS_RETRY:
case SS_TUR:
if ((status & SS_ERRMASK) == EBUSY) {
AHC_SET_DV_STATE(ahc, targ, AHC_DV_STATE_BUSY);
break;
}
AHC_SET_DV_STATE(ahc, targ, targ->dv_state);
if (ahc_cmd_get_transaction_status(cmd)
== CAM_REQUEUE_REQ) {
targ->dv_state_retry--;
} else if ((status & SSQ_FALLBACK) != 0) {
if (ahc_linux_fallback(ahc, devinfo) != 0) {
AHC_SET_DV_STATE(ahc, targ,
AHC_DV_STATE_EXIT);
break;
}
/*
* Do not count "falling back"
* against our retries.
*/
targ->dv_state_retry = 0;
}
if (targ->dv_state_retry >= 10) {
#ifdef AHC_DEBUG
if (ahc_debug & AHC_SHOW_DV) {
ahc_print_devinfo(ahc, devinfo);
printf("DV TUR reties exhausted\n");
}
#endif
AHC_SET_DV_STATE(ahc, targ, AHC_DV_STATE_EXIT);
break;
}
if (status & SSQ_DELAY)
scsi_sleep(1 * HZ);
break;
case SS_START:
AHC_SET_DV_STATE(ahc, targ, AHC_DV_STATE_SU);
break;
case SS_INQ_REFRESH:
AHC_SET_DV_STATE(ahc, targ, AHC_DV_STATE_INQ_ASYNC);
break;
default:
AHC_SET_DV_STATE(ahc, targ, AHC_DV_STATE_EXIT);
break;
}
break;
case AHC_DV_STATE_REBD:
switch (status & SS_MASK) {
case SS_NOP:
{
uint32_t echo_size;
AHC_SET_DV_STATE(ahc, targ, AHC_DV_STATE_WEB);
echo_size = scsi_3btoul(&targ->dv_buffer[1]);
echo_size &= 0x1FFF;
#ifdef AHC_DEBUG
if (ahc_debug & AHC_SHOW_DV) {
ahc_print_devinfo(ahc, devinfo);
printf("Echo buffer size= %d\n", echo_size);
}
#endif
if (echo_size == 0) {
AHC_SET_DV_STATE(ahc, targ, AHC_DV_STATE_EXIT);
break;
}
/* Generate the buffer pattern */
targ->dv_echo_size = echo_size;
ahc_linux_generate_dv_pattern(targ);
/*
* Setup initial negotiation values.
*/
ahc_linux_filter_inquiry(ahc, devinfo);
break;
}
case SS_INQ_REFRESH:
AHC_SET_DV_STATE(ahc, targ, AHC_DV_STATE_INQ_ASYNC);
break;
case SS_RETRY:
AHC_SET_DV_STATE(ahc, targ, targ->dv_state);
if (ahc_cmd_get_transaction_status(cmd)
== CAM_REQUEUE_REQ)
targ->dv_state_retry--;
if (targ->dv_state_retry <= 10)
break;
#ifdef AHC_DEBUG
if (ahc_debug & AHC_SHOW_DV) {
ahc_print_devinfo(ahc, devinfo);
printf("DV REBD reties exhausted\n");
}
#endif
/* FALLTHROUGH */
case SS_FATAL:
default:
/*
* Setup initial negotiation values
* and try level 1 DV.
*/
ahc_linux_filter_inquiry(ahc, devinfo);
AHC_SET_DV_STATE(ahc, targ, AHC_DV_STATE_INQ_VERIFY);
targ->dv_echo_size = 0;
break;
}
break;
case AHC_DV_STATE_WEB:
switch (status & SS_MASK) {
case SS_NOP:
AHC_SET_DV_STATE(ahc, targ, AHC_DV_STATE_REB);
break;
case SS_INQ_REFRESH:
AHC_SET_DV_STATE(ahc, targ, AHC_DV_STATE_INQ_ASYNC);
break;
case SS_RETRY:
AHC_SET_DV_STATE(ahc, targ, targ->dv_state);
if (ahc_cmd_get_transaction_status(cmd)
== CAM_REQUEUE_REQ) {
targ->dv_state_retry--;
} else if ((status & SSQ_FALLBACK) != 0) {
if (ahc_linux_fallback(ahc, devinfo) != 0) {
AHC_SET_DV_STATE(ahc, targ,
AHC_DV_STATE_EXIT);
break;
}
/*
* Do not count "falling back"
* against our retries.
*/
targ->dv_state_retry = 0;
}
if (targ->dv_state_retry <= 10)
break;
/* FALLTHROUGH */
#ifdef AHC_DEBUG
if (ahc_debug & AHC_SHOW_DV) {
ahc_print_devinfo(ahc, devinfo);
printf("DV WEB reties exhausted\n");
}
#endif
default:
AHC_SET_DV_STATE(ahc, targ, AHC_DV_STATE_EXIT);
break;
}
break;
case AHC_DV_STATE_REB:
switch (status & SS_MASK) {
case SS_NOP:
if (memcmp(targ->dv_buffer, targ->dv_buffer1,
targ->dv_echo_size) != 0) {
if (ahc_linux_fallback(ahc, devinfo) != 0)
AHC_SET_DV_STATE(ahc, targ,
AHC_DV_STATE_EXIT);
else
AHC_SET_DV_STATE(ahc, targ,
AHC_DV_STATE_WEB);
break;
}
if (targ->dv_buffer != NULL) {
free(targ->dv_buffer, M_DEVBUF);
targ->dv_buffer = NULL;
}
if (targ->dv_buffer1 != NULL) {
free(targ->dv_buffer1, M_DEVBUF);
targ->dv_buffer1 = NULL;
}
AHC_SET_DV_STATE(ahc, targ, AHC_DV_STATE_EXIT);
break;
case SS_INQ_REFRESH:
AHC_SET_DV_STATE(ahc, targ, AHC_DV_STATE_INQ_ASYNC);
break;
case SS_RETRY:
AHC_SET_DV_STATE(ahc, targ, targ->dv_state);
if (ahc_cmd_get_transaction_status(cmd)
== CAM_REQUEUE_REQ) {
targ->dv_state_retry--;
} else if ((status & SSQ_FALLBACK) != 0) {
if (ahc_linux_fallback(ahc, devinfo) != 0) {
AHC_SET_DV_STATE(ahc, targ,
AHC_DV_STATE_EXIT);
break;
}
/*
* Do not count "falling back"
* against our retries.
*/
targ->dv_state_retry = 0;
}
if (targ->dv_state_retry <= 10) {
if ((status & (SSQ_DELAY_RANDOM|SSQ_DELAY))!= 0)
scsi_sleep(devinfo->our_scsiid*HZ/10);
break;
}
#ifdef AHC_DEBUG
if (ahc_debug & AHC_SHOW_DV) {
ahc_print_devinfo(ahc, devinfo);
printf("DV REB reties exhausted\n");
}
#endif
/* FALLTHROUGH */
default:
AHC_SET_DV_STATE(ahc, targ, AHC_DV_STATE_EXIT);
break;
}
break;
case AHC_DV_STATE_SU:
switch (status & SS_MASK) {
case SS_NOP:
case SS_INQ_REFRESH:
AHC_SET_DV_STATE(ahc, targ, AHC_DV_STATE_INQ_ASYNC);
break;
default:
AHC_SET_DV_STATE(ahc, targ, AHC_DV_STATE_EXIT);
break;
}
break;
case AHC_DV_STATE_BUSY:
switch (status & SS_MASK) {
case SS_NOP:
case SS_INQ_REFRESH:
AHC_SET_DV_STATE(ahc, targ, AHC_DV_STATE_INQ_ASYNC);
break;
case SS_TUR:
case SS_RETRY:
AHC_SET_DV_STATE(ahc, targ, targ->dv_state);
if (ahc_cmd_get_transaction_status(cmd)
== CAM_REQUEUE_REQ) {
targ->dv_state_retry--;
} else if (targ->dv_state_retry < 60) {
if ((status & SSQ_DELAY) != 0)
scsi_sleep(1 * HZ);
} else {
#ifdef AHC_DEBUG
if (ahc_debug & AHC_SHOW_DV) {
ahc_print_devinfo(ahc, devinfo);
printf("DV BUSY reties exhausted\n");
}
#endif
AHC_SET_DV_STATE(ahc, targ, AHC_DV_STATE_EXIT);
}
break;
default:
AHC_SET_DV_STATE(ahc, targ, AHC_DV_STATE_EXIT);
break;
}
break;
default:
printf("%s: Invalid DV completion state %d\n", ahc_name(ahc),
targ->dv_state);
AHC_SET_DV_STATE(ahc, targ, AHC_DV_STATE_EXIT);
break;
}
}
#endif
static
uint32_t
aic_dv_error_action
(
struct
scsi_cmnd
*
cmd
,
struct
scsi_inquiry_data
*
inq_data
)
{
...
...
@@ -3317,46 +2731,6 @@ ahc_linux_dv_inq(struct ahc_softc *ahc, struct scsi_cmnd *cmd,
memset
(
cmd
->
request_buffer
,
0
,
AHC_LINUX_DV_INQ_LEN
);
}
#if 0
/*
* Synthesize an inquiry command. On the return trip, it'll be
* sniffed and the device transfer settings set for us.
*/
static void
ahc_linux_dv_inq(struct ahc_softc *ahc, struct scsi_cmnd *cmd,
struct ahc_devinfo *devinfo, struct ahc_linux_target *targ)
{
#ifdef AHC_DEBUG
if (ahc_debug & AHC_SHOW_DV) {
ahc_print_devinfo(ahc, devinfo);
printf("Sending INQ\n");
}
#endif
if (targ->inq_data == NULL)
targ->inq_data = malloc(AHC_LINUX_DV_INQ_LEN,
M_DEVBUF, M_WAITOK);
if (targ->dv_state != AHC_DV_STATE_INQ_ASYNC) {
if (targ->dv_buffer != NULL)
free(targ->dv_buffer, M_DEVBUF);
targ->dv_buffer = malloc(AHC_LINUX_DV_INQ_LEN,
M_DEVBUF, M_WAITOK);
}
ahc_linux_dv_fill_cmd(ahc, cmd, devinfo);
cmd->sc_data_direction = SCSI_DATA_READ;
cmd->cmd_len = 6;
cmd->cmnd[0] = INQUIRY;
cmd->cmnd[4] = AHC_LINUX_DV_INQ_LEN;
cmd->request_bufflen = AHC_LINUX_DV_INQ_LEN;
if (targ->dv_state != AHC_DV_STATE_INQ_ASYNC)
cmd->request_buffer = targ->dv_buffer;
else
cmd->request_buffer = targ->inq_data;
memset(cmd->request_buffer, 0, AHC_LINUX_DV_INQ_LEN);
}
#endif
static
void
ahc_linux_dv_tur
(
struct
ahc_softc
*
ahc
,
struct
scsi_cmnd
*
cmd
,
struct
ahc_devinfo
*
devinfo
)
...
...
@@ -3540,11 +2914,11 @@ ahc_linux_fallback(struct ahc_softc *ahc, struct ahc_devinfo *devinfo)
fallback_speed
=
ahc_linux_calc_speed
(
width
,
period
+
1
,
offset
);
#ifdef AHC_DEBUG
if
(
ahc_debug
&
AHC_SHOW_DV
)
{
#endif
printf
(
"cur_speed= %d, wide_speed= %d, narrow_speed= %d, "
"fallback_speed= %d
\n
"
,
cur_speed
,
wide_speed
,
narrow_speed
,
fallback_speed
);
}
#endif
if
(
cur_speed
>
160000
)
{
/*
...
...
@@ -3662,179 +3036,6 @@ ahc_linux_fallback(struct ahc_softc *ahc, struct ahc_devinfo *devinfo)
return
(
0
);
}
#if 0
static int
ahc_linux_fallback(struct ahc_softc *ahc, struct ahc_devinfo *devinfo)
{
struct ahc_linux_target *targ;
struct ahc_initiator_tinfo *tinfo;
struct ahc_transinfo *goal;
struct ahc_tmode_tstate *tstate;
struct ahc_syncrate *syncrate;
u_long s;
u_int width;
u_int period;
u_int offset;
u_int ppr_options;
u_int cur_speed;
u_int wide_speed;
u_int narrow_speed;
u_int fallback_speed;
#ifdef AHC_DEBUG
if (ahc_debug & AHC_SHOW_DV) {
ahc_print_devinfo(ahc, devinfo);
printf("Trying to fallback\n");
}
#endif
ahc_lock(ahc, &s);
targ = ahc->platform_data->targets[devinfo->target_offset];
tinfo = ahc_fetch_transinfo(ahc, devinfo->channel,
devinfo->our_scsiid,
devinfo->target, &tstate);
goal = &tinfo->goal;
width = goal->width;
period = goal->period;
offset = goal->offset;
ppr_options = goal->ppr_options;
if (offset == 0)
period = AHC_ASYNC_XFER_PERIOD;
if (targ->dv_next_narrow_period == 0)
targ->dv_next_narrow_period = MAX(period, AHC_SYNCRATE_ULTRA2);
if (targ->dv_next_wide_period == 0)
targ->dv_next_wide_period = period;
if (targ->dv_max_ppr_options == 0)
targ->dv_max_ppr_options = ppr_options;
if (targ->dv_last_ppr_options == 0)
targ->dv_last_ppr_options = ppr_options;
cur_speed = ahc_linux_calc_speed(width, period, offset);
wide_speed = ahc_linux_calc_speed(MSG_EXT_WDTR_BUS_16_BIT,
targ->dv_next_wide_period,
MAX_OFFSET);
narrow_speed = ahc_linux_calc_speed(MSG_EXT_WDTR_BUS_8_BIT,
targ->dv_next_narrow_period,
MAX_OFFSET);
fallback_speed = ahc_linux_calc_speed(width, period+1, offset);
#ifdef AHC_DEBUG
if (ahc_debug & AHC_SHOW_DV) {
printf("cur_speed= %d, wide_speed= %d, narrow_speed= %d, "
"fallback_speed= %d\n", cur_speed, wide_speed,
narrow_speed, fallback_speed);
}
#endif
if (cur_speed > 160000) {
/*
* Paced/DT/IU_REQ only transfer speeds. All we
* can do is fallback in terms of syncrate.
*/
period++;
} else if (cur_speed > 80000) {
if ((ppr_options & MSG_EXT_PPR_IU_REQ) != 0) {
/*
* Try without IU_REQ as it may be confusing
* an expander.
*/
ppr_options &= ~MSG_EXT_PPR_IU_REQ;
} else {
/*
* Paced/DT only transfer speeds. All we
* can do is fallback in terms of syncrate.
*/
period++;
ppr_options = targ->dv_max_ppr_options;
}
} else if (cur_speed > 3300) {
/*
* In this range we the following
* options ordered from highest to
* lowest desireability:
*
* o Wide/DT
* o Wide/non-DT
* o Narrow at a potentally higher sync rate.
*
* All modes are tested with and without IU_REQ
* set since using IUs may confuse an expander.
*/
if ((ppr_options & MSG_EXT_PPR_IU_REQ) != 0) {
ppr_options &= ~MSG_EXT_PPR_IU_REQ;
} else if ((ppr_options & MSG_EXT_PPR_DT_REQ) != 0) {
/*
* Try going non-DT. We also disable QAS
* since we may need a non-PPR message to
* work with an expander.
*/
ppr_options = targ->dv_max_ppr_options;
ppr_options &=
~(MSG_EXT_PPR_DT_REQ|MSG_EXT_PPR_QAS_REQ);
} else if (width == MSG_EXT_WDTR_BUS_16_BIT) {
/*
* If the next narrow speed is greater than
* the next wide speed, fallback to narrow.
* Otherwise fallback to the next DT/Wide setting.
* The narrow async speed will always be smaller
* than the wide async speed, so handle this case
* specifically.
*/
ppr_options = targ->dv_max_ppr_options;
if (narrow_speed > fallback_speed
|| period >= AHC_ASYNC_XFER_PERIOD) {
targ->dv_next_wide_period = period+1;
width = MSG_EXT_WDTR_BUS_8_BIT;
period = targ->dv_next_narrow_period;
} else {
period++;
}
} else if ((ahc->features & AHC_WIDE) != 0
&& tinfo->user.width != 0
&& wide_speed >= fallback_speed
&& (targ->dv_next_wide_period <= AHC_ASYNC_XFER_PERIOD
|| period >= AHC_ASYNC_XFER_PERIOD)) {
/*
* We are narrow. Try falling back
* to the next wide speed with
* all supported ppr options set.
*/
targ->dv_next_narrow_period = period+1;
width = MSG_EXT_WDTR_BUS_16_BIT;
period = targ->dv_next_wide_period;
ppr_options = targ->dv_max_ppr_options;
} else {
/* Only narrow fallback is allowed. */
period++;
ppr_options = targ->dv_max_ppr_options;
}
} else {
ahc_unlock(ahc, &s);
return (-1);
}
offset = MAX_OFFSET;
syncrate = ahc_find_syncrate(ahc, &period, &ppr_options,
AHC_SYNCRATE_DT);
ahc_set_width(ahc, devinfo, width, AHC_TRANS_GOAL, FALSE);
if (period == 0) {
period = 0;
offset = 0;
ppr_options = 0;
if (width == MSG_EXT_WDTR_BUS_8_BIT)
targ->dv_next_narrow_period = AHC_ASYNC_XFER_PERIOD;
else
targ->dv_next_wide_period = AHC_ASYNC_XFER_PERIOD;
} else
period = syncrate->period;
ahc_set_syncrate(ahc, devinfo, syncrate, period, offset,
ppr_options, AHC_TRANS_GOAL, FALSE);
ahc_unlock(ahc, &s);
return (0);
}
#endif
static
void
ahc_linux_dv_timeout
(
struct
scsi_cmnd
*
cmd
)
{
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment