diff options
Diffstat (limited to 'drivers/scsi/aic94xx/aic94xx_seq.c')
-rw-r--r-- | drivers/scsi/aic94xx/aic94xx_seq.c | 45 |
1 files changed, 35 insertions, 10 deletions
diff --git a/drivers/scsi/aic94xx/aic94xx_seq.c b/drivers/scsi/aic94xx/aic94xx_seq.c index 845112539d05..eae7a247bece 100644 --- a/drivers/scsi/aic94xx/aic94xx_seq.c +++ b/drivers/scsi/aic94xx/aic94xx_seq.c | |||
@@ -810,6 +810,8 @@ static void asd_init_lseq_mdp(struct asd_ha_struct *asd_ha, int lseq) | |||
810 | /* No delay for the first NOTIFY to be sent to the attached target. */ | 810 | /* No delay for the first NOTIFY to be sent to the attached target. */ |
811 | asd_write_reg_word(asd_ha, LmSEQ_NOTIFY_TIMER_DOWN_COUNT(lseq), | 811 | asd_write_reg_word(asd_ha, LmSEQ_NOTIFY_TIMER_DOWN_COUNT(lseq), |
812 | ASD_NOTIFY_DOWN_COUNT); | 812 | ASD_NOTIFY_DOWN_COUNT); |
813 | asd_write_reg_word(asd_ha, LmSEQ_NOTIFY_TIMER_INITIAL_COUNT(lseq), | ||
814 | ASD_NOTIFY_DOWN_COUNT); | ||
813 | 815 | ||
814 | /* LSEQ Mode dependent, mode 0 and 1, page 1 setup. */ | 816 | /* LSEQ Mode dependent, mode 0 and 1, page 1 setup. */ |
815 | for (i = 0; i < 2; i++) { | 817 | for (i = 0; i < 2; i++) { |
@@ -907,6 +909,16 @@ static void asd_init_scb_sites(struct asd_ha_struct *asd_ha) | |||
907 | for (i = 0; i < ASD_SCB_SIZE; i += 4) | 909 | for (i = 0; i < ASD_SCB_SIZE; i += 4) |
908 | asd_scbsite_write_dword(asd_ha, site_no, i, 0); | 910 | asd_scbsite_write_dword(asd_ha, site_no, i, 0); |
909 | 911 | ||
912 | /* Initialize SCB Site Opcode field to invalid. */ | ||
913 | asd_scbsite_write_byte(asd_ha, site_no, | ||
914 | offsetof(struct scb_header, opcode), | ||
915 | 0xFF); | ||
916 | |||
917 | /* Initialize SCB Site Flags field to mean a response | ||
918 | * frame has been received. This means inadvertent | ||
919 | * frames received to be dropped. */ | ||
920 | asd_scbsite_write_byte(asd_ha, site_no, 0x49, 0x01); | ||
921 | |||
910 | /* Workaround needed by SEQ to fix a SATA issue is to exclude | 922 | /* Workaround needed by SEQ to fix a SATA issue is to exclude |
911 | * certain SCB sites from the free list. */ | 923 | * certain SCB sites from the free list. */ |
912 | if (!SCB_SITE_VALID(site_no)) | 924 | if (!SCB_SITE_VALID(site_no)) |
@@ -922,16 +934,6 @@ static void asd_init_scb_sites(struct asd_ha_struct *asd_ha) | |||
922 | /* Q_NEXT field of the last SCB is invalidated. */ | 934 | /* Q_NEXT field of the last SCB is invalidated. */ |
923 | asd_scbsite_write_word(asd_ha, site_no, 0, first_scb_site_no); | 935 | asd_scbsite_write_word(asd_ha, site_no, 0, first_scb_site_no); |
924 | 936 | ||
925 | /* Initialize SCB Site Opcode field to invalid. */ | ||
926 | asd_scbsite_write_byte(asd_ha, site_no, | ||
927 | offsetof(struct scb_header, opcode), | ||
928 | 0xFF); | ||
929 | |||
930 | /* Initialize SCB Site Flags field to mean a response | ||
931 | * frame has been received. This means inadvertent | ||
932 | * frames received to be dropped. */ | ||
933 | asd_scbsite_write_byte(asd_ha, site_no, 0x49, 0x01); | ||
934 | |||
935 | first_scb_site_no = site_no; | 937 | first_scb_site_no = site_no; |
936 | max_scbs++; | 938 | max_scbs++; |
937 | } | 939 | } |
@@ -1173,6 +1175,16 @@ static void asd_init_ddb_0(struct asd_ha_struct *asd_ha) | |||
1173 | set_bit(0, asd_ha->hw_prof.ddb_bitmap); | 1175 | set_bit(0, asd_ha->hw_prof.ddb_bitmap); |
1174 | } | 1176 | } |
1175 | 1177 | ||
1178 | static void asd_seq_init_ddb_sites(struct asd_ha_struct *asd_ha) | ||
1179 | { | ||
1180 | unsigned int i; | ||
1181 | unsigned int ddb_site; | ||
1182 | |||
1183 | for (ddb_site = 0 ; ddb_site < ASD_MAX_DDBS; ddb_site++) | ||
1184 | for (i = 0; i < sizeof(struct asd_ddb_ssp_smp_target_port); i+= 4) | ||
1185 | asd_ddbsite_write_dword(asd_ha, ddb_site, i, 0); | ||
1186 | } | ||
1187 | |||
1176 | /** | 1188 | /** |
1177 | * asd_seq_setup_seqs -- setup and initialize central and link sequencers | 1189 | * asd_seq_setup_seqs -- setup and initialize central and link sequencers |
1178 | * @asd_ha: pointer to host adapter structure | 1190 | * @asd_ha: pointer to host adapter structure |
@@ -1182,6 +1194,9 @@ static void asd_seq_setup_seqs(struct asd_ha_struct *asd_ha) | |||
1182 | int lseq; | 1194 | int lseq; |
1183 | u8 lseq_mask; | 1195 | u8 lseq_mask; |
1184 | 1196 | ||
1197 | /* Initialize DDB sites */ | ||
1198 | asd_seq_init_ddb_sites(asd_ha); | ||
1199 | |||
1185 | /* Initialize SCB sites. Done first to compute some values which | 1200 | /* Initialize SCB sites. Done first to compute some values which |
1186 | * the rest of the init code depends on. */ | 1201 | * the rest of the init code depends on. */ |
1187 | asd_init_scb_sites(asd_ha); | 1202 | asd_init_scb_sites(asd_ha); |
@@ -1232,6 +1247,13 @@ static int asd_seq_start_lseq(struct asd_ha_struct *asd_ha, int lseq) | |||
1232 | return asd_seq_unpause_lseq(asd_ha, lseq); | 1247 | return asd_seq_unpause_lseq(asd_ha, lseq); |
1233 | } | 1248 | } |
1234 | 1249 | ||
1250 | int asd_release_firmware(void) | ||
1251 | { | ||
1252 | if (sequencer_fw) | ||
1253 | release_firmware(sequencer_fw); | ||
1254 | return 0; | ||
1255 | } | ||
1256 | |||
1235 | static int asd_request_firmware(struct asd_ha_struct *asd_ha) | 1257 | static int asd_request_firmware(struct asd_ha_struct *asd_ha) |
1236 | { | 1258 | { |
1237 | int err, i; | 1259 | int err, i; |
@@ -1375,7 +1397,9 @@ void asd_update_port_links(struct asd_ha_struct *asd_ha, struct asd_phy *phy) | |||
1375 | u8 phy_is_up; | 1397 | u8 phy_is_up; |
1376 | u8 mask; | 1398 | u8 mask; |
1377 | int i, err; | 1399 | int i, err; |
1400 | unsigned long flags; | ||
1378 | 1401 | ||
1402 | spin_lock_irqsave(&asd_ha->hw_prof.ddb_lock, flags); | ||
1379 | for_each_phy(phy_mask, mask, i) | 1403 | for_each_phy(phy_mask, mask, i) |
1380 | asd_ddbsite_write_byte(asd_ha, 0, | 1404 | asd_ddbsite_write_byte(asd_ha, 0, |
1381 | offsetof(struct asd_ddb_seq_shared, | 1405 | offsetof(struct asd_ddb_seq_shared, |
@@ -1395,6 +1419,7 @@ void asd_update_port_links(struct asd_ha_struct *asd_ha, struct asd_phy *phy) | |||
1395 | break; | 1419 | break; |
1396 | } | 1420 | } |
1397 | } | 1421 | } |
1422 | spin_unlock_irqrestore(&asd_ha->hw_prof.ddb_lock, flags); | ||
1398 | 1423 | ||
1399 | if (err) | 1424 | if (err) |
1400 | asd_printk("couldn't update DDB 0:error:%d\n", err); | 1425 | asd_printk("couldn't update DDB 0:error:%d\n", err); |