[SCSI] aic79xx: sane pci probing
remove ahd_tailq and do sane pci probing. ported over from aic7xxx. Signed-off-by: Christoph Hellwig <hch@lst.de> Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
This commit is contained in:
parent
d46b1d549e
commit
85a46523ff
|
@ -1247,9 +1247,6 @@ struct ahd_softc {
|
||||||
uint16_t user_tagenable;/* Tagged Queuing allowed */
|
uint16_t user_tagenable;/* Tagged Queuing allowed */
|
||||||
};
|
};
|
||||||
|
|
||||||
TAILQ_HEAD(ahd_softc_tailq, ahd_softc);
|
|
||||||
extern struct ahd_softc_tailq ahd_tailq;
|
|
||||||
|
|
||||||
/*************************** IO Cell Configuration ****************************/
|
/*************************** IO Cell Configuration ****************************/
|
||||||
#define AHD_PRECOMP_SLEW_INDEX \
|
#define AHD_PRECOMP_SLEW_INDEX \
|
||||||
(AHD_ANNEXCOL_PRECOMP_SLEW - AHD_ANNEXCOL_PER_DEV0)
|
(AHD_ANNEXCOL_PRECOMP_SLEW - AHD_ANNEXCOL_PER_DEV0)
|
||||||
|
@ -1374,8 +1371,6 @@ void ahd_enable_coalescing(struct ahd_softc *ahd,
|
||||||
void ahd_pause_and_flushwork(struct ahd_softc *ahd);
|
void ahd_pause_and_flushwork(struct ahd_softc *ahd);
|
||||||
int ahd_suspend(struct ahd_softc *ahd);
|
int ahd_suspend(struct ahd_softc *ahd);
|
||||||
int ahd_resume(struct ahd_softc *ahd);
|
int ahd_resume(struct ahd_softc *ahd);
|
||||||
void ahd_softc_insert(struct ahd_softc *);
|
|
||||||
struct ahd_softc *ahd_find_softc(struct ahd_softc *ahd);
|
|
||||||
void ahd_set_unit(struct ahd_softc *, int);
|
void ahd_set_unit(struct ahd_softc *, int);
|
||||||
void ahd_set_name(struct ahd_softc *, char *);
|
void ahd_set_name(struct ahd_softc *, char *);
|
||||||
struct scb *ahd_get_scb(struct ahd_softc *ahd, u_int col_idx);
|
struct scb *ahd_get_scb(struct ahd_softc *ahd, u_int col_idx);
|
||||||
|
@ -1524,7 +1519,6 @@ void ahd_print_scb(struct scb *scb);
|
||||||
void ahd_print_devinfo(struct ahd_softc *ahd,
|
void ahd_print_devinfo(struct ahd_softc *ahd,
|
||||||
struct ahd_devinfo *devinfo);
|
struct ahd_devinfo *devinfo);
|
||||||
void ahd_dump_sglist(struct scb *scb);
|
void ahd_dump_sglist(struct scb *scb);
|
||||||
void ahd_dump_all_cards_state(void);
|
|
||||||
void ahd_dump_card_state(struct ahd_softc *ahd);
|
void ahd_dump_card_state(struct ahd_softc *ahd);
|
||||||
int ahd_print_register(ahd_reg_parse_entry_t *table,
|
int ahd_print_register(ahd_reg_parse_entry_t *table,
|
||||||
u_int num_entries,
|
u_int num_entries,
|
||||||
|
|
|
@ -52,8 +52,6 @@
|
||||||
#include <dev/aic7xxx/aicasm/aicasm_insformat.h>
|
#include <dev/aic7xxx/aicasm/aicasm_insformat.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/******************************** Globals *************************************/
|
|
||||||
struct ahd_softc_tailq ahd_tailq = TAILQ_HEAD_INITIALIZER(ahd_tailq);
|
|
||||||
|
|
||||||
/***************************** Lookup Tables **********************************/
|
/***************************** Lookup Tables **********************************/
|
||||||
char *ahd_chip_names[] =
|
char *ahd_chip_names[] =
|
||||||
|
@ -5179,74 +5177,6 @@ ahd_softc_init(struct ahd_softc *ahd)
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
ahd_softc_insert(struct ahd_softc *ahd)
|
|
||||||
{
|
|
||||||
struct ahd_softc *list_ahd;
|
|
||||||
|
|
||||||
#if AHD_PCI_CONFIG > 0
|
|
||||||
/*
|
|
||||||
* Second Function PCI devices need to inherit some
|
|
||||||
* settings from function 0.
|
|
||||||
*/
|
|
||||||
if ((ahd->features & AHD_MULTI_FUNC) != 0) {
|
|
||||||
TAILQ_FOREACH(list_ahd, &ahd_tailq, links) {
|
|
||||||
ahd_dev_softc_t list_pci;
|
|
||||||
ahd_dev_softc_t pci;
|
|
||||||
|
|
||||||
list_pci = list_ahd->dev_softc;
|
|
||||||
pci = ahd->dev_softc;
|
|
||||||
if (ahd_get_pci_slot(list_pci) == ahd_get_pci_slot(pci)
|
|
||||||
&& ahd_get_pci_bus(list_pci) == ahd_get_pci_bus(pci)) {
|
|
||||||
struct ahd_softc *master;
|
|
||||||
struct ahd_softc *slave;
|
|
||||||
|
|
||||||
if (ahd_get_pci_function(list_pci) == 0) {
|
|
||||||
master = list_ahd;
|
|
||||||
slave = ahd;
|
|
||||||
} else {
|
|
||||||
master = ahd;
|
|
||||||
slave = list_ahd;
|
|
||||||
}
|
|
||||||
slave->flags &= ~AHD_BIOS_ENABLED;
|
|
||||||
slave->flags |=
|
|
||||||
master->flags & AHD_BIOS_ENABLED;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Insertion sort into our list of softcs.
|
|
||||||
*/
|
|
||||||
list_ahd = TAILQ_FIRST(&ahd_tailq);
|
|
||||||
while (list_ahd != NULL
|
|
||||||
&& ahd_softc_comp(ahd, list_ahd) <= 0)
|
|
||||||
list_ahd = TAILQ_NEXT(list_ahd, links);
|
|
||||||
if (list_ahd != NULL)
|
|
||||||
TAILQ_INSERT_BEFORE(list_ahd, ahd, links);
|
|
||||||
else
|
|
||||||
TAILQ_INSERT_TAIL(&ahd_tailq, ahd, links);
|
|
||||||
ahd->init_level++;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Verify that the passed in softc pointer is for a
|
|
||||||
* controller that is still configured.
|
|
||||||
*/
|
|
||||||
struct ahd_softc *
|
|
||||||
ahd_find_softc(struct ahd_softc *ahd)
|
|
||||||
{
|
|
||||||
struct ahd_softc *list_ahd;
|
|
||||||
|
|
||||||
TAILQ_FOREACH(list_ahd, &ahd_tailq, links) {
|
|
||||||
if (list_ahd == ahd)
|
|
||||||
return (ahd);
|
|
||||||
}
|
|
||||||
return (NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
ahd_set_unit(struct ahd_softc *ahd, int unit)
|
ahd_set_unit(struct ahd_softc *ahd, int unit)
|
||||||
{
|
{
|
||||||
|
@ -7902,18 +7832,10 @@ ahd_reset_channel(struct ahd_softc *ahd, char channel, int initiate_reset)
|
||||||
static void
|
static void
|
||||||
ahd_reset_poll(void *arg)
|
ahd_reset_poll(void *arg)
|
||||||
{
|
{
|
||||||
struct ahd_softc *ahd;
|
struct ahd_softc *ahd = arg;
|
||||||
u_int scsiseq1;
|
u_int scsiseq1;
|
||||||
u_long l;
|
|
||||||
u_long s;
|
u_long s;
|
||||||
|
|
||||||
ahd_list_lock(&l);
|
|
||||||
ahd = ahd_find_softc((struct ahd_softc *)arg);
|
|
||||||
if (ahd == NULL) {
|
|
||||||
printf("ahd_reset_poll: Instance %p no longer exists\n", arg);
|
|
||||||
ahd_list_unlock(&l);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
ahd_lock(ahd, &s);
|
ahd_lock(ahd, &s);
|
||||||
ahd_pause(ahd);
|
ahd_pause(ahd);
|
||||||
ahd_update_modes(ahd);
|
ahd_update_modes(ahd);
|
||||||
|
@ -7924,7 +7846,6 @@ ahd_reset_poll(void *arg)
|
||||||
ahd_reset_poll, ahd);
|
ahd_reset_poll, ahd);
|
||||||
ahd_unpause(ahd);
|
ahd_unpause(ahd);
|
||||||
ahd_unlock(ahd, &s);
|
ahd_unlock(ahd, &s);
|
||||||
ahd_list_unlock(&l);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7936,25 +7857,16 @@ ahd_reset_poll(void *arg)
|
||||||
ahd->flags &= ~AHD_RESET_POLL_ACTIVE;
|
ahd->flags &= ~AHD_RESET_POLL_ACTIVE;
|
||||||
ahd_unlock(ahd, &s);
|
ahd_unlock(ahd, &s);
|
||||||
ahd_release_simq(ahd);
|
ahd_release_simq(ahd);
|
||||||
ahd_list_unlock(&l);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**************************** Statistics Processing ***************************/
|
/**************************** Statistics Processing ***************************/
|
||||||
static void
|
static void
|
||||||
ahd_stat_timer(void *arg)
|
ahd_stat_timer(void *arg)
|
||||||
{
|
{
|
||||||
struct ahd_softc *ahd;
|
struct ahd_softc *ahd = arg;
|
||||||
u_long l;
|
|
||||||
u_long s;
|
u_long s;
|
||||||
int enint_coal;
|
int enint_coal;
|
||||||
|
|
||||||
ahd_list_lock(&l);
|
|
||||||
ahd = ahd_find_softc((struct ahd_softc *)arg);
|
|
||||||
if (ahd == NULL) {
|
|
||||||
printf("ahd_stat_timer: Instance %p no longer exists\n", arg);
|
|
||||||
ahd_list_unlock(&l);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
ahd_lock(ahd, &s);
|
ahd_lock(ahd, &s);
|
||||||
|
|
||||||
enint_coal = ahd->hs_mailbox & ENINT_COALESCE;
|
enint_coal = ahd->hs_mailbox & ENINT_COALESCE;
|
||||||
|
@ -7981,7 +7893,6 @@ ahd_stat_timer(void *arg)
|
||||||
ahd_timer_reset(&ahd->stat_timer, AHD_STAT_UPDATE_US,
|
ahd_timer_reset(&ahd->stat_timer, AHD_STAT_UPDATE_US,
|
||||||
ahd_stat_timer, ahd);
|
ahd_stat_timer, ahd);
|
||||||
ahd_unlock(ahd, &s);
|
ahd_unlock(ahd, &s);
|
||||||
ahd_list_unlock(&l);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************** Status Processing *****************************/
|
/****************************** Status Processing *****************************/
|
||||||
|
@ -8745,16 +8656,6 @@ ahd_probe_stack_size(struct ahd_softc *ahd)
|
||||||
return (last_probe);
|
return (last_probe);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
ahd_dump_all_cards_state(void)
|
|
||||||
{
|
|
||||||
struct ahd_softc *list_ahd;
|
|
||||||
|
|
||||||
TAILQ_FOREACH(list_ahd, &ahd_tailq, links) {
|
|
||||||
ahd_dump_card_state(list_ahd);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
int
|
||||||
ahd_print_register(ahd_reg_parse_entry_t *table, u_int num_entries,
|
ahd_print_register(ahd_reg_parse_entry_t *table, u_int num_entries,
|
||||||
const char *name, u_int address, u_int value,
|
const char *name, u_int address, u_int value,
|
||||||
|
|
|
@ -59,11 +59,6 @@ static struct scsi_transport_template *ahd_linux_transport_template = NULL;
|
||||||
#include <linux/blkdev.h> /* For block_size() */
|
#include <linux/blkdev.h> /* For block_size() */
|
||||||
#include <linux/delay.h> /* For ssleep/msleep */
|
#include <linux/delay.h> /* For ssleep/msleep */
|
||||||
|
|
||||||
/*
|
|
||||||
* Lock protecting manipulation of the ahd softc list.
|
|
||||||
*/
|
|
||||||
spinlock_t ahd_list_spinlock;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Bucket size for counting good commands in between bad ones.
|
* Bucket size for counting good commands in between bad ones.
|
||||||
*/
|
*/
|
||||||
|
@ -302,13 +297,6 @@ static uint32_t aic79xx_pci_parity = ~0;
|
||||||
*/
|
*/
|
||||||
uint32_t aic79xx_allow_memio = ~0;
|
uint32_t aic79xx_allow_memio = ~0;
|
||||||
|
|
||||||
/*
|
|
||||||
* aic79xx_detect() has been run, so register all device arrivals
|
|
||||||
* immediately with the system rather than deferring to the sorted
|
|
||||||
* attachment performed by aic79xx_detect().
|
|
||||||
*/
|
|
||||||
int aic79xx_detect_complete;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* So that we can set how long each device is given as a selection timeout.
|
* So that we can set how long each device is given as a selection timeout.
|
||||||
* The table of values goes like this:
|
* The table of values goes like this:
|
||||||
|
@ -387,7 +375,9 @@ static void ahd_linux_setup_tag_info_global(char *p);
|
||||||
static aic_option_callback_t ahd_linux_setup_tag_info;
|
static aic_option_callback_t ahd_linux_setup_tag_info;
|
||||||
static aic_option_callback_t ahd_linux_setup_iocell_info;
|
static aic_option_callback_t ahd_linux_setup_iocell_info;
|
||||||
static int aic79xx_setup(char *c);
|
static int aic79xx_setup(char *c);
|
||||||
static int ahd_linux_next_unit(void);
|
|
||||||
|
static int ahd_linux_unit;
|
||||||
|
|
||||||
|
|
||||||
/****************************** Inlines ***************************************/
|
/****************************** Inlines ***************************************/
|
||||||
static __inline void ahd_linux_unmap_scb(struct ahd_softc*, struct scb*);
|
static __inline void ahd_linux_unmap_scb(struct ahd_softc*, struct scb*);
|
||||||
|
@ -417,50 +407,6 @@ ahd_linux_unmap_scb(struct ahd_softc *ahd, struct scb *scb)
|
||||||
#define BUILD_SCSIID(ahd, cmd) \
|
#define BUILD_SCSIID(ahd, cmd) \
|
||||||
((((cmd)->device->id << TID_SHIFT) & TID) | (ahd)->our_id)
|
((((cmd)->device->id << TID_SHIFT) & TID) | (ahd)->our_id)
|
||||||
|
|
||||||
/*
|
|
||||||
* Try to detect an Adaptec 79XX controller.
|
|
||||||
*/
|
|
||||||
static int
|
|
||||||
ahd_linux_detect(struct scsi_host_template *template)
|
|
||||||
{
|
|
||||||
struct ahd_softc *ahd;
|
|
||||||
int found;
|
|
||||||
int error = 0;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* If we've been passed any parameters, process them now.
|
|
||||||
*/
|
|
||||||
if (aic79xx)
|
|
||||||
aic79xx_setup(aic79xx);
|
|
||||||
|
|
||||||
template->proc_name = "aic79xx";
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Initialize our softc list lock prior to
|
|
||||||
* probing for any adapters.
|
|
||||||
*/
|
|
||||||
ahd_list_lockinit();
|
|
||||||
|
|
||||||
#ifdef CONFIG_PCI
|
|
||||||
error = ahd_linux_pci_init();
|
|
||||||
if (error)
|
|
||||||
return error;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Register with the SCSI layer all
|
|
||||||
* controllers we've found.
|
|
||||||
*/
|
|
||||||
found = 0;
|
|
||||||
TAILQ_FOREACH(ahd, &ahd_tailq, links) {
|
|
||||||
|
|
||||||
if (ahd_linux_register_host(ahd, template) == 0)
|
|
||||||
found++;
|
|
||||||
}
|
|
||||||
aic79xx_detect_complete++;
|
|
||||||
return found;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Return a string describing the driver.
|
* Return a string describing the driver.
|
||||||
*/
|
*/
|
||||||
|
@ -760,6 +706,7 @@ ahd_linux_bus_reset(struct scsi_cmnd *cmd)
|
||||||
struct scsi_host_template aic79xx_driver_template = {
|
struct scsi_host_template aic79xx_driver_template = {
|
||||||
.module = THIS_MODULE,
|
.module = THIS_MODULE,
|
||||||
.name = "aic79xx",
|
.name = "aic79xx",
|
||||||
|
.proc_name = "aic79xx",
|
||||||
.proc_info = ahd_linux_proc_info,
|
.proc_info = ahd_linux_proc_info,
|
||||||
.info = ahd_linux_info,
|
.info = ahd_linux_info,
|
||||||
.queuecommand = ahd_linux_queue,
|
.queuecommand = ahd_linux_queue,
|
||||||
|
@ -1072,7 +1019,7 @@ ahd_linux_register_host(struct ahd_softc *ahd, struct scsi_host_template *templa
|
||||||
host->max_lun = AHD_NUM_LUNS;
|
host->max_lun = AHD_NUM_LUNS;
|
||||||
host->max_channel = 0;
|
host->max_channel = 0;
|
||||||
host->sg_tablesize = AHD_NSEG;
|
host->sg_tablesize = AHD_NSEG;
|
||||||
ahd_set_unit(ahd, ahd_linux_next_unit());
|
ahd_set_unit(ahd, ahd_linux_unit++);
|
||||||
sprintf(buf, "scsi%d", host->host_no);
|
sprintf(buf, "scsi%d", host->host_no);
|
||||||
new_name = malloc(strlen(buf) + 1, M_DEVBUF, M_NOWAIT);
|
new_name = malloc(strlen(buf) + 1, M_DEVBUF, M_NOWAIT);
|
||||||
if (new_name != NULL) {
|
if (new_name != NULL) {
|
||||||
|
@ -1100,29 +1047,6 @@ ahd_linux_get_memsize(void)
|
||||||
return ((uint64_t)si.totalram << PAGE_SHIFT);
|
return ((uint64_t)si.totalram << PAGE_SHIFT);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* Find the smallest available unit number to use
|
|
||||||
* for a new device. We don't just use a static
|
|
||||||
* count to handle the "repeated hot-(un)plug"
|
|
||||||
* scenario.
|
|
||||||
*/
|
|
||||||
static int
|
|
||||||
ahd_linux_next_unit(void)
|
|
||||||
{
|
|
||||||
struct ahd_softc *ahd;
|
|
||||||
int unit;
|
|
||||||
|
|
||||||
unit = 0;
|
|
||||||
retry:
|
|
||||||
TAILQ_FOREACH(ahd, &ahd_tailq, links) {
|
|
||||||
if (ahd->unit == unit) {
|
|
||||||
unit++;
|
|
||||||
goto retry;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return (unit);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Place the SCSI bus into a known state by either resetting it,
|
* Place the SCSI bus into a known state by either resetting it,
|
||||||
* or forcing transfer negotiations on the next command to any
|
* or forcing transfer negotiations on the next command to any
|
||||||
|
@ -2755,23 +2679,31 @@ static struct spi_function_template ahd_linux_transport_functions = {
|
||||||
.show_hold_mcs = 1,
|
.show_hold_mcs = 1,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static int __init
|
static int __init
|
||||||
ahd_linux_init(void)
|
ahd_linux_init(void)
|
||||||
{
|
{
|
||||||
ahd_linux_transport_template = spi_attach_transport(&ahd_linux_transport_functions);
|
int error = 0;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If we've been passed any parameters, process them now.
|
||||||
|
*/
|
||||||
|
if (aic79xx)
|
||||||
|
aic79xx_setup(aic79xx);
|
||||||
|
|
||||||
|
ahd_linux_transport_template =
|
||||||
|
spi_attach_transport(&ahd_linux_transport_functions);
|
||||||
if (!ahd_linux_transport_template)
|
if (!ahd_linux_transport_template)
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
|
|
||||||
scsi_transport_reserve_target(ahd_linux_transport_template,
|
scsi_transport_reserve_target(ahd_linux_transport_template,
|
||||||
sizeof(struct ahd_linux_target));
|
sizeof(struct ahd_linux_target));
|
||||||
scsi_transport_reserve_device(ahd_linux_transport_template,
|
scsi_transport_reserve_device(ahd_linux_transport_template,
|
||||||
sizeof(struct ahd_linux_device));
|
sizeof(struct ahd_linux_device));
|
||||||
if (ahd_linux_detect(&aic79xx_driver_template) > 0)
|
|
||||||
return 0;
|
|
||||||
spi_release_transport(ahd_linux_transport_template);
|
|
||||||
|
|
||||||
return -ENODEV;
|
error = ahd_linux_pci_init();
|
||||||
|
if (error)
|
||||||
|
spi_release_transport(ahd_linux_transport_template);
|
||||||
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void __exit
|
static void __exit
|
||||||
|
|
|
@ -120,7 +120,6 @@ typedef struct scsi_cmnd *ahd_io_ctx_t;
|
||||||
|
|
||||||
/************************* Configuration Data *********************************/
|
/************************* Configuration Data *********************************/
|
||||||
extern uint32_t aic79xx_allow_memio;
|
extern uint32_t aic79xx_allow_memio;
|
||||||
extern int aic79xx_detect_complete;
|
|
||||||
extern struct scsi_host_template aic79xx_driver_template;
|
extern struct scsi_host_template aic79xx_driver_template;
|
||||||
|
|
||||||
/***************************** Bus Space/DMA **********************************/
|
/***************************** Bus Space/DMA **********************************/
|
||||||
|
@ -532,17 +531,6 @@ void ahd_format_transinfo(struct info_str *info,
|
||||||
struct ahd_transinfo *tinfo);
|
struct ahd_transinfo *tinfo);
|
||||||
|
|
||||||
/******************************** Locking *************************************/
|
/******************************** Locking *************************************/
|
||||||
/* Lock protecting internal data structures */
|
|
||||||
static __inline void ahd_lockinit(struct ahd_softc *);
|
|
||||||
static __inline void ahd_lock(struct ahd_softc *, unsigned long *flags);
|
|
||||||
static __inline void ahd_unlock(struct ahd_softc *, unsigned long *flags);
|
|
||||||
|
|
||||||
/* Lock held during ahd_list manipulation and ahd softc frees */
|
|
||||||
extern spinlock_t ahd_list_spinlock;
|
|
||||||
static __inline void ahd_list_lockinit(void);
|
|
||||||
static __inline void ahd_list_lock(unsigned long *flags);
|
|
||||||
static __inline void ahd_list_unlock(unsigned long *flags);
|
|
||||||
|
|
||||||
static __inline void
|
static __inline void
|
||||||
ahd_lockinit(struct ahd_softc *ahd)
|
ahd_lockinit(struct ahd_softc *ahd)
|
||||||
{
|
{
|
||||||
|
@ -561,24 +549,6 @@ ahd_unlock(struct ahd_softc *ahd, unsigned long *flags)
|
||||||
spin_unlock_irqrestore(&ahd->platform_data->spin_lock, *flags);
|
spin_unlock_irqrestore(&ahd->platform_data->spin_lock, *flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
static __inline void
|
|
||||||
ahd_list_lockinit(void)
|
|
||||||
{
|
|
||||||
spin_lock_init(&ahd_list_spinlock);
|
|
||||||
}
|
|
||||||
|
|
||||||
static __inline void
|
|
||||||
ahd_list_lock(unsigned long *flags)
|
|
||||||
{
|
|
||||||
spin_lock_irqsave(&ahd_list_spinlock, *flags);
|
|
||||||
}
|
|
||||||
|
|
||||||
static __inline void
|
|
||||||
ahd_list_unlock(unsigned long *flags)
|
|
||||||
{
|
|
||||||
spin_unlock_irqrestore(&ahd_list_spinlock, *flags);
|
|
||||||
}
|
|
||||||
|
|
||||||
/******************************* PCI Definitions ******************************/
|
/******************************* PCI Definitions ******************************/
|
||||||
/*
|
/*
|
||||||
* PCIM_xxx: mask to locate subfield in register
|
* PCIM_xxx: mask to locate subfield in register
|
||||||
|
|
|
@ -92,27 +92,31 @@ struct pci_driver aic79xx_pci_driver = {
|
||||||
static void
|
static void
|
||||||
ahd_linux_pci_dev_remove(struct pci_dev *pdev)
|
ahd_linux_pci_dev_remove(struct pci_dev *pdev)
|
||||||
{
|
{
|
||||||
struct ahd_softc *ahd;
|
struct ahd_softc *ahd = pci_get_drvdata(pdev);
|
||||||
u_long l;
|
u_long s;
|
||||||
|
|
||||||
/*
|
ahd_lock(ahd, &s);
|
||||||
* We should be able to just perform
|
ahd_intr_enable(ahd, FALSE);
|
||||||
* the free directly, but check our
|
ahd_unlock(ahd, &s);
|
||||||
* list for extra sanity.
|
ahd_free(ahd);
|
||||||
*/
|
}
|
||||||
ahd_list_lock(&l);
|
|
||||||
ahd = ahd_find_softc((struct ahd_softc *)pci_get_drvdata(pdev));
|
|
||||||
if (ahd != NULL) {
|
|
||||||
u_long s;
|
|
||||||
|
|
||||||
TAILQ_REMOVE(&ahd_tailq, ahd, links);
|
static void
|
||||||
ahd_list_unlock(&l);
|
ahd_linux_pci_inherit_flags(struct ahd_softc *ahd)
|
||||||
ahd_lock(ahd, &s);
|
{
|
||||||
ahd_intr_enable(ahd, FALSE);
|
struct pci_dev *pdev = ahd->dev_softc, *master_pdev;
|
||||||
ahd_unlock(ahd, &s);
|
unsigned int master_devfn = PCI_DEVFN(PCI_SLOT(pdev->devfn), 0);
|
||||||
ahd_free(ahd);
|
|
||||||
} else
|
master_pdev = pci_get_slot(pdev->bus, master_devfn);
|
||||||
ahd_list_unlock(&l);
|
if (master_pdev) {
|
||||||
|
struct ahd_softc *master = pci_get_drvdata(master_pdev);
|
||||||
|
if (master) {
|
||||||
|
ahd->flags &= ~AHD_BIOS_ENABLED;
|
||||||
|
ahd->flags |= master->flags & AHD_BIOS_ENABLED;
|
||||||
|
} else
|
||||||
|
printk(KERN_ERR "aic79xx: no multichannel peer found!\n");
|
||||||
|
pci_dev_put(master_pdev);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
|
@ -125,22 +129,6 @@ ahd_linux_pci_dev_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
|
||||||
char *name;
|
char *name;
|
||||||
int error;
|
int error;
|
||||||
|
|
||||||
/*
|
|
||||||
* Some BIOSen report the same device multiple times.
|
|
||||||
*/
|
|
||||||
TAILQ_FOREACH(ahd, &ahd_tailq, links) {
|
|
||||||
struct pci_dev *probed_pdev;
|
|
||||||
|
|
||||||
probed_pdev = ahd->dev_softc;
|
|
||||||
if (probed_pdev->bus->number == pdev->bus->number
|
|
||||||
&& probed_pdev->devfn == pdev->devfn)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (ahd != NULL) {
|
|
||||||
/* Skip duplicate. */
|
|
||||||
return (-ENODEV);
|
|
||||||
}
|
|
||||||
|
|
||||||
pci = pdev;
|
pci = pdev;
|
||||||
entry = ahd_find_pci_device(pci);
|
entry = ahd_find_pci_device(pci);
|
||||||
if (entry == NULL)
|
if (entry == NULL)
|
||||||
|
@ -190,16 +178,17 @@ ahd_linux_pci_dev_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
|
||||||
ahd_free(ahd);
|
ahd_free(ahd);
|
||||||
return (-error);
|
return (-error);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Second Function PCI devices need to inherit some
|
||||||
|
* * settings from function 0.
|
||||||
|
*/
|
||||||
|
if ((ahd->features & AHD_MULTI_FUNC) && PCI_FUNC(pdev->devfn) != 0)
|
||||||
|
ahd_linux_pci_inherit_flags(ahd);
|
||||||
|
|
||||||
pci_set_drvdata(pdev, ahd);
|
pci_set_drvdata(pdev, ahd);
|
||||||
if (aic79xx_detect_complete) {
|
|
||||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
|
ahd_linux_register_host(ahd, &aic79xx_driver_template);
|
||||||
ahd_linux_register_host(ahd, &aic79xx_driver_template);
|
|
||||||
#else
|
|
||||||
printf("aic79xx: ignoring PCI device found after "
|
|
||||||
"initialization\n");
|
|
||||||
return (-ENODEV);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -283,7 +283,6 @@ int
|
||||||
ahd_pci_config(struct ahd_softc *ahd, struct ahd_pci_identity *entry)
|
ahd_pci_config(struct ahd_softc *ahd, struct ahd_pci_identity *entry)
|
||||||
{
|
{
|
||||||
struct scb_data *shared_scb_data;
|
struct scb_data *shared_scb_data;
|
||||||
u_long l;
|
|
||||||
u_int command;
|
u_int command;
|
||||||
uint32_t devconfig;
|
uint32_t devconfig;
|
||||||
uint16_t subvendor;
|
uint16_t subvendor;
|
||||||
|
@ -373,16 +372,9 @@ ahd_pci_config(struct ahd_softc *ahd, struct ahd_pci_identity *entry)
|
||||||
* Allow interrupts now that we are completely setup.
|
* Allow interrupts now that we are completely setup.
|
||||||
*/
|
*/
|
||||||
error = ahd_pci_map_int(ahd);
|
error = ahd_pci_map_int(ahd);
|
||||||
if (error != 0)
|
if (!error)
|
||||||
return (error);
|
ahd->init_level++;
|
||||||
|
return error;
|
||||||
ahd_list_lock(&l);
|
|
||||||
/*
|
|
||||||
* Link this softc in with all other ahd instances.
|
|
||||||
*/
|
|
||||||
ahd_softc_insert(ahd);
|
|
||||||
ahd_list_unlock(&l);
|
|
||||||
return (0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -285,21 +285,13 @@ int
|
||||||
ahd_linux_proc_info(struct Scsi_Host *shost, char *buffer, char **start,
|
ahd_linux_proc_info(struct Scsi_Host *shost, char *buffer, char **start,
|
||||||
off_t offset, int length, int inout)
|
off_t offset, int length, int inout)
|
||||||
{
|
{
|
||||||
struct ahd_softc *ahd;
|
struct ahd_softc *ahd = *(struct ahd_softc **)shost->hostdata;
|
||||||
struct info_str info;
|
struct info_str info;
|
||||||
char ahd_info[256];
|
char ahd_info[256];
|
||||||
u_long l;
|
|
||||||
u_int max_targ;
|
u_int max_targ;
|
||||||
u_int i;
|
u_int i;
|
||||||
int retval;
|
int retval;
|
||||||
|
|
||||||
retval = -EINVAL;
|
|
||||||
ahd_list_lock(&l);
|
|
||||||
ahd = ahd_find_softc(*(struct ahd_softc **)shost->hostdata);
|
|
||||||
|
|
||||||
if (ahd == NULL)
|
|
||||||
goto done;
|
|
||||||
|
|
||||||
/* Has data been written to the file? */
|
/* Has data been written to the file? */
|
||||||
if (inout == TRUE) {
|
if (inout == TRUE) {
|
||||||
retval = ahd_proc_write_seeprom(ahd, buffer, length);
|
retval = ahd_proc_write_seeprom(ahd, buffer, length);
|
||||||
|
@ -349,6 +341,5 @@ ahd_linux_proc_info(struct Scsi_Host *shost, char *buffer, char **start,
|
||||||
}
|
}
|
||||||
retval = info.pos > info.offset ? info.pos - info.offset : 0;
|
retval = info.pos > info.offset ? info.pos - info.offset : 0;
|
||||||
done:
|
done:
|
||||||
ahd_list_unlock(&l);
|
|
||||||
return (retval);
|
return (retval);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue